35 lines
1.7 KiB
JavaScript
35 lines
1.7 KiB
JavaScript
#!/usr/bin/env node
|
|
/** enforce-verdict-surface — UserPromptSubmit. Дренит вердикты сессии → громкий баннер +
|
|
* императив подтверждения в additionalContext. Помечает pending-ack для Stop-стража.
|
|
* Fail-quiet: ошибка → пустой вывод, никогда не роняет ход. (SP1) */
|
|
import { drainVerdicts, markSurfaced } from './verdict-surface-store.mjs';
|
|
import { buildVerdictBanner } from './verdict-outcome-line.mjs';
|
|
|
|
const IMPERATIVE = 'ПЕРВОЙ строкой ответа подтверди: `вердикт: <outcome>` — иначе считается пропущенным.';
|
|
|
|
/** Чистая: список вердиктов → текст additionalContext, либо null если пусто. */
|
|
export function buildSurfaceOutput(verdicts) {
|
|
if (!Array.isArray(verdicts) || verdicts.length === 0) return null;
|
|
return verdicts.map(buildVerdictBanner).join('\n') + '\n' + IMPERATIVE;
|
|
}
|
|
|
|
async function readStdin() { let b = ''; for await (const c of process.stdin) b += c; return b; }
|
|
function emitNone() { process.stdout.write('{}'); }
|
|
|
|
async function main() {
|
|
try {
|
|
const ev = JSON.parse(await readStdin());
|
|
const sid = ev.session_id || ev.sessionId || 'unknown';
|
|
const verdicts = drainVerdicts(sid);
|
|
const out = buildSurfaceOutput(verdicts);
|
|
if (!out) return emitNone();
|
|
markSurfaced(sid, verdicts.map((v) => v.outcome));
|
|
process.stdout.write(JSON.stringify({
|
|
hookSpecificOutput: { hookEventName: 'UserPromptSubmit', additionalContext: out },
|
|
}));
|
|
} catch { emitNone(); }
|
|
}
|
|
|
|
const isCli = process.argv[1] && process.argv[1].replace(/\\/g, '/').endsWith('/enforce-verdict-surface.mjs');
|
|
if (isCli) main();
|