mirror of
https://github.com/Gmaker689/ai-diff-preview.git
synced 2026-09-27 03:21:52 +08:00
79 lines
2.1 KiB
JavaScript
79 lines
2.1 KiB
JavaScript
|
|
#!/usr/bin/env node
|
||
|
|
/**
|
||
|
|
* Claude Code PostToolUse Hook 脚本
|
||
|
|
*
|
||
|
|
* 当 Claude Code 执行 Write 或 Edit 工具后,此脚本被调用。
|
||
|
|
* 它从 stdin 读取 JSON,将事件写入触发文件,供 VSCode 扩展监听。
|
||
|
|
*
|
||
|
|
* stdin JSON 格式:
|
||
|
|
* {
|
||
|
|
* "session_id": "abc123",
|
||
|
|
* "tool_name": "Write" | "Edit",
|
||
|
|
* "tool_input": { "file_path": "...", "content": "..." },
|
||
|
|
* "tool_response": { "success": true }
|
||
|
|
* }
|
||
|
|
*/
|
||
|
|
|
||
|
|
const fs = require('fs');
|
||
|
|
const path = require('path');
|
||
|
|
|
||
|
|
// 触发文件目录 - VSCode 扩展会监听此目录
|
||
|
|
const TRIGGER_DIR = path.join(__dirname, '..', '.claude', 'hooks');
|
||
|
|
const TRIGGER_FILE = path.join(TRIGGER_DIR, 'pending.json');
|
||
|
|
|
||
|
|
async function main() {
|
||
|
|
// 读取 stdin
|
||
|
|
const chunks = [];
|
||
|
|
for await (const chunk of process.stdin) {
|
||
|
|
chunks.push(chunk);
|
||
|
|
}
|
||
|
|
const input = Buffer.concat(chunks).toString('utf-8');
|
||
|
|
|
||
|
|
let data;
|
||
|
|
try {
|
||
|
|
data = JSON.parse(input);
|
||
|
|
} catch (e) {
|
||
|
|
// 非 JSON 输入,忽略
|
||
|
|
process.exit(0);
|
||
|
|
}
|
||
|
|
|
||
|
|
const { tool_name, tool_input, tool_response } = data;
|
||
|
|
|
||
|
|
// 只处理成功的 Write/Edit 操作
|
||
|
|
if (!tool_response || tool_response.error) {
|
||
|
|
process.exit(0);
|
||
|
|
}
|
||
|
|
|
||
|
|
const filePath = tool_input?.file_path || tool_response?.filePath;
|
||
|
|
if (!filePath) {
|
||
|
|
process.exit(0);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 构造事件数据
|
||
|
|
const event = {
|
||
|
|
type: tool_name === 'Write' ? 'after_write_file' : 'after_code_edit',
|
||
|
|
filePath: filePath,
|
||
|
|
content: tool_input?.content || '',
|
||
|
|
patch: tool_input?.new_content || tool_input?.content || '',
|
||
|
|
oldString: tool_input?.old_string || '',
|
||
|
|
newString: tool_input?.new_string || '',
|
||
|
|
timestamp: Date.now(),
|
||
|
|
toolName: tool_name,
|
||
|
|
};
|
||
|
|
|
||
|
|
// 确保目录存在
|
||
|
|
if (!fs.existsSync(TRIGGER_DIR)) {
|
||
|
|
fs.mkdirSync(TRIGGER_DIR, { recursive: true });
|
||
|
|
}
|
||
|
|
|
||
|
|
// 写入触发文件(原子写入:先写临时文件再重命名)
|
||
|
|
const tmpFile = TRIGGER_FILE + '.tmp';
|
||
|
|
fs.writeFileSync(tmpFile, JSON.stringify(event, null, 2), 'utf-8');
|
||
|
|
fs.renameSync(tmpFile, TRIGGER_FILE);
|
||
|
|
}
|
||
|
|
|
||
|
|
main().catch(() => {
|
||
|
|
// 静默失败,不阻塞 Claude Code
|
||
|
|
process.exit(0);
|
||
|
|
});
|