57 lines
2.1 KiB
JavaScript
57 lines
2.1 KiB
JavaScript
|
|
#!/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);
|
|||
|
|
})();
|