#!/usr/bin/env node import fs from 'node:fs/promises'; import path from 'node:path'; import { normalizeMemoryV2AdapterScaffoldOptions, renderMemoryV2AdapterScaffold, } from '../memory-v2-adapter-scaffold.mjs'; function usage() { return `Usage: node scripts/scaffold-memory-v2-backend.mjs --name --category --capability [options] Options: --name Backend name, normalized to kebab-case. --category semantic | extraction | lifecycle | behavior | policy. --role Backend role. Default: optional-plugin. --capability resolve | write | compact. Repeatable. --flag Feature flag. Default: MEMORY__ENABLED. --out Output path. Default: memory-v2-.mjs. --write Write file. Default is dry-run to stdout. -h, --help Show this help. `; } export function parseMemoryV2ScaffoldArgs(argv = []) { const options = { name: null, category: null, role: 'optional-plugin', capabilities: [], flag: null, out: null, write: false, help: false, }; for (let i = 0; i < argv.length; i += 1) { const arg = argv[i]; if (arg === '--name') { options.name = argv[++i] ?? ''; } else if (arg === '--category') { options.category = argv[++i] ?? ''; } else if (arg === '--role') { options.role = argv[++i] ?? ''; } else if (arg === '--capability') { options.capabilities.push(argv[++i] ?? ''); } else if (arg === '--flag') { options.flag = argv[++i] ?? ''; } else if (arg === '--out') { options.out = argv[++i] ?? ''; } else if (arg === '--write') { options.write = true; } else if (arg === '-h' || arg === '--help') { options.help = true; } else { throw new Error(`Unknown argument: ${arg}`); } } return options; } export async function runMemoryV2ScaffoldCli({ argv = process.argv.slice(2), stdout = process.stdout, cwd = process.cwd(), } = {}) { const parsed = parseMemoryV2ScaffoldArgs(argv); if (parsed.help) { stdout.write(usage()); return { ok: true, mode: 'help' }; } const normalized = normalizeMemoryV2AdapterScaffoldOptions(parsed); const source = renderMemoryV2AdapterScaffold(normalized); const outPath = parsed.out || `memory-v2-${normalized.name}.mjs`; if (!parsed.write) { stdout.write(source); return { ok: true, mode: 'dry-run', outPath }; } const absoluteOut = path.resolve(cwd, outPath); await fs.mkdir(path.dirname(absoluteOut), { recursive: true }); try { await fs.writeFile(absoluteOut, source, { encoding: 'utf8', flag: 'wx' }); } catch (err) { if (err?.code === 'EEXIST') { throw new Error(`Refusing to overwrite existing adapter: ${absoluteOut}`); } throw err; } stdout.write(`Memory V2 backend scaffold created: ${absoluteOut}\n`); return { ok: true, mode: 'write', outPath: absoluteOut }; } if (import.meta.url === `file://${process.argv[1]}`) { runMemoryV2ScaffoldCli().then((result) => { process.exitCode = result.ok ? 0 : 1; }).catch((err) => { console.error(err instanceof Error ? err.message : err); process.exitCode = 1; }); }