Files
cli/references/behaviors.md
T
jiantw83 03e59c69bd feat(狀態回報): 收尾寫一筆 skill-end 事件
現行紀錄只記「被叫用」,沒有成敗也沒有結束碼。跑完整輪的技能與開場就
中止的技能,在紀錄裡長得一模一樣。

start 由技能用量 hook 順手發,不必改技能文件。end 只能由技能自己在收尾
步驟寫——hook 接在技能工具呼叫上,而實際工作發生在之後的模型輪次,它在
原理上看不到成敗。有 start 沒有配對的 end,就是那一輪中止了。

status 五選一,每支技能各自寫明什麼情況選哪一個。找不到回報腳本就安靜
跳過,回報失敗一律不改變技能自己的結論。
2026-09-02 16:01:14 +08:00

54 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# jsc-cli 技能行為清單
本頁記錄 jsc-cli 每支技能的行為基準,供技能驗證比對。技能異動時,在同一個 PR 內一起更新這一頁。
## delegate
| 項目 | 內容 |
| --- | --- |
| 觸發時機 | 一件邊界清楚的工作要交給另一支已安裝的 AI agent CLI 執行時用。盤點模型(models)、部署技能組(deploy)、必須留在目前 agent 手上的工作都不用;給不出通過或失敗判準的目標也不用 |
| 關鍵步驟 | 寫下一句目標與可判定通過或失敗的驗收條件、同時起跑 detect-clis.sh 與 list-models.sh 取得 CLI 清單與模型清單、先選定目標 CLI 再用 model-tags.sh 的 gate 或 model 驗證模型能力標籤、組出帶目標、驗收條件、目標 CLI、模型代號、最小脈絡、寫入範圍與 TSV 輸出合約的提示、開一個 sub agent 執行、查驗回傳的結束碼與 result、summary、criterion、wrote 各行、把成功、失敗、需要使用者補充分三段回報,最後呼叫 jsc-hooks/tools/report-status.sh skill-end jsc-cli:delegate 寫下這一輪的結果。收尾那一筆走每一條出口,連停在能力閘門那一條也要寫;status 五選一,sub agent 回 0 且每條驗收條件都 pass、wrote 也都在範圍內是 ok,能力鎖擋下所有候選模型、或一支 CLI 都沒偵測到、整輪沒開 sub agent 是 blocked,sub agent 非零退出、回傳格式不符、有驗收條件 fail、或 wrote 越界是 failed,sub agent 回 needs-input、工作只做一半等使用者補資料是 degraded,目標給不出通過或失敗判準、或請求裡包了兩個以上獨立目標而主動停手是 aborted。detail 只放目標 CLI 與模型代號,不放 sub agent 的輸出。腳本不在這台機器就安靜跳過,回報失敗不得改變這支技能的結果 |
| 外部呼叫 | jsc-cli/tools/detect-clis.sh、jsc-cli/tools/list-models.sh、jsc-cli/tools/model-tags.sh(gate 與 model 兩個子命令)、jsc-hooks/tools/report-status.sh skill-end、一個代跑工作的 sub agent |
| 完成條件 | 目標 CLI 與模型各只有一個,且模型通過能力要求;sub agent 回傳的每一條驗收條件都有判定;每個 wrote 路徑都落在寫入範圍內;報告分三段列出結果。中途停下時,停下的原因要寫在報告裡。這一輪還要留下一筆 skill-end 事件,或是腳本不在而略過,兩者都算收好;略過不影響這支技能的結束碼 |
| 可驗證跡象 | 技能自己只寫這一筆事件。$JSC_HOME/usage/events.jsonl 會多一筆 {kind:skill,phase:end} 事件,name 是 jsc-cli:delegate,status 與 exit 就是這一輪的結果。另一項可檢查的是 sub agent 依寫入範圍實際改動的檔案,逐條列在回傳的 wrote 行上,照那些路徑去看即可比對;寫入範圍為空的唯讀委派沒有其他寫入跡象,只有回報內容與那一筆事件 |
## deploy
| 項目 | 內容 |
| --- | --- |
| 觸發時機 | 整組 jsc 技能要在這台機器的每一支已安裝 CLI 上安裝、更新或解除安裝時用。只處理單一技能不用;只想知道版本落後與否,看 doctor 就夠 |
| 關鍵步驟 | 同時取得三項事實(detect-clis.sh 的 CLI 清單、version-guard.sh 的 report 版本表與 recommend 結論、marketplace.json 的 domain 清單)、把版本表原樣秀出並定出建議、依 jsc-ask 決策樹問出模式(呼叫端已帶模式就沿用並標明來源)、每支 CLI 各開一個 sub agent 同時跑 tools/deploy.sh {mode} {cli} {domain}...、安裝或更新後把 CLI 清單交給 jsc-hooks:hooks-install、整台機器跑一次 tools/write-guides.sh、彙整每支 CLI 的結果並要求重新啟動工作階段,最後呼叫 jsc-hooks/tools/report-status.sh skill-end jsc-cli:deploy 寫下這一輪的結果。收尾那一筆接在彙整回報之後,不取代它;走每一條出口,連停在偵測不到 CLI 那一條也要寫。status 五選一,每支 CLI 都回 0、hooks-install 判定乾淨、兩份指引都寫成是 ok,偵測不到任何 CLI、整輪沒下過任何外掛命令是 blocked,marketplace 讀不到或每支 CLI 都失敗、冒煙結果出現 No such file 是 failed,部分 CLI 成功部分失敗、有 domain 被 skip、或 write-guides.sh 回 4 讓機器沒有最新指引是 degraded,使用者沒選模式或在第一支 CLI 開跑前停手是 aborted。detail 只放模式與各項筆數,cmd 與 exit 行留在回報裡 |
| 外部呼叫 | jsc-cli/tools/detect-clis.sh、jsc-cli/tools/deploy.sh、jsc-cli/tools/write-guides.sh、jsc-cli/tools/check-requires.sh(由 deploy.sh 在每個 domain 更新前轉呼叫)、jsc-hooks/hooks/version-guard.sh 的 report 與 recommend、jsc-hooks/hooks/restart-gate.sh require(由 deploy.sh 收尾轉呼叫)、jsc-gitea/tools/gitea.sh 讀 plugins/meta 的 marketplace.json、jsc-hooks/tools/report-status.sh skill-end、jsc-ask:ask、jsc-hooks:hooks-install |
| 完成條件 | 每一支偵測到的 CLI 都回報結束碼與 result 行,每個 skip、warn、compat 行都照實列出;安裝或更新還要拿到 hooks-install 對每支 CLI 的總結,兩份指引都印出 wrote,收尾印出重啟指示與兩份指引路徑。這一輪還要留下一筆 skill-end 事件,或是腳本不在而略過,兩者都算收好;略過不影響這支技能的結束碼 |
| 可驗證跡象 | 各 CLI 的外掛目錄多出或少掉 jsc-{domain}:claude 與 codex 在各自的 plugin 快取、copilot 在 installed-plugins、antigravity 與 kiro 走 $JSC_LOCAL_PLUGINS 的本地 clone 與 $JSC_KIRO_SKILLS 的複製。$JSC_HOME/restart-required.d/{cli} 出現這次的重啟狀態檔;$JSC_HOME/update-guide.md 與 $JSC_HOME/remove-guide.md 被重寫;各 CLI 的 hook 設定檔由 hooks-install 改寫;$JSC_HOME/usage/events.jsonl 會多一筆 {kind:skill,phase:end} 事件,name 是 jsc-cli:deploy,status 與 exit 就是這一輪的結果 |
## doctor
| 項目 | 內容 |
| --- | --- |
| 觸發時機 | 裝完或更新完技能組、技能因設定或接線問題失敗、機器要交接前用。要動手修不用這支,那是 jsc-cli:setup |
| 關鍵步驟 | 同時開四個 sub agent 收版本、hook 接線、設定與未登錄變數,每個 sub agent 回傳原始輸出行、把四份輸出各存成檔、依 templates/check-page.md 印出五個區塊並寫明掃描的專案目錄、用 tools/build-todo.sh 把三份輸出合成待修項目表、用程式取短主機名與登入帳號(主機名切掉第一個點之後的網域)交給 hash-id 算出 HASH、用 wiki-repo CHECK 解出的存取庫透過 jsc-gitea:wiki 整頁覆寫 CHECK_{HASH}、寫完再用 wiki-url 取該頁絕對網址、把要寫進兩頁的每個連結交給 jsc-gitea/tools/link-check.sh 驗證且只有結束碼 0 才往下寫、第 1 欄的連結寫成 `[CHECK_{HASH}]({絕對網址})`、用 wiki-contents.sh upsert CHECK 4 以第 4 欄的裸 HASH 當鍵把本機那一列寫進 CONTENTS 存取庫的 CHECK_CONTENTS、報出四項計數並視情況建議 /jsc-cli:setup,最後呼叫 jsc-hooks/tools/report-status.sh skill-end jsc-cli:doctor 寫下這一輪的結果。這一筆是這支技能唯一的寫入動作,記的是查到什麼,不動設定、不動接線、不動版本,唯讀合約照樣成立;走每一條出口都要寫。status 五選一,四項檢查都有結論、五個區塊與待修項目表都在畫面上、兩頁都寫成是 ok,任何一項報成無法驗證、離線讓 Gitea 相關列變成 skipped、或 wiki-repo 回 3 而略過寫頁是 degraded——唯讀技能讀不到來源就是這一種,金鑰失效回 7 或其他 API 失敗回 8 讓紀錄寫不成是 failed,使用者在寫頁之前喊停是 aborted。blocked 這支用不到:沒 CLI、沒登錄檔、沒 wiki 存放庫的機器一樣查得出四項發現,報成 blocked 會把做完的一輪講成沒做事。detail 只放四項計數 |
| 外部呼叫 | jsc-hooks/hooks/version-guard.sh report、jsc-cli/tools/detect-clis.sh、jsc-hooks/tools/wire-cli.sh status(一律帶 JSC_READONLY=1)、jsc-cli/tools/scan-config.sh 的 scan all 與 orphans、jsc-cli/tools/build-todo.sh、jsc-gitea/tools/gitea.sh 的 wiki-repo、hash-id 與 wiki-url、jsc-gitea/tools/link-check.sh、jsc-gitea/tools/wiki-contents.sh upsert、jsc-hooks/tools/report-status.sh skill-end、jsc-gitea:wiki |
| 完成條件 | 四項檢查各有結論,或明寫無法驗證與原因;五個區塊與待修項目表都在畫面上;每個要寫進頁面的連結都經 link-check.sh 驗過,結束碼 0 才寫,1 就兩頁都不寫並列出 DEAD 那幾筆,3 把 GITEA_HOST 排進待修項目最前面,7 停下來回報金鑰問題而不判成死連結;連結一律寫成文字加絕對網址的形式;兩頁各自寫成功,或寫入略過連同結束碼一起回報,wiki-contents.sh 宣告的 0、1、2、3、4、7、8 每一碼都有分流,建不建新頁的判斷留在腳本裡,技能不自己建;必要項缺漏、設定錯誤、CLI 未接線、domain 落後四項計數都講出來。這一輪還要留下一筆 skill-end 事件,或是腳本不在而略過,兩者都算收好;略過不影響這支技能的結束碼 |
| 可驗證跡象 | wiki 的 CHECK_{HASH} 頁(雜湊來源是 {短主機名}/{登入帳號})被整頁覆寫成這次的結果;另一個存取庫的 CHECK_CONTENTS 多出本機那一列,或該列的缺漏數與最後體檢時間被更新;第 1 欄是 `[CHECK_{HASH}]({絕對網址})` 這種文字加連結的寫法,點下去連得到體檢頁,頁面上找不到同 wiki 的雙括號連結;第 4 欄是裸 HASH,也就是比對用的鍵,同一台機器重跑幾次都只有這一列,別台機器的列一個位元組都沒變;連結驗不過的那一輪,兩頁都維持上一輪的內容。$JSC_HOME/usage/events.jsonl 會多一筆 {kind:skill,phase:end} 事件,name 是 jsc-cli:doctor,status 與 exit 就是這一輪的結果,那也是這支技能唯一寫得出來的檔案痕跡。機器本身的設定、接線與版本都不動:這支技能不寫任何設定 |
## models
| 項目 | 內容 |
| --- | --- |
| 觸發時機 | 要盤點各 CLI 可用模型、確認模型合不合 SDLC 階段的能力要求、或檢視階段閘門設定時用。切換模型不用,改 .jsc/models 與 models.conf 也不用 |
| 關鍵步驟 | 同時起跑三個收集器(detect-clis.sh、list-models.sh 以 sub agent 執行、model-config.sh list)、對讀不到設定的 CLI 補上標「預設推定」的預設模型、依 references/model-tags.md 為每個模型掛能力標籤、印出 CLI、模型、標籤、使用中四欄表、跑 tools/model-tags.sh sync 把標籤表寫進 $JSC_HOME/model-tags.tsv、附上 SDLC 階段需求表與階段偏好模型表,最後呼叫 jsc-hooks/tools/report-status.sh skill-end jsc-cli:models 寫下這一輪的結果。收尾那一筆走每一條出口,連停在偵測不到 CLI 那一條也要寫;status 五選一,每支 CLI 都有模型清單、每個模型都掛到標籤、sync 回 0 印出路徑、兩張階段表都在是 ok,偵測不到任何 CLI、盤點那半段整個沒開始是 blocked,sync 非零而 model-tags.tsv 沒寫成、SDLC 閘門判不出來是 failed,讀不到某支 CLI 的設定而改用預設推定、有模型查不到標籤只能排進發問、或 model-config.sh 失敗讓偏好表變成未取得是 degraded,使用者在 sync 寫檔之前停手是 aborted。detail 只放 CLI 與模型筆數 |
| 外部呼叫 | jsc-cli/tools/detect-clis.sh、jsc-cli/tools/list-models.sh、jsc-cli/tools/model-config.sh list、jsc-cli/tools/model-tags.sh sync、jsc-hooks/tools/report-status.sh skill-end、references/model-tags.md;標籤表上查不到的模型改用 jsc-ask:ask 發問 |
| 完成條件 | 每支偵測到的 CLI 都有模型清單或一組預設推定;每個模型都掛到標籤,或已排進發問;sync 印出寫入路徑,失敗則連同結束碼回報;兩張階段表都列滿 plan、analyze、implement、maintain 四個階段。這一輪還要留下一筆 skill-end 事件,或是腳本不在而略過,兩者都算收好;略過不影響這支技能的結束碼 |
| 可驗證跡象 | $JSC_HOME/model-tags.tsv 被重寫,內容就是這次掛好的標籤表;jsc-hooks/hooks/sdlc-gate.sh 讀的正是這份檔,檔案不在,SDLC 階段閘門就判不出來。$JSC_HOME/usage/events.jsonl 會多一筆 {kind:skill,phase:end} 事件,name 是 jsc-cli:models,status 與 exit 就是這一輪的結果。各 CLI 的模型設定檔不動 |
## setup
| 項目 | 內容 |
| --- | --- |
| 觸發時機 | doctor 報出待修項目、要實際動手修這台機器時用。只想做唯讀體檢不用這支,那是 jsc-cli:doctor |
| 關鍵步驟 | 用程式取短主機名與登入帳號算出 HASH,從 wiki-repo CHECK 解出的存取庫讀 CHECK_{HASH} 的待修項目表,讀不到就以 sub agent 同時重跑設定、接線、版本三個檢查器再用 build-todo.sh 合併、依 jsc-ask 決策樹逐項循序確認、依 fix 欄分流(auto 與 ask 走 apply-config.sh 的 set 或 mkdir、manual 印出步驟交給操作者、domain 落後轉呼叫 jsc-cli:deploy 並附上手上的版本報告、hook 未接線轉呼叫 jsc-hooks:hooks-install、缺 model-tags.tsv 轉呼叫 jsc-cli:models)、同時重驗每個已套用項目、重寫 CHECK_{HASH}、再用 wiki-url 取它的絕對網址、把要寫進兩頁的每個連結交給 jsc-gitea/tools/link-check.sh 驗證且只有結束碼 0 才往下寫、第 1 欄的連結寫成 `[CHECK_{HASH}]({絕對網址})`、以 wiki-contents.sh upsert CHECK 4 用第 4 欄的裸 HASH 當鍵更新 CONTENTS 存取庫的 CHECK_CONTENTS、報出已修、略過、轉呼叫、未修好四項計數,最後呼叫 jsc-hooks/tools/report-status.sh skill-end jsc-cli:setup 寫下這一輪的結果。收尾那一筆走每一條出口,連停在讀不到待修項目那一條也要寫;status 五選一,每一項都修好也重驗過、沒有略過、兩頁都寫成是 ok,環境不允許寫入、apply-config.sh 每一項都回 4 而一個 rc 檔都沒動到是 blocked,已套用的項目重驗仍失敗、apply-config.sh 回 2 是這支技能自己下錯命令、或金鑰失效回 7 與其他 API 失敗回 8 讓紀錄改寫不成是 failed,使用者否決某一項而那一項記成略過、或轉呼叫出去的修正沒收尾是 degraded,使用者在逐項確認到一半喊停、剩下的項目沒問到是 aborted。detail 只放四項計數,不放使用者輸入的值 |
| 外部呼叫 | jsc-cli/tools/scan-config.sh、jsc-cli/tools/detect-clis.sh、jsc-hooks/tools/wire-cli.sh status(一律帶 JSC_READONLY=1)、jsc-hooks/hooks/version-guard.sh report、jsc-cli/tools/build-todo.sh、jsc-cli/tools/apply-config.sh 的 set、mkdir 與 show、jsc-gitea/tools/gitea.sh 的 wiki-repo、hash-id 與 wiki-url、jsc-gitea/tools/link-check.sh、jsc-gitea/tools/wiki-contents.sh upsert、jsc-hooks/tools/report-status.sh skill-end、jsc-ask:ask、jsc-gitea:wiki、jsc-cli:deploy、jsc-hooks:hooks-install、jsc-cli:models |
| 完成條件 | 每一項都有已修、略過、轉呼叫或未修好的結果;每個已套用項目都由自己那一列指定的檢查器重驗過;每個寫進去的環境變數都附上 export 那一行;每個要寫進頁面的連結都經 link-check.sh 驗過,結束碼 0 才寫,1 就兩頁都不寫並列出 DEAD 那幾筆,3 回報 GITEA_HOST 仍未修好,7 停下來回報金鑰問題而不判成死連結;連結一律寫成文字加絕對網址的形式;兩頁各自寫好或略過都有回報,wiki-contents.sh 宣告的 0、1、2、3、4、7、8 每一碼都有分流,建不建新頁的判斷留在腳本裡,技能不自己建;四項計數都講出來。這一輪還要留下一筆 skill-end 事件,或是腳本不在而略過,兩者都算收好;略過不影響這支技能的結束碼 |
| 可驗證跡象 | 各 shell rc 檔的 `# jsc-config` 區塊被改寫,改寫前的備份落在 $JSC_HOME/backup/config/{時間戳}/;auto 路線建立的目錄實際出現在磁碟上;wiki CHECK_{HASH} 被改寫成修完後的狀態,另一個存取庫的 CHECK_CONTENTS 只有本機那一列跟著更新,第 1 欄是 `[CHECK_{HASH}]({絕對網址})` 這種文字加連結的寫法、點下去連得到體檢頁,頁面上找不到同 wiki 的雙括號連結,第 4 欄是當鍵用的裸 HASH;連結驗不過的那一輪,兩頁都維持上一輪的內容;轉呼叫出去的項目留下各自技能的跡象,也就是 deploy 的重啟狀態檔、hooks-install 改寫的接線設定、models 產生的 model-tags.tsv;$JSC_HOME/usage/events.jsonl 會多一筆 {kind:skill,phase:end} 事件,name 是 jsc-cli:setup,status 與 exit 就是這一輪的結果 |