Delegate work from pi to any harness — Claude Code, Muse (Codex), OpenCode, Amp, Devin — with
one tool, normalized permissions, multi-harness fan-out and
portable templates. Successor to
pi-claude-delegate.
pi install git:github.com/yorch/pi-harness-delegate
· needs at least one harness binary (claude --version,
codex --version, opencode --version, amp --version,
devin --version) on PATH
~/.pi/agent/delegate/outputs/<harness>/…
delegate { harness:claude|codex|opencode|amp|devin}
— same task, same streaming, per-harness runners under
extensions/harnesses/.
readonly → edit → danger
maps to each harness native.
danger
only via allowDangerous:true — never a default.
harness: "all"
or a comma list runs the same task on every detected harness
concurrently
and returns one comparison report — costs N× a single run, budget accordingly.
Markdown with frontmatter in templates/shared +
templates/<harness>. User/project overlays win on collision.
A template's verify: command runs on the host after the harness exits — report-only, never on
a readonly template, and never a model-settable tool parameter.
Live feed (tool ✓/✗, thinking, text tail), framed overlay (m
minimize, double-esc
cancel), full transcript partitioned by harness.
Every harness runs over its native CLI's stdout by default.
opencode
also speaks ACP, opt-in per harness; devin is
ACP-only.
Tokens, context% and spend flow into pi footer stats via tool
Usage. Per-harness modelAliases, /delegate status spend rollup.
| Harness | readonly → edit → danger | Cost | Context % | ACP | Notes |
|---|---|---|---|---|---|
| claude claude |
plan acceptEdits bypassPermissions | reported | reported | no | Full stream-json + verbose. Schema-verified against Claude Code 2.1.247. |
| codex codex |
read-only workspace-write danger-full-access | unmeasured | unmeasured | no |
codex exec --json, tolerant parser. No $ cost on ChatGPT-plan auth.
Schema-verified against codex-cli 0.149.1.
|
| opencode opencode |
plan build build --auto | stdout: no · acp: yes | stdout: no · acp: yes | opt-in |
opencode run --format json
(default) or opencode acp
(transport: "acp"). Schema-verified against opencode 1.18.16.
|
| amp (omp) amp |
always-ask write yolo | reported | never | not offered |
<binary> -p --mode json. Real acp subcommand exists but has fewer
permission tiers than stdout — a regression, not offered as a transport. Schema-verified against omp
17.2.9.
|
| devin devin |
plan accept-edits bypass | never | reported | only mode |
Runs devin acp — no stdout mode exists. Real tool-call ids, working
session/load
resume. Schema-verified against devin 3000.6.7 (260a97c8).
|
Native escape hatch: permissionMode: dontAsk /
sandbox: …
in frontmatter overrides normalized (must still pass allowDangerous for danger). Detect
availability: delegate checks harness --version at startup.
// agent-driven delegate({ harness: "codex", mode: "review", task: "review the auth diff", scope: "diff" }) // slash — harness as first word /delegate codex review the auth flow /codex review --scope=auth/ // aliases /claude plan the migration /opencode implement caching /amp --mode=docs --scope=README.md … /devin review the new auth flow // fan out to every detected harness /delegate all review the auth flow /delegate claude,codex plan the migration
# partitioned transcripts ~/.pi/agent/delegate/outputs/ claude/2026-08-25-…-review.md codex/2026-08-25-…-plan.md # resume /delegate --resume=<id> follow up /codex --resume=<id> fix nits # config (settings.json → "delegate" key) { "delegate": { "defaultHarness":"claude", "maxConcurrent": 4, "harnesses":{ "codex":{"model":"gpt-5"}, "opencode":{"transport":"acp"} } }} # /delegate config · /delegate config init · /delegate status
| Mode | Permission | Purpose |
|---|---|---|
review |
readonly | Code review, cites file:line, prioritized |
plan |
readonly | Implementation plan + risks |
implement |
edit | Edits + checks |
security-audit |
readonly | Injection/auth/secrets/supply chain |
docs |
edit | Docs matching repo style |
general |
edit | Any task |
Each mode is a markdown template with frontmatter (permission, model,
maxBudgetUsd, optional verify). No template ships a verify by default —
readonly
templates never run one even if configured.
harness
also accepts all or a comma-separated list. The same task runs on every harness at once
(bounded by maxConcurrent, default 4) and comes back as one synthesized comparison
report, ordered by the resolved harness list — not one report per harness.
all
resolves against whatever's actually detected; an uninstalled or unknown harness is named in the
report rather than failing the run.
This is genuinely simultaneous spend
— a 5-harness fan-out can bill all five at once, not one after another. maxBudgetUsd still
applies per run;
maxConcurrent: 1
restores one-at-a-time behavior everywhere, single runs included.
╭─ ⠋ delegate all · review · 1/4 · ⏱ 0:42──╮ │ ✓ claude 0:38 done │ │ ⠹ codex 0:41 ▶ Bash: bun test │ │ ⠹ opencode 0:12 ✍ looking at auth… │ │ … amp queued │ │ esc cancel all · m minimize │ ╰────────────────────────────────────────────╯
Double-esc
cancels every in-flight and queued run at once; the status bar chip shows aggregate state and spend so far
(e.g. ● 1✓ 1✗ 1▶ 1… · ⏱ 0:42 · $0.175).
Config lives under the delegate key in ~/.pi/agent/settings.json —
defaultHarness, maxBudgetUsd, maxConcurrent,
modelAliases, per-harness harnesses.<name>.model /
.transport. Legacy claudeDelegate auto-migrates.
Project-local templates (.pi/delegate/templates/) load only when
pi itself
considers the project trusted. As of 0.6.0,
.pi/trusted
and the PI_TRUSTED/PI_DELEGATE_TRUSTED
environment variables no longer grant trust — a repo could commit
.pi/trusted
and silently widen a builtin template's permission on clone. Trust a project via pi's own trust prompt or
defaultProjectTrust
instead.
claude_delegate
→
delegate { harness:claude}
· /claude alias still works · claudeDelegate config auto-migrates · transcripts
stay readable
pi install npm:pi-harness-delegate