docs(tools): 補上腳本結束碼說明,並改指階梯規則正本

腳本標頭沒把每個結束碼代表什麼、該怎麼處理寫清楚,呼叫端只能用猜的。階梯表又同時抄在說明檔與技能內文,改規則時兩邊容易不同步。

- 推導基底的腳本標頭逐碼說明狀況與處置,並標明該碼屬於哪一種模式。
- 產生分支名的腳本標頭補上參數不足的結束碼。
- 說明檔刪掉重複的階梯表,改指向指引的階梯章節。
- 說明檔補上型別優先序腳本的說明,並更新兩支技能的摘要。
This commit is contained in:
2026-08-31 11:05:49 +08:00
parent fcd0b3b8c0
commit 25792fd279
3 changed files with 28 additions and 18 deletions
+5 -11
View File
@@ -24,19 +24,13 @@ Marketplace 統一為 `jsc`(https://gitea.jsc.idv.tw/plugins/meta.git),安
| --- | --- |
| `tools/base-branch.sh` | 決定 PR 基底分支。兩種模式:不帶旗標時,呼叫方傳入的分支最優先,沒傳才依序試 develop、main、master;`--derive [分支]` 從分支名推出階梯的上一階。一律確認分支存在於遠端,找不到就回傳非零。「沒傳」看參數個數,傳入空字串算錯誤,不會退回 develop |
| `tools/slugify.sh` | 把類型與英文短語組成 ASCII 分支名 `{type}/{slug}`;輸入含非 ASCII 或 slug 化後為空,就回傳非零並要求先翻譯成英文短語。第一個參數可以帶斜線,所以連叫兩次就組得出 `feat/{功能}/{子功能}` |
| `tools/pick-type.sh` | 從一組 commit 型別中選出優先度最高的一個,是型別優先序的唯一真實來源。參數或標準輸入都收,commit 標題整行餵進來也認得出型別;沒有輸入回傳 2,輸入裡沒有階梯表型別回傳 3 |
## PR 階梯
每個 PR 只往上一階開,禁止越級。基底一律由 `tools/base-branch.sh --derive` 推導,不手挑。
階梯規則的唯一真實來源是 `jsc-meta` 的 `references/guidelines.md` 「PR 分支階梯」一節,本檔不再抄一份。基底一律由 `tools/base-branch.sh --derive` 推導,不手挑。
| Commit 類型 | 階梯 |
| --- | --- |
| feat、docs、style、refactor、perf、test、chore、revert | `{類型}/{功能}/{子功能}` → `{類型}/{功能}/main` → `develop` → `master` |
| fix | `fix/{修改}` → `develop` → `master` |
`{子功能}` 可以多層(例:`feat/a/b/c`),推導一律把最後一段換成 `main`。推不出唯一合法基底就回傳 7 並中止,由呼叫端問使用者,不猜也不退回 develop。功能主幹 `{類型}/{功能}/main` 不在遠端時,自動以 develop 為起點建立並推上去,再把建立了哪一條分支印到 stderr。
分支名只允許 ASCII(小寫、數字、連字號、斜線)。中文簡述先過 `tools/slugify.sh`,`--derive` 不收非 ASCII 分支名。
腳本這一側的行為:推不出唯一合法基底就回傳 7 並中止,由呼叫端問使用者,不猜也不退回 develop。功能主幹不在遠端時,自動以 develop 為起點建立並推上去,再把建立了哪一條分支印到 stderr。分支名只允許 ASCII(小寫、數字、連字號、斜線),中文簡述先過 `tools/slugify.sh`,`--derive` 不收非 ASCII 分支名。
## Skills 目錄
@@ -46,11 +40,11 @@ Marketplace 統一為 `jsc`(https://gitea.jsc.idv.tw/plugins/meta.git),安
### `commit`
追蹤所有檔案變更,依 Commit 格式 `{類型}({需求 or 功能}): {訊息}` 將同類型與同需求的變更認可在一起。認可前先跑 `jsc-hooks` 的 `comment-scope.sh sweep` 掃過工作區,攔下夾帶文件相關資訊的註解;腳本不在本機就跳過並在回報中說明,不中止認可。訊息格式三選一:完整版(What/Why/How/Who)、簡易版(依 git diff 總結一句)、自訂。認可完成後,目前分支若已有開啟中的 PR,就交給 `pr` 校準標題、描述與前置 PR 依賴。
追蹤所有檔案變更,依 Commit 格式 `{類型}({需求 or 功能}): {訊息}` 將同類型與同需求的變更認可在一起。盤點與註解掃描兩件事同時跑,分組草擬要吃盤點的檔案清單,排在盤點之後,可以與掃描並行;掃描要求的修正仍在第一個 commit 之前完成;註解掃描跑 `jsc-hooks` 的 `comment-scope.sh sweep`,攔下夾帶文件相關資訊的註解,腳本不在本機就跳過並在回報中說明,不中止認可。`git add -A` 後單次提交與非繁中訊息由 `jsc-hooks` 的 PreToolUse `Bash` 閘門在程式層擋下,只有 claude 有這道閘門,其餘四支 CLI 仍靠技能內文的規則。訊息格式三選一:完整版(What/Why/How/Who)、簡易版(依 git diff 總結一句)、自訂。由 `pr` 呼叫進來時不查 PR,結果由 `pr` 傳入;單獨呼叫時查一次 `gitea.sh pr-of-branch`,查到就交給 `pr` 校準標題、描述與前置 PR 依賴。
### `pr`
先認可所有變更,再依階梯命名目標分支、push、以範本描述建立 Gitea PR。基底分支由 `base-branch.sh --derive` 從分支名推出上一階;呼叫方傳入的基底與推導結果不同,就當成越級擋下並說明正確階梯,不會悄悄改目標。分支名只允許 ASCII:類型取 commit 優先度最高者,功能與標題先翻譯成英文短語再 slug 化。分支已有開啟中的 PR 時不重開,改成比對標題、描述、前置 PR 依賴三項,只有不一樣的那幾項才送出 API 呼叫。收尾回報使用 `jsc-meta/references/pr-report.md` 的 PR 資訊表格。
呼叫方傳入的基底先驗合法性,再認可所有變更,然後依階梯命名目標分支、push、以範本描述建立 Gitea PR。基底分支由 `base-branch.sh --derive` 從分支名推出上一階;呼叫方傳入的基底與推導結果不同,就當成越級擋下並說明正確階梯,不會悄悄改目標。分支名只允許 ASCII:類型交給 `pick-type.sh` 選,功能與標題先翻譯成英文短語再 slug 化。分支命名完成就同時啟動 PR 查詢與描述草擬,不等 push。整條呼叫鏈只查一次 `gitea.sh pr-of-branch`;分支已有開啟中的 PR 時不重開,改用該次查詢帶回的標題、base 與描述比對三項,只有不一樣的那幾項才送出 API 呼叫。收尾回報使用 `jsc-meta/references/pr-report.md` 的 PR 資訊表格。
<!-- JSC-SKILLS:END -->
+17 -6
View File
@@ -22,12 +22,23 @@
# 分支名只允許 ASCII(a-z0-9 與 /、-)。中文簡述先交給同目錄的 slugify.sh 轉成 ASCII slug,
# 再組成分支名,這支腳本不接受非 ASCII 分支名。
#
# 輸出: 選中的分支名(一行)。
# 護欄: 參數過多回傳 2;抓不到遠端回傳 3;呼叫方指定的分支不在遠端回傳 4;
# develop、main、master 都不在遠端回傳 5;傳入空字串回傳 6;
# 推不出唯一合法基底回傳 7;推導出的基底不在遠端又不能自動建立回傳 8;
# 自動建立功能主幹失敗回傳 9。
# 錯誤訊息一律印繁中到 stderr。
# 輸出: 選中的分支名(一行)。錯誤訊息一律印繁中到 stderr。
# 結束碼: 0=stdout 印出一個基底分支名,兩種模式共用。直接拿它開 PR。
# 2=參數過多(兩種模式共用)。分支名要用引號包成單一參數,再重跑。
# 3=連不上 origin,git fetch 失敗(兩種模式共用)。先確認遠端可以連線,再重跑。
# 4=(呼叫方模式)呼叫方指定的分支不在 origin 上。停下來問使用者原本要的是哪一條,
# 不要自行改用其他分支。
# 5=(呼叫方模式)origin 上找不到 develop、main、master。這個碼只在完全沒傳參數時
# 才會出現,所以真正的問題通常是基底參數在路上掉了。請由呼叫方指定基底分支。
# 6=(呼叫方模式)傳進來的是空字串。回去補上分支變數的值,不要改成整個參數不傳——
# 不傳會悄悄退回 develop。
# 7=(--derive 模式)推不出唯一合法基底:站在斷頭狀態、站在 master、分支名含非 ASCII
# 或其他不允許的字元、類型不在階梯表內、feat 這類階梯少了功能層,或 fix 寫成多層。
# 照 stderr 的訊息修分支名再重跑,不要退回 develop。
# 8=(--derive 模式)推導出的基底不在 origin 上,而且它不是可以自動建立的功能主幹。
# 先把那條分支建出來並推上 origin,再重跑。
# 9=(--derive 模式)自動建立功能主幹失敗:origin 上沒有 develop,或推送被拒。
# 先建好 develop,或確認推送權限,再重跑。
set -u
MODE=caller
+6 -1
View File
@@ -4,7 +4,12 @@
# 規則: 全部轉小寫,非 a-z0-9 的字元換成連字號,
# 連續連字號合併成一個,並去除開頭與結尾的連字號。
# 輸出: {type}/{slug}(例如: slugify.sh feat "export report" → feat/export-report)
# 護欄: 輸入含非 ASCII 字元回傳 2;slug 化後為空回傳 3。兩者都印繁中錯誤到 stderr。
# 結束碼: 0=stdout 印出 {type}/{slug},直接拿去當分支名。
# 1=參數少於兩個。補上 type 與 phrase 再重跑。
# 2=type 或 phrase 含非 ASCII 字元。先把描述翻成英文短語再重跑,
# 不要自己動手拼分支名。
# 3=phrase slug 化之後是空字串(裡面一個 a-z0-9 都沒有)。換一句英文短語再重跑。
# 錯誤訊息都印到 stderr,其中 2 與 3 印繁體中文。
set -u
if [ "$#" -lt 2 ]; then