Files
memind/scripts/scaffold-memory-v2-backend.mjs
2026-07-03 09:46:03 +08:00

102 lines
3.2 KiB
JavaScript

#!/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;
});
}