Files
gitea/skills/wiki/SKILL.md
T
jiantw83 f69b4b6f85 feat(狀態回報): 收尾寫一筆 skill-end 事件
現行紀錄只記「被叫用」,沒有成敗也沒有結束碼。跑完整輪的技能與開場就
中止的技能,在紀錄裡長得一模一樣。

start 由技能用量 hook 順手發,不必改技能文件。end 只能由技能自己在收尾
步驟寫——hook 接在技能工具呼叫上,而實際工作發生在之後的模型輪次,它在
原理上看不到成敗。有 start 沒有配對的 end,就是那一輪中止了。

status 五選一,每支技能各自寫明什麼情況選哪一個。找不到回報腳本就安靜
跳過,回報失敗一律不改變技能自己的結論。
2026-09-02 16:01:15 +08:00

15 KiB

name, description
name description
wiki Read or write a Gitea wiki page through tools/gitea.sh, tools/hash-id and tools/page-name.sh. Resolve the wiki repo per page type with JSC_WIKI_REPO_{TYPE} first, then JSC_WIKI_REPO, and ask only when neither is set - every *_CONTENTS page resolves through type CONTENTS and is updated with tools/wiki-contents.sh, and {HASH} is the full 40-char uppercase SHA-1 from tools/hash-id. Page content is chart-first - prefer mermaid diagrams and markdown tables over plain prose, and every link is written as [text](absolute URL) that tools/link-check.sh passed before the write. Callers are jsc-ask, jsc-sdlc, jsc-log, jsc-hooks (ERROR), jsc-cli (CHECK), jsc-meta (SKILLSET, TOOLING) and jsc-assist (MONITOR). Use for any wiki page in the skill set; not for repo code files.

wiki — read and write Gitea wiki pages

Every wiki operation in the jsc skill set goes through this skill. One entry point, one permission path.

Resolve the wiki location

Different page types can live in different {owner}/{repo} repos, classified by the page-name prefix.

  1. Host gate. Confirm GITEA_HOST holds a value in the current shell. When it is missing, ask for it per the jsc-ask:ask rules before any tools/gitea.sh call that reaches the API; otherwise the first thing the user sees is the script's GITEA_HOST is required line instead of a decision-tree question. GITEA_TOKEN needs no inventory here — the script resolves it, retries once with the tea CLI login token, and exits 7 when neither works. Done when GITEA_HOST holds a value.
  2. Run tools/gitea.sh wiki-repo {TYPE}. Allowed types are QUESTION, PLAN, ANALYZE, DELIVER, MAINTAIN, REPO, LOG, LEARN, ERROR, CHECK, REPORT, SKILLSET, TOOLING, MONITOR, and CONTENTS. Every *_CONTENTS page resolves through CONTENTS — all contents pages live in one dedicated repo, so never pass a contents page its own prefix. A content page (*_{HASH}) resolves through its own type. The script reads JSC_WIKI_REPO_{TYPE} first and JSC_WIKI_REPO second, straight from the inherited environment, so take no separate inventory of those two variables. Never borrow another type's repo. Done when the command has printed exactly one {owner}/{repo}, or exited 3 and sent this page type to step 3, or exited 2 on a type outside the list above and stopped the run.
  3. On exit 3 (neither variable is set), ask the user for that page type's {owner}/{repo} per the jsc-ask:ask rules, and suggest setting JSC_WIKI_REPO_{TYPE} (can differ per type, and JSC_WIKI_REPO_CONTENTS holds every contents page) or JSC_WIKI_REPO (shared default). Done when the user has supplied one {owner}/{repo} for that page type.

Operations

Action Command
list pages tools/gitea.sh wiki-list {owner}/{repo}
read page tools/gitea.sh wiki-get {owner}/{repo} {page}
write page write the content to a temp file first, then tools/gitea.sh wiki-put {owner}/{repo} {page} {file} (asks for confirmation first, then creates or updates)
delete page tools/gitea.sh wiki-delete {owner}/{repo} {page} — asks for the same confirmation as a write. Only a migration or an explicit user request may call it
page URL tools/gitea.sh wiki-url {owner}/{repo} {page} — the page's absolute URL, taken from the API's html_url
update a contents page tools/wiki-contents.sh upsert {TYPE} {key-col} {key} {row-file} [template-file] — resolves the CONTENTS repo, replaces the row whose key column matches, appends when none does, writes the whole page back. {key-col} is the column's 1-based position number, not the column name
check a page name tools/page-name.sh check {page} — the single source of the page-name pattern; tools/page-name.sh regex prints it
move pages to the current rules tools/migrate-wiki.sh [--apply] [--key {key}]... — prints the mapping table and the orphan list; writes only with --apply
check links before a write tools/link-check.sh {url}... — prints {OK|DEAD|SKIP}<TAB>{url}<TAB>{reason} per URL; exit 0 means every link is reachable

Every link in a page is written as [text](absolute URL), and the URL comes from wiki-url — one form for every target, inside this wiki or not. Every link goes through tools/link-check.sh before the page is written. Full rules, and why [[...]] was dropped: references/wiki-links.md.

Exit codes

Route every tools/gitea.sh call in this skill on its exit code. A code with no branch below stops the run and gets reported as it is.

Code Meaning What this skill does
0 success use the output
2 usage error, or a page type outside the allowed list fix the arguments, then call again; never repeat the same call unchanged
3 wiki-repo: neither JSC_WIKI_REPO_{TYPE} nor JSC_WIKI_REPO is set go to step 3 and ask
4 HTTP 404: wiki-get and wiki-url found no such page, or wiki-delete found nothing to delete for a read the caller expects to succeed, stop and report the page name; this is the only code that opens the create path of rule 4 — write the page from the template instead of appending. For wiki-delete it means the page is already gone: report it and move on, do not retry
5 wiki-url: the page exists but the API returned no html_url stop and report it. There is no second link form to fall back on, and a hand-built path is not a substitute — never fabricate the URL
7 HTTP 401 or 403 after the tea-token retry: the key is invalid or lacks permission stop the whole operation and report the key problem. Never read this as an empty or missing page, and never take the create path of rule 4: writing a fresh page over one you could not read destroys the record that is still there
8 any other API failure, HTTP status in the message stop and report that status; call again only after the cause is fixed

Helper scripts

Every code below gets its own branch. Nothing here is retried unchanged.

Script Code Meaning What this skill does
tools/hash-id 0 the full 40-char uppercase hash use it as {HASH}
1 this machine has neither sha1sum nor shasum stop, report that one of them has to be installed, compute no hash by hand
2 no text given, or the text was empty fix the key you passed, then call again; never fall back to a hand-made page name
tools/page-name.sh 0 the page name follows the pattern continue with that page name
1 the page name breaks the pattern stop and report the name; build the correct one instead of writing to a wrong page
2 usage error fix the arguments, then call again
tools/wiki-contents.sh 0 the row was updated or added report which of the two, and the page
1 the write failed, or the page held no markdown table stop and report; fix the page or the row before calling again
2 usage error, or an unknown page type fix the arguments, then call again
3 the CONTENTS repo is not configured go to step 3 and ask for JSC_WIKI_REPO_CONTENTS
4 the page is not there and no template was given supply the template for that page type, then call again
7 the key is invalid or lacks permission stop the whole operation and report the key problem; create no page
8 any other API failure stop and report the status
tools/link-check.sh 0 every link is reachable write the page; this is the only code that opens wiki-put
1 at least one link is dead do not write. Report the DEAD rows verbatim, fix or drop those links, then check again
2 usage error: no URL was given fix the arguments, then call again; never skip the check because the list looked empty
3 the list holds a Gitea URL but GITEA_HOST is not set set GITEA_HOST and call again. Never write the page unchecked
7 HTTP 401 or 403: the key is invalid or lacks permission stop the whole operation and report the key problem. Those pages are not dead — treating them as dead deletes or rewrites links to pages that are still there
tools/migrate-wiki.sh 0 every page moved, or the preview found nothing to move report the mapping table
1 at least one page failed to move report the failure list; the old pages of the failed entries stay in place
2 usage error, including an unconfigured CONTENTS repo fix the arguments or set JSC_WIKI_REPO_CONTENTS, then call again
3 something needs manual handling: an orphan page, a page that links to a moved page without being moved itself, or a destination page that already holds content report those lists and hand them to the user; guess no key, and rewrite no link the script left alone

Close the run

Record how the run ended. This is the last thing this skill does, and it runs on every path out of the skill, the ones that stop at the host gate included. Call

jsc-hooks/tools/report-status.sh skill-end jsc-gitea:wiki {status} {exit code} [detail]

{exit code} is the exit code of whatever decided the outcome — the gitea.sh, link-check.sh or wiki-contents.sh call that ruled the run — and 0 when nothing failed. {detail} is one short line, no more than 200 characters; put the page name there, never the page content. If the script is not on this machine, skip this step in silence and finish the run as it stood — missing infrastructure is not a failure, and a reporting call may never change what this skill returns to its caller.

This skill is called by almost every other one, so its status is what the caller reads back. Report the status of this wiki operation only, never the caller's own outcome.

status When this skill uses it
ok The read returned the page, or the write landed: link-check.sh exited 0, the confirmation was given, and wiki-put exited 0
blocked The location could not be resolved, so nothing was read and nothing was written: GITEA_HOST holds no value and the user gave none, or wiki-repo exited 3 and the user supplied no {owner}/{repo} for that page type
failed The operation ran and broke. Exit 7 belongs here: the key is invalid or lacks permission, so the whole operation stopped, and that is a failure, never an absent page. Exit 8, a wiki-put that did not land, a link-check.sh exit 1 that refused the write, and a hash-id or page-name.sh rejection all sit here too
degraded The content page landed and the contents page did not — wiki-put on {TYPE}_{HASH} exited 0, then wiki-contents.sh upsert exited 3 with no CONTENTS repo configured, or exited 1 on a page holding no markdown table. The record exists but nothing indexes it, so the next reader will not find it. A migration that moved some pages and left orphans or occupied destinations behind sits here as well
aborted The premise did not hold or the user stopped it: write-confirm.sh was refused before a write or a delete, or the caller asked for a page type outside the allowed list and the run stopped at wiki-repo exit 2

Completion condition: exactly one skill-end line was recorded for this run, or the script was absent and the run finished without it.

Rules

  1. Page names must follow the wiki naming table in the skill guidelines (see jsc-meta/references/guidelines.md). Check any page name you build with tools/page-name.sh check {page} before it reaches an API call.
  2. Use tools/hash-id for {HASH} values. It returns the full 40 uppercase SHA-1 hex chars — no truncation, no prefix. Never compute a hash by hand: a hand-made page name lands the content on a page nobody else reads.
  3. To update a contents page (*_CONTENTS), run tools/wiki-contents.sh upsert {TYPE} {key-col} {key} {row-file} [template-file], where {key-col} is the column's 1-based position number, not the column name. It reads the page, replaces the row whose key column equals the key, appends the row when no line matches, and writes the whole page back through the same confirmation. Never overwrite entries owned by others. Whether the page may be created from the template instead is decided by rule 4, and by nothing else.
  4. Only exit 4 means the page is not there yet — this rule binds every "create it if it does not exist" path, without exception. It is not limited to contents pages: a content page (*_{HASH}), a work log, an error page, a report, any page at all, follows the same branch.
    • Correct branch. Read the page with wiki-get. Exit 0 means the page exists, so append or modify the content that came back and wiki-put the whole page. Exit 4 (HTTP 404) is the one and only code that permits creating a new page from the template.
    • Exit 7 and exit 8 abort. Exit 7 (HTTP 401 or 403) and exit 8 (any other API failure) both mean the old content is unknown, never that the page is missing. Stop the operation and report the exit code with its cause. Create no page, write nothing, and do not retry the same call unchanged.
    • Why. Wiki writes in this skill set are append-not-overwrite, and that semantics rests entirely on reading the old page back first. Reading a 401 as a 404 makes the caller believe it holds a brand-new page and wiki-put a fresh template over a live one, and the whole earlier record is gone — the write carries no merge and no backup.
    • tools/wiki-contents.sh implements exactly this branch for contents pages and reports the same codes.
  5. Write all wiki content in UTF-8 Traditional Chinese, per the STE100 output rule.
  6. Prefer visual forms for page content: use mermaid diagrams (flowchart, sequence, gantt, pie) and markdown tables wherever the information allows. Prose is capped at 3 sentences per section, and a sentence stays only when neither a mermaid diagram nor a markdown table can carry the same information.
  7. tools/gitea.sh retries once with the tea CLI login token when GITEA_TOKEN is missing or the response is 401/403. Report a failure only after that retry also fails.
  8. Rule A — every link is written as [text](absolute URL). That is the only form. [[page]] and [[display|page]] are gone, and there is no longer a same-repo case that keeps them. The URL always comes from tools/gitea.sh wiki-url {owner}/{repo} {page}, never from a path built by hand. Why: [[...]] resolves only inside the current wiki, so a cross-repo link silently lands on a same-named page in this one — and it fails as plain text or a dead link, with nothing to catch it. Contents pages and content pages already live in different repos, so keeping two forms would mean judging, link by link, which repo each end resolves to.
  9. Rule B — check every link before the write. Run tools/link-check.sh {url}... over every link that is going into the page. Exit 0 is the only code that opens wiki-put. Exit 1 means at least one link is dead: write nothing, and hand the caller the DEAD rows. Exit 7 means the key failed, not that the pages are gone — stop and report the key problem. Checking after the write is not the same thing: the dead link is already published, and the next reader follows it.
  10. wiki-delete removes a page for good. Call it only from tools/migrate-wiki.sh --apply, or when the user has asked for that exact page to go. In a migration the delete comes last: write the new page, read it back, then delete the old one.