bookworm-smart-assistant/hooks/check-gray-expiry.js

71 lines
2.8 KiB
JavaScript
Raw Normal View History

#!/usr/bin/env node
/**
* check-gray-expiry.js · 2026-04-25
* UserPromptSubmit hook. Scans state/gray-observations/*.json, if any expired
* emits prominent banner via additionalContext so user & AI see it on session start.
*/
'use strict';
const fs = require('fs');
const path = require('path');
const ROOT = path.resolve(__dirname, '..');
const DIR = path.join(ROOT, 'state', 'gray-observations');
function loadObservations() {
if (!fs.existsSync(DIR)) return [];
const out = [];
for (const name of fs.readdirSync(DIR)) {
if (!name.endsWith('.json')) continue;
try {
const j = JSON.parse(fs.readFileSync(path.join(DIR, name), 'utf8'));
j._file = name;
out.push(j);
} catch (_) {}
}
return out;
}
function main() {
const now = Date.now();
const obs = loadObservations();
const expired = obs.filter(o => {
if (o.resolved) return false;
const exp = new Date(o.expires_at).getTime();
return Number.isFinite(exp) && exp <= now;
});
if (expired.length === 0) process.exit(0);
const lines = [];
lines.push('');
lines.push('╔══════════════════════════════════════════════════════════════╗');
lines.push('║ ⚠️ 灰度观察到期提醒 · GRAY OBSERVATION EXPIRED ║');
lines.push('╠══════════════════════════════════════════════════════════════╣');
for (const o of expired) {
lines.push('║ ID: ' + (o.observation_id || o._file).padEnd(56) + '║');
lines.push('║ 到期: ' + (o.expires_at || '').slice(0, 19).padEnd(54) + '║');
if (o.watched_flag) lines.push('║ 关注 flag: ' + String(o.watched_flag).padEnd(50) + '║');
if (o.on_expiry_action) {
const act = String(o.on_expiry_action);
for (let i = 0; i < act.length; i += 58) {
lines.push('║ → ' + act.slice(i, i + 58).padEnd(58) + '║');
}
}
lines.push('║' + ' '.repeat(62) + '║');
}
lines.push('║ 建议: 查看 manifest.jsonl 统计 → 决定 warn→enforce 升级 ║');
lines.push('║ 解决后: resolved:true 写入对应 .json 停止提醒 ║');
lines.push('╚══════════════════════════════════════════════════════════════╝');
lines.push('');
const output = {
hookSpecificOutput: {
hookEventName: 'UserPromptSubmit',
additionalContext: lines.join('\n'),
},
};
process.stdout.write(JSON.stringify(output));
process.exit(0);
}
try { main(); } catch (_) { process.exit(0); }