依 todo.md 執行的規範治理專案:新增 spec-preflight 等 14 個共用規範(含 conventional-commit/pull-request/git-push/issue-read/todo-list/ask-user/ subagent/no-scratch-files/skill-invocation/script-path/action-scaffold/ node-src-layout/plugin-cli/model),擴充 spec-git-safety 與 spec-gitea(token 優先序、機密遮蔽、Wiki 頁名轉義規則);新增可執行 skill `models`(模型能力 查詢與標籤)與 `todo`(依指定模型產生/附加 todo.md);新增 plugin.meta.json 單一事實來源與 gen-plugin-files.mjs 樣板產生器,統一四個 repo 的 manifest/ README/AGENTS.md 並移除寫死的本機使用者路徑;新增 shared/scripts/lib 的 log/機密遮蔽三語言參考實作。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
5.8 KiB
5.8 KiB
name, description
| name | description |
|---|---|
| spec-pull-request | JSC plugins 共用「PR 建立流程」:目標分支不得臆測(明確得知或詢問使用者)、解析 origin 座標決定 owner/repo(host 依 spec-gitea 主機決定順序)、full 與 simple 兩種 PR 描述模式、`POST /pulls` 的 body 以 UTF-8 檔案帶入(不可字面 `\n`)、已有相同 head→base 的 open PR 時沿用不重開、API 失敗遮蔽 token、完成後提醒清除對話內文。當其他 skill 內文引用 spec-pull-request 或 /jsc-shared:spec-pull-request、或需要透過 Gitea API 建立 PR 時載入此 skill。單獨被使用者呼叫時,直接說明本規範內容。 |
spec-pull-request — 共用 PR 建立流程
所有 JSC skills 需要透過 Gitea API 開 Pull Request(例如 review-resolve 依議題/findings 修復後發 PR、target 每日待辦完成後對預設分支發 PR)時,一律遵守以下規範。本 spec 只講 PR 流程本身;token 機密保護與遮蔽規則一律引用 /jsc-shared:spec-gitea,不在此重複。
目標分支不得臆測
- 目標分支必須是明確得知(呼叫端參數帶入、或流程中已確認的遠端預設分支)或詢問使用者取得,嚴禁猜測或預設(不可自行假設
develop/main/master)。 - 若呼叫端有「遠端預設分支」這類已判定好的來源(如
git symbolic-ref refs/remotes/origin/HEAD),可直接採用視為「明確得知」,不需再問;沒有把握時一律停下詢問,可用git branch -r列出分支輔助使用者選擇。 - 目標分支一旦確定,後續建立 PR、查詢既有 PR 都以同一個值為準,不可中途換掉。
解析 origin 座標(host/owner/repo)
PR 相關的 API 呼叫都建立在 <owner>/<repo> 這個座標上,一律從 git remote get-url origin 解析:
git remote get-url origin
# 例:https://gitea.jsc.idv.tw/plugins/code-review.git
# → host=gitea.jsc.idv.tw、owner=plugins、repo=code-review
- host 的決定順序(
--host參數/$GITEA_HOST/origin 所在主機/詢問使用者)是唯一權威流程,一律引用/jsc-shared:spec-gitea的「gitea 主機決定順序」,不在此另行複述或改動順序。 - 解析失敗(origin 不是 Gitea 網址、或無法拆出 owner/repo)→ 回報並停止,不猜測替代座標。
已有相同 head→base 的 open PR 時沿用不重開
每次開 PR 前必須先查,不可直接送出建立請求造成重複 PR:
curl -sS -H "Authorization: token ${GITEA_TOKEN}" \
"https://<host>/api/v1/repos/<owner>/<repo>/pulls?state=open&base=<目標分支>"
- API 只能用
base篩選,head 需要在回應中自行比對:分頁完整讀取(依/jsc-shared:spec-gitea的分頁慣例),逐筆檢查head.ref(或對等欄位)是否等於本次 PR 的來源分支。 - 找到
head=<來源分支>→base=<目標分支>的 open PR → 沿用它,不重複建立:- 回報既有 PR 的連結/編號給使用者。
- 本次新推的 commit 會自動出現在該 PR 上;視情境需要可在該 PR 補一則本次進度留言,但不再呼叫
POST /pulls。
- 沒找到才進入下一節建立新 PR。
PR 描述模式(full / simple)
呼叫端依需求二選一,未指定時預設 full,不要為描述形式中斷詢問:
| 模式 | 內容 | 產生方式 |
|---|---|---|
full(完整版) |
結構化繁體中文說明——變更摘要、影響範圍、重點檔案/模組、風險或注意事項 | 重新分析並總結 git diff <目標分支>...<PR 來源分支>(比對來源分支自分岔點以來的變更),不是貼原始 diff,而是「人讀得懂的總結」 |
simple(簡單版) |
逐條列出本分支領先目標分支的 commit 訊息 | git log --oneline "<目標分支>..<PR 來源分支>",以條列呈現每行 commit 訊息 |
- 呼叫端也可直接提供自訂描述文字取代以上兩種模式;此時原樣採用,不再套用
full/simple的產生方式。 - 標題預設取一句總結(可用首個
feat/fixcommit 訊息或分支用途);呼叫端若有更貼合情境的固定命名規則(例如含日期的前綴),可自行覆寫此預設。
建立 PR:body 一律用 UTF-8 檔案帶入
POST /pulls 的 body 必須以 UTF-8 檔案帶入,換行用實際換行,不可送出字面 \n(例如讓 PR 顯示成 ## Commit\n\n- ... 這種未展開的跳脫字串):
# body.json 先以 UTF-8 檔案(heredoc/printf/程式寫檔)準備好,換行是實際換行
curl -sS -X POST \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
"https://<host>/api/v1/repos/<owner>/<repo>/pulls" \
--data @body.json
- 不可用 shell 字面
"標題\n內容"這種寫法組 body;若用jq組 JSON,改用jq --rawfile或等效方式帶入多行內容。 - 成功:取回應中的 PR 連結/編號回報使用者。
- 失敗:顯示 API 回應的錯誤訊息供排查,先依
/jsc-shared:spec-gitea的機密遮蔽規則遮蔽 token 才能輸出。常見錯誤:- 目標分支不存在。
- 已有相同 head→base 的 open PR(回到上一節查詢並沿用,不當作失敗處理)。
- token 權限不足(401/403)。
完成後提醒清除對話內文
push/API 呼叫過程可能讓 token 殘留在對話內文,PR 建立完成後:
- 通知使用者:PR 連結/編號、目標分支、採用的描述形式(
full/simple/自訂)。 - 提醒清除對話內文以防 token 外洩(互動情境用 Claude Code
/clear或當前助理對等指令;排程情境只寫 log、不輸出 token)。 - 清除前再次確認輸出與 log 中沒有明文 token——細節與遮蔽規則一律依
/jsc-shared:spec-gitea,本 spec 不重複。