model-tags.sh 的 gate 原本用同一個結束碼表示兩件事:模型缺能力標籤, 以及這支腳本被叫錯。delegate 讀到用法錯誤時,會當成模型沒通過檢查, 默默把一個能用的模型丟掉。真正的錯在哪,永遠不會浮出來。現在用法錯誤 改走另一個碼,兩種「無法判定」也歸到同一個碼,呼叫端只要認碼就分得出 三種結果。model-config.sh 照同一套規則調整,兩支腳本的契約才一致。 check-requires.sh 在沒有 python3 的機器上,會直接讓 shell 回一個沒宣告過 的碼,呼叫端讀不到原因。現在先確認 python3 在不在,並印出擋下的理由, manifest 相依檢查才是真的做得到的事。 delegate 的七個步驟原本沒有任何完成條件,引用了不存在的 plugin,也把 CLI 偵測與標籤篩選寫成文字敘述,可是這兩件事早就有腳本負責。挑模型那 一步需要模型 id,全篇卻沒有任何步驟產得出來。現在每一步都寫出完成條件, 資料一律取自腳本,模型夠不夠格由結束碼判定,不讓模型自評標籤。 setup 的環境變數重驗原本去讀目前這個 shell。可是寫進 rc 檔的值,要等新的 shell 起來才存在,所以重驗永遠回報「沒設到」,把修好的項目誤判成失敗。 現在只驗 rc 段落裡確實有那一行,環境層面交給下一次體檢。
106 lines
8.2 KiB
Markdown
106 lines
8.2 KiB
Markdown
---
|
|
name: delegate
|
|
description: 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.
|
|
|
|
## 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.
|