From 465670524e0f634b987a58a8d2b1d51359e7092b Mon Sep 17 00:00:00 2001 From: Jeffery Date: Thu, 18 Jun 2026 04:52:10 +0000 Subject: [PATCH] =?UTF-8?q?docs(code-review-resolve):=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=20findings=20=E8=88=87=20exclusions=20=E8=99=95=E7=90=86?= =?UTF-8?q?=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- skills/code-review-resolve/SKILL.md | 98 ++++++++++++++++++++--------- 1 file changed, 68 insertions(+), 30 deletions(-) diff --git a/skills/code-review-resolve/SKILL.md b/skills/code-review-resolve/SKILL.md index 7563f65..ce3dc25 100644 --- a/skills/code-review-resolve/SKILL.md +++ b/skills/code-review-resolve/SKILL.md @@ -1,17 +1,17 @@ --- name: code-review-resolve -description: 解決 `.gitea/ai-review/findings.json` 的 AI review findings,先同步 git(fetch → pull,必要時嘗試解衝突),再依嚴重度逐條修復或標示待人工處理,完成後清空 findings;接著可將工作區變更依 conventional commit 類型分類提交、push 當前分支,並透過 Gitea API 對指定目標分支開 PR。當使用者說解決 findings、處理 AI review 問題、修掉 `.gitea/ai-review` 問題、依嚴重度修復後分類提交,或要分類 commit 並 push/開 PR 時觸發。不適用於:產生 findings、單純 code review 不修改、只保存裁決紀錄,或只要不分類的單一 commit。 +description: 解決 `.gitea/ai-review/findings.json` 的 AI review findings,先同步 git(fetch → pull,必要時嘗試解衝突),再依嚴重度逐條修復;可判斷為誤報者寫入 `.gitea/ai-review/exclusions.json`,已解決或已登記為誤報的 finding 可自 findings 移除;接著可將工作區變更依 conventional commit 類型分類提交、push 當前分支,並透過 Gitea API 對指定目標分支開 PR。當使用者說解決 findings、處理 AI review 問題、修掉 `.gitea/ai-review` 問題、依嚴重度修復後分類提交,或要分類 commit 並 push/開 PR 時觸發。不適用於:產生 findings、單純 code review 不修改、只保存裁決紀錄,或只要不分類的單一 commit。 argument-hint: "[--findings ] [--target <目標分支>] [--pr-desc ] [--no-commit] [--no-pr] [--yes]" --- # code-review-resolve — 解決 AI review findings、分類提交、push 並開 PR -五階段 skill:先執行 **git 同步**(`git fetch` → `git pull`,必要時告知並嘗試解衝突),再**逐條修掉** `.gitea/ai-review/findings.json` 裡的問題並清空該檔,接著把工作區所有變更**依 conventional commit 類型分門別類 commit**,然後 **push 當前分支**,最後**透過 Gitea API 發 PR**。 +五階段 skill:先執行 **git 同步**(`git fetch` → `git pull`,必要時告知並嘗試解衝突),再**逐條處理** `.gitea/ai-review/findings.json` 裡的問題;成立問題修復後自 findings 移除,可判斷為誤報者寫入 `.gitea/ai-review/exclusions.json` 後也可自 findings 移除,接著把工作區所有變更**依 conventional commit 類型分門別類 commit**,然後 **push 當前分支**,最後**透過 Gitea API 發 PR**。 | 階段 | 動作 | | --- | --- | | A. Git 同步 | `git fetch` → `git pull` → 若有衝突則告知並嘗試解衝突 | -| B. 解決問題 | 讀 `findings.json` → 依等級 🔴→🟠→🟡→🔵 逐條修復程式碼 → 清空 `findings.json` 為 `[]` | +| B. 解決問題 | 讀 `findings.json` / `exclusions.json` → 依等級 🔴→🟠→🟡→🔵 逐條修復或判斷誤報 → 已解決者自 `findings.json` 移除,誤報寫入 `exclusions.json` 後也可移除 | | C. 分類提交 | 分析工作區所有變更 → 依 feat/fix/docs/style/refactor/perf/test/chore/revert 分組 → 各組一個 commit | | D. Push 當前分支 | 認證管理器 → 失敗改 token → 再失敗詢問使用者 | | E. 發出 PR | 確定目標分支(不明必問)→ 選 PR 描述(完整/簡單/自訂)→ token 呼叫 Gitea API 建 PR → 通知並清除內文 | @@ -22,12 +22,12 @@ argument-hint: "[--findings ] [--target <目標分支>] [- - **語言**:所有面向使用者的輸出(修復清單、提交計畫、總結、反問)與 **commit 訊息** 一律使用**繁體中文(台灣用語)**; 僅程式碼識別字、檔名、git 指令、conventional commit 的 `type`(`feat`/`fix`…)等技術標識保留原文,**不可**使用簡體字。 -- **編碼無亂碼(含繁中、全形標點、emoji)**:凡輸出或寫入只要含繁體中文,一律 **UTF-8(不含 BOM)**,不得出現問號方框()或錯碼。涵蓋:清空後的 `findings.json`、**commit 訊息**、**PR 標題/描述**、終端訊息,與等級 emoji 🔴🟠🟡🔵。實作要點: +- **編碼無亂碼(含繁中、全形標點、emoji)**:凡輸出或寫入只要含繁體中文,一律 **UTF-8(不含 BOM)**,不得出現問號方框()或錯碼。涵蓋:更新後的 `findings.json` / `exclusions.json`、**commit 訊息**、**PR 標題/描述**、終端訊息,與等級 emoji 🔴🟠🟡🔵。實作要點: - **寫檔**:優先用助理的檔案寫入工具(預設 UTF-8 無 BOM)。若改用 shell 寫檔,**避免 PowerShell 的 `>`/`Out-File`**(預設可能寫成 UTF-16 或加 BOM);需要時用 `Set-Content -Encoding utf8NoBOM`,或在 bash 用 `printf`/heredoc。 - **commit 訊息**:用 `git commit -m` 直接帶字串,或寫進 UTF-8 無 BOM 的檔案再 `git commit -F `;確保 `git config i18n.commitEncoding utf-8`。 - **PR body**:以 UTF-8 JSON 經 API 送出(如 `--data @body.json`,該檔為 UTF-8 無 BOM)。 - **送出前自我檢查**:產生含繁中的檔案/訊息後,回頭確認沒有亂碼或 BOM 再提交/送出。 -- **修改程式碼、commit、push、開 PR 屬於更動專案/對外行為**:除非帶 `--yes` 或使用者已明確授權,**否則每階段動手前先輸出計畫(預覽)並取得同意**;使用者拒絕則只輸出計畫、不動檔不提交不推送。 +- **自動執行原則**:除非使用者明確要求先確認,或遇到不可忽略的必要決策(例如目標分支缺失、pull 策略不明、無法安全解衝突、需人工判斷的設計取捨、push 憑證皆失敗),否則各階段只需輸出簡短計畫/進度後直接執行到完成;不要為一般修復、寫檔、分類 commit、push 或開 PR 反覆詢問。 - **Token 機密保護(極重要)**:gitea token 一律**從環境變數讀取**(如 `$GITEA_TOKEN`),**絕不**寫死在 skill、commit、PR 內文或任何輸出;**不可** echo 含 token 的指令或 URL、不可寫進 log。所有顯示給使用者的指令/錯誤訊息都要**遮蔽 token**(如以 `***` 取代)。階段 E 完成後依規範清除對話內文(見 E6)。 --- @@ -38,10 +38,10 @@ argument-hint: "[--findings ] [--target <目標分支>] [- - `--findings <路徑>`:findings 檔路徑。**省略時預設 `.gitea/ai-review/findings.json`**(相對於工作目錄根)。 - `--target <目標分支>`:PR 的目標分支。**省略時必須詢問使用者,不可猜測**;若需要避免把同名來源分支誤推到目標分支,可能會在階段 D 先詢問並於階段 E 沿用。 -- `--pr-desc `:PR 描述形式。`full`=完整版(重新分析 diff 總結)、`simple`=簡單版(逐條列 commit 訊息)、或直接給自訂文字;省略則於階段 E 詢問。 -- `--no-commit`:只做階段 A/B(git 同步 + 修復 + 清空 findings),**不**執行階段 C/D/E(不提交、不推送、不開 PR)。 +- `--pr-desc `:PR 描述形式。`full`=完整版(重新分析 diff 總結)、`simple`=簡單版(逐條列 commit 訊息)、或直接給自訂文字;省略時預設 `simple`,不要為描述形式中斷詢問。 +- `--no-commit`:只做階段 A/B(git 同步 + 修復 + 更新 findings/exclusions),**不**執行階段 C/D/E(不提交、不推送、不開 PR)。 - `--no-pr`:執行到階段 D(push)為止,**不**開 PR(階段 E 略過)。 -- `--yes`:略過各階段的同意確認,直接執行(修復、清空、commit、push、開 PR 一氣呵成)。未帶時每階段先預覽再確認。 +- `--yes`:明確要求全自動執行(修復、更新 findings/exclusions、commit、push、開 PR 一氣呵成);即使未帶此參數,也依「自動執行原則」盡量不中斷,只有必要決策才詢問。 --- @@ -56,7 +56,7 @@ git rev-parse --abbrev-ref HEAD git status --porcelain ``` -- **若工作區已有未提交變更**:先告知使用者同步可能需要 merge / rebase 並可能與本地變更衝突;未帶 `--yes` 時先取得同意再繼續。 +- **若工作區已有未提交變更**:先告知使用者同步可能需要 merge / rebase 並可能與本地變更衝突;除非使用者要求先確認或目前狀態明顯容易覆蓋未提交工作,否則繼續同步。 - **若目前不在一般分支上**(例如 detached HEAD):回報狀態並停止,請使用者切到要處理的分支後再執行。 ### A2. Fetch 遠端更新 @@ -90,9 +90,9 @@ git pull --- -## 階段 B:依嚴重等級逐條解決問題 +## 階段 B:依嚴重等級逐條解決問題或登記誤報 -### B1. 讀取 findings +### B1. 讀取 findings 與 exclusions 讀 `--findings` 指定(或預設 `.gitea/ai-review/findings.json`)的檔案,內容為 **top-level JSON 陣列**,每筆是一個問題物件。常見欄位(不同產生器命名略有差異,需容錯對應): @@ -105,40 +105,78 @@ git pull | 問題描述 | `description` / `detail` / `描述` | | 修正建議 | `suggestion` / `fix` / `建議` | +`findings.json` 與 `.gitea/ai-review/exclusions.json` 的 canonical 格式須對齊 `https://gitea.jsc.idv.tw/actions/code-review`: + +- 兩者都使用 **top-level JSON array**,不得包在 `{ "findings": [...] }`、`{ "exclusions": [...] }` 或 `{ "excluded_findings": [...] }`。 +- `findings.json` 每筆至少保留 action 使用的必要欄位: + + ```json + { + "level": "critical|warning|info", + "role": "審查角色名稱", + "location": "檔案路徑:行號 或 檔案路徑", + "suggestion": "繁體中文(台灣用語)的具體修改建議" + } + ``` + +- `exclusions.json` 每筆以最小且穩定的排除條目為主,優先保留原始問題文字、語言與語意;建議欄位: + + ```json + { + "location": "檔案路徑:行號 或 檔案路徑", + "role": "審查角色名稱", + "original_finding": "原 finding 的 suggestion 或完整問題文字", + "reason": "判斷為誤報或不適用的原因" + } + ``` + + 若既有 exclusions 使用 `suggestion`、`title`、`note` 等欄位,讀取時可容錯;寫回時仍要維持 top-level array,並盡量採用上述 canonical 欄位。 + - **檔案不存在、內容為 `[]` 或空白** → 視為「無問題待解決」,輸出告知並**直接跳到階段 C**(仍會把工作區既有變更分類提交,除非 `--no-commit`)。 - **JSON 解析失敗** → 回報錯誤與檔案路徑並停止,不臆測內容、不亂改檔。 +- `exclusions.json` 不存在時視為空陣列,必要時建立 `.gitea/ai-review/exclusions.json` 並寫入 `[]` 或新增後的排除項目。 +- 若 `exclusions.json` 是舊 wrapper 格式(例如 `{ "exclusions": [...] }` 或 `{ "excluded_findings": [...] }`),先正規化為 top-level array 再寫回。 ### B2. 依嚴重等級排序 把所有 finding 依等級由高到低排序:**🔴 嚴重 → 🟠 高 → 🟡 中 → 🔵 低**。 -英文/其他寫法對應:`critical`/`blocker`→🔴、`high`/`major`→🟠、`medium`/`moderate`→🟡、`low`/`minor`/`info`→🔵;無法辨識的等級**排在最後**並標註「等級未知」。 +canonical 等級為 `critical` / `warning` / `info`;其他寫法容錯對應:`critical`/`blocker`→🔴、`high`/`major`/`warning`→🟠、`medium`/`moderate`→🟡、`low`/`minor`/`info`→🔵;無法辨識的等級**排在最後**並標註「等級未知」。寫回 `findings.json` 時盡量保留原欄位值,除非需要修正成 canonical 格式。 -### B3. 逐條修復(高等級先) +### B3. 逐條處理(高等級先) -輸出一張「修復計畫」表並(未帶 `--yes` 時)請使用者確認後,**依排序由上而下逐條**處理: +輸出一張「處理計畫」表,除非使用者要求確認或遇到必要決策,否則**依排序由上而下逐條**處理: -| # | 等級 | 問題 | 檔案位置 | 行數 | 修復方式 | +| # | 等級 | 問題 | 檔案位置 | 行數 | 處理方式 | | --- | --- | --- | --- | --- | --- | 對每一條 finding: 1. 讀取對應檔案與其脈絡(依 `file` / `line`)。 -2. 依 `suggestion`/`description` 在程式碼中**實作修正**;建議含糊或與現況不符時,依原始碼脈絡做最小且合理的修正。 -3. **無法安全自動修復**(例如需求不明、牽涉設計取捨、檔案不存在)→ **不硬改**,標記為「待人工處理」並記錄原因,繼續下一條。 -4. 逐條完成後,記錄該條結果(✅ 已修復 / ⏭️ 待人工處理 + 原因)。 +2. 先判斷是否為誤報或不適用:例如程式碼脈絡證明指控不成立、已有等價防護、問題來自 action 已知排除規則、CI/CD 必要權限、或 finding 對非本次變更做不合理要求。 +3. **可判斷為誤報** → 不改程式碼;將排除條目 append 到 `.gitea/ai-review/exclusions.json`,保留原始 finding 的語言與語意,避免過度改寫;若已有等價 exclusion(同檔案路徑、角色、原始文字或 suggestion 高度相似)則不要重複新增。 +4. **確認為真問題且可安全修復** → 依 `suggestion`/`description` 在程式碼中實作最小合理修正;建議含糊或與現況不符時,依原始碼脈絡做最小且合理的修正。 +5. **無法安全自動修復或無法確認真偽**(例如需求不明、牽涉設計取捨、檔案不存在)→ **不硬改**,標記為「待人工處理」並記錄原因,繼續下一條。 +6. 逐條完成後,記錄該條結果(✅ 已解決 / 🚫 誤報已寫入 exclusions / ⏭️ 待人工處理 + 原因)。 > 一次只處理一條、修完再處理下一條,避免互相干擾;同檔多條問題可合併讀取但仍逐條套用修正。 -### B4. 清空 findings.json +### B4. 更新 findings.json 與 exclusions.json -**所有可修復條目處理完畢後**,把 `findings.json` 內容覆寫為**空陣列**: +**所有條目處理完畢後**,依結果更新 `findings.json` 與 `exclusions.json`: + +- **只有確認已解決,或已確認為誤報並成功寫入 `exclusions.json` 的 finding,才可從 `findings.json` 移除**。 +- 誤報移出 `findings.json` 前,必須先確認 `exclusions.json` 已存在、格式合法、且該排除條目已寫入或已有等價條目;若 exclusions 寫入失敗,該 finding 必須保留。 +- 待人工處理、無法確認真偽、或修復未驗證成功的 finding 必須保留在 `findings.json`。 +- 寫回 `findings.json` 時只保留尚未解決且尚未登記為誤報的 finding;已解決或已登記為誤報的 finding 逐項移除,不需要等待其他問題也處理完。 +- 如果移除後沒有任何 finding 需要保留,將 `findings.json` 寫成空陣列: ```json [] ``` -- 以 UTF-8(不含 BOM)寫入,結尾保留一個換行。 -- **若仍有「待人工處理」條目**:先回報這些條目,**詢問**使用者是否仍要清空(清空代表這些問題不再留在檔案中)。未帶 `--yes` 且使用者未同意 → **保留**這些條目於檔案、只移除已修復的條目,並在總結說明。 +- 寫回 `findings.json` 時保留未解決 finding 的 canonical 欄位(`level`、`role`、`location`、`suggestion`)與有用原欄位;依嚴重度排序。 +- 寫回 `exclusions.json` 時使用 top-level JSON array;新增項目 append 後依既有順序保留並去重。 +- 兩個檔案都以 UTF-8(不含 BOM)寫入,結尾保留一個換行。 --- @@ -171,11 +209,11 @@ git diff --staged # 已暫存變更 | `revert` | 還原先前的提交 | - **同一檔案橫跨多型** → 以該檔**主要異動性質**歸類;難以拆分時就近歸入影響最大的一類,並在總結註記。 -- **階段 B 修復產生的變更**:依其性質歸類(修 bug→`fix`、補功能→`feat`、改文件→`docs`…)。`findings.json` 被清空這項異動歸 `chore`。 +- **階段 B 修復產生的變更**:依其性質歸類(修 bug→`fix`、補功能→`feat`、改文件→`docs`…)。`findings.json` / `exclusions.json` 的問題狀態更新歸 `chore`。 -### C3. 產出提交計畫並確認 +### C3. 產出提交計畫 -把變更檔依 type 分組,**每個 type 一個 commit**,輸出提交計畫供確認(未帶 `--yes` 時): +把變更檔依 type 分組,**每個 type 一個 commit**,輸出提交計畫;除非使用者要求確認或分組有不可忽略的取捨,否則直接提交: | 順序 | type(範圍) | commit 訊息 | 納入檔案 | | --- | --- | --- | --- | @@ -188,7 +226,7 @@ git diff --staged # 已暫存變更 - ❌ 錯(只是重述 type,禁止):`feat(新增功能)`、`fix(修正錯誤)`、`perf(優化效能)`、`docs(文件)`、`chore(雜項)`。 - 一組異動橫跨多個功能而無單一主體時,才退而取最貼近的上層範圍(例如多個 manifest → `plugin 設定`)。 - `一句總結`:把這個 commit 內所有異動**總結成一句**繁體中文(簡短、聚焦做了什麼)。 - - 範例:`feat(使用者登入): 新增帳密登入與 token 簽發`、`fix(結帳流程): 修正空購物車導致的結帳例外`、`perf(物件查詢): 改用批次查詢降低 DB 往返`、`docs(README): 補上安裝與呼叫方式說明`、`chore(plugin 版本): bump 至 0.0.8 並清空 findings.json`。 + - 範例:`feat(使用者登入): 新增帳密登入與 token 簽發`、`fix(結帳流程): 修正空購物車導致的結帳例外`、`perf(物件查詢): 改用批次查詢降低 DB 往返`、`docs(README): 補上安裝與呼叫方式說明`、`chore(ai-review 狀態): 更新 findings.json 與 exclusions.json`。 - **提交順序建議**:`fix`/`feat` 等核心異動在前,`docs`/`style`/`chore` 在後(純屬建議,可依相依性調整)。 ### C4. 執行分類提交 @@ -218,7 +256,7 @@ git rev-parse --verify "origin/${source_branch}" ``` - 若來源分支沒有對應的 `origin/`,先記錄「無遠端基準」並繼續;後續若 source/base 同名,階段 E2 仍必須以 `origin/` 作為帶入 commit 的比較基準。 -- 若後續會建立 PR(未帶 `--no-pr`)且尚未知道目標分支,先依階段 E1 的規則詢問目標分支,避免把 commit 直接推進目標分支後才發現 source/base 相同。 +- 若後續會建立 PR(未帶 `--no-pr`)且尚未知道目標分支,先依階段 E1 的規則詢問目標分支,這屬於不可忽略的必要決策,避免把 commit 直接推進目標分支後才發現 source/base 相同。 - 若來源分支名稱與目標分支相同,**不要 push 原來源分支**;記下來源分支與遠端基準,直接進入階段 E,由 E2 建立新的 PR 來源分支、帶入 commit 後再 push 新分支。 1. **認證管理器(優先)**:直接用 git 既有的 credential helper(如 Windows 的 `manager-core`): @@ -298,7 +336,7 @@ git rev-parse --abbrev-ref HEAD ### E4. 決定 PR 描述形式(完整版/簡單版/使用者輸入) -依 `--pr-desc`(或詢問)三選一: +依 `--pr-desc` 三選一;若未提供則預設使用 `simple`,不要為描述形式中斷詢問: - **完整版(`full`)**:**重新分析並總結** `git diff ...`(比對 source 自分岔點以來的變更),整理成結構化繁體中文說明 —— 變更摘要、影響範圍、重點檔案/模組、風險或注意事項。不是貼原始 diff,而是「人讀得懂的總結」。 - **簡單版(`simple`)**:直接把本分支領先 target 的 commit 訊息**逐條列出**: @@ -343,7 +381,7 @@ curl -sS -X POST \ 各階段執行後輸出: - **階段 A**:git fetch / pull 是否成功、是否發生衝突、衝突是否已解決或仍需人工處理。 -- **階段 B**:已修復 N 條(依等級分佈)、待人工處理 M 條(列出原因)、findings.json 是否已清空。 +- **階段 B**:已解決 N 條(依等級分佈)、誤報寫入 exclusions M 條、待人工處理 K 條(列出原因)、`findings.json` 保留/移除筆數與 `exclusions.json` 新增筆數。 - **階段 C**:建立了哪幾個 commit(type+訊息+檔數),或為何略過(`--no-commit` / 無變更)。 - **階段 D**:push 成功與否、用了哪種方式(認證管理器/token/使用者指定),遠端分支名。 - **階段 E**:PR 連結/編號、目標分支、描述形式;並提醒已(或請使用者)清除對話內文以防 token 外洩。 @@ -359,4 +397,4 @@ curl -sS -X POST \ | --- | --- | | Claude Code / Antigravity | `/jsc:code-review-resolve`,或 `/jsc:code-review-resolve --target develop --pr-desc full --yes`、`/jsc:code-review-resolve --no-pr`、`/jsc:code-review-resolve --no-commit` | | Codex | `$code-review-resolve`,或 `$code-review-resolve --target develop --pr-desc simple --yes`,或用 `/skills` 選單 | -| OpenCode | 描述需求(如「讀 .gitea/ai-review/findings.json 依嚴重度逐條修好、清空該檔,把工作區變更依 conventional commit 分類提交,push 後對 develop 發 PR(完整版描述)」)自動觸發 | +| OpenCode | 描述需求(如「讀 .gitea/ai-review/findings.json 依嚴重度逐條處理,更新 findings/exclusions,把工作區變更依 conventional commit 分類提交,push 後對 develop 發 PR(完整版描述)」)自動觸發 |