diff --git a/README.md b/README.md index 1536331..269b7a5 100644 --- a/README.md +++ b/README.md @@ -20,22 +20,67 @@ AI Code Diff Preview 为 VSCode 注入 Cursor 风格的 Accept/Reject 差异审 ## 安装 +### 方式 A:直接安装 .vsix 文件(推荐) + +1. 从 [Releases](https://github.com/YonHaoGuo/ai-diff-preview/releases) 下载最新 `ai-diff-preview-*.vsix` +2. VSCode 中 `Ctrl+Shift+P` → **Extensions: Install from VSIX** → 选择下载的文件 +3. 重启 VSCode + +### 方式 B:源码编译安装 + ```bash -# 克隆仓库 git clone https://github.com/YonHaoGuo/ai-diff-preview.git cd ai-diff-preview - -# 安装依赖 npm install - -# 编译 npm run build - -# 打包 vsix -npm run package +npm run package # 生成 ai-diff-preview-*.vsix +# 然后按方式 A 的第2步安装 ``` -或通过 VSCode 扩展市场安装(即将发布)。 +--- + +## ⚠️ 必须配置:启用 Claude Code Hooks + +**插件依赖 Claude Code 的 Hooks 机制才能工作,安装后必须配置,否则不会触发!** + +打开 Claude Code 配置文件(**任选其一**): + +| 作用范围 | 配置文件路径 | +|----------|-------------| +| **当前项目**(推荐) | 项目根目录 `.claude/settings.json` | +| **所有项目** | Windows: `C:\Users\<用户名>\.claude\settings.json`
macOS/Linux: `~/.claude/settings.json` | + +将以下内容**合并**到你已有的配置文件中(`hooks` 是顶层字段,和现有字段平级): + +```json +{ + "hooks": { + "PostToolUse": [ + { + "matcher": "tool_name === 'Edit' || tool_name === 'Write'", + "hooks": [ + { + "type": "command", + "command": "node -e \"const fs=require('fs');const p=process.cwd()+'/.claude/hooks/pending.json';try{fs.mkdirSync(require('path').dirname(p),{recursive:true});fs.writeFileSync(p,JSON.stringify({toolName:process.env.CLAUDE_TOOL_NAME,filePath:process.env.CLAUDE_TOOL_INPUT_FILE_PATH,oldString:process.env.CLAUDE_TOOL_INPUT_OLD_STRING||'',newString:process.env.CLAUDE_TOOL_INPUT_NEW_STRING||'',content:process.env.CLAUDE_TOOL_INPUT_CONTENT||'',timestamp:Date.now(),type:'edit'}));}catch(e){console.error(e)}\"" + } + ] + } + ], + "Stop": [ + { + "hooks": [ + { + "type": "command", + "command": "node -e \"const fs=require('fs');const p=process.cwd()+'/.claude/hooks/pending.json';try{fs.mkdirSync(require('path').dirname(p),{recursive:true});fs.writeFileSync(p,JSON.stringify({toolName:'Stop',filePath:'',oldString:'',newString:'',content:'',timestamp:Date.now(),type:'stop'}));}catch(e){console.error(e)}\"" + } + ] + } + ] + } +} +``` + +配置完成后,**重启 Claude Code 对话**即可生效。 ## 使用方法 diff --git a/claude-hooks-config.example.jsonc b/claude-hooks-config.example.jsonc deleted file mode 100644 index 239a301..0000000 --- a/claude-hooks-config.example.jsonc +++ /dev/null @@ -1,48 +0,0 @@ -// ============================================================ -// AI Code Diff Preview — Claude Code Hooks 配置 -// ============================================================ -// -// 使用方式(二选一): -// -// 方式 A:项目级配置 -// 将以下内容写入项目根目录的 .claude/settings.json 中 -// -// 方式 B:用户级配置 -// 将以下内容写入 %USERPROFILE%/.claude/settings.json 中 -// (Windows: C:\Users\<用户名>\.claude\settings.json) -// (macOS/Linux: ~/.claude/settings.json) -// -// 注意:如果 .claude/settings.json 已存在,请合并 "hooks" 部分, -// 不要覆盖已有配置。 -// ============================================================ - -{ - "hooks": { - // PostToolUse: 每次 Claude 调用 Edit/Write 工具后触发 - // 写入事件到 pending.json → VSCode 插件监听到 → 记录变更 - "PostToolUse": [ - { - // 匹配条件:只有 Edit 或 Write 工具调用才触发 - "matcher": "tool_name === 'Edit' || tool_name === 'Write'", - "hooks": [ - { - "type": "command", - "command": "node -e \"const fs=require('fs');const p=process.cwd()+'/.claude/hooks/pending.json';try{fs.mkdirSync(require('path').dirname(p),{recursive:true});fs.writeFileSync(p,JSON.stringify({toolName:process.env.CLAUDE_TOOL_NAME,filePath:process.env.CLAUDE_TOOL_INPUT_FILE_PATH,oldString:process.env.CLAUDE_TOOL_INPUT_OLD_STRING||'',newString:process.env.CLAUDE_TOOL_INPUT_NEW_STRING||'',content:process.env.CLAUDE_TOOL_INPUT_CONTENT||'',timestamp:Date.now(),type:'edit'}));}catch(e){console.error(e)}\"" - } - ] - } - ], - // Stop: Claude 对话结束时触发 - // 写入 Stop 事件 → 插件弹出 QuickPick 总览 - "Stop": [ - { - "hooks": [ - { - "type": "command", - "command": "node -e \"const fs=require('fs');const p=process.cwd()+'/.claude/hooks/pending.json';try{fs.mkdirSync(require('path').dirname(p),{recursive:true});fs.writeFileSync(p,JSON.stringify({toolName:'Stop',filePath:'',oldString:'',newString:'',content:'',timestamp:Date.now(),type:'stop'}));}catch(e){console.error(e)}\"" - } - ] - } - ] - } -} \ No newline at end of file