- VERSION file as authoritative version source - export.mjs reads VERSION with package.json fallback - bw-ota.ps1 DryRun mode for safe testing - auto-setup.ps1 bumped to v3.2.0 (Phase 8 OTA)
133 lines
4.4 KiB
JavaScript
133 lines
4.4 KiB
JavaScript
#!/usr/bin/env node
|
||
/**
|
||
* patch-p2-handoff-mechanism.js
|
||
*
|
||
* P2 /handoff 机制改造 patch:
|
||
* 1. context-pressure-monitor.js: CRITICAL 消息改为建议 /handoff
|
||
* 2. pre-compact-handoff.js: 添加过期 handoff 文件清理 (保留最新 5 个)
|
||
* 3. CLAUDE.md: 上下文管理节添加 /handoff 说明
|
||
* 4. SKILL-REGISTRY.md: 添加 handoff 技能条目 + 更新统计
|
||
*
|
||
* 幂等: 每处修改前检查 sentinel,已 patch 则跳过
|
||
*/
|
||
'use strict';
|
||
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
const CLAUDE_ROOT = path.join(require('os').homedir(), '.claude');
|
||
const HOOKS_DIR = path.join(CLAUDE_ROOT, 'hooks');
|
||
|
||
const results = [];
|
||
|
||
function patchFile(filePath, label, patches) {
|
||
if (!fs.existsSync(filePath)) {
|
||
results.push(`[SKIP] ${label}: 文件不存在 ${filePath}`);
|
||
return false;
|
||
}
|
||
const bak = filePath + '.bak';
|
||
let content = fs.readFileSync(filePath, 'utf8');
|
||
let changed = false;
|
||
|
||
for (const p of patches) {
|
||
if (p.sentinel && content.includes(p.sentinel)) {
|
||
results.push(`[SKIP] ${label}/${p.name}: sentinel 已存在`);
|
||
continue;
|
||
}
|
||
if (p.find && !content.includes(p.find)) {
|
||
results.push(`[SKIP] ${label}/${p.name}: 未找到目标文本`);
|
||
continue;
|
||
}
|
||
if (p.find) {
|
||
content = content.replace(p.find, p.replace);
|
||
} else if (p.insertAfter) {
|
||
const idx = content.indexOf(p.insertAfter);
|
||
if (idx === -1) {
|
||
results.push(`[SKIP] ${label}/${p.name}: 未找到插入锚点`);
|
||
continue;
|
||
}
|
||
const insertAt = idx + p.insertAfter.length;
|
||
content = content.slice(0, insertAt) + p.insert + content.slice(insertAt);
|
||
}
|
||
changed = true;
|
||
results.push(`[OK] ${label}/${p.name}`);
|
||
}
|
||
|
||
if (changed) {
|
||
if (!fs.existsSync(bak)) fs.copyFileSync(filePath, bak);
|
||
fs.writeFileSync(filePath, content, 'utf8');
|
||
}
|
||
return changed;
|
||
}
|
||
|
||
// === 1. context-pressure-monitor.js: CRITICAL 消息 ===
|
||
patchFile(
|
||
path.join(HOOKS_DIR, 'context-pressure-monitor.js'),
|
||
'context-pressure-monitor',
|
||
[{
|
||
name: 'critical-msg-handoff',
|
||
sentinel: '/handoff',
|
||
find: 'dump 当前关键决策到 .bookworm-progress.md, 然后请用户 /clear',
|
||
replace: '调用 /handoff 保存当前进度到 .bookworm-progress.md, 然后请用户 /clear'
|
||
}]
|
||
);
|
||
|
||
// === 2. pre-compact-handoff.js: 添加过期 handoff 清理 ===
|
||
patchFile(
|
||
path.join(HOOKS_DIR, 'pre-compact-handoff.js'),
|
||
'pre-compact-handoff',
|
||
[{
|
||
name: 'cleanup-old-handoffs',
|
||
sentinel: 'PATCH-P2-HANDOFF-CLEANUP',
|
||
insertAfter: 'fs.renameSync(_tmpHandoff, HANDOFF_PATH);',
|
||
insert: `
|
||
|
||
// [PATCH-P2-HANDOFF-CLEANUP] 清理过期 handoff 时间戳文件, 保留最新 5 个
|
||
try {
|
||
const files = fs.readdirSync(SESSION_STATE_DIR)
|
||
.filter(f => /^handoff-\\d+\\.json$/.test(f))
|
||
.map(f => ({ name: f, time: parseInt(f.match(/\\d+/)[0], 10) }))
|
||
.sort((a, b) => b.time - a.time);
|
||
const toDelete = files.slice(5);
|
||
for (const f of toDelete) {
|
||
try { fs.unlinkSync(path.join(SESSION_STATE_DIR, f.name)); } catch {}
|
||
}
|
||
} catch {}
|
||
`
|
||
}]
|
||
);
|
||
|
||
// === 3. CLAUDE.md: 上下文管理节添加 /handoff ===
|
||
patchFile(
|
||
path.join(CLAUDE_ROOT, 'CLAUDE.md'),
|
||
'CLAUDE.md',
|
||
[{
|
||
name: 'handoff-doc',
|
||
sentinel: '/handoff',
|
||
insertAfter: '- 长会话(>20 轮工具调用)时主动建议 `/clear` 重置上下文',
|
||
insert: '\n- **主动交接** (P2): 上下文压力 CRITICAL 时自动建议 `/handoff`; 手动 `/handoff` 可随时调用, 将进度写入 `.bookworm-progress.md` + 生成继续提示词 + 清理过期 handoff JSON'
|
||
}]
|
||
);
|
||
|
||
// === 4. SKILL-REGISTRY.md: 添加 handoff 条目 ===
|
||
const registryPath = path.join(CLAUDE_ROOT, 'SKILL-REGISTRY.md');
|
||
patchFile(registryPath, 'SKILL-REGISTRY', [
|
||
{
|
||
name: 'add-handoff-entry',
|
||
sentinel: '| 102 | handoff',
|
||
insertAfter: '| 101 | mcp-prune | stable | MCP 剪枝分析工具 (Phase 1 · T1.4)。基于使用率识别低频 MCP 候选,生成剪枝 plan。永不自动修改 .claude.json。 |',
|
||
insert: '\n| 102 | handoff | stable | 上下文交接/进度保存/.bookworm-progress.md 生成/继续提示词 |'
|
||
},
|
||
{
|
||
name: 'update-skill-count',
|
||
sentinel: '95 (',
|
||
find: '- **总计**: 94 (',
|
||
replace: '- **总计**: 95 ('
|
||
}
|
||
]);
|
||
|
||
// === 输出摘要 ===
|
||
console.log('=== patch-p2-handoff-mechanism ===');
|
||
for (const r of results) console.log(r);
|
||
console.log('=== done ===');
|