bookworm-smart-assistant/scripts/patches/patch-p0-2-session-once.js

84 lines
3.0 KiB
JavaScript
Raw Normal View History

#!/usr/bin/env node
/**
* P0-2 Patch: Hook Session-Once
* - session-start-mcp-probe.js: 追加 session-once early-exit + markRun
* - session-start-memory-audit.js: 追加 session-once early-exit + markRun
* 幂等: sentinel [P0-2] SESSION_ONCE_v1
*/
'use strict';
const fs = require('fs');
const path = require('path');
const HOOKS = path.resolve(__dirname, '..', '..', 'hooks');
const SENTINEL = '[P0-2] SESSION_ONCE_v1';
function patchFile(name, fn) {
const fp = path.join(HOOKS, name);
if (!fs.existsSync(fp)) { process.stderr.write('[SKIP] ' + name + ' not found\n'); return false; }
const src = fs.readFileSync(fp, 'utf8');
if (src.includes(SENTINEL)) { process.stderr.write('[SKIP] ' + name + ' already patched\n'); return false; }
fs.writeFileSync(fp + '.bak-p02.' + Date.now(), src);
const out = fn(src);
const tmp = fp + '.tmp.' + process.pid;
fs.writeFileSync(tmp, out, 'utf8');
fs.renameSync(tmp, fp);
process.stderr.write('[DONE] ' + name + '\n');
return true;
}
// --- session-start-mcp-probe.js ---
function patchMcpProbe(src) {
// early-exit 插在 feature flag 检查之前 (main 函数第一行)
const marker = ' // Feature flag 检查';
if (!src.includes(marker)) throw new Error('marker not found in mcp-probe');
const earlyExit = [
' // ' + SENTINEL + ' — 会话级去重 (<1ms)',
' try { if (require(\'./lib/session-once.js\').hasRun(\'mcp-probe\')) return safeExit(); } catch {}',
'',
marker,
].join('\n');
let result = src.replace(marker, earlyExit);
// markRun 插在原子写成功之后
const writeMarker = " fs.renameSync(tmp, HEALTH_FILE);";
if (!result.includes(writeMarker)) throw new Error('write marker not found');
result = result.replace(
writeMarker,
writeMarker + '\n // ' + SENTINEL + '\n try { require(\'./lib/session-once.js\').markRun(\'mcp-probe\'); } catch {}'
);
return result;
}
// --- session-start-memory-audit.js ---
function patchMemoryAudit(src) {
// early-exit 插在 feature flag 之前
const marker = ' // Feature flag';
if (!src.includes(marker)) throw new Error('marker not found in memory-audit');
const earlyExit = [
' // ' + SENTINEL + ' — 会话级去重 (<1ms)',
' try { if (require(\'./lib/session-once.js\').hasRun(\'memory-audit\')) return safeExit(); } catch {}',
'',
marker,
].join('\n');
let result = src.replace(marker, earlyExit);
// markRun 插在 stamp 更新之后
const stampMarker = " fs.writeFileSync(STAMP_FILE, TODAY);";
if (!result.includes(stampMarker)) throw new Error('stamp marker not found');
result = result.replace(
stampMarker,
stampMarker + '\n // ' + SENTINEL + '\n try { require(\'./lib/session-once.js\').markRun(\'memory-audit\'); } catch {}'
);
return result;
}
// --- Execute ---
let count = 0;
if (patchFile('session-start-mcp-probe.js', patchMcpProbe)) count++;
if (patchFile('session-start-memory-audit.js', patchMemoryAudit)) count++;
process.stderr.write('\nP0-2 Session-Once: ' + count + '/2 files patched\n');