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

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

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

8.2 KiB

name, description
name description
wiki-to-issue Turn one Gitea wiki page into an issue in the same repository. Parse the link with tools/gitea-link.sh, read the page through jsc-gitea:wiki, draft title and body as a sub agent, then create the issue with tools/issue.sh - labels picked from the repository's existing set per the jsc-ask decision tree, project board attached or reported as manual when the site has no board API. A request without a wiki link stops the skill immediately: never guess the repository or the page. Use when a wiki page has to become trackable work; not for issues drafted from scratch, and not for syncing an issue that already exists.

wiki-to-issue — a wiki page becomes an issue

The wiki link is the only input. Everything else — repository, page name, host — comes out of that link.

Steps

  1. Input gate — the link and the host, checked in the same batch. Neither depends on the other, so run both before anything else and report every failure found, not just the first.

    • The link. Run tools/gitea-link.sh parse {url} on the link the user gave. Exit 3, no link in the request, or kind=issue (this skill reads wiki pages, not issues) all mean the same thing: stop and report which one it was. Exit 2 is a usage error — fix the arguments and call again. Never ask for a repository name instead, and never fall back to the working directory's remote — a page written into the wrong repository's issue tracker is public and hard to take back.
    • The host. Confirm GITEA_HOST holds a value in the current shell; ask for it per the jsc-ask:ask rules when it does not. GITEA_TOKEN needs no inventory — tools/gitea.sh resolves it, retries once with the tea CLI login token, and exits 7 when neither works.

    Completion condition: the parse printed kind=wiki with repo, page and host known, and GITEA_HOST holds a value — both, or the run has stopped with the reason named.

  2. Run these three tracks at the same time. The label list and the board list depend on the repository only, not on the page, so they start in the same batch as the read rather than queueing behind the draft.

    • Track A — read and draft. Read the page with jsc-gitea:wiki (wiki-get {repo} {page}) and take its absolute URL from wiki-url in the same pass. Route the exit codes by that skill's table: 4 means the page does not exist, 7 means the key is invalid or lacks permission, 8 is any other API failure — all three stop this skill with the page name in the report. Drafting MUST run as a sub agent. Title: the page's first heading, or the page name when it has none. Body: the page content in Traditional Chinese, opening with a 「來源:{絕對網址}」 line so the issue points back at the wiki. Links are written as [文字](絕對網址); a wiki-internal link left over from an older page becomes an absolute URL from wiki-url, because that form resolves only inside a wiki and an issue is not one. Drop personal data — an issue is read by more people than a wiki page.
    • Track B — label list. Run tools/issue.sh labels {repo}. Exit 1 means the label list could not be read: stop and report it, because the alternative is inventing labels. Exit 2 is a usage error — fix the arguments and call again.
    • Track C — board list. Run tools/issue.sh projects {repo}. Exit 3 means this Gitea has no board API — keep the board URL the script printed for step 4. Exit 1 means the call failed for another reason: report it and treat the board link as outstanding. Exit 2 is a usage error — fix the arguments and call again.

    Completion condition: the title and body file exist with the source line and every link in the body written as [文字](絕對網址), the repository's label list is in hand or the run has stopped, and the board list is either in hand or recorded as unavailable.

  3. Labels come from what the repository already has. Propose the fitting ones from track B's list with a reason each, and confirm per jsc-ask:ask rules — every option states its impact scope (a label drives filters and board rules, so a wrong one routes the work to the wrong queue). Turn the confirmed names into ids with tools/issue.sh label-ids {repo} {names}. Exit 4 means a name is not in the repository: go back to the list and pick again, never create the label to make the command pass. Exit 1 means the call failed — report it and stop. An empty label list, or nothing fitting: ask whether to create the issue with no label, and record that answer. Never invent a label that the repository does not have. Completion condition: the user has confirmed a label set — possibly empty — and its ids are resolved.

  4. Project board. Track C returned a board list: let the user pick one per jsc-ask:ask rules, attach it, and report the failure verbatim if the attach call is refused. Track C exited 3: say plainly that this Gitea has no board API, and hand the user the board URL the script printed so they can drag the issue in themselves. Completion condition: the issue is either attached to a board, or the report states in one line that the board link is still outstanding and who has to do it.

  5. Create the issue: tools/issue.sh create {repo} {title} {body-file} [--labels {ids}]. The script asks for confirmation before it writes, so expect that prompt and hand the user the title, the labels and the board it is about to apply. Exit 0: report the index= and url= it prints. Exit 1 means no issue was created — report that plainly, and hand back the path of the drafted body file so the draft is not lost. Exit 2 is a usage error, usually a body file that is not there — fix the arguments and call again. Completion condition: the issue URL is reported to the user together with the labels applied and the board status from step 4, or the report states that no issue was created and where the draft is.

  6. 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 step 1 included. Call

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

    {exit code} is the exit code of whatever decided the outcome, and 0 when nothing failed. {detail} is one short line, no more than 200 characters — the issue index fits there, the issue body does not. 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 or reports.

    status When this skill uses it
    ok issue.sh create exited 0, and the report carries the issue URL, the labels applied and a board that is attached
    blocked The host gate stopped the run: GITEA_HOST holds no value and the user gave none, so the page was never read and no issue was drafted
    failed The work started and broke: wiki-get returned 4, 7 or 8, issue.sh labels returned 1 so no label could be picked without inventing one, or issue.sh create returned 1 and no issue exists. Report the draft path in {detail} when the create failed
    degraded The issue was created, but part of it stays outstanding — track C exited 3 because this Gitea has no board API, or the attach call was refused, so the report hands the board link back to the user to drag in by hand. The issue is real, its place on the board is not
    aborted The premise did not hold, so the skill stopped on its own: the request carried no wiki link, gitea-link.sh parse returned 3, or the link parsed as kind=issue. Also used when the user refuses the confirmation issue.sh create asks for, so nothing was written

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

Rules

  • One wiki page, one issue. Splitting a page into several issues is analysis work, not conversion — hand that to jsc-sdlc:analyze.
  • The issue body stays Traditional Chinese per the STE100 rule, and keeps the source line at the top.
  • Creating an issue is an outward-facing action: the title, body, labels and board pick are confirmed with the user before the create call, never after.