Merge Memory V2 runtime facade
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
#!/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 <backend> --category <category> --capability <op> [options]
|
||||
|
||||
Options:
|
||||
--name <name> Backend name, normalized to kebab-case.
|
||||
--category <category> semantic | extraction | lifecycle | behavior | policy.
|
||||
--role <role> Backend role. Default: optional-plugin.
|
||||
--capability <op> resolve | write | compact. Repeatable.
|
||||
--flag <ENV_FLAG> Feature flag. Default: MEMORY_<NAME>_ENABLED.
|
||||
--out <path> Output path. Default: memory-v2-<name>.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;
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user