程式碼審查基礎:使用 /plannotator-review 審查 Git Diff
學完你能做什麼
- ✅ 使用
/plannotator-review指令審查 Git Diff - ✅ 在 side-by-side 和 unified 檢視間切換
- ✅ 點擊行號選取程式碼範圍,新增行級註解
- ✅ 新增不同類型的註解(comment/suggestion/concern)
- ✅ 切換不同的 diff 類型(uncommitted/staged/last commit/branch)
- ✅ 將審查回饋傳送給 AI Agent
你現在的困境
問題 1:用 git diff 檢視程式碼變更時,輸出在終端機裡捲動,難以全面理解改動內容。
問題 2:想給 Agent 回饋程式碼問題時,只能用文字描述「第 10 行有問題」、「修改這個函式」,容易產生歧義。
問題 3:不知道 Agent 具體改了哪些檔案,在大量改動中難以聚焦關鍵部分。
問題 4:審查程式碼後,想把結構化回饋傳送給 Agent,讓它根據建議重新修改。
Plannotator 能幫你:
- 視覺化 Git Diff,支援 side-by-side 和 unified 兩種檢視
- 點擊行號即可選取程式碼範圍,精確標註問題位置
- 新增行級註解(comment/suggestion/concern),附帶建議程式碼
- 一鍵切換 diff 類型(uncommitted、staged、last commit、branch)
- 註解自動轉換為 Markdown,Agent 準確理解你的回饋
什麼時候用這一招
使用情境:
- Agent 完成程式碼修改後,你需要審查改動內容
- 提交程式碼前,想全面檢查自己的變更
- 與團隊協作時,需要結構化回饋程式碼問題
- 想在多個 diff 類型間切換(未提交 vs 已暫存 vs 上次提交)
不適用情境:
- 審查 AI 產生的實施計畫(使用計畫審查功能)
- 直接在終端機中使用
git diff(不需要視覺化介面)
🎒 開始前的準備
前置條件:
- ✅ 已安裝 Plannotator CLI(詳見 快速開始)
- ✅ 已設定 Claude Code 或 OpenCode 外掛(詳見對應安裝指南)
- ✅ 目前目錄在 Git 儲存庫中
觸發方式:
- 在 Claude Code 或 OpenCode 中執行
/plannotator-review指令
核心思路
程式碼審查是什麼
程式碼審查是 Plannotator 提供的視覺化 Git Diff 審查工具,讓你在瀏覽器中檢視程式碼變更並新增行級註解。
為什麼需要程式碼審查?
AI Agent 完成程式碼修改後,通常會用終端機輸出 git diff 內容。這種純文字方式難以全面理解改動,也不方便精確標註問題位置。Plannotator 提供視覺化介面(side-by-side 或 unified),支援點擊行號新增註解,並將結構化回饋傳送給 Agent,讓它根據建議重新修改程式碼。
運作流程
┌─────────────────┐
│ 使用者 │
│ (執行指令) │
└────────┬────────┘
│
│ /plannotator-review
▼
┌─────────────────┐
│ CLI │
│ (執行 git) │
│ git diff HEAD │
└────────┬────────┘
│
│ rawPatch + gitRef
▼
┌─────────────────┐
│ Review Server │ ← 本機伺服器啟動
│ /api/diff │
└────────┬────────┘
│
│ 瀏覽器開啟 UI
▼
┌─────────────────┐
│ Review UI │
│ │
│ ┌───────────┐ │
│ │ File Tree │ │
│ │ (檔案清單) │ │
│ └───────────┘ │
│ │ │
│ ▼ │
│ ┌───────────┐ │
│ │ DiffViewer │ │
│ │ (程式碼對比) │ │
│ │ split/ │ │
│ │ unified │ │
│ └───────────┘ │
│ │ │
│ │ 點擊行號
│ ▼ │
│ ┌───────────┐ │
│ │ 新增註解 │ │
│ │ comment/ │ │
│ │ suggestion/│ │
│ │ concern │ │
│ └───────────┘ │
│ │ │
│ ▼ │
│ ┌───────────┐ │
│ │ 傳送回饋 │ │
│ │ Send │ │
│ │ Feedback │ │
│ │ 或 LGTM │ │
│ └───────────┘ │
└────────┬────────┘
│
│ Markdown 格式回饋
▼
┌─────────────────┐
│ AI Agent │
│ (根據建議修改) │
└─────────────────┘檢視模式
| 檢視模式 | 描述 | 適用情境 |
|---|---|---|
| Split (Side-by-side) | 左右分割,舊程式碼在左,新程式碼在右 | 對比大段改動,清晰看到修改前後 |
| Unified | 上下合併,刪除和新增在同一欄 | 檢視小改動,節省垂直空間 |
註解類型
Plannotator 支援三種程式碼註解類型:
| 註解類型 | 用途 | UI 表現 |
|---|---|---|
| Comment | 評論某行程式碼,提出問題或說明 | 紫色/藍色邊框標記 |
| Suggestion | 提供具體的程式碼修改建議 | 綠色邊框標記,附帶建議程式碼區塊 |
| Concern | 標記需要關注的潛在問題 | 黃色/橙色邊框標記 |
註解類型的區別
- Comment:用於提問、說明、一般性回饋
- Suggestion:用於提供具體的程式碼修改方案(附帶建議程式碼)
- Concern:用於標記需要修復的問題或潛在風險
Diff 類型
| Diff 類型 | Git 指令 | 描述 |
|---|---|---|
| Uncommitted | git diff HEAD | 未提交的變更(預設) |
| Staged | git diff --staged | 已暫存的變更 |
| Unstaged | git diff | 未暫存的變更 |
| Last commit | git diff HEAD~1..HEAD | 上次提交的內容 |
| Branch | git diff main..HEAD | 目前分支與預設分支的對比 |
跟我做
第 1 步:觸發程式碼審查
在 Claude Code 或 OpenCode 中執行 /plannotator-review 指令:
使用者:/plannotator-review
CLI:正在執行 git diff...
瀏覽器已開啟你應該看到:
- 瀏覽器自動開啟 Plannotator 程式碼審查介面
- 左側顯示檔案清單(File Tree)
- 右側顯示 Diff Viewer(預設為 split 檢視)
- 頂部有檢視切換按鈕(Split/Unified)
- 底部有「Send Feedback」和「LGTM」按鈕
第 2 步:瀏覽檔案清單
在左側的 File Tree 中檢視改動的檔案:
- 檔案按路徑分組顯示
- 每個檔案顯示變更統計(additions/deletions)
- 點擊檔案切換到對應的 diff 內容
你應該看到:
src/
auth/
login.ts (+12, -5) ← 點擊檢視這個檔案的 diff
user.ts (+8, -2)
api/
routes.ts (+25, -10)第 3 步:切換檢視模式
在頁面頂部點擊「Split」或「Unified」按鈕切換檢視:
Split 檢視(Side-by-side):
- 舊程式碼在左(灰色背景,紅色刪除線)
- 新程式碼在右(白色背景,綠色新增線)
- 適合對比大段改動
Unified 檢視(合併):
- 舊程式碼和新程式碼在同一欄
- 刪除的行用紅色背景,新增的行用綠色背景
- 適合檢視小改動
你應該看到:
- Split 檢視:左右分割,清晰對比修改前後
- Unified 檢視:上下合併,節省垂直空間
第 4 步:選取程式碼行,新增註解
新增 Comment 註解:
- 將滑鼠懸停在程式碼行上,行號旁會出現
+按鈕 - 點擊
+按鈕,或直接點擊行號選取該行 - 選取多行:點擊起始行號,按住 Shift 點擊結束行號
- 在彈出的工具列中輸入評論內容
- 點擊「Add Comment」按鈕
新增 Suggestion 註解(附帶建議程式碼):
- 按照上述步驟新增註解
- 在工具列中點擊「Add suggested code」按鈕
- 在彈出的程式碼框中輸入建議的程式碼
- 點擊「Add Comment」按鈕
你應該看到:
- 註解顯示在程式碼行下方
- Comment 註解:紫色/藍色邊框標記,顯示評論內容
- Suggestion 註解:綠色邊框標記,顯示評論內容和建議程式碼區塊
- 右側側邊欄會顯示所有註解清單
第 5 步:切換 Diff 類型
在頁面頂部選擇不同的 diff 類型:
- Uncommitted changes(預設):未提交的變更
- Staged changes:已暫存的變更
- Last commit:上次提交的內容
- vs main(如果不在預設分支):與預設分支的對比
你應該看到:
- Diff Viewer 更新為新選擇的 diff 內容
- 檔案清單重新整理顯示新的變更統計
第 6 步:傳送回饋給 Agent
Send Feedback(傳送回饋):
- 新增必要的註解(Comment/Suggestion/Concern)
- 點擊頁面底部的「Send Feedback」按鈕
- 如果沒有註解,會彈出確認對話框詢問是否繼續
LGTM(Looks Good To Me):
如果程式碼沒有問題,點擊「LGTM」按鈕。
你應該看到:
- 瀏覽器自動關閉(1.5 秒延遲)
- 終端機顯示回饋內容或「LGTM - no changes requested.」
- Agent 收到回饋後開始修改程式碼
第 7 步:檢視回饋內容(可選)
如果你想檢視 Plannotator 傳送給 Agent 的回饋內容,可以在終端機中檢視:
# Code Review Feedback
## src/auth/login.ts
### Line 15 (new)
這裡需要新增錯誤處理邏輯。
### Line 20-25 (old)
**Suggested code:**
```typescript
try {
await authenticate(req);
} catch (error) {
return res.status(401).json({ error: 'Authentication failed' });
}src/api/routes.ts
Line 10 (new)
這個函式缺少輸入驗證。
**你應該看到**:
- 回饋按檔案分組
- 每個註解顯示檔案路徑、行號、類型
- Suggestion 註解附帶建議程式碼區塊
## 檢查點 ✅
完成以上步驟後,你應該能夠:
- [ ] 執行 `/plannotator-review` 指令,瀏覽器自動開啟程式碼審查介面
- [ ] 在 File Tree 中檢視改動的檔案清單
- [ ] 在 Split 和 Unified 檢視間切換
- [ ] 點擊行號或 `+` 按鈕選取程式碼行
- [ ] 新增 Comment、Suggestion、Concern 註解
- [ ] 在註解中新增建議程式碼
- [ ] 切換不同的 diff 類型(uncommitted/staged/last commit/branch)
- [ ] 點擊 Send Feedback,瀏覽器關閉,終端機顯示回饋內容
- [ ] 點擊 LGTM,瀏覽器關閉,終端機顯示「LGTM - no changes requested.」
**如果某一步失敗**,詳見:
- [常見問題](../../faq/common-problems/)
- [Claude Code 安裝指南](../../start/installation-claude-code/)
- [OpenCode 安裝指南](../../start/installation-opencode/)
## 踩坑提醒
**常見錯誤 1**:執行 `/plannotator-review` 後,瀏覽器沒有開啟
**原因**:可能是連接埠佔用或伺服器啟動失敗。
**解決**:
- 檢查終端機中是否有錯誤訊息
- 嘗試手動在瀏覽器中開啟顯示的 URL
- 如果問題持續,詳見 [故障排除](../../faq/troubleshooting/)
**常見錯誤 2**:點擊行號後,沒有彈出工具列
**原因**:可能是因為選取的是空行,或者瀏覽器視窗太小。
**解決**:
- 嘗試選取包含程式碼的行
- 放大瀏覽器視窗
- 確保沒有停用 JavaScript
**常見錯誤 3**:新增註解後,註解沒有顯示在程式碼下方
**原因**:可能是因為選取的是空行,或者瀏覽器視窗太小。
**解決**:
- 嘗試選取包含程式碼的行
- 放大瀏覽器視窗
- 確保沒有停用 JavaScript
- 檢查右側側邊欄是否顯示了註解清單
**常見錯誤 4**:點擊 Send Feedback 後,終端機沒有顯示回饋內容
**原因**:可能是網路問題或伺服器錯誤。
**解決**:
- 檢查終端機中是否有錯誤訊息
- 嘗試重新傳送回饋
- 如果問題持續,詳見 [故障排除](../../faq/troubleshooting/)
**常見錯誤 5**:Agent 收到回饋後,沒有按照建議修改程式碼
**原因**:Agent 可能沒有正確理解註解的意圖。
**解決**:
- 嘗試使用更明確的註解(Suggestion 比 Comment 更明確)
- 使用 Comment 新增詳細說明
- 在 Suggestion 中提供完整的建議程式碼
- 如果問題持續,可以再次執行 `/plannotator-review` 審查新的改動
**常見錯誤 6**:切換 diff 類型後,檔案清單為空
**原因**:可能是因為選取的 diff 類型沒有變更內容。
**解決**:
- 嘗試切換回「Uncommitted changes」
- 檢查 git 狀態,確認是否有變更
- 使用 `git status` 檢視目前狀態
## 本課小結
程式碼審查是 Plannotator 提供的視覺化 Git Diff 審查工具:
**核心操作**:
1. **觸發**:執行 `/plannotator-review`,瀏覽器自動開啟 UI
2. **瀏覽**:在 File Tree 中檢視改動的檔案清單
3. **檢視**:在 Split(side-by-side)和 Unified 檢視間切換
4. **註解**:點擊行號選取程式碼行,新增 Comment/Suggestion/Concern 註解
5. **切換**:選擇不同的 diff 類型(uncommitted/staged/last commit/branch)
6. **回饋**:點擊 Send Feedback 或 LGTM,回饋傳送給 Agent
**檢視模式**:
- **Split(Side-by-side)**:左右分割,舊程式碼在左,新程式碼在右
- **Unified**:上下合併,刪除和新增在同一欄
**註解類型**:
- **Comment**:評論某行程式碼,提出問題或說明
- **Suggestion**:提供具體的程式碼修改建議(附帶建議程式碼)
- **Concern**:標記需要關注的潛在問題
**Diff 類型**:
- **Uncommitted**:未提交的變更(預設)
- **Staged**:已暫存的變更
- **Unstaged**:未暫存的變更
- **Last commit**:上次提交的內容
- **Branch**:目前分支與預設分支的對比
## 下一課預告
> 下一課我們學習 **[新增程式碼註解](../code-review-annotations/)**。
>
> 你會學到:
> - 如何精確使用 Comment、Suggestion、Concern 註解
> - 如何新增建議程式碼並格式化顯示
> - 如何編輯和刪除註解
> - 註解的最佳實踐和常見情境
> - 如何在 side-by-side 檢視中選擇 old/new 側
---
## 附錄:原始碼參考
<details>
<summary><strong>點擊展開檢視原始碼位置</strong></summary>
> 更新時間:2026-01-24
| 功能 | 檔案路徑 | 行號 |
|--- | --- | ---|
| 程式碼審查伺服器 | [`packages/server/review.ts`](https://github.com/backnotprop/plannotator/blob/main/packages/server/review.ts#L1-L302) | 1-302 |
| 程式碼審查 UI | [`packages/review-editor/App.tsx`](https://github.com/backnotprop/plannotator/blob/main/packages/review-editor/App.tsx#L1-L150) | 1-150 |
| DiffViewer 元件 | [`packages/review-editor/components/DiffViewer.tsx`](https://github.com/backnotprop/plannotator/blob/main/packages/review-editor/components/DiffViewer.tsx#L1-L349) | 1-349 |
| Git 工具 | [`packages/server/git.ts`](https://github.com/backnotprop/plannotator/blob/main/packages/server/git.ts#L1-L148) | 1-148 |
| Hook 入口(review) | [`apps/hook/server/index.ts`](https://github.com/backnotprop/plannotator/blob/main/apps/hook/server/index.ts#L46-L84) | 46-84 |
| 程式碼註解類型定義 | [`packages/ui/types.ts`](https://github.com/backnotprop/plannotator/blob/main/packages/ui/types.ts#L53-L83) | 53-83 |
**關鍵類型**:
- `CodeAnnotationType`:程式碼註解類型列舉(comment、suggestion、concern)(`packages/ui/types.ts:53`)
- `CodeAnnotation`:程式碼註解介面(`packages/ui/types.ts:55-66`)
- `DiffType`:Diff 類型列舉(uncommitted、staged、unstaged、last-commit、branch)(`packages/server/git.ts:10-15`)
- `GitContext`:Git 上下文介面(`packages/server/git.ts:22-26`)
**關鍵函式**:
- `startReviewServer()`:啟動程式碼審查伺服器(`packages/server/review.ts:79`)
- `runGitDiff()`:執行 git diff 指令(`packages/server/git.ts:101`)
- `getGitContext()`:取得 Git 上下文(分支資訊和 diff 選項)(`packages/server/git.ts:79`)
- `parseDiffToFiles()`:將 diff 解析為檔案清單(`packages/review-editor/App.tsx:48`)
- `exportReviewFeedback()`:將註解匯出為 Markdown 回饋(`packages/review-editor/App.tsx:86`)
**API 路由**:
- `GET /api/diff`:取得 diff 內容(`packages/server/review.ts:118`)
- `POST /api/diff/switch`:切換 diff 類型(`packages/server/review.ts:130`)
- `POST /api/feedback`:提交審查回饋(`packages/server/review.ts:222`)
- `GET /api/image`:取得圖片(`packages/server/review.ts:164`)
- `POST /api/upload`:上傳圖片(`packages/server/review.ts:181`)
- `GET /api/agents`:取得可用 agents(OpenCode)(`packages/server/review.ts:204`)
**業務規則**:
- 預設檢視未提交的 diff(`apps/hook/server/index.ts:55`)
- 支援切換到 vs main diff(`packages/server/git.ts:131`)
- 回饋格式化為 Markdown(`packages/review-editor/App.tsx:86`)
- 批准時傳送「LGTM」文字(`packages/review-editor/App.tsx:430`)
</details>