docs(skills): 五支技能與盤點技能的目錄頁呼叫敘述同步條列版面
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
- 本存取庫六支會寫目錄頁的技能。
- 稽核與驗證流程改拿新的行為清單比對。
This commit is contained in:
+12
-12
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: skill-check
|
||||
description: Routine compliance, script, hook, flow-efficiency, and cost-efficiency audit of the whole jsc skill set with no change request in hand. Sync every domain repo from the Gitea canonical marketplace, then run three parallel groups - lint-scripts.sh plus lint-frontmatter.sh plus check-behaviors.sh plus ste100-lint.sh plus check-link-format.sh plus check-wiki-rules.sh plus check-page-name.sh plus hook smoke, the guidelines.md checklist audit, and an optimization review that first reads each domain's SKILLSET_{HASH} so suggestions already applied or deferred are never re-scanned or re-asked, then covers parallelism, tool extraction, repeated interaction, redundant checks, misplaced gates, and avoidable token, sub-agent, API, scan, or interaction cost. Confirm compliance fixes and optimization suggestions before applying them, recording each decision with its date, re-check until accepted fixes pass, then open a PR per affected repo via jsc-git pr. Close by appending the round's result to every changed domain's SKILLSET_{HASH} and its SKILLSET_CONTENTS row, or to the plugins/meta page when no domain was changed. Use for periodic or on-demand skill-set checks; not for applying a change request (use skillset-update) or editing one skill (use skill-update).
|
||||
description: Routine compliance, script, hook, flow-efficiency, and cost-efficiency audit of the whole jsc skill set with no change request in hand. Sync every domain repo from the Gitea canonical marketplace, then run three parallel groups - lint-scripts.sh plus lint-frontmatter.sh plus check-behaviors.sh plus ste100-lint.sh plus check-link-format.sh plus check-wiki-rules.sh plus check-page-name.sh plus hook smoke, the guidelines.md checklist audit, and an optimization review that first reads each domain's SKILLSET_{HASH} so suggestions already applied or deferred are never re-scanned or re-asked, then covers parallelism, tool extraction, repeated interaction, redundant checks, misplaced gates, and avoidable token, sub-agent, API, scan, or interaction cost. Confirm compliance fixes and optimization suggestions before applying them, recording each decision with its date, re-check until accepted fixes pass, then open a PR per affected repo via jsc-git pr. Close by appending the round's result to every changed domain's SKILLSET_{HASH} and its SKILLSET_CONTENTS block, or to the plugins/meta page when no domain was changed. Use for periodic or on-demand skill-set checks; not for applying a change request (use skillset-update) or editing one skill (use skill-update).
|
||||
---
|
||||
|
||||
# skill-check — audit compliance, flow efficiency, and cost efficiency
|
||||
@@ -94,14 +94,14 @@ Single source of guidelines: [`../../references/guidelines.md`](../../references
|
||||
- **Which page.** For every domain repo actually changed in this round, resolve `gitea.sh wiki-repo SKILLSET` and append one section to `SKILLSET_` plus `gitea.sh hash-id "{owner}/{repo}"` of that domain repo. Append; never overwrite — the page accumulates every change that domain has ever seen.
|
||||
- **When nothing changed.** No domain repo changed in this round means one page, hashed from `plugins/meta`, gets one section recording 「本輪無發現」 with the group verdicts that produced that conclusion. A round that found nothing still has to leave the evidence that it ran.
|
||||
- **What each section holds.** The layout is [`../../templates/skillset-page.md`](../../templates/skillset-page.md): date, change type `skill-check`, the change request in one sentence, the skills touched, the files changed, the PR URL from step 7, the deploy-route verdict and the verification result. The `skill-check` section additionally carries the 優化建議 table, every row filled including 決議 and 決議日期 — that table is exactly what the next round reads in step 2's group 3.
|
||||
- **Directory page.** Refresh that page's row in `SKILLSET_CONTENTS` with `jsc-gitea/tools/wiki-contents.sh` — never by hand, and never through `jsc-gitea:wiki`. Build one file holding the single row from [`../../templates/skillset-contents.md`](../../templates/skillset-contents.md), then run:
|
||||
- **Directory page.** Refresh that page's own block in `SKILLSET_CONTENTS` with `jsc-gitea/tools/wiki-contents.sh` — never by hand, and never through `jsc-gitea:wiki`. That page is a heading-plus-bullets list and holds no markdown table: one `## SKILLSET_{HASH}` block per domain repo, every field one `- {欄位名}:{值}` line under it. Build one file holding this domain's single block, following [`../../templates/skillset-contents.md`](../../templates/skillset-contents.md), then run:
|
||||
|
||||
`jsc-gitea/tools/wiki-contents.sh upsert SKILLSET 2 "{owner}/{repo}" {row file} templates/skillset-contents.md`
|
||||
`jsc-gitea/tools/wiki-contents.sh upsert SKILLSET 2 "SKILLSET_{HASH}" {entry file} templates/skillset-contents.md`
|
||||
|
||||
The key column is `2`, the 存取庫 column, and the key is that domain repo's `{owner}/{repo}` written exactly as the row file writes it; the string is the same every round, so one domain keeps exactly one row. The script resolves the CONTENTS repo itself — the directory page lives there, never in the SKILLSET repo — reads the whole page, replaces the row whose key column matches, appends when none matches, and writes the page back, so every row owned by another domain stays as it was.
|
||||
The key is the H2 heading `SKILLSET_{HASH}`, and that page name depends only on the domain repo's `{owner}/{repo}`, so it reads the same every round and one domain keeps exactly one block. The `2` is the key column: the index of the column that held the content-page link in the **old markdown table**, and it matters only when such an old table still has to be converted automatically — the conversion takes the last path segment of that column's link URL as the H2 heading. Count that index from the **live page's own column layout**, never from the template's: the live `SKILLSET_CONTENTS` reads `| 存放庫 | 異動報告 | 目前版本 | 最後更新 |`, so the link sits in column 2 while column 1 is plain text like `plugins/ask`. Passing `1` would make the heading `plugins/ask`, which never matches the key `SKILLSET_{HASH}`, so the existing entry is appended as a brand-new one — one domain ends up with two blocks and the older one is never updated again. The fourth argument is the whole block, not a table row. The script resolves the CONTENTS repo itself — the directory page lives there, never in the SKILLSET repo — reads the whole page, converts any leftover table to blocks, replaces the block whose heading matches, appends when none matches, and writes the page back, so every block owned by another domain stays as it was.
|
||||
|
||||
The 異動頁 cell is written as `[SKILLSET_{HASH}]({url})`, the URL being the **absolute** one from `gitea.sh wiki-url {SKILLSET repo} SKILLSET_{HASH}`. Every link on both pages takes that `[{text}]({url})` form — the double-bracket wiki-link form is never used, because it resolves only inside one wiki. Fetch that URL only after the content page is written: **write the content page first** — a directory row naming a page whose write failed is worse than a missing row.
|
||||
- **Check the links before writing.** Hand every URL going onto the content page and into the directory row to `jsc-gitea/tools/link-check.sh` and write only when it exits 0. It verifies through the Gitea API, never a web status code: a private repo answers 404 to an unauthenticated web request, so a status-code check would call a live page dead and rewrite pages that are fine.
|
||||
The 異動頁 bullet is written as `[SKILLSET_{HASH}]({url})`, the URL being the **absolute** one from `gitea.sh wiki-url {SKILLSET repo} SKILLSET_{HASH}`; the H2 heading itself carries no link, no URL, no affix and no date. Every link on both pages takes that `[{text}]({url})` form — the double-bracket wiki-link form is never used, because it resolves only inside one wiki. Fetch that URL only after the content page is written: **write the content page first** — a directory block naming a page whose write failed is worse than a missing block.
|
||||
- **Check the links before writing.** Hand every URL going onto the content page and into the directory block to `jsc-gitea/tools/link-check.sh` and write only when it exits 0. It verifies through the Gitea API, never a web status code: a private repo answers 404 to an unauthenticated web request, so a status-code check would call a live page dead and rewrite pages that are fine.
|
||||
- **Exit codes.** Route every one of them. None of these calls may be read as success by default.
|
||||
|
||||
| Call | Exit | Do |
|
||||
@@ -113,23 +113,23 @@ Single source of guidelines: [`../../references/guidelines.md`](../../references
|
||||
| Content page read | 0 | Append into the sections already there |
|
||||
| | 4 | The page does not exist yet, so build it from the template |
|
||||
| | 7 or 8 | Stop and write nothing, because a page rebuilt on top of an unread read loses every section already on it |
|
||||
| `gitea.sh wiki-url` | 4 | The content page is not there, so the write above did **not** succeed. Go back and write it; put no directory row in until the page exists, because a row may not name a page that failed |
|
||||
| `gitea.sh wiki-url` | 4 | The content page is not there, so the write above did **not** succeed. Go back and write it; put no directory block in until the page exists, because a block may not name a page that failed |
|
||||
| | 5 | The API answered with no `html_url`. Stop and report it; never assemble the URL by hand from the host and the page name |
|
||||
| `link-check.sh` | 0 | Every link is reachable. Write the page |
|
||||
| | 1 | At least one link is dead. Write nothing, and report the `DEAD` lines it printed |
|
||||
| | 2 | No URL was passed, which is a defect here. Pass the links and rerun |
|
||||
| | 3 | `GITEA_HOST` is unset. Set it and rerun; never skip the check instead |
|
||||
| | 7 | Gitea authentication failed. Stop and report the key problem, and never read it as a dead link |
|
||||
| `wiki-contents.sh upsert` | 0 | The row is in place. Report the `updated` or `added` it printed, with the page it named |
|
||||
| | 1 | The write failed, or the directory page holds no markdown table. Report `SKILLSET_CONTENTS` as not written, together with the row content |
|
||||
| `wiki-contents.sh upsert` | 0 | The block is in place. Report the `updated` or `added` it printed, with the page it named |
|
||||
| | 1 | The page content could not be assembled, or the write failed. A page with no matching block is not an error — that case appends. Report `SKILLSET_CONTENTS` as not written, together with the block content |
|
||||
| | 2 | An argument was rejected. Fix it and rerun; nothing was written |
|
||||
| | 3 | No CONTENTS wiki repo is configured. Report `JSC_WIKI_REPO_CONTENTS` and `JSC_WIKI_REPO` as the two variables to set. The round's section is on `SKILLSET_{HASH}` and stays there |
|
||||
| | 4 | The directory page is absent and no template was passed. Rerun with `templates/skillset-contents.md` as the fifth argument |
|
||||
| | 7 | The token is invalid or lacks permission, so the other domains' rows are unknown. Stop, report the token problem, and create no page — writing nothing is what keeps those rows alive |
|
||||
| | 7 | The token is invalid or lacks permission, so the other domains' blocks are unknown. Stop, report the token problem, and create no page — writing nothing is what keeps those blocks alive |
|
||||
| | 8 | Some other API failure. Stop, report that status, and create no page |
|
||||
- **On a failed write.** Retry once. Still failing, hand the user the page name and the full section that was not written, so the round's result is not lost. **Never close the run reporting a page as written when it was not**, and never close it silently with the content only in the transcript.
|
||||
|
||||
Completion condition: every changed domain repo has one new section on its `SKILLSET_{HASH}` and one row in `SKILLSET_CONTENTS` written by a `wiki-contents.sh upsert` that exited 0, or — where nothing changed — the `plugins/meta` page carries the 「本輪無發現」 section and its row on the same terms; every content-page write is confirmed by a successful read-back or reported as not written with its full content handed back.
|
||||
Completion condition: every changed domain repo has one new section on its `SKILLSET_{HASH}` and one `## SKILLSET_{HASH}` block in `SKILLSET_CONTENTS` written by a `wiki-contents.sh upsert` that exited 0, or — where nothing changed — the `plugins/meta` page carries the 「本輪無發現」 section and its block on the same terms; every content-page write is confirmed by a successful read-back or reported as not written with its full content handed back.
|
||||
9. Report this round's outcome to the local event stream — the last step of every run, the ones that stop early included. Run:
|
||||
|
||||
`jsc-hooks/tools/report-status.sh skill-end jsc-meta:skill-check {status} {exit code} [detail]`
|
||||
@@ -143,7 +143,7 @@ Single source of guidelines: [`../../references/guidelines.md`](../../references
|
||||
| `ok` | every domain ended with a complete checklist, every accepted fix passed its re-check, every affected repo has a PR URL, and every wiki write exited 0 |
|
||||
| `blocked` | a gate or a missing prerequisite stopped the round before anything was audited — `sync-domains.sh` never reached exit 0, or the call itself was refused |
|
||||
| `failed` | the round broke mid-way — a re-check in step 6 kept failing, or a wiki write failed again after its one retry |
|
||||
| `degraded` | the round finished with a part missing — a domain carries 「本輪未取得已決議清單,優化建議暫不提出」, or a content page was written while its `SKILLSET_CONTENTS` row was not |
|
||||
| `degraded` | the round finished with a part missing — a domain carries 「本輪未取得已決議清單,優化建議暫不提出」, or a content page was written while its `SKILLSET_CONTENTS` block was not |
|
||||
| `aborted` | the user stopped the round, or a prerequisite turned out not to hold and this skill stopped on its own |
|
||||
|
||||
`{exit code}` is this round's own result as a number: `0` for `ok`, non-zero otherwise. `detail` is optional, one line, at most 200 characters.
|
||||
|
||||
@@ -36,12 +36,12 @@ Single source of guidelines: [`../../references/guidelines.md`](../../references
|
||||
On any mismatch — the deleted skill still listed, a leftover from exit 1, a fixed caller that now fails, a prompt failure, or unexpected stderr — fix the cause and rerun this step from 8.1. Completion condition: the skill is absent from the list, the verification script exits 0 or its exit 3 is reported as「無處可查」and carried into step 8.3, every fixed caller ran, every checkable CLI completed the prompt with the expected result, and every untestable CLI has a stated reason.
|
||||
3. Write the change report to the wiki — this part MUST run as a sub agent. It is two pages in two repos, and they must not be mixed up.
|
||||
- **Content page `SKILLSET_{HASH}`.** Resolve its repo with `jsc-gitea/tools/gitea.sh wiki-repo SKILLSET`, which reads `JSC_WIKI_REPO_SKILLSET` first, then `JSC_WIKI_REPO`. `{HASH}` is `gitea.sh hash-id "{owner}/{repo}"` of the domain repo that lost the skill, used at the full 40 characters it prints. Write it through `jsc-gitea:wiki` following [`../../templates/skillset-page.md`](../../templates/skillset-page.md): **append** a section for this change — date, 「刪除」, skill name, changed files (the step 5 inventory verdicts included), PR URL, the step 8.1 route verdict and the step 8.2 verification result per item, the deep-delete verdict「無處可查」included when it applies — and keep every earlier section.
|
||||
- **Directory page `SKILLSET_CONTENTS`.** It lives in the CONTENTS repo, never in the SKILLSET one. `wiki-contents.sh` resolves it itself with `gitea.sh wiki-repo CONTENTS`, whose chain is `JSC_WIKI_REPO_CONTENTS` then `JSC_WIKI_REPO` and never falls back to `JSC_WIKI_REPO_SKILLSET`. Build one file holding the single row from [`../../templates/skillset-contents.md`](../../templates/skillset-contents.md), its 異動頁 cell written as `[SKILLSET_{HASH}]({url})` with the **absolute** URL from `gitea.sh wiki-url {SKILLSET repo} SKILLSET_{HASH}`. Every link on both pages takes that `[{text}]({url})` form; the double-bracket wiki-link form resolves only inside one wiki, so it is never used. Then run:
|
||||
- **Directory page `SKILLSET_CONTENTS`.** It lives in the CONTENTS repo, never in the SKILLSET one. `wiki-contents.sh` resolves it itself with `gitea.sh wiki-repo CONTENTS`, whose chain is `JSC_WIKI_REPO_CONTENTS` then `JSC_WIKI_REPO` and never falls back to `JSC_WIKI_REPO_SKILLSET`. That page is a heading-plus-bullets list and holds no markdown table: one `## SKILLSET_{HASH}` block per domain repo, every field one `- {欄位名}:{值}` line under it. Build one file holding this domain's single block, following [`../../templates/skillset-contents.md`](../../templates/skillset-contents.md), with its 異動頁 bullet written as `[SKILLSET_{HASH}]({url})` from the **absolute** URL that `gitea.sh wiki-url {SKILLSET repo} SKILLSET_{HASH}` prints. The H2 heading itself carries no link, no URL, no affix and no date — only the content page name. Every link on both pages takes that `[{text}]({url})` form; the double-bracket wiki-link form resolves only inside one wiki, so it is never used. Then run:
|
||||
|
||||
`jsc-gitea/tools/wiki-contents.sh upsert SKILLSET 2 "{owner}/{repo}" {row file} templates/skillset-contents.md`
|
||||
`jsc-gitea/tools/wiki-contents.sh upsert SKILLSET 2 "SKILLSET_{HASH}" {entry file} templates/skillset-contents.md`
|
||||
|
||||
The key column is `2`, the 存取庫 column, holding that repo's `{owner}/{repo}` exactly as the row file writes it, so one domain keeps exactly one row and no other domain's row moves. Never hand-edit the directory page. Write the content page first and fetch the URL only after it exists.
|
||||
- **Check the links before writing.** Hand every URL going onto the content page and into the directory row to `jsc-gitea/tools/link-check.sh`, and write only when it exits 0. It verifies through the Gitea API, never a web status code: a private repo answers 404 to an unauthenticated web request, so a status-code check would call a live page dead.
|
||||
The key is the H2 heading `SKILLSET_{HASH}`, so one domain keeps exactly one block and no other domain's block moves. That page name depends only on `{owner}/{repo}`, which is why it is the key: a host rename or a changed `JSC_WIKI_REPO_SKILLSET` leaves it untouched, so the match still finds the existing block. The `2` is the key column: the index of the column that held the content-page link in the **old markdown table**, and it matters only when such an old table still has to be converted automatically — the conversion takes the last path segment of that column's link URL as the H2 heading. Count that index from the **live page's own column layout**, never from the template's: the live `SKILLSET_CONTENTS` reads `| 存放庫 | 異動報告 | 目前版本 | 最後更新 |`, so the link sits in column 2 while column 1 is plain text like `plugins/ask`. Passing `1` would make the heading `plugins/ask`, which never matches the key `SKILLSET_{HASH}`, so the existing entry is appended as a brand-new one — one domain ends up with two blocks and the older one is never updated again. The fourth argument is the whole block, not a table row. Never hand-edit the directory page. Write the content page first and fetch the URL only after it exists.
|
||||
- **Check the links before writing.** Hand every URL going onto the content page and into the directory block to `jsc-gitea/tools/link-check.sh`, and write only when it exits 0. It verifies through the Gitea API, never a web status code: a private repo answers 404 to an unauthenticated web request, so a status-code check would call a live page dead.
|
||||
- **Exit codes.** Route every one of them:
|
||||
|
||||
| Call | Exit | Do |
|
||||
@@ -53,22 +53,22 @@ Single source of guidelines: [`../../references/guidelines.md`](../../references
|
||||
| Content page read | 0 | Append into the sections already there |
|
||||
| | 4 | The page does not exist yet, so build it from `templates/skillset-page.md` |
|
||||
| | 7 or 8 | Stop and write nothing: a page rebuilt on top of an unread read loses every section already on it |
|
||||
| `gitea.sh wiki-url` | 4 | The content page is not there, so the write above did **not** succeed. Go back and write it, and add no directory row until the page exists |
|
||||
| `gitea.sh wiki-url` | 4 | The content page is not there, so the write above did **not** succeed. Go back and write it, and add no directory block until the page exists |
|
||||
| | 5 | The API answered with no `html_url`. Stop and report it; never assemble the URL by hand from the host and the page name |
|
||||
| `link-check.sh` | 0 | Every link is reachable. Write the page |
|
||||
| | 1 | At least one link is dead. Write nothing, and report the `DEAD` lines it printed |
|
||||
| | 2 | No URL was passed, which is a defect here. Pass the links and rerun |
|
||||
| | 3 | `GITEA_HOST` is unset. Set it and rerun; never skip the check instead |
|
||||
| | 7 | Gitea authentication failed. Stop and report the key problem, and never read it as a dead link |
|
||||
| `wiki-contents.sh upsert` | 0 | The row is in place. Report the `updated` or `added` it printed |
|
||||
| | 1 | The write failed. Report `SKILLSET_CONTENTS` as not written, together with the row content |
|
||||
| `wiki-contents.sh upsert` | 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. Report `SKILLSET_CONTENTS` as not written, together with the block content |
|
||||
| | 2 | An argument was rejected. Fix it and rerun; nothing was written |
|
||||
| | 3 | No CONTENTS wiki repo is configured. Report `JSC_WIKI_REPO_CONTENTS` and `JSC_WIKI_REPO` as the two variables to set; the new section is on `SKILLSET_{HASH}` and stays there |
|
||||
| | 4 | The directory page is absent and no template was passed. Rerun with `templates/skillset-contents.md` as the fifth argument |
|
||||
| | 7 | The token is invalid or lacks permission, so the other domains' rows are unknown. Stop, report the token problem, and create no page |
|
||||
| | 7 | The token is invalid or lacks permission, so the other domains' blocks are unknown. Stop, report the token problem, and create no page |
|
||||
| | 8 | Some other API failure. Stop, report that status, and create no page |
|
||||
|
||||
On any failure, hand the page name and the unwritten entry back to the user and leave this step open; never close the flow on an unwritten report. Completion condition: `SKILLSET_{HASH}` holds the new section plus all earlier sections, and `wiki-contents.sh upsert` exited 0 with this domain's row on `SKILLSET_CONTENTS` linking that page by absolute URL.
|
||||
On any failure, hand the page name and the unwritten entry back to the user and leave this step open; never close the flow on an unwritten report. Completion condition: `SKILLSET_{HASH}` holds the new section plus all earlier sections, and `wiki-contents.sh upsert` exited 0 with this domain's `## SKILLSET_{HASH}` block on `SKILLSET_CONTENTS` linking that page by absolute URL.
|
||||
9. Report this run's outcome to the local event stream — the last step of every run, the ones that stop early included. Run:
|
||||
|
||||
`jsc-hooks/tools/report-status.sh skill-end jsc-meta:skill-delete {status} {exit code} [detail]`
|
||||
@@ -82,7 +82,7 @@ Single source of guidelines: [`../../references/guidelines.md`](../../references
|
||||
| `ok` | the skill directory and its behavior-list section are gone, the PR is open, `deploy-verify.md` sections 1 to 5 hold, `verify-skill-removed.sh` exited 0, and both wiki writes exited 0 |
|
||||
| `blocked` | a gate or a missing prerequisite stopped the run before any file changed — `sync-domains.sh` never reached exit 0, or no skill could be listed to pick from |
|
||||
| `failed` | the run broke mid-way — a leftover from `verify-skill-removed.sh` exit 1 could not be removed, or a wiki write failed again after its one retry |
|
||||
| `degraded` | the deletion landed with a part missing — the deep-delete check came back 「無處可查」, or the content page was written while its `SKILLSET_CONTENTS` row was not |
|
||||
| `degraded` | the deletion landed with a part missing — the deep-delete check came back 「無處可查」, or the content page was written while its `SKILLSET_CONTENTS` block was not |
|
||||
| `aborted` | the user stopped the run, or a prerequisite turned out not to hold and 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.
|
||||
|
||||
+10
-10
@@ -45,12 +45,12 @@ Single source of guidelines: [`../../references/guidelines.md`](../../references
|
||||
1. Follow [`../../references/deploy-verify.md`](../../references/deploy-verify.md) from section 1 to section 5: `tools/deploy-route.sh {domain-path}` picks the route, the deploy route or the worktree route runs, and the verification then runs in a **fresh CLI process**, never in the session that ran the deploy. That session raised the restart gate itself and still holds the old skill body, so verifying inside it either gets blocked or passes on stale behavior. Verify the added skill's row in `tools/list-skills.sh`, every tool the skill added, and one minimal prompt per checkable CLI — the per-CLI prompts run in parallel. Completion condition: every completion condition in `deploy-verify.md` sections 1 to 5 holds for this domain repo.
|
||||
2. Write the change report to the wiki — this part MUST run as a sub agent. It is two pages in two repos, and they must not be mixed up.
|
||||
- **Content page `SKILLSET_{HASH}`.** Resolve its repo with `jsc-gitea/tools/gitea.sh wiki-repo SKILLSET`, which reads `JSC_WIKI_REPO_SKILLSET` first, then `JSC_WIKI_REPO`. `{HASH}` is `gitea.sh hash-id "{owner}/{repo}"` of the domain repo that gained the skill, used at the full 40 characters it prints. Write it through `jsc-gitea:wiki` following [`../../templates/skillset-page.md`](../../templates/skillset-page.md): **append** a section for this change — date, 「新增」, skill name, changed files, PR URL, the step 6.1 route verdict and verification result per item — and keep every earlier section.
|
||||
- **Directory page `SKILLSET_CONTENTS`.** It lives in the CONTENTS repo, never in the SKILLSET one. `wiki-contents.sh` resolves it itself with `gitea.sh wiki-repo CONTENTS`, whose chain is `JSC_WIKI_REPO_CONTENTS` then `JSC_WIKI_REPO` and never falls back to `JSC_WIKI_REPO_SKILLSET`. Build one file holding the single row from [`../../templates/skillset-contents.md`](../../templates/skillset-contents.md), its 異動頁 cell written as `[SKILLSET_{HASH}]({url})` with the **absolute** URL from `gitea.sh wiki-url {SKILLSET repo} SKILLSET_{HASH}`. Every link on both pages takes that `[{text}]({url})` form; the double-bracket wiki-link form resolves only inside one wiki, so it is never used. Then run:
|
||||
- **Directory page `SKILLSET_CONTENTS`.** It lives in the CONTENTS repo, never in the SKILLSET one. `wiki-contents.sh` resolves it itself with `gitea.sh wiki-repo CONTENTS`, whose chain is `JSC_WIKI_REPO_CONTENTS` then `JSC_WIKI_REPO` and never falls back to `JSC_WIKI_REPO_SKILLSET`. That page is a heading-plus-bullets list and holds no markdown table: one `## SKILLSET_{HASH}` block per domain repo, every field one `- {欄位名}:{值}` line under it. Build one file holding this domain's single block, following [`../../templates/skillset-contents.md`](../../templates/skillset-contents.md), with its 異動頁 bullet written as `[SKILLSET_{HASH}]({url})` from the **absolute** URL that `gitea.sh wiki-url {SKILLSET repo} SKILLSET_{HASH}` prints. The H2 heading itself carries no link, no URL, no affix and no date — only the content page name. Every link on both pages takes that `[{text}]({url})` form; the double-bracket wiki-link form resolves only inside one wiki, so it is never used. Then run:
|
||||
|
||||
`jsc-gitea/tools/wiki-contents.sh upsert SKILLSET 2 "{owner}/{repo}" {row file} templates/skillset-contents.md`
|
||||
`jsc-gitea/tools/wiki-contents.sh upsert SKILLSET 2 "SKILLSET_{HASH}" {entry file} templates/skillset-contents.md`
|
||||
|
||||
The key column is `2`, the 存取庫 column, holding that repo's `{owner}/{repo}` exactly as the row file writes it, so one domain keeps exactly one row and no other domain's row moves. Never hand-edit the directory page. Write the content page first and fetch the URL only after it exists.
|
||||
- **Check the links before writing.** Hand every URL going onto the content page and into the directory row to `jsc-gitea/tools/link-check.sh`, and write only when it exits 0. It verifies through the Gitea API, never a web status code: a private repo answers 404 to an unauthenticated web request, so a status-code check would call a live page dead.
|
||||
The key is the H2 heading `SKILLSET_{HASH}`, so one domain keeps exactly one block and no other domain's block moves. That page name depends only on `{owner}/{repo}`, which is why it is the key: a host rename or a changed `JSC_WIKI_REPO_SKILLSET` leaves it untouched, so the match still finds the existing block. The `2` is the key column: the index of the column that held the content-page link in the **old markdown table**, and it matters only when such an old table still has to be converted automatically — the conversion takes the last path segment of that column's link URL as the H2 heading. Count that index from the **live page's own column layout**, never from the template's: the live `SKILLSET_CONTENTS` reads `| 存放庫 | 異動報告 | 目前版本 | 最後更新 |`, so the link sits in column 2 while column 1 is plain text like `plugins/ask`. Passing `1` would make the heading `plugins/ask`, which never matches the key `SKILLSET_{HASH}`, so the existing entry is appended as a brand-new one — one domain ends up with two blocks and the older one is never updated again. The fourth argument is the whole block, not a table row. Never hand-edit the directory page. Write the content page first and fetch the URL only after it exists.
|
||||
- **Check the links before writing.** Hand every URL going onto the content page and into the directory block to `jsc-gitea/tools/link-check.sh`, and write only when it exits 0. It verifies through the Gitea API, never a web status code: a private repo answers 404 to an unauthenticated web request, so a status-code check would call a live page dead.
|
||||
- **Exit codes.** Route every one of them:
|
||||
|
||||
| Call | Exit | Do |
|
||||
@@ -62,22 +62,22 @@ Single source of guidelines: [`../../references/guidelines.md`](../../references
|
||||
| Content page read | 0 | Append into the sections already there |
|
||||
| | 4 | The page does not exist yet, so build it from `templates/skillset-page.md` |
|
||||
| | 7 or 8 | Stop and write nothing: a page rebuilt on top of an unread read loses every section already on it |
|
||||
| `gitea.sh wiki-url` | 4 | The content page is not there, so the write above did **not** succeed. Go back and write it, and add no directory row until the page exists |
|
||||
| `gitea.sh wiki-url` | 4 | The content page is not there, so the write above did **not** succeed. Go back and write it, and add no directory block until the page exists |
|
||||
| | 5 | The API answered with no `html_url`. Stop and report it; never assemble the URL by hand from the host and the page name |
|
||||
| `link-check.sh` | 0 | Every link is reachable. Write the page |
|
||||
| | 1 | At least one link is dead. Write nothing, and report the `DEAD` lines it printed |
|
||||
| | 2 | No URL was passed, which is a defect here. Pass the links and rerun |
|
||||
| | 3 | `GITEA_HOST` is unset. Set it and rerun; never skip the check instead |
|
||||
| | 7 | Gitea authentication failed. Stop and report the key problem, and never read it as a dead link |
|
||||
| `wiki-contents.sh upsert` | 0 | The row is in place. Report the `updated` or `added` it printed |
|
||||
| | 1 | The write failed. Report `SKILLSET_CONTENTS` as not written, together with the row content |
|
||||
| `wiki-contents.sh upsert` | 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. Report `SKILLSET_CONTENTS` as not written, together with the block content |
|
||||
| | 2 | An argument was rejected. Fix it and rerun; nothing was written |
|
||||
| | 3 | No CONTENTS wiki repo is configured. Report `JSC_WIKI_REPO_CONTENTS` and `JSC_WIKI_REPO` as the two variables to set; the new section is on `SKILLSET_{HASH}` and stays there |
|
||||
| | 4 | The directory page is absent and no template was passed. Rerun with `templates/skillset-contents.md` as the fifth argument |
|
||||
| | 7 | The token is invalid or lacks permission, so the other domains' rows are unknown. Stop, report the token problem, and create no page |
|
||||
| | 7 | The token is invalid or lacks permission, so the other domains' blocks are unknown. Stop, report the token problem, and create no page |
|
||||
| | 8 | Some other API failure. Stop, report that status, and create no page |
|
||||
|
||||
On any failure, hand the page name and the unwritten entry back to the user and leave this step open; never close the flow on an unwritten report. Completion condition: `SKILLSET_{HASH}` holds the new section plus all earlier sections, and `wiki-contents.sh upsert` exited 0 with this domain's row on `SKILLSET_CONTENTS` linking that page by absolute URL.
|
||||
On any failure, hand the page name and the unwritten entry back to the user and leave this step open; never close the flow on an unwritten report. Completion condition: `SKILLSET_{HASH}` holds the new section plus all earlier sections, and `wiki-contents.sh upsert` exited 0 with this domain's `## SKILLSET_{HASH}` block on `SKILLSET_CONTENTS` linking that page by absolute URL.
|
||||
7. Report this run's outcome to the local event stream — the last step of every run, the ones that stop early included. Run:
|
||||
|
||||
`jsc-hooks/tools/report-status.sh skill-end jsc-meta:skill-new {status} {exit code} [detail]`
|
||||
@@ -91,7 +91,7 @@ Single source of guidelines: [`../../references/guidelines.md`](../../references
|
||||
| `ok` | the new `SKILL.md` and its behavior-list section are in place, the checklist passes, the PR is open, `deploy-verify.md` sections 1 to 5 hold, and both wiki writes exited 0 |
|
||||
| `blocked` | a gate or a missing prerequisite stopped the run before any file was created — `sync-domains.sh` never reached exit 0, or Gitea refused the repository creation and nobody created it by hand |
|
||||
| `failed` | the run broke mid-way — `sync-marketplace.sh` or `sync-skill-manifest.sh` kept failing, or a wiki write failed again after its one retry |
|
||||
| `degraded` | the skill landed with a part missing — the content page was written while its `SKILLSET_CONTENTS` row was not, or a CLI could not be verified and the reason was recorded |
|
||||
| `degraded` | the skill landed with a part missing — the content page was written while its `SKILLSET_CONTENTS` block was not, or a CLI could not be verified and the reason was recorded |
|
||||
| `aborted` | the user stopped the run, or a prerequisite turned out not to hold and 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.
|
||||
|
||||
@@ -20,12 +20,12 @@ Single source of guidelines: [`../../references/guidelines.md`](../../references
|
||||
1. Follow [`../../references/deploy-verify.md`](../../references/deploy-verify.md) from section 1 to section 5: `tools/deploy-route.sh {domain-path}` picks the route, the deploy route or the worktree route runs, and the verification then runs in a **fresh CLI process**, never in the session that ran the deploy. That session raised the restart gate itself and still holds the old skill body, so verifying inside it either gets blocked or passes on stale behavior. Verify the updated `description` in the skill's `tools/list-skills.sh` row, every tool this change touched, and one minimal prompt per checkable CLI — the per-CLI prompts run in parallel. Completion condition: every completion condition in `deploy-verify.md` sections 1 to 5 holds for this domain repo.
|
||||
2. Write the change report to the wiki — this part MUST run as a sub agent. It is two pages in two repos, and they must not be mixed up.
|
||||
- **Content page `SKILLSET_{HASH}`.** Resolve its repo with `jsc-gitea/tools/gitea.sh wiki-repo SKILLSET`, which reads `JSC_WIKI_REPO_SKILLSET` first, then `JSC_WIKI_REPO`. `{HASH}` is `gitea.sh hash-id "{owner}/{repo}"` of the changed domain repo, used at the full 40 characters it prints. Write it through `jsc-gitea:wiki` following [`../../templates/skillset-page.md`](../../templates/skillset-page.md): **append** a section for this change — date, 「更新」, skill name, changed files, PR URL, the step 8.1 route verdict and verification result per item — and keep every earlier section.
|
||||
- **Directory page `SKILLSET_CONTENTS`.** It lives in the CONTENTS repo, never in the SKILLSET one. `wiki-contents.sh` resolves it itself with `gitea.sh wiki-repo CONTENTS`, whose chain is `JSC_WIKI_REPO_CONTENTS` then `JSC_WIKI_REPO` and never falls back to `JSC_WIKI_REPO_SKILLSET`. Build one file holding the single row from [`../../templates/skillset-contents.md`](../../templates/skillset-contents.md), its 異動頁 cell written as `[SKILLSET_{HASH}]({url})` with the **absolute** URL from `gitea.sh wiki-url {SKILLSET repo} SKILLSET_{HASH}`. Every link on both pages takes that `[{text}]({url})` form; the double-bracket wiki-link form resolves only inside one wiki, so it is never used. Then run:
|
||||
- **Directory page `SKILLSET_CONTENTS`.** It lives in the CONTENTS repo, never in the SKILLSET one. `wiki-contents.sh` resolves it itself with `gitea.sh wiki-repo CONTENTS`, whose chain is `JSC_WIKI_REPO_CONTENTS` then `JSC_WIKI_REPO` and never falls back to `JSC_WIKI_REPO_SKILLSET`. That page is a heading-plus-bullets list and holds no markdown table: one `## SKILLSET_{HASH}` block per domain repo, every field one `- {欄位名}:{值}` line under it. Build one file holding this domain's single block, following [`../../templates/skillset-contents.md`](../../templates/skillset-contents.md), with its 異動頁 bullet written as `[SKILLSET_{HASH}]({url})` from the **absolute** URL that `gitea.sh wiki-url {SKILLSET repo} SKILLSET_{HASH}` prints. The H2 heading itself carries no link, no URL, no affix and no date — only the content page name. Every link on both pages takes that `[{text}]({url})` form; the double-bracket wiki-link form resolves only inside one wiki, so it is never used. Then run:
|
||||
|
||||
`jsc-gitea/tools/wiki-contents.sh upsert SKILLSET 2 "{owner}/{repo}" {row file} templates/skillset-contents.md`
|
||||
`jsc-gitea/tools/wiki-contents.sh upsert SKILLSET 2 "SKILLSET_{HASH}" {entry file} templates/skillset-contents.md`
|
||||
|
||||
The key column is `2`, the 存取庫 column, holding that repo's `{owner}/{repo}` exactly as the row file writes it, so one domain keeps exactly one row and no other domain's row moves. Never hand-edit the directory page. Write the content page first and fetch the URL only after it exists.
|
||||
- **Check the links before writing.** Hand every URL going onto the content page and into the directory row to `jsc-gitea/tools/link-check.sh`, and write only when it exits 0. It verifies through the Gitea API, never a web status code: a private repo answers 404 to an unauthenticated web request, so a status-code check would call a live page dead.
|
||||
The key is the H2 heading `SKILLSET_{HASH}`, so one domain keeps exactly one block and no other domain's block moves. That page name depends only on `{owner}/{repo}`, which is why it is the key: a host rename or a changed `JSC_WIKI_REPO_SKILLSET` leaves it untouched, so the match still finds the existing block. The `2` is the key column: the index of the column that held the content-page link in the **old markdown table**, and it matters only when such an old table still has to be converted automatically — the conversion takes the last path segment of that column's link URL as the H2 heading. Count that index from the **live page's own column layout**, never from the template's: the live `SKILLSET_CONTENTS` reads `| 存放庫 | 異動報告 | 目前版本 | 最後更新 |`, so the link sits in column 2 while column 1 is plain text like `plugins/ask`. Passing `1` would make the heading `plugins/ask`, which never matches the key `SKILLSET_{HASH}`, so the existing entry is appended as a brand-new one — one domain ends up with two blocks and the older one is never updated again. The fourth argument is the whole block, not a table row. Never hand-edit the directory page. Write the content page first and fetch the URL only after it exists.
|
||||
- **Check the links before writing.** Hand every URL going onto the content page and into the directory block to `jsc-gitea/tools/link-check.sh`, and write only when it exits 0. It verifies through the Gitea API, never a web status code: a private repo answers 404 to an unauthenticated web request, so a status-code check would call a live page dead.
|
||||
- **Exit codes.** Route every one of them:
|
||||
|
||||
| Call | Exit | Do |
|
||||
@@ -37,22 +37,22 @@ Single source of guidelines: [`../../references/guidelines.md`](../../references
|
||||
| Content page read | 0 | Append into the sections already there |
|
||||
| | 4 | The page does not exist yet, so build it from `templates/skillset-page.md` |
|
||||
| | 7 or 8 | Stop and write nothing: a page rebuilt on top of an unread read loses every section already on it |
|
||||
| `gitea.sh wiki-url` | 4 | The content page is not there, so the write above did **not** succeed. Go back and write it, and add no directory row until the page exists |
|
||||
| `gitea.sh wiki-url` | 4 | The content page is not there, so the write above did **not** succeed. Go back and write it, and add no directory block until the page exists |
|
||||
| | 5 | The API answered with no `html_url`. Stop and report it; never assemble the URL by hand from the host and the page name |
|
||||
| `link-check.sh` | 0 | Every link is reachable. Write the page |
|
||||
| | 1 | At least one link is dead. Write nothing, and report the `DEAD` lines it printed |
|
||||
| | 2 | No URL was passed, which is a defect here. Pass the links and rerun |
|
||||
| | 3 | `GITEA_HOST` is unset. Set it and rerun; never skip the check instead |
|
||||
| | 7 | Gitea authentication failed. Stop and report the key problem, and never read it as a dead link |
|
||||
| `wiki-contents.sh upsert` | 0 | The row is in place. Report the `updated` or `added` it printed |
|
||||
| | 1 | The write failed. Report `SKILLSET_CONTENTS` as not written, together with the row content |
|
||||
| `wiki-contents.sh upsert` | 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. Report `SKILLSET_CONTENTS` as not written, together with the block content |
|
||||
| | 2 | An argument was rejected. Fix it and rerun; nothing was written |
|
||||
| | 3 | No CONTENTS wiki repo is configured. Report `JSC_WIKI_REPO_CONTENTS` and `JSC_WIKI_REPO` as the two variables to set; the new section is on `SKILLSET_{HASH}` and stays there |
|
||||
| | 4 | The directory page is absent and no template was passed. Rerun with `templates/skillset-contents.md` as the fifth argument |
|
||||
| | 7 | The token is invalid or lacks permission, so the other domains' rows are unknown. Stop, report the token problem, and create no page |
|
||||
| | 7 | The token is invalid or lacks permission, so the other domains' blocks are unknown. Stop, report the token problem, and create no page |
|
||||
| | 8 | Some other API failure. Stop, report that status, and create no page |
|
||||
|
||||
On any failure, hand the page name and the unwritten entry back to the user and leave this step open; never close the flow on an unwritten report. Completion condition: `SKILLSET_{HASH}` holds the new section plus all earlier sections, and `wiki-contents.sh upsert` exited 0 with this domain's row on `SKILLSET_CONTENTS` linking that page by absolute URL.
|
||||
On any failure, hand the page name and the unwritten entry back to the user and leave this step open; never close the flow on an unwritten report. Completion condition: `SKILLSET_{HASH}` holds the new section plus all earlier sections, and `wiki-contents.sh upsert` exited 0 with this domain's `## SKILLSET_{HASH}` block on `SKILLSET_CONTENTS` linking that page by absolute URL.
|
||||
9. Report this run's outcome to the local event stream — the last step of every run, the ones that stop early included. Run:
|
||||
|
||||
`jsc-hooks/tools/report-status.sh skill-end jsc-meta:skill-update {status} {exit code} [detail]`
|
||||
@@ -66,7 +66,7 @@ Single source of guidelines: [`../../references/guidelines.md`](../../references
|
||||
| `ok` | the skill files and the behavior-list section carry the change, the checklist passes, the PR is open, `deploy-verify.md` sections 1 to 5 hold, and both wiki writes exited 0 |
|
||||
| `blocked` | a gate or a missing prerequisite stopped the run before any file changed — `sync-domains.sh` never reached exit 0, or no skill could be listed to pick from |
|
||||
| `failed` | the run broke mid-way — the step 6 checklist loop kept failing, or a wiki write failed again after its one retry |
|
||||
| `degraded` | the update landed with a part missing — the content page was written while its `SKILLSET_CONTENTS` row was not, or a CLI could not be verified and the reason was recorded |
|
||||
| `degraded` | the update landed with a part missing — the content page was written while its `SKILLSET_CONTENTS` block was not, or a CLI could not be verified and the reason was recorded |
|
||||
| `aborted` | the user stopped the run, or a prerequisite turned out not to hold and 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.
|
||||
|
||||
@@ -21,12 +21,12 @@ Single source of guidelines: [`../../references/guidelines.md`](../../references
|
||||
1. Follow [`../../references/deploy-verify.md`](../../references/deploy-verify.md) from section 1 to section 5, once per affected domain repo — the route judgements run in parallel. The batch takes the deploy route only when **every** affected repo's `tools/deploy-route.sh` exits 0; a single exit 3 puts the whole batch on the worktree route, because the change reaches the CLIs only when the last repo merges, so name every outstanding release PR. The verification then runs in a **fresh CLI process**, never in the session that ran the deploy: that session raised the restart gate itself and still holds the old skill bodies. Verify every touched skill's row in `tools/list-skills.sh`, every tool this change touched, and one minimal prompt per affected domain per checkable CLI — the per-CLI and per-domain prompts run in parallel. Completion condition: every completion condition in `deploy-verify.md` sections 1 to 5 holds for every affected domain repo.
|
||||
2. Write the change report to the wiki — this part MUST run as a sub agent, one sub agent per affected domain repo, run in parallel. Each sub agent writes two pages in two repos, and they must not be mixed up.
|
||||
- **Content page `SKILLSET_{HASH}`.** Resolve its repo with `jsc-gitea/tools/gitea.sh wiki-repo SKILLSET`, which reads `JSC_WIKI_REPO_SKILLSET` first, then `JSC_WIKI_REPO`. `{HASH}` is `gitea.sh hash-id "{owner}/{repo}"` of that repo, used at the full 40 characters it prints. Write it through `jsc-gitea:wiki` following [`../../templates/skillset-page.md`](../../templates/skillset-page.md): **append** a section for this change — date, 「批次更新」, the change request in one line, touched skills, changed files, PR URL, the step 5.1 route verdict and verification result per item — and keep every earlier section.
|
||||
- **Directory page `SKILLSET_CONTENTS`.** One shared page holds every domain's row, so each sub agent writes only its own. It lives in the CONTENTS repo, never in the SKILLSET one: `wiki-contents.sh` resolves it itself with `gitea.sh wiki-repo CONTENTS`, whose chain is `JSC_WIKI_REPO_CONTENTS` then `JSC_WIKI_REPO` and never falls back to `JSC_WIKI_REPO_SKILLSET`. Build one file holding the single row from [`../../templates/skillset-contents.md`](../../templates/skillset-contents.md), its 異動頁 cell written as `[SKILLSET_{HASH}]({url})` with the **absolute** URL from `gitea.sh wiki-url {SKILLSET repo} SKILLSET_{HASH}`. Every link on both pages takes that `[{text}]({url})` form; the double-bracket wiki-link form resolves only inside one wiki, so it is never used. Then run:
|
||||
- **Directory page `SKILLSET_CONTENTS`.** One shared page holds every domain's block, so each sub agent writes only its own. It lives in the CONTENTS repo, never in the SKILLSET one: `wiki-contents.sh` resolves it itself with `gitea.sh wiki-repo CONTENTS`, whose chain is `JSC_WIKI_REPO_CONTENTS` then `JSC_WIKI_REPO` and never falls back to `JSC_WIKI_REPO_SKILLSET`. That page is a heading-plus-bullets list and holds no markdown table: one `## SKILLSET_{HASH}` block per domain repo, every field one `- {欄位名}:{值}` line under it. Build one file holding this domain's single block, following [`../../templates/skillset-contents.md`](../../templates/skillset-contents.md), with its 異動頁 bullet written as `[SKILLSET_{HASH}]({url})` from the **absolute** URL that `gitea.sh wiki-url {SKILLSET repo} SKILLSET_{HASH}` prints. The H2 heading itself carries no link, no URL, no affix and no date — only the content page name. Every link on both pages takes that `[{text}]({url})` form; the double-bracket wiki-link form resolves only inside one wiki, so it is never used. Then run:
|
||||
|
||||
`jsc-gitea/tools/wiki-contents.sh upsert SKILLSET 2 "{owner}/{repo}" {row file} templates/skillset-contents.md`
|
||||
`jsc-gitea/tools/wiki-contents.sh upsert SKILLSET 2 "SKILLSET_{HASH}" {entry file} templates/skillset-contents.md`
|
||||
|
||||
The key column is `2`, the 存取庫 column, holding that repo's `{owner}/{repo}` exactly as the row file writes it, so one domain keeps exactly one row and no sibling sub agent's row moves. Never hand-edit the directory page, and never overwrite it as a whole. Write the content page first and fetch the URL only after it exists.
|
||||
- **Check the links before writing.** Hand every URL going onto the content page and into the directory row to `jsc-gitea/tools/link-check.sh`, and write only when it exits 0. It verifies through the Gitea API, never a web status code: a private repo answers 404 to an unauthenticated web request, so a status-code check would call a live page dead.
|
||||
The key is the H2 heading `SKILLSET_{HASH}`, so one domain keeps exactly one block and no sibling sub agent's block moves. That page name depends only on `{owner}/{repo}`, which is why it is the key: a host rename or a changed `JSC_WIKI_REPO_SKILLSET` leaves it untouched, so the match still finds the existing block. The `2` is the key column: the index of the column that held the content-page link in the **old markdown table**, and it matters only when such an old table still has to be converted automatically — the conversion takes the last path segment of that column's link URL as the H2 heading. Count that index from the **live page's own column layout**, never from the template's: the live `SKILLSET_CONTENTS` reads `| 存放庫 | 異動報告 | 目前版本 | 最後更新 |`, so the link sits in column 2 while column 1 is plain text like `plugins/ask`. Passing `1` would make the heading `plugins/ask`, which never matches the key `SKILLSET_{HASH}`, so the existing entry is appended as a brand-new one — one domain ends up with two blocks and the older one is never updated again. The fourth argument is the whole block, not a table row. Never hand-edit the directory page, and never overwrite it as a whole. Write the content page first and fetch the URL only after it exists.
|
||||
- **Check the links before writing.** Hand every URL going onto the content page and into the directory block to `jsc-gitea/tools/link-check.sh`, and write only when it exits 0. It verifies through the Gitea API, never a web status code: a private repo answers 404 to an unauthenticated web request, so a status-code check would call a live page dead.
|
||||
- **Exit codes.** Route every one of them:
|
||||
|
||||
| Call | Exit | Do |
|
||||
@@ -38,22 +38,22 @@ Single source of guidelines: [`../../references/guidelines.md`](../../references
|
||||
| Content page read | 0 | Append into the sections already there |
|
||||
| | 4 | The page does not exist yet, so build it from `templates/skillset-page.md` |
|
||||
| | 7 or 8 | Stop and write nothing: a page rebuilt on top of an unread read loses every section already on it |
|
||||
| `gitea.sh wiki-url` | 4 | The content page is not there, so the write above did **not** succeed. Go back and write it, and add no directory row until the page exists |
|
||||
| `gitea.sh wiki-url` | 4 | The content page is not there, so the write above did **not** succeed. Go back and write it, and add no directory block until the page exists |
|
||||
| | 5 | The API answered with no `html_url`. Stop and report it; never assemble the URL by hand from the host and the page name |
|
||||
| `link-check.sh` | 0 | Every link is reachable. Write the page |
|
||||
| | 1 | At least one link is dead. Write nothing, and report the `DEAD` lines it printed |
|
||||
| | 2 | No URL was passed, which is a defect here. Pass the links and rerun |
|
||||
| | 3 | `GITEA_HOST` is unset. Set it and rerun; never skip the check instead |
|
||||
| | 7 | Gitea authentication failed. Stop and report the key problem, and never read it as a dead link |
|
||||
| `wiki-contents.sh upsert` | 0 | The row is in place. Report the `updated` or `added` it printed |
|
||||
| | 1 | The write failed. Report `SKILLSET_CONTENTS` as not written, together with the row content |
|
||||
| `wiki-contents.sh upsert` | 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. Report `SKILLSET_CONTENTS` as not written, together with the block content |
|
||||
| | 2 | An argument was rejected. Fix it and rerun; nothing was written |
|
||||
| | 3 | No CONTENTS wiki repo is configured. Report `JSC_WIKI_REPO_CONTENTS` and `JSC_WIKI_REPO` as the two variables to set; the new section is on `SKILLSET_{HASH}` and stays there |
|
||||
| | 4 | The directory page is absent and no template was passed. Rerun with `templates/skillset-contents.md` as the fifth argument |
|
||||
| | 7 | The token is invalid or lacks permission, so the other domains' rows are unknown. Stop, report the token problem, and create no page |
|
||||
| | 7 | The token is invalid or lacks permission, so the other domains' blocks are unknown. Stop, report the token problem, and create no page |
|
||||
| | 8 | Some other API failure. Stop, report that status, and create no page |
|
||||
|
||||
On any failure, hand the page name and the unwritten entry back to the user and leave this step open; never close the flow on an unwritten report. Completion condition: every affected repo's `SKILLSET_{HASH}` holds the new section plus all earlier sections, and every one of those repos has a row on `SKILLSET_CONTENTS` written by a `wiki-contents.sh upsert` that exited 0, linking its page by absolute URL.
|
||||
On any failure, hand the page name and the unwritten entry back to the user and leave this step open; never close the flow on an unwritten report. Completion condition: every affected repo's `SKILLSET_{HASH}` holds the new section plus all earlier sections, and every one of those repos has a `## SKILLSET_{HASH}` block on `SKILLSET_CONTENTS` written by a `wiki-contents.sh upsert` that exited 0, linking its page by absolute URL.
|
||||
6. Report this run's outcome to the local event stream — the last step of every run, the ones that stop early included. One event for the whole batch, not one per domain. Run:
|
||||
|
||||
`jsc-hooks/tools/report-status.sh skill-end jsc-meta:skillset-update {status} {exit code} [detail]`
|
||||
@@ -67,7 +67,7 @@ Single source of guidelines: [`../../references/guidelines.md`](../../references
|
||||
| `ok` | every affected repo carries the change and its behavior-list update, every checklist passes, every repo has a PR URL, `deploy-verify.md` sections 1 to 5 hold for all of them, and every wiki write exited 0 |
|
||||
| `blocked` | a gate or a missing prerequisite stopped the run before any file changed — `sync-domains.sh` never reached exit 0, or the affected-skill list was never agreed |
|
||||
| `failed` | the run broke mid-way — the step 3 checklist loop kept failing for some repo, or a wiki write failed again after its one retry |
|
||||
| `degraded` | part of the batch landed and part did not — some repos got their PR and others did not, or a content page was written while its `SKILLSET_CONTENTS` row was not. Name the repos in `detail` |
|
||||
| `degraded` | part of the batch landed and part did not — some repos got their PR and others did not, or a content page was written while its `SKILLSET_CONTENTS` block was not. Name the repos in `detail` |
|
||||
| `aborted` | the user stopped the run, or a prerequisite turned out not to hold and 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.
|
||||
|
||||
@@ -18,7 +18,7 @@ Single source of guidelines: [`../../references/guidelines.md`](../../references
|
||||
- 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`.
|
||||
- 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.
|
||||
@@ -86,18 +86,25 @@ Done when the scope and the output target are each written down as one of the va
|
||||
|
||||
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 write in this step targets it.
|
||||
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 contents page for the same reason as every other jsc skill — a contents row 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.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.** Read that page first, then route the read exit code:
|
||||
- 0 — the page is there. Find the row whose host, tool, and account all match this run, refresh that one row per `templates/tooling-contents.md`, leave every other row exactly as it was, and write the whole page back.
|
||||
- 4 — the page does not exist yet. **This is the only code that allows creating it.** Build it from the template with this run's rows.
|
||||
- 7 or 8 — the key was rejected, or the API failed, so the old content is unknown. Stop. Create nothing and overwrite nothing: a page built on top of unknown content deletes rows that nobody can get back. Report the exit code and the page name.
|
||||
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:
|
||||
|
||||
Completion condition: `TOOLING_CONTENTS` holds one row per page written in step 7.3, every row belonging to another machine or CLI is unchanged, or the step stopped with the read exit code and the page name reported.
|
||||
`jsc-gitea/tools/wiki-contents.sh upsert TOOLING 1 "TOOLING_{HASH}" {entry file} templates/tooling-contents.md`
|
||||
|
||||
7.5 **Route a failed write.** Retry the failed `jsc-gitea:wiki` write once. 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.
|
||||
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:
|
||||
|
||||
@@ -140,4 +147,4 @@ The guide must include these fields in this order:
|
||||
|
||||
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 row registered in `TOOLING_CONTENTS` follows `templates/tooling-contents.md`. Both templates own their own field lists; do not restate them here.
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user