Files
pkg/skills/pkg-update/SKILL.md
T
jiantw83andClaude Opus 5 ea11ca0590 fix(pkg): 補齊稽核缺失並修掉護欄失效
What:依 jsc-meta:skill-check 的稽核結果修正技能與工具——補上每個步驟的可檢核完成條件、
把留在內文的標準輸入輸出流程下放 tools/、修正查表與退碼路由造成的誤判。

Why:稽核發現這些缺失會讓技能在實際執行時走錯分支或靜默通過。
完成條件缺漏是最常被違反的一項;退碼誤判與查表錯誤則會讓良性狀況被當成失敗。

How:逐項對照 references/guidelines.md 的審核檢查清單修正,新增的工具都有
documented exit codes,並以真實執行驗證每條路徑。

Who:jsc-meta:skill-check 例行稽核(2026-08-25)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 14:58:54 +08:00

6.9 KiB

name, description
name description
pkg-update Update every external package of a project to its latest stable version using list-packages.sh and latest-version.sh, then run build and tests. Revert all changes on failure. Supports nodejs, python, and dotnet projects. Use for dependency refresh; not for adding or removing packages.

pkg-update — batch-update packages

Exit-code routes

Every tool exit code below has exactly one route. Three routes exist:

  • skip — record the reason, keep going.
  • stop — report and end the run. Change no file, and never enter step 5.
  • revert — go to step 5, which reverts the working tree.

Only a real install, build or test failure takes the revert route. A missing input, a bad argument, an unknown ecosystem or a missing command is a broken call or a broken toolchain, so it takes the stop route.

One number carries one meaning across all five tools. Exit 6 is always a missing project directory and always stops the run — never fold it into the exit 3 skip, or a bad path hides as "nothing to do".

Tool 0 1 (bad argument count) 2 (unknown ecosystem) 3 (no source file) 4 5 6 (project dir not found) other
list-packages.sh continue stop — — stop (python3 missing) — stop stop
latest-version.sh continue stop stop — skip (not in registry) stop (curl or python3 missing) — (takes no project dir) stop
apply-version.sh continue stop stop skip skip (package absent from the file) stop (python3 missing) stop stop
install-deps.sh continue stop stop skip stop (npm, pip or dotnet missing) — stop revert
build-test.sh continue stop stop — (uses 5 instead) stop (npm, python3, pytest or dotnet missing) ask the user stop revert

Exit 4 and exit 5 are the two codes whose meaning depends on the tool, so read them off this table rather than from memory.

Steps

  1. Run tools/list-packages.sh {project dir} to get every external package (ecosystem, name, current version). Route the exit code per the table above. Step 1 is done only when the tool exited 0 and at least one row came back, with an ecosystem, a name and a current version in every row. Zero rows → stop and report the project directory you scanned plus the supported ecosystems (nodejs / python / dotnet), and run no further step.

  2. Prove the project directory is a git repository with a clean tree. Run this before any step changes a file:

    1. Run git -C {project dir} rev-parse --git-dir. Exit 0 is required to continue, because step 5's revert is impossible outside a git repository. Any other exit code → stop and report the directory, and run no further step.
    2. Run git -C {project dir} status --porcelain. Continuing requires that it prints nothing at all. Any output stops the run and reports that output, including ?? untracked lines: step 5 runs git clean -fd, which deletes untracked files with no reflog and no way back.
    3. Step 2 is done only when rev-parse --git-dir exited 0 and status --porcelain printed zero bytes. Report both results, then enter step 3.
  3. Update ecosystem by ecosystem. This step MUST run as a sub agent (one sub agent per ecosystem):

    1. For every package, run tools/latest-version.sh {ecosystem} {name} for the latest stable version, then tools/apply-version.sh {ecosystem} {project dir} {name} {version} to rewrite the version source file (package.json / requirements.txt / pyproject.toml / *.csproj). This substep is done when every package of the ecosystem carries either an applied version or a skip reason from substep 2.
    2. Route every exit code per the table above. The skip route covers latest-version.sh exit 4 (package not found in the registry), apply-version.sh exit 3 (no version source file) and apply-version.sh exit 4 (package absent from the file): record the package and the reason, move on to the next package, and never abort the whole ecosystem. The stop route covers exit 1, exit 2, latest-version.sh or apply-version.sh exit 5 (a required command is missing) and apply-version.sh exit 6 (project directory not found): report the code and end the run without entering step 5. This substep is done when every exit code seen has taken exactly one route.
    3. Run tools/install-deps.sh {ecosystem} {project dir} once, after every package of that ecosystem is applied. Exit 0 means the install finished. Exit 3 means this ecosystem has no dependency source file, which is the same documented skip as substep 2: record the ecosystem and the reason, and install nothing. Exit 1, exit 2, exit 4 and exit 6 take the stop route — exit 6 is a missing project directory, so report it instead of skipping it. Only another non-zero code is a real install failure and goes to step 5. This substep is done when the exit code is recorded together with the route it took.
    4. The sub agent returns one row per package from substep 1: name, old version, new version — or skipped plus the reason. It also returns the install-deps.sh exit code and its route. The ecosystem is done only when every package appears in exactly one row.
  4. Run tools/build-test.sh {ecosystem} {project dir} for every ecosystem and route on the exit code:

    • 0 → this ecosystem passed.
    • 1, 2, 4 or 6 → stop route. Report the code and the missing argument, ecosystem, command or directory, and enter no further step. Exit 4 means the toolchain is broken, not that the packages are broken, so reverting would destroy files for nothing.
    • 5 → no build or test command could be inferred. Ask the user for the build command and the test command per the jsc-ask:ask rules, run the answers in that order, and take their exit codes as this ecosystem's result: all 0 → passed; any non-zero → step 5.
    • any other code → a real build or test failure. Go to step 5.

    Step 4 is done only when every ecosystem reached exit 0, from the tool or from the user's own commands.

  5. A real install, build or test failure reached this step → revert:

    1. Run git -C {project dir} checkout -- . to restore every tracked file to HEAD.
    2. Run git -C {project dir} clean -fd to remove the untracked files and directories this run created, such as a new lock file. 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. Do not reach for -fdx — it deletes far more than this run created.
    3. The revert is done only when git -C {project dir} status --porcelain prints nothing. Report the failing packages with an error summary after that check passes.
  6. Success → report the update list (package, old version, new version), plus every skip and its reason, and hand off to jsc-git:commit. Step 6 is done when the hand-off is made and every package from step 1 appears either as an update or as a skip.