Files
memind/scripts/auto-review-memory-v2-candidates.mjs
T
john 6f3e53a56a feat(memory-v2): close Phase A with auto-review, product events, and H5 recall UI.
Add candidate auto-review pipeline, shadow audit tooling, admin metrics page,
and user-visible memory recall hints in chat with phase-a readiness checks.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-01 17:14:06 +08:00

73 lines
2.5 KiB
JavaScript

#!/usr/bin/env node
import { pathToFileURL } from 'node:url';
import { createDbPool, isDatabaseConfigured } from '../db.mjs';
import { runCandidateAutoReviewBatch } from '../memory-v2-candidate-auto-review.mjs';
function usage() {
return [
'Usage: node scripts/auto-review-memory-v2-candidates.mjs [--apply] [--user-id <id>] [--limit <n>] [--json]',
'',
'Default is dry-run summary against pending candidates.',
].join('\n');
}
function parseArgs(argv) {
const options = { apply: false, userId: null, limit: 200, json: false, help: false };
for (let index = 0; index < argv.length; index += 1) {
const arg = argv[index];
if (arg === '--help' || arg === '-h') options.help = true;
else if (arg === '--apply') options.apply = true;
else if (arg === '--json') options.json = true;
else if (arg === '--user-id') options.userId = String(argv[++index] ?? '').trim() || null;
else if (arg === '--limit') options.limit = Number(argv[++index]);
else throw new Error(`Unknown argument: ${arg}`);
}
return options;
}
export async function runAutoReviewMemoryV2CandidatesCli(
argv = process.argv.slice(2),
env = process.env,
) {
const options = parseArgs(argv);
if (options.help) {
console.log(usage());
return { ok: true, mode: 'help' };
}
if (!isDatabaseConfigured()) {
throw new Error('DATABASE_URL or MYSQL_* must be configured');
}
const pool = createDbPool();
try {
const result = await runCandidateAutoReviewBatch(pool, {
env,
userId: options.userId,
limit: options.limit,
reviewedBy: options.apply ? 'system:auto-review-cli' : 'system:auto-review-dry-run',
dryRun: !options.apply,
});
const payload = {
...result,
mode: options.apply ? 'apply' : 'dry-run',
note: options.apply
? 'Auto-review applied to pending candidates'
: 'Dry-run only; pass --apply to mutate candidate statuses',
};
if (options.json) console.log(JSON.stringify(payload, null, 2));
else {
console.log(`${payload.mode}: scanned=${payload.scanned ?? 0} accept=${payload.accepted ?? 0} reject=${payload.rejected ?? 0} pending=${payload.pending ?? 0}`);
if (payload.samples?.length) console.log(JSON.stringify(payload.samples, null, 2));
}
return payload;
} finally {
await pool.end?.();
}
}
if (import.meta.url === pathToFileURL(process.argv[1]).href) {
runAutoReviewMemoryV2CandidatesCli().catch((err) => {
console.error(err instanceof Error ? err.message : err);
process.exit(1);
});
}