--- name: setup description: Fix what jsc-cli:doctor found, one confirmed item at a time. Read the 待修項目 table from wiki CHECK_{HASH}, or rebuild it by running the three checkers in parallel and merging them with tools/build-todo.sh. Route each item by its fix column - auto writes it through tools/apply-config.sh, ask collects the value through the jsc-ask decision tree first, manual prints the steps for the operator. Delegate compound repairs to their owners, handing jsc-cli:deploy the mode and the version report it already has. Re-verify every item after writing and rewrite the CHECK page; use when doctor reports something to fix, not for a read-only checkup. --- # setup — guide or apply the fixes doctor found This skill writes. Every write is confirmed first, backed up, and verified afterwards. ## 1. Get the work list Read the 待修項目 table from wiki `CHECK_{HASH}` — repo from `jsc-gitea/tools/gitea.sh wiki-repo CHECK`, page name from `gitea.sh hash-id "{hostname}/{user}"`. No page, or `wiki-repo` exits 3, or any other non-zero exit from `wiki-repo`, `hash-id` or the wiki read → rebuild the list here. Rebuilding **MUST run as a sub agent**, and its three checkers **start together**: they read different files and share no state, so serialising them only triples the wait. | Checker | Command | Exit branching | | --- | --- | --- | | Settings | `tools/scan-config.sh scan all` | 0 → use the rows; 2 → usage error, report it as a defect in this skill; 3 → spec table missing, name the path and `JSC_CONFIG_SPEC`; other → report settings as 無法驗證 | | Wiring | `tools/detect-clis.sh`, then `JSC_READONLY=1 jsc-hooks/tools/wire-cli.sh status {cli}` per detected CLI — this step only takes stock, and `wire-cli.sh` without a subcommand rewires, so the read-only contract is carried in the environment rather than trusted to a correctly typed subcommand | detect-clis exit 0 with no row → no CLI to wire, say so and skip; detect-clis non-zero → report wiring as 無法驗證 with the exit code. Per CLI: 0 wired and 1 degraded → nothing to fix; 2 → usage error, defect in this skill; 3 → CLI not installed, drop it; 5 → collect its `missing` items; 6 → readonly refused the call, which means the subcommand was mistyped into a writing one — nothing on the machine changed; fix the command and rerun that CLI; other → report that CLI as 無法驗證 | | Versions | `jsc-hooks/hooks/version-guard.sh report` | 0 → use the rows, and treat a report with no `{domain}` row or a `noregistry` line as 無法驗證 — other exits → report versions as 無法驗證 with the exit code | Merge the three with `tools/build-todo.sh --config {設定輸出} --wiring {cli}={接線輸出} --version {版本輸出}` so the ordering rule lives in one place. Exit 0 → the `todo` rows are the work list; exit 2 → usage error, report it as a defect in this skill; exit 3 → name the unreadable input and rerun that one checker; any other exit → stop and report, because a half-merged list would silently drop a whole class of items. Keep the version report from that run. Step 3 hands it to `jsc-cli:deploy` instead of making it query again. State which source the list came from. A stale page and a live scan can disagree, and the operator has to know which one is on screen. Done when every item carries its class, scope, current state and fix route, and the source of the list is named. ## 2. Confirm each item Ask per the `jsc-ask:ask` decision tree, one item at a time, in the table's order. Confirmation stays strictly sequential: each answer can change what the next item should be, and a batch of questions fired at once takes that away from the operator. Every option states its impact scope: which file gets written, which skills start working, what stays broken when skipped. An `ask` item needs its value in the same question — the wiki repo as `{owner}/{repo}`, the Gitea host, the directory path. Never invent one. Skipping is always an option and is recorded as skipped, not as fixed. Done when every item is either confirmed with a value or recorded as skipped. ## 3. Apply | Route | Action | | --- | --- | | `auto` on a variable | `tools/apply-config.sh set {KEY} {VALUE}` | | `auto` on a directory | `tools/apply-config.sh mkdir {PATH}` | | `ask` | same two commands, with the value the user just gave | | `manual` | print the exact steps and the file to edit; the operator does it | | domain 落後 | call `jsc-cli:deploy` with mode `update` **and the version report from step 1**, so it neither re-asks the mode nor re-queries the versions | | hook unwired | call `jsc-hooks:hooks-install` | | `$JSC_HOME/model-tags.tsv` missing | call `jsc-cli:models` | `apply-config.sh` exit codes: | Exit | Action | | --- | --- | | 0 | Written. Record the `wrote` or `created` result and the `backup` path | | 2 | Usage error — the subcommand, the key or the value is wrong. Record the item as 未修好 with that reason, and do not retry with a guessed argument | | 4 | Backup or write failed, so nothing was written. Record the item as 未修好 and name the rc file and the stderr, then say the machine is unchanged | | other | Record the item as 未修好 with the exit code and stderr. Never mark it fixed on an unrecognised exit | `apply-config.sh` writes into the `# jsc-config` block of every existing shell rc file, backs each one up to `$JSC_HOME/backup/config/{timestamp}/` before touching it, and rewrites the block whole. It never edits anything outside that block. Report the `backup` path it prints. That path is the whole undo story for this run. Done when every confirmed item has a `wrote`, `created`, delegated or 未修好 result. ## 4. Re-verify Re-verify every applied item. The items are independent, so **run the re-verifications in parallel** — one batch, one wait. Only the confirmation in step 2 has to stay sequential. Pick the check by what was actually written, because the two kinds of write become true at different moments: | What was written | Re-verify with | Why this check | | --- | --- | --- | | An environment variable in a shell rc file | `tools/apply-config.sh show`, confirming the `KEYVALUE` line is in the `# jsc-config` block | The block is a fact that is already true. The variable reaching the environment is not — a rc file does not touch the running shell | | A directory | `tools/scan-config.sh scan {scope}`, confirming the row is no longer `missing` or `invalid` | The directory exists the moment it is created | | Wiring, versions, model tags (delegated) | The owner skill's own returned result | The owner already ran its own verification | The same exit branching as step 1 applies to `scan-config.sh` and to `apply-config.sh`. An item that still fails is reported as 未修好 with the reason. Never mark it fixed because the write succeeded: writing the variable and the variable verifying are two different facts. For every environment variable written, print the matching `export KEY=VALUE` line for the current session and tell the operator to open a new shell or `source` the rc file. The environment-level proof is handed to the next `/jsc-cli:doctor` run, which starts in a fresh shell — asserting it here would read the shell that could not have picked the value up yet, and report a false failure every time. Done when every applied item has a fresh verdict from the checker its own row names, and every environment variable carries its `export` line. ## 5. Record Rewrite `CHECK_{HASH}` through `jsc-gitea:wiki` with the post-fix state, per `templates/check-page.md`. That page is a **content page** and keeps only the latest run, so this overwrites the pre-fix picture on purpose. `CHECK_CONTENTS` is a **contents page** and gets the opposite treatment: read it back first, then upsert this machine's row per `templates/check-contents.md` — add the row if missing, otherwise refresh its counts and 最後體檢. Never overwrite the whole page, and never touch another machine's row. The `CHECK_CONTENTS` read branches by exit code, and only exit 4 opens the create path. Exit 0 means upsert into the content that came back. Exit 4 means the page really is not there yet, so build it from the template. Exit 7 (key invalid or no permission) and exit 8 (any other API failure) mean the old rows are unknown, not that the page is missing: skip the `CHECK_CONTENTS` write, name the exit code, and create nothing — the overwrite that is correct for `CHECK_{HASH}` would here destroy every other machine's row, unread and unrecoverable. No wiki repo configured, or any non-zero exit from the wiki write → report the tables on screen, say the record was skipped, and name the exit code. Then state the counts: fixed, skipped, delegated, and 未修好. Recommend `/jsc-cli:doctor` for a clean re-check when anything was delegated. Done when the page is written or the skip is reported, and the four counts are stated.