What
- `skills/skill-new`、`skills/skill-update`、`skills/skill-delete`、`skills/skillset-update`、`skills/skill-check`:目錄頁寫入步驟的呼叫從「單列 upsert」改成單一 H2 區塊 upsert,鍵補上內容頁頁名這個引數,並註明第四個引數是區塊檔而不是列檔。
- `skills/tooling-guide`:盤點結果寫回目錄頁的敘述照同一套改寫,並寫明鍵是內容頁頁名。
- `references/behaviors.md`:六支技能的關鍵步驟、外部呼叫與可驗證跡象三列同步,跡象從「留下自己那一列」改成留下自己那一個 H2 區塊,區塊內的連結寫成一條欄位。
Why
- 範本與準則已經改成條列版面,技能內文還寫著「那一列」,執行時就會照舊敘述組出表格列,跟工具的區塊 upsert 對不上。
- 呼叫少帶鍵這個引數,工具無從判斷要換掉哪一個區塊,同一筆會被當成新的附加上去。
- 行為清單是稽核與驗證的比對基準,敘述沒跟上,稽核會拿舊描述判合規。
How
- 六支技能的呼叫一律寫成 `wiki-contents.sh upsert {TYPE} {鍵欄} "{內容頁頁名}" {區塊檔} [{範本}]`,並在旁邊點明目錄頁一律大標題加條列。
- 完成條件與可驗證跡象改用區塊的說法,連結範例改成 `- {欄位名}:[{頁名}]({連結})` 的形態。
- 只改敘述,不動任何腳本;轉檔與 upsert 的實作在別的存取庫。
Who
- 本存取庫六支會寫目錄頁的技能。
- 稽核與驗證流程改拿新的行為清單比對。
151 lines
20 KiB
Markdown
151 lines
20 KiB
Markdown
---
|
||
name: tooling-guide
|
||
description: Inventory the current jsc plugins, skills, hook management, and usage paths as the baseline tooling guide, taking the skill, CLI, and hook-wiring facts from one inventory-tooling.sh run rather than re-running the scripts it already called. On request, publish that inventory through jsc-gitea:wiki to TOOLING_{HASH}, hashed from {hostname}/{tool}/{account}, and register it in TOOLING_CONTENTS. Use when the user asks for a skill-set guide, tooling map, supported plugin list, supported skill list, hook management overview, or onboarding reference. Do not use for installing, updating, deleting, auditing, or repairing the skill set; use jsc-cli:deploy, jsc-meta:skill-check, jsc-meta:skill-update, jsc-meta:skill-delete, or jsc-hooks:hooks-install instead.
|
||
---
|
||
|
||
# tooling-guide - build the baseline tooling guide
|
||
|
||
Goal: produce a current guide for the jsc skill set from the local repos and the supported tooling scripts.
|
||
|
||
Single source of guidelines: [`../../references/guidelines.md`](../../references/guidelines.md).
|
||
|
||
## Rules
|
||
|
||
- Every factual claim in the guide carries the source path or the tool output line it came from.
|
||
- Prefer script output over copied lists.
|
||
- Use `tools/inventory-tooling.sh` for the baseline inventory.
|
||
- Keep command syntax in the guide only when it comes from README files or tool output.
|
||
- Do not modify README files, manifests, marketplace files, hooks, tools, or other skills.
|
||
- Put generated guide text in the response or in the user-requested target only.
|
||
- Run detail synthesis as a sub agent when the guide needs explanations, grouping, or onboarding prose.
|
||
- Route every wiki read and write through `jsc-gitea:wiki`, and every `{HASH}` through `jsc-gitea/tools/hash-id`. The directory page `TOOLING_CONTENTS` is the one exception: it goes through `jsc-gitea/tools/wiki-contents.sh`, which owns the directory-page layout for every page type, so this skill never assembles that page itself.
|
||
- Close every run with the step 8 `skill-end` event. That one line in `$JSC_HOME/usage/events.jsonl` is the only thing this skill writes outside the recorded output target, and the rule above about not modifying files does not cover it.
|
||
|
||
Done when each rule above has a recorded pass, or a recorded exception naming the claim and the reason, checked before the final report.
|
||
|
||
## Inputs
|
||
|
||
- Optional user scope: plugin inventory, skill inventory, hook management, CLI usage, or all areas.
|
||
- Optional output target: chat response, wiki draft text, a named file that the user explicitly requests, or the wiki pages `TOOLING_{HASH}` and `TOOLING_CONTENTS`.
|
||
|
||
Done when the scope and the output target are each written down as one of the values listed above. With no scope given, write down `all areas`. With no target given, write down `chat response`. Only the `wiki page` target runs step 7.
|
||
|
||
## Flow
|
||
|
||
1. Confirm the working roots. Run `tools/plugins-root.sh` — it prints the workspace root that holds the domain checkouts, and it is the same derivation every other tool here uses. Exit 1 means the root could not be derived: read stderr, set `JSC_PLUGINS_ROOT` to the directory that holds the domain repos, and rerun. Under a plugin install the tools sit in the CLI's plugin cache, so the built-in guess lands in that cache instead of the workspace. The meta root is `{root}/meta`, or `{root}/jsc-meta` when that is the checkout name; the sibling directories under `{root}` are the domain checkouts. Completion condition: the script exits 0, and the meta root it names exists and contains `references/guidelines.md`.
|
||
|
||
2. Sync the domain inventory with `tools/sync-domains.sh`. This script owns marketplace discovery and local repo synchronization.
|
||
- Exit 0: continue with the printed `domain<TAB>path` rows.
|
||
- Exit 3: keep the printed rows, report every skipped or dirty repo from stderr as stale input, and continue only after the user accepts a guide with stale rows.
|
||
- Exit 2: report the clone failure and stop.
|
||
- Exit 1: report which cause stderr names — the root could not be derived, `gitea.sh` was not found, or the canonical marketplace was unreadable — then stop. For the root case, fix it the same way as step 1 and rerun.
|
||
|
||
Completion condition: each plugin row used by the guide has a domain and a local path, or the stale-input decision is recorded.
|
||
|
||
3. Collect the baseline inventory and the management-flow facts. The two halves are independent — one reads tool output, the other reads files — so run them **at the same time**.
|
||
|
||
**Baseline inventory.** Build it with `tools/inventory-tooling.sh` and use its Markdown output as the base document.
|
||
- Exit 0: continue with the generated guide.
|
||
- Exit 1: report which cause stderr names — the root could not be derived, the root does not exist, or the marketplace or `list-skills.sh` is missing — then stop.
|
||
- Any other exit: report the command, exit code, and stderr, then stop.
|
||
|
||
**This one run already covers the skill catalog, the CLI detection and the hook wiring status.** Internally it runs `meta/tools/list-skills.sh`, `cli/tools/detect-clis.sh` and `hooks/tools/wire-cli.sh status {cli}` and writes each result into its own section, so read those sections instead of calling the three scripts again:
|
||
- `Supported skills` — one row per skill, from `list-skills.sh`. An empty table means no skill was scanned; return to step 2.
|
||
- `Supported CLIs` — one row per detected CLI with its path and version, from `detect-clis.sh`. The single placeholder row means no CLI is installed here, or `detect-clis.sh` is missing; mark CLI-specific checks as not available on this machine.
|
||
- `Hook wiring status` — one row per detected CLI with the `wire-cli.sh status` exit code and verdict, `CLI 代號不符合 wire-cli.sh 用法` for exit 2 and `未知狀態,結束碼 {rc}` for anything outside 0, 1, 3 and 5. The single placeholder row means no CLI was detected or `wire-cli.sh` is missing; state the hook verdict as unknown and say why.
|
||
|
||
Re-running those three scripts on top of this buys nothing and can disagree with the base document — the second run sees a different machine state, and the guide then carries two answers for one fact. What that costs is written down under `Notes`.
|
||
|
||
**Management-flow facts.** Collect them from the current docs and skills. Read only README files, `SKILL.md` files, and tool help or headers from `tools/` under the domain repo paths that step 2 printed — never a hardcoded absolute path, because the workspace root differs per machine and per install form. Do not infer support from missing or stale files.
|
||
|
||
Completion condition: the generated guide contains `Source freshness`, `Supported plugins`, `Supported skills`, `Supported CLIs`, `Hook wiring status`, `Hook management`, `Plugin and skill management`, `Operational checks` and `Use this when`; the skill, CLI and hook facts used by the guide are quoted from those sections; and each management flow in the guide points to one source file or one tool output.
|
||
|
||
4. Synthesize the guide. This step MUST run as a sub agent when the output needs explanations, grouping, onboarding prose, or cross-domain comparison. Give the sub agent only the collected inventories, the relevant README and SKILL paths, and this required section list:
|
||
- Supported plugins
|
||
- Supported skills
|
||
- Supported CLIs and usage forms
|
||
- Hook management
|
||
- Plugin and skill management
|
||
- Health checks and repair paths
|
||
- Known coverage limits
|
||
|
||
Completion condition: the sub agent returns a guide draft with every required section and with source paths for each factual claim.
|
||
|
||
5. Verify the draft in the main agent.
|
||
- Check that each plugin comes from the step 2 `sync-domains.sh` rows.
|
||
- Check that each skill comes from the step 3 `Supported skills` section.
|
||
- Check that each CLI fact comes from the step 3 `Supported CLIs` section, and each hook-wiring fact from the step 3 `Hook wiring status` section.
|
||
- Check that install, update, delete, audit, repair, and health-check actions point to the owning skill or tool.
|
||
- Check that the draft does not copy long implementation details from README files or scripts.
|
||
|
||
Completion condition: every factual claim has a source path or tool output, and no required section is empty.
|
||
|
||
6. Deliver the guide in the requested target. If the target is chat, keep it concise and include the source paths used. If the target is a file, write only that user-requested file and do not update manifests or README files. If the target is the wiki page, step 7 performs the delivery — keep the chat summary short here and let step 7 report the page names and URLs. Completion condition: the guide is delivered and the final report names the target, source freshness, stale inputs if any, and any unknown hook verdicts.
|
||
|
||
7. Publish the inventory to the wiki. Run this step only when the recorded output target is the wiki page; for any other target, record `wiki publish skipped — target is {target}` and go to the final report. **This whole step MUST run as a sub agent.** Every wiki read and write goes through `jsc-gitea:wiki`; never assemble a Gitea API call here.
|
||
|
||
7.1 **Build one page name per detected CLI.** Take the CLI code names from the step 3 `Supported CLIs` section — that section already carries the first column of `jsc-cli/tools/detect-clis.sh`, one of `claude`, `codex`, `copilot`, `antigravity`, `kiro`. Pair each code name with this machine's host name and the current login account, then hand `{hostname}/{tool}/{account}` to `jsc-gitea/tools/hash-id`. The hash rules live in `../../references/guidelines.md` and are not restated here; compute nothing by hand. One page per host, CLI, and account: every CLI carries its own installed plugin set and its own hook wiring, and the tool segment is what keeps five CLIs off one page. A missing host name, tool name, or account stops the step — name the missing segment and substitute no default value. `hash-id` exit 1 means this machine has neither `sha1sum` nor `shasum`: stop and report that one of them has to be installed. Completion condition: every detected CLI has one `TOOLING_{HASH}` name built from three non-empty segments, all of them produced by `hash-id`.
|
||
|
||
7.2 **Resolve the wiki repo** for type `TOOLING` through `jsc-gitea:wiki`, which reads `JSC_WIKI_REPO_TOOLING` first and `JSC_WIKI_REPO` second. Exit 3 — neither variable is set: ask for that type's `{owner}/{repo}` per the `jsc-ask:ask` rules. Exit 2 — the installed `jsc-gitea` does not accept the `TOOLING` type yet: stop and report that the type has to be registered there first. Completion condition: exactly one `{owner}/{repo}` is recorded, and every **content page** write in this step targets it; the directory page lives in the CONTENTS repo instead, and `wiki-contents.sh` resolves that one itself in step 7.4.
|
||
|
||
7.3 **Write the content pages first.** Render `templates/tooling-page.md` for each `TOOLING_{HASH}` from the step 3 inventory, keeping only that page's own CLI row in the `Supported CLIs` and `Hook wiring status` tables. Each run overwrites the whole page: it records what this machine looks like right now, so keeping earlier runs buys nothing. Content pages go before the directory page for the same reason as every other jsc skill — a directory block must never point at a page whose write failed. Completion condition: every `TOOLING_{HASH}` write returned exit 0, or its failure went to step 7.5.
|
||
|
||
7.4 **Register the pages in `TOOLING_CONTENTS` second, with `jsc-gitea/tools/wiki-contents.sh`.** That page is a heading-plus-bullets list and holds no markdown table: one `## TOOLING_{HASH}` block per machine, CLI and account, every field one `- {欄位名}:{值}` line under it, following [`../../templates/tooling-contents.md`](../../templates/tooling-contents.md). Build one file holding this run's single block, its 盤點頁 bullet written as `[TOOLING_{HASH}]({url})` from the **absolute** URL that `jsc-gitea/tools/gitea.sh wiki-url {TOOLING repo} TOOLING_{HASH}` prints; the H2 heading itself carries no link, no URL, no affix and no date — only the content page name. Hand every URL to `jsc-gitea/tools/link-check.sh` first and write only when it exits 0; it verifies through the Gitea API, because a private repo answers 404 to an unauthenticated web request. Then run this once per page written in step 7.3:
|
||
|
||
`jsc-gitea/tools/wiki-contents.sh upsert TOOLING 1 "TOOLING_{HASH}" {entry file} templates/tooling-contents.md`
|
||
|
||
That tool owns the whole read-modify-write of the directory page: it resolves the CONTENTS repo itself, reads the page, converts any leftover markdown table to blocks, replaces the block whose heading matches, appends when none matches, and writes the page back, so every block belonging to another machine or CLI stays as it was. The key is the H2 heading `TOOLING_{HASH}`, and that name is hashed from `{hostname}/{tool}/{account}`, so a heading match already proves all three segments match — no per-field comparison is needed. The `1` is the key column, and it only matters while the page is still an old markdown table: it names the 盤點頁 column, whose cell text is that same page name, so the automatic conversion produces headings that match. The fourth argument is the whole block, not a table row. Route each exit code:
|
||
- 0 — the block is in place. Report the `updated` or `added` it printed.
|
||
- 1 — the page content could not be assembled, or the write failed. A page holding no matching block is **not** this case; that one appends. Report `TOOLING_CONTENTS` as not written together with the block content, and take it to step 7.5.
|
||
- 2 — an argument was rejected. Fix it and rerun; nothing was written.
|
||
- 3 — no CONTENTS wiki repo is configured. Name `JSC_WIKI_REPO_CONTENTS` and `JSC_WIKI_REPO`, ask per the `jsc-ask:ask` rules, then rerun. The content pages of step 7.3 stay written.
|
||
- 4 — the directory page is absent and no template was passed. Rerun with `templates/tooling-contents.md` as the fifth argument. **This is the only path that creates that page.**
|
||
- 7 or 8 — the token was rejected, or the API failed, so the other machines' blocks are unknown. Stop. Create nothing and overwrite nothing: a page built on top of unknown content deletes blocks that nobody can get back. Report the exit code and the page name.
|
||
|
||
Completion condition: `TOOLING_CONTENTS` holds one `## TOOLING_{HASH}` block per page written in step 7.3, each written by an `upsert` that exited 0, every block belonging to another machine or CLI is unchanged, or the step stopped with the exit code and the page name reported.
|
||
|
||
7.5 **Route a failed write.** Retry the failed write once — a `jsc-gitea:wiki` content-page write, or a `wiki-contents.sh upsert` that exited 1. When it fails again, stop the publish and report the page name together with the content that never reached the wiki, so the user can place it by hand. Report a page as written only after its write returned exit 0. Completion condition: every page named in this step is either confirmed written with its page name, or listed as unwritten with its exit code and its full content.
|
||
|
||
8. Report this run's outcome to the local event stream — the last step of every run, the ones that stop early included, and the ones whose target was the chat response. Run:
|
||
|
||
`jsc-hooks/tools/report-status.sh skill-end jsc-meta:tooling-guide {status} {exit code} [detail]`
|
||
|
||
Resolve `jsc-hooks` from the `domain<TAB>path` row step 2 printed for the `hooks` domain, the same way this skill resolves every other cross-plugin script; when step 2 never produced rows, take the sibling checkout under the root step 1 printed. **When the script is not on this machine, skip this step in silence and close the run as normal.** A reporting path that is absent must never fail the run it reports on, and this call's own exit code never changes what this skill reports.
|
||
|
||
Pick `{status}` from what the run actually did:
|
||
|
||
| status | Use it when |
|
||
| --- | --- |
|
||
| `ok` | the guide holds every required section with a source behind each claim, it reached the recorded target, and — for the wiki target — every page write and the `TOOLING_CONTENTS` registration returned exit 0 |
|
||
| `blocked` | a gate or a missing prerequisite stopped the run before any inventory was built — `tools/plugins-root.sh` exited 1, or `sync-domains.sh` exited 2 or 1 |
|
||
| `failed` | the run broke mid-way — `inventory-tooling.sh` exited non-zero, or a wiki write failed again after its one retry |
|
||
| `degraded` | the guide was delivered with a part missing — stale rows were accepted from `sync-domains.sh` exit 3, a hook verdict stayed unknown, or the content pages were written while `TOOLING_CONTENTS` was not |
|
||
| `aborted` | the user stopped the run, or the user refused a guide built on stale input so this skill stopped on its own |
|
||
|
||
`{exit code}` is this run's own result as a number: `0` for `ok`, non-zero otherwise. `detail` is optional, one line, at most 200 characters.
|
||
|
||
The matching `skill-start` comes free from the hook, which fires when the skill loads. The inventory and the delivery happen in the model turns after that, so no hook can see how the run ended — a `start` with no `end` reads as an abort, which is why writing the `end` is this skill's own job. This is the one write a read-only skill still makes.
|
||
|
||
Completion condition: one `skill-end` line for this run is appended to `$JSC_HOME/usage/events.jsonl`, or the script was absent and the final report says so.
|
||
|
||
## Notes
|
||
|
||
- **Removed protection, on purpose.** The flow used to carry three more steps that re-ran `list-skills.sh`, `detect-clis.sh` and `wire-cli.sh status {cli}` after `inventory-tooling.sh` had already called all three. That second pass doubled as an independent cross-check: it read the same three facts straight from the source scripts, so a wrong skill row, a missing CLI, or a stale hook verdict produced by `inventory-tooling.sh` surfaced as a disagreement between the two sets. That cross-check is gone. The guide now takes the skill catalog, the CLI list and the hook wiring status from one `inventory-tooling.sh` run, with no second raw output to compare against, so a bug in that script's own scanning, parsing, or section writing reaches the guide unnoticed and reads as fact. Two things bound the risk: step 5 still rejects any claim with no source section behind it, and `Hook wiring status` carries the per-CLI exit code, so a nonsense verdict stays visible. When a decision rests on the guide's skill, CLI, or hook facts, get the second opinion elsewhere — run the three scripts by hand and compare, or run `jsc-cli:doctor` for an independent wiring verdict.
|
||
|
||
## Output Contract
|
||
|
||
The guide must include these fields in this order:
|
||
|
||
1. `Source freshness`: synced, stale accepted, or blocked.
|
||
2. `Supported plugins`: one row per domain.
|
||
3. `Supported skills`: one row per skill.
|
||
4. `Supported CLIs`: one row per detected CLI, or one sentence for none detected.
|
||
5. `Hook management`: wiring, smoke, error scan, repair owner, and coverage limits, with the per-CLI wiring verdicts from `Hook wiring status`.
|
||
6. `Plugin and skill management`: install, update, delete, audit, and creation owners.
|
||
7. `Operational checks`: doctor, setup, version guard, restart gate, language guard, and comment-scope guard.
|
||
8. `Use this when`: short usage guidance for maintainers.
|
||
|
||
Done when the output has all fields in order and each non-empty table has at least one source reference.
|
||
|
||
For the wiki-page target, the same fields go to `TOOLING_{HASH}` in the section order of `templates/tooling-page.md`, and the `## TOOLING_{HASH}` block registered in `TOOLING_CONTENTS` follows `templates/tooling-contents.md`. Both templates own their own field lists; do not restate them here.
|