What:CHECK_CONTENTS 改由 wiki-repo CONTENTS 解析並透過 wiki-contents.sh upsert
寫入,CHECK_{HASH} 仍走 wiki-repo CHECK。目錄頁新增一欄裸 HASH 當比對鍵。主機名
改由程式取短名,不再交給模型自由填。
Why:比對鍵原本是含網址的儲存格,換主機或換存取庫就比對不到,每跑一次體檢就替同一台
機器多附一列,畫面上還看不出來。主機名短名與 FQDN 不一致時,同一台機器會分裂成兩張頁,
而助理巡檢那邊是用程式取值的,兩邊對不起來。
How:設定規格表同一輪補齊三處既有缺漏——補上漏掉的 JSC_WIKI_REPO_MONITOR,體檢本來
看不到它而孤兒掃描還會誤報;刪掉指向不存在頁面的 MAINTAIN 內容頁字樣;MAINTAIN 那一列
改成不需要使用者處理,免得體檢叫人去設一支管不到任何頁的變數。整列保留,刪掉會讓孤兒
掃描開始誤報那個變數。
Who:jsc-cli
133 lines
12 KiB
Markdown
133 lines
12 KiB
Markdown
---
|
|
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 "{host}/{user}"`, where `host` is the **short hostname** and `user` the login account, both taken from the machine:
|
|
|
|
```sh
|
|
host=$(hostname 2>/dev/null || uname -n 2>/dev/null || printf 'unknown'); host=${host%%.*}
|
|
user=${USER:-$(id -un 2>/dev/null || printf 'unknown')}
|
|
```
|
|
|
|
`${host%%.*}` matters: `hostname` prints the FQDN on some machines, and a hash built on the long name reads a page doctor never wrote. This is the same value doctor hashes, so it must be taken the same way.
|
|
|
|
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 `KEY<TAB>VALUE` 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
|
|
|
|
The two pages live in **two different wiki repos**. Resolve each one on its own.
|
|
|
|
Rewrite `CHECK_{HASH}` through `jsc-gitea:wiki` with the post-fix state, per `templates/check-page.md` — repo from `gitea.sh wiki-repo CHECK`. 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**, it lives in the contents repo (`gitea.sh wiki-repo CONTENTS`, never a fallback to `JSC_WIKI_REPO_CHECK`), and it gets the opposite treatment. Write the row with
|
|
|
|
`jsc-gitea/tools/wiki-contents.sh upsert CHECK 4 "{HASH}" {row file} templates/check-contents.md`
|
|
|
|
which reads the page back and refreshes this machine's row, or appends it when missing. Never overwrite the whole page, and never touch another machine's row.
|
|
|
|
**The key is column 4, the bare `HASH`.** `4` is the 1-based index of the `HASH` column in `templates/check-contents.md`, and the key is exactly what `hash-id` printed for `{host}/{user}` in step 1 — 40 uppercase hex characters, not shortened, not prefixed, not wrapped in a link. The script compares the whole cell, so the key and that cell must match character for character.
|
|
|
|
A cell holding a URL would make a moving key: it changes with `GITEA_HOST`, with a move of `JSC_WIKI_REPO_CHECK` to another repo, and with Gitea's encoding of the page name. The comparison then never matches, and every run appends a second row for the same machine instead of updating it.
|
|
|
|
Column 1 stays the human-facing link and is never the key. Build it as an **absolute URL** from `gitea.sh wiki-url {CHECK repo} CHECK_{HASH}`, fetched after `CHECK_{HASH}` is rewritten. `[[CHECK_{HASH}]]` resolves only inside its own wiki, and the two pages are no longer in the same one.
|
|
|
|
| Exit | Action |
|
|
| --- | --- |
|
|
| 0 | Report the `updated` or `added` result with the repo and page it named |
|
|
| 1 | Write failed and nothing landed. Report it with the stderr |
|
|
| 2 | Usage error. Report it as a defect in this skill; do not retry with guessed arguments. A `templates/check-contents.md` that is not on disk also lands here — then name the path the script looked for, confirm the plugin install is complete, and rerun |
|
|
| 3 | No contents repo configured. Skip this write and report `JSC_WIKI_REPO_CONTENTS` as still unfixed |
|
|
| 4 | Unreachable the way this skill calls the script — the command above always passes `templates/check-contents.md`, and a template that is not on disk comes back as exit 2. So treat a 4 as a malformed call: report it as a defect in this skill, name the command that produced it, and do not retry with guessed arguments |
|
|
| 7 | Key invalid or no permission. Nothing was read or written; name the exit code and create nothing |
|
|
| 8 | Any other API failure. Same as 7 |
|
|
|
|
Exits 7 and 8 never mean the page is missing: the whole-page overwrite that is correct for `CHECK_{HASH}` would here destroy every other machine's row, unread and unrecoverable. The script creates a page only when its own read reported that page absent, and it owns that branch.
|
|
|
|
`gitea.sh wiki-url` has its own exits, and they are read before the upsert runs. Exit 4 means `CHECK_{HASH}` is not on the wiki yet, so rewrite that page first and fetch the URL again. Any other non-zero exit: name the exit code and stop — never hand-build the URL, because a guessed link goes into the row and points nowhere.
|
|
|
|
No wiki repo configured, or any non-zero exit from `wiki-repo`, `hash-id`, `wiki-url` or 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 each of the two pages is written or its skip is reported, and the four counts are stated.
|