#!/usr/bin/env node /** * optimize-lens CLI — feeds the v5.7 optimization lens (CA-OPT) `/config-audit * optimize` command. It produces the two halves of the hybrid motor as one JSON * payload: * * 1. `deterministic` — the OPT scanner's high-precision findings (CA-OPT-001: * a long numbered procedure in CLAUDE.md → skill). Already part of the * orchestrated audit; surfaced here so /optimize is a complete view. * 2. `candidates` — recall-oriented prose-judgment candidates from the * lens-prefilter (lifecycle → hook, unscoped path-specific → rule, "never" * → permission), each stamped with the CONFIRMED register entry it might fit * (claim / recommendation / source / severity). The opus * optimization-lens-agent is the precision gate over these. * * Only CONFIRMED register entries are attached (Verifiseringsplikt); a candidate * whose register rule is missing or unconfirmed is dropped, so the agent never * sees an unverifiable recommendation. * * Usage: * node optimize-lens-cli.mjs [path] [--output-file ] [--global] * * Exit codes: 0=ok, 3=unrecoverable error. Zero external dependencies. */ import { resolve } from 'node:path'; import { writeFile, readFile, stat } from 'node:fs/promises'; import { discoverConfigFiles } from './lib/file-discovery.mjs'; import { resetCounter } from './lib/output.mjs'; import { parseFrontmatter } from './lib/yaml-parser.mjs'; import { loadRegister, getEntry } from './lib/best-practices-register.mjs'; import { prefilterClaudeMd, LENS_DETECTORS } from './lib/lens-prefilter.mjs'; import { scan as optScan } from './optimization-lens-scanner.mjs'; /** Confirmed register entry for `id`, or null. */ function confirmedEntry(register, id) { const e = getEntry(register, id); return e && e.confidence === 'confirmed' ? e : null; } async function main() { const args = process.argv.slice(2); let targetPath = '.'; let outputFile = null; let includeGlobal = false; for (let i = 0; i < args.length; i++) { if (args[i] === '--global') includeGlobal = true; else if (args[i] === '--output-file' && args[i + 1]) outputFile = args[++i]; else if (!args[i].startsWith('-')) targetPath = args[i]; } const absPath = resolve(targetPath); try { const s = await stat(absPath); if (!s.isDirectory()) { process.stderr.write(`Error: ${absPath} is not a directory\n`); process.exit(3); } } catch { process.stderr.write(`Error: path does not exist: ${absPath}\n`); process.exit(3); } // Load the register once; tolerate its absence (deterministic half still runs). let register = null; try { register = loadRegister(); } catch { register = null; } resetCounter(); const discovery = await discoverConfigFiles(absPath, { includeGlobal }); // ── Deterministic half: the OPT scanner (CA-OPT-001) ── const opt = await optScan(absPath, discovery); // ── Recall half: prose-judgment candidates from the pre-filter ── const claudeMdFiles = (discovery.files || []).filter((f) => f.type === 'claude-md'); const candidates = []; for (const file of claudeMdFiles) { let content; try { content = await readFile(file.absPath, 'utf-8'); } catch { continue; } const parsed = parseFrontmatter(content); const body = parsed.body || content; const bodyStartLine = parsed.bodyStartLine || 1; for (const cand of prefilterClaudeMd(body)) { const entry = register ? confirmedEntry(register, cand.registerId) : null; if (!entry) continue; // never surface an unverifiable recommendation candidates.push({ file: file.relPath || file.absPath, line: bodyStartLine - 1 + cand.line, lensCheck: cand.lensCheck, mechanism: cand.mechanism, signalText: cand.text, register: { id: entry.id, claim: entry.claim, recommendation: entry.recommendation || null, severity: entry.severity || 'low', source: entry.source, }, }); } } // The CONFIRMED prose-judgment entries, so the agent has full provenance even // for a detector class that produced no candidates this run. const registerEntries = register ? LENS_DETECTORS.map((d) => confirmedEntry(register, d.registerId)) .filter(Boolean) .map((e) => ({ id: e.id, lensCheck: e.lensCheck, claim: e.claim, recommendation: e.recommendation || null, mechanism: e.mechanism || null, severity: e.severity || 'low', source: e.source, })) : []; const payload = { status: 'ok', target: absPath, deterministic: opt.findings || [], candidates, register: registerEntries, counts: { deterministic: (opt.findings || []).length, candidates: candidates.length, byLensCheck: candidates.reduce((acc, c) => { acc[c.lensCheck] = (acc[c.lensCheck] || 0) + 1; return acc; }, {}), }, }; const json = JSON.stringify(payload, null, 2); if (outputFile) { await writeFile(outputFile, json, 'utf-8'); } if (!outputFile) { process.stdout.write(json + '\n'); } } const isDirectRun = process.argv[1] && resolve(process.argv[1]) === resolve(new URL(import.meta.url).pathname); if (isDirectRun) { main().catch((err) => { process.stderr.write(`Fatal: ${err.message}\n`); process.exit(3); }); }