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

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

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

4.9 KiB

name, description
name description
repo-sync Batch-sync all readable repos of a chosen Gitea owner into the working directory. List owners, let the user pick, then clone or update each repo through tools/repo-sync.sh; a repo reported dirty goes to jsc-git:pr against the base branch that same script reports. Use for workspace bootstrap or bulk refresh; not for a single repo.

repo-sync — batch-sync repositories

Steps

  1. Run tools/gitea.sh owners to list every {owner} the user can read. The script reads GITEA_HOST and GITEA_TOKEN from the inherited environment and retries once with the tea CLI login token, so take no separate inventory first — a missing value surfaces here, before any work is done. Route on the result: at least one {owner} printed → next step; the script stops with GITEA_HOST is required or GITEA_TOKEN is required → ask the user for that one value per the jsc-ask:ask rules and run the command again, guessing no host; exit 7 → report that the key is invalid or lacks permission, and stop; exit 8 → report the HTTP status in the message, and stop; exit 0 with no output → report that this key can read no owner, and stop. Done when at least one {owner} is printed, or the run stopped with one of those reasons.

  2. Ask the user which {owner} to sync, per the jsc-ask:ask rules. Every option states the owner's repo count and impact scope. Done when the user has named exactly one {owner} from that list.

  3. Run tools/gitea.sh repos {owner} to list every readable {repo} under that owner. Exit 7 and exit 8 stop the run with the same report as step 1; an empty list means this owner has no readable repo and there is nothing to sync. Done when the command has printed the full {owner}/{repo} list for the chosen owner, or the run stopped.

  4. Sync every {repo} from step 3 in parallel — one sub agent per repo, all launched in the same batch, never one after another. Each repo has its own directory and its own remote, so nothing makes them wait for each other, and a hundred-repo owner otherwise costs a hundred sequential clones. Each sub agent does this:

    1. Run tools/repo-sync.sh {owner}/{repo}. The script owns the clone-versus-pull decision and the base-branch precedence, so run no git clone, git checkout or git pull by hand, and derive no branch name yourself. Route on its single line of output: cloned or updated (exit 0) → this repo is done; dirty {branch} (exit 0) → go to substep 2; failed {reason} (exit 1) → record that reason and stop this repo. Done when exactly one of those four outcomes is recorded for this repo.
    2. dirty {branch} → call jsc-git:pr with {branch} from that same output line as the base, passed through verbatim. It commits, branches, pushes and opens the PR itself, so add none of those steps. Done when jsc-git:pr returns the PR URL and reports it with the table format in jsc-meta/references/pr-report.md.

    Done when every repo's sub agent has returned one of those outcomes; one repo failing never cancels the others.

  5. Report the sync result for every repo: cloned, updated, PR table row, or the failure reason. Done when every {repo} from step 3 carries one of those four results, and all PR rows share one table when more than one PR exists.

  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:repo-sync {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 repo counts fit there, the per-repo list 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 Every repo from step 3 came back cloned, updated, or dirty with its PR opened
    blocked Nothing could be listed, so no repo was touched: GITEA_HOST or GITEA_TOKEN was required and the user gave none, or owners exited 0 with no owner this key can read
    failed The listing broke mid-run — owners or repos returned 7 or 8 — or every repo in step 4 came back failed. No repo reached the working directory
    degraded Some repos synced and some did not: at least one failed {reason} next to at least one cloned, updated or PR row. One repo failing never cancels the others, so the run finishes with part of the workspace missing
    aborted The user named no owner at step 2, or stopped the run before step 4 started

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