| name | pi-dispatch |
| description | Orchestrate pi coding agents with DAG-aware dependency resolution, git worktree isolation, automatic retry, and structured JSON output.
Use this skill when: - spawning pi agents for any subtask - tasks have dependency ordering (A must finish before B starts) - parallel agents need isolated git workspaces - you need structured output + automatic revert on failure |
Pi-Dispatch Skill
Describes how to delegate coding plans to orchestrated teams of pi agents. Claude's role: write JSON → run script → read JSON.
Path convention: {{SKILL_DIR}} = the directory containing this SKILL.md. Resolve it from the file path you used to read this skill. All paths below are relative to {{SKILL_DIR}}.
When to Use
Use pi-dispatch for any pi agent work. Use the native Agent tool for Claude subagents (sonnet/opus/haiku).
Config
{{SKILL_DIR}}/config.json — edit pi_models to swap models, default_timeout_minutes for global default.
{
"provider": "openrouter",
"default_timeout_minutes": 5,
"task_routing": {
"hard": { "pi_tier": "hard" },
"moderate": { "pi_tier": "hard" },
"easy": { "pi_tier": "easy" },
"mechanical": { "pi_tier": "easy" },
"verification": { "pi_tier": "easy" }
},
"pi_models": {
"hard": ["xiaomi/mimo-v2.5-pro", "z-ai/glm-5.1"],
"easy": [
"qwen/qwen3.6-plus",
"deepseek/deepseek-v4-pro",
"z-ai/glm-5-turbo"
]
}
}
Step 1 — Write the dispatch JSON
Write to .pi_agent_dispatch/<YYYYMMDDTHHmmss>.json:
{
"spawned_at": "2026-05-02T10:00:00",
"task": "one-line description",
"agents": [
{
"id": "research",
"task_type": "easy",
"timeout_minutes": 10,
"depends": [],
"prompt": "Full self-contained prompt. End with: \"Output a concise summary of changes made.\"\nUse relative paths — pi runs inside the worktree."
},
{
"id": "implement",
"task_type": "hard",
"depends": ["research"],
"prompt": "..."
},
{
"id": "tests",
"task_type": "easy",
"depends": ["implement"],
"prompt": "..."
},
{
"id": "docs",
"task_type": "mechanical",
"depends": ["implement"],
"prompt": "..."
},
{
"id": "special",
"pi_model": "xiaomi/mimo-v2.5-pro",
"depends": ["tests", "docs"],
"prompt": "..."
}
]
}
Field reference:
| Field | Required | Notes |
|---|
id | yes | unique within file |
task_type | yes unless pi_model explicit | key from config.json:task_routing |
pi_model | no | explicit model; overrides tier; no retry on failure |
timeout_minutes | no | per-agent; default = config.default_timeout_minutes |
provider | no | per-agent; default = config.provider (e.g. openrouter) |
depends | no | list of agent ids; missing = [] |
prompt | yes | self-contained; end with summary instruction; use relative paths |
Prompt Writing Guidelines:
When writing the prompt for a subagent, avoid writing the exact expected content (e.g., the exact code or output). Instead, write a compressed version that preserves the meaning anchors for the subagent to figure out the rest. Choose the approach that is likely to yield the most concise and effective prompt for the task.
Use one of the following strategies or a combination of them:
- Goal and Constraint Description: Describe the goal of the task and the constraints (e.g., function signature, style, output format). The subagent will figure out the exact content.
- Requirements List: Write a list of requirements that the expected result must satisfy. The subagent will produce a result that meets all requirements.
- Step-by-step Outcomes: Break the task into steps and describe the expected outcome of each step in a high-level way.
- Test‑First Specification: Create executable tests (or verification scripts) in the proper location following repository conventions. Provide a brief prompt that includes design and business context, points the subagent to the test file(s), and specifies the exact command to run them. The subagent’s goal is to make all tests pass.
Remember to end every prompt with an explicit summary instruction.
Authoring rules:
- Two agents that touch the same file MUST be sequenced via
depends. Parallel = disjoint file scope.
- Every prompt must end with an explicit summary instruction. That summary becomes the
output field in JSON.
- Use relative paths only — pi is spawned inside the worktree.
Step 2 — Run the Orchestrator
python {{SKILL_DIR}}/orchestrate.py .pi_agent_dispatch/<file>.json
Step 3 — Read Output
Success (status: complete): all changes are merged into your working branch. Read per-agent output summaries. attempt: 2 means a retry was needed.
Failure (status: conflict_paused): integration branch is preserved; working branch is untouched. Read failure_reason:
-
merge conflict → fix depends in JSON, then continue (not re-run):
python {{SKILL_DIR}}/orchestrate.py --continue .pi_agent_dispatch/<ts>-state.json
python {{SKILL_DIR}}/orchestrate.py --continue .pi_agent_dispatch/<ts>-state.json --json-override .pi_agent_dispatch/<fixed>.json
Already-merged agents are skipped; only the failed/pending agents re-run from the preserved integration branch.
Tool-generated files cause spurious conflicts. IDE indexes, language-server caches, linter caches, and similar tools often write files to the repo directory when they run. Each parallel agent generates its own version of these files, producing conflicts that look like depends errors but aren't. The fix is repo-level: add those paths to .gitignore before running the dispatch. Common offenders: .idea/, .vscode/, .pi-lens/, *.pyc, coverage reports, any tool that writes a cache keyed on file paths or timestamps. Run git status inside a worktree after a failed dispatch to see what unexpected files appeared.
-
non-zero exit after retry → diagnose from agent output.
Inspecting diffs after success:
git diff <checkpoint_sha>..HEAD
git show <merge_sha>
git diff <prev_merge_sha>..<this_merge_sha>
Crash Recovery
python {{SKILL_DIR}}/orchestrate.py --cleanup .pi_agent_dispatch/<ts>-state.json
Removes worktrees, deletes agent branches, reverts integration branch.
Pi CLI Reference (condensed)
pi --provider openrouter --model <model> --no-session -p "prompt"
pi --tools read,grep,find,ls -p "Review this"
pi -c "Follow up"
pi --no-session -p "one-off"
Models by tier:
Described in config.json
Default provider is configured in config.json. Override per-agent with the provider field in dispatch JSON.