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

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

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

10 KiB

name, description
name description
delegate Delegate a single bounded task to another installed AI agent CLI as a subagent, with an explicit target CLI, required capability tags, or a forced model. Use when another CLI should do the work and return structured results; not for model inventory, plugin deployment, or tasks that must stay in the current agent.

delegate — hand a task to another CLI

Use this skill when the work should move to another installed AI agent CLI instead of staying in the current agent.

Detection and tag filtering are decided in code, not in prose: jsc-cli/tools/detect-clis.sh owns the CLI list and jsc-cli/tools/model-tags.sh owns the capability table. This skill only says when to call them and what each exit code means.

Steps

  1. Bound the goal. Write one sentence for the goal, and a numbered list of acceptance criteria that a reader can mark pass or fail without asking a follow-up question.

    Two or more independent goals → split them and run this skill once per goal. A goal is not bounded enough when it has no acceptance criterion that can be checked from the subagent's returned text alone.

    Done when exactly one goal sentence and at least one pass-or-fail acceptance criterion are written down.

  2. Collect the CLI list and the model list. They read different files and share no state, so start both at once and wait for both. Step 3 has no other source for a model id: without the second script there is nothing to hand to model-tags.sh gate.

    jsc-cli/tools/detect-clis.sh prints {name}<TAB>{path}<TAB>{version} per installed CLI.

    Result Action
    exit 0, at least one row Take the candidate CLIs from those rows only
    exit 0, no row Stop. Report that no AI agent CLI is installed, and name the five it probes: claude, codex, copilot, antigravity, kiro
    any non-zero exit Stop. Report the exit code and the stderr text. Never fall back to a guessed CLI list

    jsc-cli/tools/list-models.sh prints {cli}<TAB>{model}<TAB>{in-use} per model, read from each CLI's own config, and always exits 0. It stays silent for a CLI whose config it cannot read, so a CLI with no row is a CLI with no known model, not a failure.

    Result Action
    exit 0 Take the candidate models for the target CLI from that CLI's own rows, the in-use row first
    any non-zero exit The script itself failed. Stop and report the exit code and the stderr text; never invent a model id

    Done when the candidate CLI list comes from the first TSV and holds at least one name, the model rows from the second are in hand, or the skill has stopped with the reason.

  3. Pick the target CLI, then resolve its model against the requirement. Both read step 2's two TSVs and nothing else, so they belong to one pass over that data.

    Pick the target CLI first. The user naming a CLI keeps only that CLI; a name absent from step 2's TSV stops the skill with the message that the CLI is not installed on this machine. No name from the user → keep every detected CLI as a candidate, and settle on one before any model is checked: the candidate model list is defined by the target CLI.

    Then resolve the model. Never let a model judge its own tags — the verdict comes from the script's exit code.

    The candidate models are the step 2 list-models.sh rows whose first column is the chosen target CLI, checked one at a time in that order, in-use first. A user-forced model replaces that list with itself alone. No row for the target CLI and no forced model → stop, and say the fix is to record a model for that CLI through /jsc-cli:models; a guessed model id would be gated against a table entry that has nothing to do with the CLI that will actually run the task.

    Requirement stated as an SDLC stage → run jsc-cli/tools/model-tags.sh gate {stage} {model-id} per candidate. Exit 2 covers three different faults, so read the output line to tell them apart:

    Exit Output Action
    0 PASS Keep the model and stop checking further candidates
    1 FAIL:{tags} Drop that model, name the missing tags in the report, and move to the next candidate
    2 UNKNOWN-MODEL Drop that model and move to the next candidate. Do not guess its tags. Say the fix is to add it through /jsc-cli:models
    2 UNKNOWN-STAGE Stop. The stage name is wrong; name the four valid ones: plan, analyze, implement, maintain
    2 usage text on stderr, no verdict line Stop. The call itself is malformed — report it as a defect in this skill, and never read it as a model that failed the requirement
    other — Stop. Report the exit code and the stderr text

    Every candidate exhausted without a PASS → stop, and report each candidate with its own verdict.

    Requirement stated as raw capability tags → run jsc-cli/tools/model-tags.sh model {model-id}, which always exits 0 and prints the model's tags, or prints nothing when the model is not on the table. Keep the model only when its tags cover every required tag. Empty output gets the same treatment as UNKNOWN-MODEL above.

    A forced model goes through the same check. Failing it stops the delegation rather than downgrading the requirement.

    Done when exactly one target CLI is chosen and one model id from that CLI has cleared the requirement — a PASS from gate, or tags covering every required tag — or the skill has stopped with the reason.

  4. Build the subagent prompt. It carries the goal, the acceptance criteria from step 1, the target CLI, the model id, the minimum context needed, the write scope, and the output contract below.

    The write scope is a list of paths the subagent may write, one per line, each an absolute path or a path relative to the current working directory. An empty list means read-only, and the prompt says so in those words. Anything outside the list is out of scope, including temporary files.

    The output contract is a TSV block, and the prompt states it verbatim:

    Line Meaning
    result<TAB>{ok|fail|needs-input} Exactly one, and the last line
    summary<TAB>{one line} Exactly one
    criterion<TAB>{n}<TAB>{pass|fail}<TAB>{evidence} One per acceptance criterion from step 1
    wrote<TAB>{path} One per written path, zero when read-only
    error<TAB>{message} One per failure, zero on success

    Done when the prompt holds all seven parts and the write scope is either a path list or the read-only sentence.

  5. Spawn one subagent for the goal, targeted at the CLI and the model from step 3. One goal, one subagent. Done when the subagent has returned and its exit status has been captured.

  6. Verify the returned result before reporting it. Every check below must pass:

    Check Failure handling
    Exit status is 0 Non-zero → record a failure carrying the target CLI, the exit code and the stderr text
    Exit status was obtained at all Not obtainable → treat it as a failure, exactly as a non-zero exit
    Output holds one result line and one summary line Missing either → record a failure reading 回傳格式不符
    One criterion line per acceptance criterion, all pass Any fail or missing line → report the outcome as failure, naming the criteria
    Every wrote path is inside the step 4 write scope Any path outside → report it as an out-of-scope write and name the path

    Done when every row above has a verdict, and a failing row has produced a recorded failure.

  7. Report the verified result: the target CLI, the model id, the capability requirement and how it was met, and the outcome. Keep success, failure and 需要使用者補充 in three separate sections, so a partial result is never read as a finished one.

    Done when the CLI, the model, the requirement and the per-criterion verdicts are all in the report, and every failure recorded in step 6 appears in the failure section.

  8. 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 or step 3 included. Call

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

    {exit code} is the exit code of whatever decided the outcome — the subagent's own status, or the detect-clis.sh or model-tags.sh call that ruled the run — and 0 when nothing failed. {detail} is one short line, no more than 200 characters: the target CLI and the model id fit there, the subagent's output 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 The subagent exited 0, its output held one result and one summary line, every acceptance criterion came back pass, and every wrote path sat inside the write scope
    blocked The capability gate stopped the delegation before it started, so no subagent ran: every candidate model returned FAIL or UNKNOWN-MODEL from model-tags.sh gate, detect-clis.sh exited 0 with no row, the CLI the user named is not on this machine, or the target CLI has no model row and no forced model
    failed The delegation ran and broke: the subagent exited non-zero, its exit status could not be obtained at all, its output was missing the result or summary line, a criterion came back fail, or a wrote path landed outside the write scope. detect-clis.sh or list-models.sh exiting non-zero sits here too
    degraded The subagent returned result needs-input: part of the goal is done and the rest waits on the user, so the report has a 需要使用者補充 section that is not empty. The delegation happened, the goal did not close
    aborted The premise did not hold, so the skill stopped on its own: step 1 could give the goal no pass-or-fail acceptance criterion, or the request carried two or more independent goals and has to be split. Also used when the user stops the run before step 5 spawns the subagent

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

Do not use this skill

  • Do not use it for model inventory. That is /jsc-cli:models.
  • Do not use it for plugin deployment. That is /jsc-cli:deploy.
  • Do not use it for tasks that must stay inside the current agent.
  • Do not use it for a goal that step 1 could not give a pass-or-fail acceptance criterion.