#!/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 = 'ПЕРВОЙ строкой ответа подтверди: `вердикт: ` — иначе считается пропущенным.'; /** Чистая: список вердиктов → текст 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();