From 25cb4d1f634a1bacd18d9b86203ea99b5132078d Mon Sep 17 00:00:00 2001 From: richblack Date: Tue, 23 Jun 2026 12:20:23 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20v1.2.0=20=E2=80=94=20issue=20=E8=99=95?= =?UTF-8?q?=E7=90=86=E6=8C=87=E5=BC=95=20+=20pre-write-guard=20=E5=AE=9A?= =?UTF-8?q?=E4=BD=8D=E9=87=90=E6=B8=85=20+=20=E9=96=8B=E7=99=BC=20wiki=20?= =?UTF-8?q?=E9=9A=94=E9=9B=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit issue #1:新增 /issue-handle slash command,CC 處理 GitHub issue 的 普世指引——讀回自己 repo 直接做、跨 repo 發要先問人、禁掛 Actions/cron 自動輪詢(會觸發 GitHub 異常偵測)。屬共用指引,install/update 不分模組裝。 issue #2:pre-write-guard.sh 釐清定位為「按需手填的空插槽」,非裝上就 生效的警察。檔頭明講有 CC 在場時直接叫 CC 寫貼合的 guard 更好;install/ update 安裝時提示「預設不攔,要手填才生效」,消除安全錯覺。hook 執行維持 安靜不洗版。 另:repo 自己裝了一套開發用 wiki(內部記錄),與 template/ 成品範本實體 隔離,.gitignore 排除 .claude/wiki/、.claude/hooks/、.claude/VERSION, 不推 GitHub。 升版 1.2.0,CHANGELOG 記錄。 Co-Authored-By: Claude Opus 4.8 (1M context) --- .gitignore | 7 +++ CHANGELOG.md | 18 +++++++ README.md | 1 + scripts/install.sh | 10 ++++ scripts/update.sh | 3 +- template/.claude/VERSION | 2 +- template/.claude/commands/issue-handle.md | 61 +++++++++++++++++++++++ template/.claude/hooks/pre-write-guard.sh | 24 ++++++--- 8 files changed, 118 insertions(+), 8 deletions(-) create mode 100644 template/.claude/commands/issue-handle.md diff --git a/.gitignore b/.gitignore index 100146d..ff65f13 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,10 @@ # editorial-image skill 為私房出圖工具,不上傳此公開模板 repo skills/editorial-image/ + +# 根目錄自裝的開發 wiki — 內部記錄,不推 GitHub(用戶看的是 template/ 裡的範本) +# 內容檔是我們開發此 template 的記錄;架構檔(INDEX/.wikiignore/hooks)是從 +# template/ 複製來自用的,範本本體已在 template/ 推上去,這份不重複推。 +.claude/wiki/ +.claude/hooks/ +.claude/VERSION diff --git a/CHANGELOG.md b/CHANGELOG.md index e46341f..0a075da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,24 @@ --- +## 1.2.0 — GitHub issue 指引 + pre-write-guard 定位釐清 + +**新增** +- `/issue-handle` slash command(`template/.claude/commands/issue-handle.md`): + CC 處理 GitHub issue 的普世指引,三層界線—— + ①讀/回/結案自己 repo 的 issue(直接做); + ②發 issue 給別的 repo(先問人,不擅自); + ③**禁止掛 Actions/cron/webhook 自動輪詢 issue**(會觸發 GitHub 異常偵測、被 rate limit)。 + 屬共用指引,install/update 不分模組都裝。(issue #1) + +**變更** +- `pre-write-guard.sh` 釐清定位(issue #2):它是「按需手填的空插槽」,不是裝上就生效的警察。 + - 檔頭明講:**有 CC 在場時,直接叫 CC 寫貼合的 guard hook 更好**,這個空殼範本只對「手動 DIY」用戶有價值。 + - 解決安全錯覺:install.sh / update.sh 安裝它時提示「預設不攔任何東西,要手填+掛 settings 才生效」, + 讓用戶不會誤以為裝了就有保護。(hook 執行時維持安靜,避免每次 Write 洗版。) + +--- + ## 1.1.0 — 一鍵更新 **新增** diff --git a/README.md b/README.md index 52acbcf..70e1e6f 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,7 @@ system-dev-template/ | `/wiki-capture` | 把這次對話的結論存進 wiki | | `/wiki-update` | Session 結束,更新 status.md | | `/sdd-check` | 確認當前任務有沒有對應 SDD | +| `/issue-handle` | 處理 GitHub issue(讀回自己 repo / 跨 repo 發要先問 / 禁自動輪詢)| 命名閉環:init(建) → update(存,session 末) ↔ recall(接,session 初) → capture(隨時存結論)。 diff --git a/scripts/install.sh b/scripts/install.sh index 6c3e4bd..caaac93 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -141,6 +141,9 @@ fi # ── 共用 hook:專案自訂禁令骨架(預設停用)──────── download_if_missing ".claude/hooks/pre-write-guard.sh" "$REPO_URL/.claude/hooks/pre-write-guard.sh" +# ── 共用指引:GitHub issue 處理(讀/回普世,跨 repo 發要先問,禁自動輪詢)── +download_if_missing ".claude/commands/issue-handle.md" "$REPO_URL/.claude/commands/issue-handle.md" + chmod +x .claude/hooks/*.sh 2>/dev/null || true # ── 依模組產生 settings.json 的 hooks 區塊 ──────── @@ -233,6 +236,12 @@ if [ -f ".claude/settings.json" ]; then fi fi +# pre-write-guard 是空殼,提醒它預設不攔(避免「以為有保護其實沒有」的安全錯覺) +echo "" +echo "ℹ️ .claude/hooks/pre-write-guard.sh 是「按需手填的空插槽」,預設不攔任何東西。" +echo " 需要專案禁令?最簡單是叫你的 CC 寫一支貼合的 guard hook(比範本表達力強);" +echo " 或自己填 FORBIDDEN_PATTERNS 並到 settings.json 掛上才會生效。" + echo "" echo "🚀 下一步:" if $WANT_WIKI; then @@ -242,4 +251,5 @@ fi if $WANT_SDD; then echo " 動 code 前先在 docs/3-specs/[子系統]/ 建 design.md(可用 /sdd-check 協助)" fi +echo " GitHub issue:CC 可直接 /issue-handle 讀回自己 repo 的 issue(禁自動輪詢)" echo "" diff --git a/scripts/update.sh b/scripts/update.sh index f7cb6ac..6ccd0c5 100755 --- a/scripts/update.sh +++ b/scripts/update.sh @@ -90,8 +90,9 @@ $HAS_SDD && echo " • SDD" echo "" # ── 模板/邏輯檔:覆蓋更新 ────────────────────────── -# 共用 hook +# 共用 hook 與指引 update_file ".claude/hooks/pre-write-guard.sh" "$TEMPLATE_URL/.claude/hooks/pre-write-guard.sh" +update_file ".claude/commands/issue-handle.md" "$TEMPLATE_URL/.claude/commands/issue-handle.md" update_file ".claude/VERSION" "$TEMPLATE_URL/.claude/VERSION" if $HAS_WIKI; then diff --git a/template/.claude/VERSION b/template/.claude/VERSION index 9084fa2..26aaba0 100644 --- a/template/.claude/VERSION +++ b/template/.claude/VERSION @@ -1 +1 @@ -1.1.0 +1.2.0 diff --git a/template/.claude/commands/issue-handle.md b/template/.claude/commands/issue-handle.md new file mode 100644 index 0000000..8df58d3 --- /dev/null +++ b/template/.claude/commands/issue-handle.md @@ -0,0 +1,61 @@ +--- +description: 處理本 repo 的 GitHub issue(讀/回/結案),跨 repo 發要先問人 +--- + +# /issue-handle — GitHub issue 處理指引 + +你(CC)可以、也該主動用內建的 `gh` CLI 讀寫**自己 repo** 的 GitHub issue。 +很多人不知道這件事——`gh` 已內建認證,零開發、零外部依賴。issue 同源於 repo, +比 Notion / Sheets 更適合做交辦與待辦,不必引入外部 SaaS。 + +這份指引分三層,界線要守住。 + +--- + +## 1. 讀 / 回 / 結案(普世基本功 — 直接做,不用問) + +對**自己這個 repo**,主動處理 open issue: + +```bash +gh issue list --state open # 看有哪些待辦 +gh issue view # 讀完整內容 +# …實作… +gh issue comment --body "做了什麼、怎麼決定的、改了哪些檔" +gh issue close # 確認解決後結案 +``` + +回覆要有料:說清楚**做了什麼、為什麼這樣決定、動了哪些檔**,而不是只回「done」。 +issue 作者(可能是另一個 repo 的 CC,或人類)要靠你的回覆判斷對不對。 + +--- + +## 2. 發 issue 給「別的 repo」(要先問人 — 不可擅自) + +當你發現**別的 repo** 有值得修正的地方時: + +> ❌ 不要擅自 `gh issue create -R other/repo …` +> ✅ 先問人類:「我發現 X repo 有 Y 問題,要我幫你去那邊發 issue 嗎?」得到同意才發。 + +理由:通用 template 不知道使用者對那個 repo 有沒有權限、想不想發。留一道人類確認最安全。 +(對**自己 repo** 開 issue 記待辦則可直接做——那是自己的 repo。) + +--- + +## 3. flag 安全界線(最重要 — 絕不可越) + +**「有事才讀」,禁止自動輪詢。** + +- ✅ 想看 issue → 當下主動 `gh issue list`。 +- 🚫 **禁止**掛 GitHub Actions / cron / webhook 去**自動輪詢** issue。 + +為什麼這條是硬底線:自動輪詢 + 事件 fan-out 正是會觸發 GitHub 異常偵測、 +害你的 token 被 rate limit 砍掉的流量模式。template 給很多人用,這條界線必須守住, +保護使用者不踩雷。需要「定期檢查」就由人類主動跑這個指令,不要自動化。 + +--- + +## (可選)用 label 分來源 + +若想用同一套流程同時管「內部交辦」與「外部回報」,可建兩個 label: +`internal`(協作/交辦)、`user`(外部使用者回報),靠 label 分流。 +這對通用 template 不預設——你的 repo 需要再建。 diff --git a/template/.claude/hooks/pre-write-guard.sh b/template/.claude/hooks/pre-write-guard.sh index 50f6d5f..abe5030 100755 --- a/template/.claude/hooks/pre-write-guard.sh +++ b/template/.claude/hooks/pre-write-guard.sh @@ -1,12 +1,22 @@ #!/bin/bash -# PreToolUse hook 範本骨架 —— 專案自訂禁令 -# wishlist §2 可選:讓使用者自訂專案禁令(例:「KBDB 禁動表」「某目錄唯讀」)。 +# PreToolUse hook 範本骨架 —— 專案自訂禁令(預設空殼,不攔任何東西) # -# 預設不啟用。要用時: -# 1. 在下面 FORBIDDEN_PATTERNS 填入禁改的路徑/檔名 pattern +# ⚠️ 定位(讀清楚再用): +# 這支跟其他三支 hook 不同——它不是「裝上就生效的警察」,而是一個「按需手填的 +# 空插槽」。預設狀態下 FORBIDDEN_PATTERNS 是空的,它【不攔任何東西】。 +# 別誤以為裝了它就有保護——空殼 = 沒保護。 +# +# 🤖 有 CC 在場的話,通常不需要這個範本: +# 直接叫你的 CC「幫我寫一支 guard hook,禁止改 X」。CC 現寫的條件邏輯, +# 表達力遠勝這裡的 glob FORBIDDEN_PATTERNS(例如「禁子 repo 的 code 但放行 .md」 +# 這種細緻規則,glob 寫不出來,CC 的條件判斷寫得出來)。 +# 這個範本只對「不靠 CC、想自己手動 DIY bash」的用戶有價值。 +# +# 要啟用(手動 DIY 路線): +# 1. 在下面 FORBIDDEN_PATTERNS 填禁改的路徑/檔名 pattern # 2. 到 .claude/settings.json 的 PreToolUse 加掛這支 # -# 掛在 PreToolUse(matcher: Write|Edit)。stdin 收到 JSON:{ tool_name, tool_input: { file_path } } +# 掛在 PreToolUse(matcher: Write|Edit)。stdin 收 JSON:{ tool_name, tool_input:{ file_path } } # 命中禁令 → exit 2 擋。 # # 誠實限制:只擋直接寫檔。bash 繞道、helper 間接改動擋不到。留痕可審 ≠ 技術防偽。 @@ -21,7 +31,9 @@ FORBIDDEN_PATTERNS=( # "*/your/protected/path/*" ) -# 沒設任何禁令 → 直接放行(骨架預設狀態) +# 沒設任何禁令 → 空殼狀態,安靜放行。 +# (不在這裡 print——PreToolUse 每次 Write/Edit 都會跑,每次喊話會洗版。 +# 「這是空殼」的提醒改由 install.sh / update.sh 安裝時告知,那裡用戶一定看得到。) [ ${#FORBIDDEN_PATTERNS[@]} -eq 0 ] && exit 0 INPUT=$(cat)