54 lines
2.1 KiB
JavaScript
54 lines
2.1 KiB
JavaScript
#!/usr/bin/env node
|
|
/** verdict-surface-store — пер-сессионный транзиентный стор вердиктов + pending-ack маркер (SP1).
|
|
* Fail-quiet: любая ошибка → безопасный no-op/пусто. Дефолт baseDir = ~/.claude/runtime. */
|
|
import { homedir } from 'node:os';
|
|
import { join } from 'node:path';
|
|
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
|
|
function baseOf(baseDir) { return baseDir || join(homedir(), '.claude', 'runtime'); }
|
|
function queuePath(sid, baseDir) { return join(baseOf(baseDir), `verdict-surface-${sid || 'unknown'}.json`); }
|
|
function ackPath(sid, baseDir) { return join(baseOf(baseDir), `verdict-pending-ack-${sid || 'unknown'}.json`); }
|
|
function readJson(p) { try { return JSON.parse(readFileSync(p, 'utf8')); } catch { return null; } }
|
|
function ensureDir(p) { try { mkdirSync(baseOf(p), { recursive: true }); } catch {} }
|
|
|
|
export function pushVerdict(sid, obj, baseDir) {
|
|
try {
|
|
ensureDir(baseDir);
|
|
const p = queuePath(sid, baseDir);
|
|
let arr = existsSync(p) ? readJson(p) : [];
|
|
if (!Array.isArray(arr)) arr = [];
|
|
arr.push(obj);
|
|
writeFileSync(p, JSON.stringify(arr));
|
|
return true;
|
|
} catch { return false; }
|
|
}
|
|
|
|
export function drainVerdicts(sid, baseDir) {
|
|
try {
|
|
const p = queuePath(sid, baseDir);
|
|
if (!existsSync(p)) return [];
|
|
const arr = readJson(p);
|
|
try { writeFileSync(p, '[]'); } catch {}
|
|
return Array.isArray(arr) ? arr : [];
|
|
} catch { return []; }
|
|
}
|
|
|
|
export function markSurfaced(sid, outcomes, baseDir) {
|
|
try { ensureDir(baseDir); writeFileSync(ackPath(sid, baseDir), JSON.stringify(outcomes || [])); return true; }
|
|
catch { return false; }
|
|
}
|
|
|
|
export function readPendingAck(sid, baseDir) {
|
|
try {
|
|
const p = ackPath(sid, baseDir);
|
|
if (!existsSync(p)) return null;
|
|
const v = readJson(p);
|
|
return Array.isArray(v) ? v : null;
|
|
} catch { return null; }
|
|
}
|
|
|
|
export function clearPendingAck(sid, baseDir) {
|
|
try { const p = ackPath(sid, baseDir); if (existsSync(p)) writeFileSync(p, 'null'); return true; }
|
|
catch { return false; }
|
|
}
|