feat(shared): 新增14個共用spec、models/todo工具與樣板產生器,收斂跨repo重複規範
依 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>
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
---
|
||||
name: spec-pull-request
|
||||
description: 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` 解析:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
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`/`fix` commit 訊息或分支用途);呼叫端若有更貼合情境的固定命名規則(例如含日期的前綴),可自行覆寫此預設。
|
||||
|
||||
## 建立 PR:body 一律用 UTF-8 檔案帶入
|
||||
|
||||
`POST /pulls` 的 body **必須**以 UTF-8 檔案帶入,換行用**實際換行**,不可送出字面 `\n`(例如讓 PR 顯示成 `## Commit\n\n- ...` 這種未展開的跳脫字串):
|
||||
|
||||
```bash
|
||||
# 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 建立完成後:
|
||||
|
||||
1. 通知使用者:PR 連結/編號、目標分支、採用的描述形式(`full`/`simple`/自訂)。
|
||||
2. 提醒清除對話內文以防 token 外洩(互動情境用 Claude Code `/clear` 或當前助理對等指令;排程情境只寫 log、不輸出 token)。
|
||||
3. 清除前再次確認輸出與 log 中沒有明文 token——細節與遮蔽規則一律依 `/jsc-shared:spec-gitea`,本 spec 不重複。
|
||||
Reference in New Issue
Block a user