Files
ai-diff-preview/README.md
T
Gmarker689 57632d23a5 docs: README加入安装步骤和Claude Code Hooks必须配置说明
- 删除独立的 .jsonc 示例文件(vsix不会包含)
- README新增安装方式A(vsix直接)和B(源码编译)
- README新增⚠️必须配置章节,含完整 hooks JSON 可复制粘贴
- 说明项目级/用户级 settings.json 位置
2026-06-18 19:53:36 +08:00

216 lines
9.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AI Code Diff Preview
> 类 Cursor 的 AI 代码差异预览 VSCode 插件
[![Version](https://img.shields.io/badge/version-0.2.0-blue)](https://github.com/YonHaoGuo/ai-diff-preview/blob/master/CHANGELOG.md)
[![VSCode](https://img.shields.io/badge/vscode-%5E1.85.0-brightgreen)](https://code.visualstudio.com/)
[![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
AI Code Diff Preview 为 VSCode 注入 Cursor 风格的 Accept/Reject 差异审查体验。AI 对话中的每一次代码编辑自动收集,对话结束后弹出完整的变更文件列表。点击任意文件即可在 **VSCode 内置 Diff 编辑器**中逐文件审查,状态栏实时显示 Accept/Reject 按钮,操作完成后自动推进到下一个待处理文件。
## 特性
- **VSCode 原生 Diff 编辑器** — 使用 `vscode.diff` 命令,100% 原生交互体验,无自定义 Webview
- **EditRecord 独立追踪** — 每次 `Edit`/`Write` 操作作为独立编辑记录,支持逐次编辑 Accept/Reject
- **QuickPick 总览** — 对话结束后弹出原生文件列表,含 Accept All / Reject All 一键操作
- **智能 Auto-Advance** — Accept/Reject 后自动推进到下一个待处理文件,同文件多编辑自动停留
- **状态栏常驻** — 插件激活后状态栏始终可见 `$(diff) AI Diff`,有变更时黄底高亮
- **零保存提示** — Diff 编辑器使用临时文件,关闭时自动删除,不会弹出"是否保存"对话框
- **多轮对话追踪** — 支持同一轮对话中对同文件的多次编辑合并、跨轮对话的独立追踪
## 安装
### 方式 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
npm run package # 生成 ai-diff-preview-*.vsix
# 然后按方式 A 的第2步安装
```
---
## ⚠️ 必须配置:启用 Claude Code Hooks
**插件依赖 Claude Code 的 Hooks 机制才能工作,安装后必须配置,否则不会触发!**
打开 Claude Code 配置文件(**任选其一**):
| 作用范围 | 配置文件路径 |
|----------|-------------|
| **当前项目**(推荐) | 项目根目录 `.claude/settings.json` |
| **所有项目** | Windows: `C:\Users\<用户名>\.claude\settings.json`<br>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 对话**即可生效。
## 使用方法
### 快速开始
1. **安装插件** → 重启 VSCode → 状态栏左侧出现 `$(diff) AI Diff`
2. **用 Claude Code / Cursor 对话** → 每次 Edit/Write **自动静默收集**,不打断工作流
3. **对话结束 (Stop)** → 自动弹出 **QuickPick 总览**,列出所有变更文件
4. **↑↓ 键选择文件** → 回车打开 **VSCode 内置 Diff 编辑器**,左侧原始代码、右侧变更后
5. **查看状态栏右侧** → 三个彩色按钮:`✓ Accept` `✗ Reject` `✓✓ 接受此文件全部`
6. **点击 Accept / Reject** → 变更立即应用到磁盘 → **自动推进**到下一个文件
7. **全部处理完** → 🎉 通知,状态栏回到常态
### 一键操作速查
| 操作 | 方法 |
|------|------|
| 接受**全部文件的所有变更** | QuickPick 底部选 `✅ Accept All`,或 `Ctrl+Shift+A` |
| 拒绝**全部文件的所有变更** | QuickPick 底部选 `❌ Reject All`,或 `Ctrl+Shift+R` |
| 手动打开总览 | 点击状态栏 `$(diff) AI Diff`,或 `Ctrl+Shift+D` |
| 查看当前文件 Diff | `Ctrl+Shift+F` |
| 在变更文件间导航 | `Alt+↑` / `Alt+↓` |
| 接受当前编辑 | `Tab`(需要在 Diff 编辑器内) |
### 逐文件审查流程
```
AI 对话进行中(静默收集 EditRecord)
│
Stop → QuickPick 弹窗
│
├─ 📄 file1.ts +3 -2 · 2次编辑 ← 选中回车
│ │
│ └→ VSCode 内置 Diff 打开
│ 状态栏右侧: [✓ Accept] [✗ Reject] [✓✓ 接受全部]
│ 点击 ✓ → 应用变更
│ ├→ 同文件还有待处理编辑? → 重新打开此文件 Diff
│ └→ 文件处理完毕? → 自动打开下一个文件 Diff
│
├─ 📄 file2.ts +9 -1 · 1次编辑 ← 自动推进
│ └→ ... (重复)
│
└─ 🎉 所有变更已处理完毕
```
### 快捷键
| 快捷键 | 条件 | 功能 |
| ---------------- | -------------------------- | ----------------------- |
| `Alt+↓` | `aiDiffPreview.isActive` | 下一个变更文件 |
| `Alt+↑` | `aiDiffPreview.isActive` | 上一个变更文件 |
| `Ctrl+Shift+D` | `aiDiffPreview.isActive` | 显示 QuickPick 文件列表 |
| `Ctrl+Shift+F` | `aiDiffPreview.isActive` | 查看当前文件 Diff |
| `Ctrl+Shift+A` | `aiDiffPreview.isActive` | Accept All |
| `Ctrl+Shift+R` | `aiDiffPreview.isActive` | Reject All |
### 命令
| 命令 ID | 标题 |
| ------------------------------------- | ----------------------------- |
| `aiDiffPreview.showDiffPanel` | AI Diff: 显示所有变更文件列表 |
| `aiDiffPreview.showCurrentFileDiff` | AI Diff: 查看当前文件 Diff |
| `aiDiffPreview.acceptCurrentEdit` | AI Diff: 接受当前编辑 |
| `aiDiffPreview.rejectCurrentEdit` | AI Diff: 拒绝当前编辑 |
| `aiDiffPreview.acceptAll` | AI Diff: 接受所有变更 |
| `aiDiffPreview.rejectAll` | AI Diff: 拒绝所有变更 |
| `aiDiffPreview.nextDiff` | AI Diff: 下一个变更 |
| `aiDiffPreview.prevDiff` | AI Diff: 上一个变更 |
### 配置项
| 配置项 | 类型 | 默认值 | 说明 |
| ------------------------------------- | ------- | --------------- | ------------------------------------------------ |
| `aiDiffPreview.enableAutoTrigger` | boolean | `true` | 启用自动触发(监听 pending.json) |
| `aiDiffPreview.autoShowDiffPerEdit` | boolean | `false` | 每次 Edit/Write 后自动弹出 Diff |
| `aiDiffPreview.showAllDiffsOnStop` | boolean | `true` | Stop 后自动弹出 QuickPick 总览 |
| `aiDiffPreview.floatingLabelMode` | string | `"statusBar"` | 浮动标签位置(statusBar / inline / both / none) |
| `aiDiffPreview.maxFileSize` | number | `100000` | 最大处理文件大小(字符数) |
## 项目结构
```
src/
├── extension.ts # 插件入口
├── trigger/
│ └── hookHandler.ts # Hook 处理器 + QuickPick 总览
├── snapshot/
│ └── snapshotManager.ts # 变更集管理器 (ChangeSetManager)
├── diff/
│ └── diffEngine.ts # Diff 计算引擎
├── render/
│ ├── diffViewer.ts # VSCode 内置 Diff 查看器 + 自动推进
│ ├── reviewPanel.ts # Webview 面板 (实验性/备用)
│ ├── inlineDecorator.ts # 内联装饰器 (备用)
│ ├── codeLensProvider.ts # CodeLens 提供器 (备用)
│ └── statusBar.ts # 状态栏管理器 (常驻 + Diff 模式)
├── transaction/
│ ├── acceptHandler.ts # Accept 处理器 (旧版)
│ └── rejectHandler.ts # Reject 处理器 (旧版)
├── models/
│ ├── types.ts # 类型定义
│ └── constants.ts # 常量定义
└── __tests__/
├── diffEngine.test.ts # Diff 引擎测试
└── changeSetManager.test.ts # 变更集管理器回归测试
```
## 开发
```bash
npm run watch # esbuild 监听模式 + sourcemap
npm run build # 生产构建 (minify)
npm run test # 运行测试 (13 tests)
npm run test:watch # 测试监听模式
npm run lint # ESLint
npm run package # vsce package → .vsix
```
## 技术栈
| 领域 | 选型 |
| --------- | -------------------- |
| 框架 | VSCode Extension API |
| 语言 | TypeScript (ES2022) |
| Diff 算法 | `diff` (Myers) |
| 绑定 | esbuild |
| 测试 | Vitest |
| 规范 | ESLint + Prettier |
## 许可证
MIT © 2026 [Gmaker689](https://github.com/Gmaker689)