bookworm-smart-assistant/hooks/pre-compact-handoff.js

57 lines
2.1 KiB
JavaScript
Raw Normal View History

#!/usr/bin/env node
/**
* PreCompact Hook - 上下文压缩前自动保存会话状态
* 将当前任务摘要写入 ~/.claude/session-state/handoff.json
*/
const fs = require('fs');
const path = require('path');
const CLAUDE_ROOT = require('./lib/root.js');
const readStdin = require('./lib/read-stdin.js');
const SESSION_STATE_DIR = path.join(CLAUDE_ROOT, 'session-state');
const HANDOFF_PATH = path.join(SESSION_STATE_DIR, 'handoff.json');
(async () => {
try {
let hookData = {};
try { hookData = await readStdin(); } catch (_) {}
// 确保目录存在
if (!fs.existsSync(SESSION_STATE_DIR)) {
fs.mkdirSync(SESSION_STATE_DIR, { recursive: true });
}
// 构造 handoff 数据
const handoff = {
timestamp: new Date().toISOString(),
session_id: hookData.session_id || `session-${Date.now()}`,
context_hint: '会话因上下文压缩中断,以下是压缩前的状态摘要',
conversation_summary: hookData.transcript_summary || '(由 PreCompact hook 自动捕获)',
tool_call_count: hookData.tool_call_count || 'unknown',
working_directory: process.cwd(),
note: '此文件由 pre-compact-handoff.js 自动生成SessionStart 时自动读取并注入恢复上下文'
};
fs.writeFileSync(HANDOFF_PATH, JSON.stringify(handoff, null, 2), 'utf8');
// 同时重置 heartbeat 计数器compact 相当于新会话起点)
const heartbeatFile = path.join(CLAUDE_ROOT, 'debug', 'session-heartbeat.json');
if (fs.existsSync(heartbeatFile)) {
fs.writeFileSync(heartbeatFile, JSON.stringify({
count: 0, lastActivity: Date.now(), notified: []
}), 'utf8');
}
console.log(JSON.stringify({
continue: true,
suppressOutput: false,
systemMessage: '[PRE_COMPACT] 上下文即将压缩。handoff.json 已写入。请在压缩前将当前任务的关键决策和待完成步骤总结到 handoff 记录中。'
}));
} catch {
// fail-open
console.log(JSON.stringify({ continue: true, suppressOutput: true }));
}
process.exit(0);
})();