Files
Gmarker689 a7c992a804 refactor: 重构为 Webview Review 面板架构
- 移除旧的 DiffEngine、InlineDecorator、CodeLensProvider 等模块
- 新增 ChangeSetManager 统一管理代码变更快照
- 新增 reviewPanel.ts 实现双栏 Review Webview 面板
- 简化 hookHandler.ts,直接通过 ChangeSet 收集变更
- 简化 extension.ts 入口,移除冗余模块导入
- 更新 types.ts,精简 ChangeSet 和 ChangeEntry 类型定义
- package.json 添加 onStartupFinished 激活事件
2026-06-18 00:09:56 +08:00

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);
});