Author SHA1 Message Date
admin fa15b57adc Merge pull request '釋出:收尾寫一筆執行狀態事件' (#23) from develop into master
Reviewed-on: #23
Reviewed-by: 系統管理員 <1+admin@noreply.localhost>
2026-09-04 05:02:20 +00:00
admin 19a8443d4e Merge pull request '收尾寫一筆 skill-end 事件,執行狀態才回報得到助理' (#22) from feat/status-report into develop
Reviewed-on: #22
2026-09-02 08:04:51 +00:00
jiantw83 58cbab4be5 chore(plugin 版本): 三份 manifest 升版至 0.1.0 2026-09-02 16:01:17 +08:00
jiantw83 1cbe7aac3c feat(狀態回報): 收尾寫一筆 skill-end 事件
現行紀錄只記「被叫用」,沒有成敗也沒有結束碼。跑完整輪的技能與開場就
中止的技能,在紀錄裡長得一模一樣。

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

status 五選一,每支技能各自寫明什麼情況選哪一個。找不到回報腳本就安靜
跳過,回報失敗一律不改變技能自己的結論。
2026-09-02 16:01:17 +08:00
admin 38afebcc0d Merge pull request '釋出 jsc-assist 的 marketplace 條目' (#21) from develop into master
Reviewed-on: #21
Reviewed-by: 系統管理員 <1+admin@noreply.localhost>
2026-09-01 04:57:52 +00:00
admin 3de1dcbabe Merge pull request '放行 jsc-assist 的 marketplace 條目到預設分支' (#20) from chore/marketplace-assist-registry/main into develop
Reviewed-on: #20
2026-09-01 04:55:31 +00:00
admin a4f42c91d1 Merge pull request 'chore/marketplace-assist-registry/sync-copies' (#19) from chore/marketplace-assist-registry/sync-copies into chore/marketplace-assist-registry/main
Reviewed-on: #19
2026-09-01 04:53:47 +00:00
jiantw83 a68e8fcfbb chore(marketplace): 把 jsc-assist 登錄進統一 marketplace
What:
- 兩份 marketplace 檔各加一個 jsc-assist 條目,來源網址指向 assist 存放庫。

Why:
- 準則要求每個 domain 存放庫都帶同一份 marketplace 檔,任何一個存放庫都能當註冊入口。副本之間只要有一份沒跟上,稽核就會報出不一致。
- 正本少了這個條目,各 CLI 的安裝指令就找不到 jsc-assist,這個 domain 等於發佈不出去。

How:
- 條目由 meta 的 sync-marketplace.sh 產生,同時寫進正本與每個 domain 存放庫的副本,寫完逐檔比對位元組。這一支存放庫的兩份副本就是那一輪的產物。
- 條目依名稱排序,縮排與非 ASCII 描述的處理都交給同一支腳本,不手改 JSON。
- 這一批是從最新的預設分支重新產生的。前一輪的分支基底早於監控頁型別那批改動,直接合併會把那些改動回退掉,所以整批重做而不是解衝突。

Who:
助理 domain 落地的註冊步驟在這個存放庫的同步。
2026-09-01 12:50:04 +08:00
5 changed files with 10 additions and 6 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "jsc-pkg",
"version": "0.0.9",
"version": "0.1.0",
"description": "套件批次更新(nodejs/python/dotnet),先把嫌疑套件釘回舊版重試一次,真失敗才還原",
"skills": "./skills",
"author": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "jsc-pkg",
"version": "0.0.9",
"version": "0.1.0",
"description": "套件批次更新(nodejs/python/dotnet),先把嫌疑套件釘回舊版重試一次,真失敗才還原",
"skills": "./skills",
"jsc": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "jsc-pkg",
"version": "0.0.9",
"version": "0.1.0",
"description": "套件批次更新(nodejs/python/dotnet),先把嫌疑套件釘回舊版重試一次,真失敗才還原",
"skills": "./skills/",
"jsc": {
+3 -3
View File
@@ -7,7 +7,7 @@
| 項目 | 內容 |
| --- | --- |
| 觸發時機 | 使用者要把一個專案的所有外部套件更新到最新穩定版本時使用。jsc-sdlc 維護階段也把它當成維護動作之一。專案必須是 nodejs、python 或 dotnet,而且工作區必須乾淨。不要用它新增套件、移除套件,也不要用它把單一套件改成指定版本。 |
| 關鍵步驟 | 先跑 `tools/git-guard.sh check` 當硬閘門,證明目標是 git 工作樹而且 `git status --porcelain` 沒有輸出、跑 `tools/list-packages.sh` 列出每個套件的 ecosystem、名稱與目前版本、對每個 ecosystem 跑 `tools/build-test.sh --detect` 取得建置與測試指令,推不出來就依 jsc-ask:ask 問使用者、每個 ecosystem 開一個 sub agent 並行更新,同一個 ecosystem 內先併發跑 `tools/latest-version.sh` 查版本,再逐一跑 `tools/apply-version.sh` 改寫版本來源檔案、每個 ecosystem 的套件都套用完才跑一次 `tools/install-deps.sh`、跑 `tools/build-test.sh` 建置與測試、真的失敗就從錯誤輸出點出嫌疑套件,用 `tools/apply-version.sh` 把嫌疑套件釘回舊版並寫下原因註解,重新安裝後只重試一次、重試仍失敗才跑 `tools/git-guard.sh revert --confirm-destructive` 還原、成功就報出更新、釘回舊版與跳過三份清單,交給 jsc-git:commit。 |
| 關鍵步驟 | 先跑 `tools/git-guard.sh check` 當硬閘門,證明目標是 git 工作樹而且 `git status --porcelain` 沒有輸出、跑 `tools/list-packages.sh` 列出每個套件的 ecosystem、名稱與目前版本、對每個 ecosystem 跑 `tools/build-test.sh --detect` 取得建置與測試指令,推不出來就依 jsc-ask:ask 問使用者、每個 ecosystem 開一個 sub agent 並行更新,同一個 ecosystem 內先併發跑 `tools/latest-version.sh` 查版本,再逐一跑 `tools/apply-version.sh` 改寫版本來源檔案、每個 ecosystem 的套件都套用完才跑一次 `tools/install-deps.sh`、跑 `tools/build-test.sh` 建置與測試、真的失敗就從錯誤輸出點出嫌疑套件,用 `tools/apply-version.sh` 把嫌疑套件釘回舊版並寫下原因註解,重新安裝後只重試一次、重試仍失敗才跑 `tools/git-guard.sh revert --confirm-destructive` 還原、成功就報出更新、釘回舊版與跳過三份清單,交給 jsc-git:commit、最後不論成功、還原或停手,一律呼叫 `jsc-hooks/tools/report-status.sh skill-end jsc-pkg:pkg-update {status} {結束碼} {detail}` 記下這一輪怎麼結束。那支腳本在別的 plugin,路徑一定要帶 `jsc-hooks/` 前綴,寫成本技能自己的 `tools/` 會指到不存在的檔案;檔案不在就安靜跳過,回報失敗不得變成套件更新失敗。 |
| 外部呼叫 | 腳本 `tools/git-guard.sh`、`tools/list-packages.sh`、`tools/latest-version.sh`、`tools/apply-version.sh`、`tools/install-deps.sh`、`tools/build-test.sh`。技能 jsc-ask:ask(問建置與測試指令)、jsc-git:commit(成功後提交)。外部服務為 npm、PyPI、NuGet 三個註冊處,由 `latest-version.sh` 以 curl 查詢。不呼叫 Gitea API。 |
| 完成條件 | 三種結局各自有完成條件。成功時,步驟 1 列出的每個套件都恰好出現在更新、釘回舊版、跳過其中一份清單,而且已經交給 jsc-git:commit。走還原路線時,`git-guard.sh revert` 回 0,接著報出失敗套件與錯誤摘要。走停手路線時,報出失敗的工具與結束碼、已經套用的套件、已經改寫的版本來源檔案,而且不進入還原步驟。 |
| 可驗證跡象 | 專案目錄的版本來源檔案被改寫,`git diff` 看得到 package.json、requirements.txt、pyproject.toml 或 `*.csproj` 的版本字串變動。`install-deps.sh` 跑過會留下鎖定檔與安裝產物,例如 package-lock.json、node_modules、bin、obj。釘回舊版的套件旁邊留有一行說明原因的註解,必要時附第三方 issue 連結。成功路線由 jsc-git:commit 產生 commit,`git log` 查得到。走還原路線後,`git status --porcelain` 不印任何內容,被 gitignore 的安裝產物留在原地。這支技能不寫任何 wiki 頁,也不開 PR。 |
| 完成條件 | 三種結局各自有完成條件。成功時,步驟 1 列出的每個套件都恰好出現在更新、釘回舊版、跳過其中一份清單,而且已經交給 jsc-git:commit。走還原路線時,`git-guard.sh revert` 回 0,接著報出失敗套件與錯誤摘要。走停手路線時,報出失敗的工具與結束碼、已經套用的套件、已經改寫的版本來源檔案,而且不進入還原步驟。三種結局都要再走完最後一步:呼叫 `report-status.sh skill-end`,狀態五選一——每個套件都升到新版而且建置與測試通過是 `ok`;有套件被釘回舊版或被跳過、但重試那一輪建置與測試過了而且交給 jsc-git:commit 是 `degraded`;真的安裝、建置或測試失敗而走還原是 `failed`;`git-guard.sh check` 因為工作區不乾淨或不是 git 工作樹擋下、什麼都還沒寫是 `blocked`;盤點列不出任何套件,或使用者講不出建置與測試指令而主動停手是 `aborted`。腳本不在磁碟上就跳過,這一步照樣算走完。 |
| 可驗證跡象 | 專案目錄的版本來源檔案被改寫,`git diff` 看得到 package.json、requirements.txt、pyproject.toml 或 `*.csproj` 的版本字串變動。`install-deps.sh` 跑過會留下鎖定檔與安裝產物,例如 package-lock.json、node_modules、bin、obj。釘回舊版的套件旁邊留有一行說明原因的註解,必要時附第三方 issue 連結。成功路線由 jsc-git:commit 產生 commit,`git log` 查得到。走還原路線後,`git status --porcelain` 不印任何內容,被 gitignore 的安裝產物留在原地。三種結局都會讓 `$JSC_HOME/usage/events.jsonl` 尾端多一筆 `{kind:skill,phase:end}` 事件,`name` 是 `jsc-pkg:pkg-update`,`status` 與那次結局相符,`exit` 是決定結局的工具的結束碼;`report-status.sh` 不在那台機器上就沒有這一筆,而更新結果與工作區狀態一字不變。這支技能不寫任何 wiki 頁,也不開 PR。 |
+4
View File
@@ -64,3 +64,7 @@ Exit 4 and exit 5 are the two codes whose meaning depends on the tool, so read t
Step 3 is done only when every ecosystem landed in exactly one of three end states: exit 0 on the first run; exit 0 on the single retry, with every suspect of that ecosystem carrying a written hold plus a comment naming its reason; or entered step 4.
4. A real install, build or test failure reached this step → revert. Run `tools/git-guard.sh revert {project dir} --confirm-destructive`. The script re-proves the target is a git work tree before it runs anything destructive, restores every tracked file with `git checkout -- .`, removes this run's untracked files with `git clean -fd`, and verifies `git status --porcelain` prints nothing. Gitignored paths survive `-fd` on purpose: `node_modules`, `__pycache__`, `bin/` and `obj/` stay behind, so restoring install output is out of scope for this skill. Route the exit code per the table above. Step 4 is done only when the script exited 0; report the failing packages with an error summary after that.
5. Success → report the update list (package, old version, new version), every package held at its old version by step 3 with the reason, and every skip with its reason, then hand off to `jsc-git:commit`. Step 5 is done when the hand-off is made and every package from step 1 appears exactly once, as an update, a hold or a skip.
6. **Record how the run ended.** This is the closing step and it runs on all three endings — the success of step 5, the revert of step 4, and every stop route. Run `jsc-hooks/tools/report-status.sh skill-end jsc-pkg:pkg-update {status} {exit} "{detail}"`; the leading `jsc-hooks/` is the whole point — every other script this skill runs is its own `tools/{name}.sh`, and this one lives in a sibling plugin, so a bare `tools/` path would resolve to a file that is not there. What records a skill's start cannot see how it ended, so an ending that is never written reads afterwards as a run that was abandoned mid-way, and a reverted run looks the same as a clean one.
- `{status}` is one of five. `ok`: every package landed on its new version and build and test passed, with no hold and no skip. `degraded`: the run finished and part of it did not land — a package held at its old version by step 3 while build and test passed on the retry, or a package skipped for a missing registry entry or a missing version source file. That is `degraded` and never `failed`, because step 5 was reached and the hand-off to `jsc-git:commit` was made. `failed`: a real install, build or test failure that step 3's single retry did not clear, so step 4 reverted the working tree. `blocked`: `git-guard.sh check` refused the run because the tree was not clean or was not a git work tree, so nothing was ever written. `aborted`: the run stopped before it could do its work on a precondition that does not hold — the inventory listed zero packages, or the user could not name a build and test command at substep 1.3.
- Take `{exit}` from the tool that decided the ending — the `build-test.sh`, `install-deps.sh` or `git-guard.sh` code that routed the run — and otherwise use 0 for `ok` and 1 for every other status. `{detail}` is optional, one line, at most 200 characters: the counts of updated, held and skipped packages, or the failing tool with its code. Never put a build log or a package list of unbounded length there; the full lists belong in the report of step 5.
- Reporting never changes the run. A machine without `report-status.sh` skips this step in silence and keeps its step 5 result exactly as it stands; the script swallows its own write failures and always exits 0, so nothing here is worth routing on. Step 6 is done when the call was made, or the script was absent and the step was skipped without a word.