pi extension — streaming · permission-bounded · fan-out across 5 harnesses

pi / harness
delegate

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.

claude /claude codex /codex opencode /opencode amp /amp · /omp devin /devin
npm pi install npm:pi-harness-delegate
GitHub →
also: 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 — harness delegate
▲ user  review the auth flow
● delegate all · review · 3/5 · ⏱ 0:41
  ✓ claude   0:38  done
  ✓ codex    0:35  done
  ✓ opencode 0:40  done
  ⠹ devin    0:12  ▶ Read: auth/session.ts
  … amp      queued
▶ Read: auth/login.ts ✓ ▶ Grep: TODO ✓ 💭 thinking… 3 turn(s) · $0.543 · 6.2% ctx
illustrative — layout mirrors the real fan-out overlay, not a screenshot
live activity feed
codex review · GPT-5
claude plan · sonnet
context6.2% · 1.0M
cost$0.12
transcript → ~/.pi/agent/delegate/outputs/<harness>/…

Why this exists

One tool, five harnesses

delegate { harness:claude|codex|opencode|amp|devin} — same task, same streaming, per-harness runners under extensions/harnesses/.

/delegate · /claude · /codex · /opencode · /amp · /omp · /devin

Normalized permissions

readonly → edit → danger maps to each harness native. danger only via allowDangerous:true — never a default.

review/plan/security-audit = readonly · implement = edit

Fan out, compare

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.

/delegate all review the auth flow

Portable templates

Markdown with frontmatter in templates/shared + templates/<harness>. User/project overlays win on collision.

harness frontmatter selects model

Host-run verify

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.

verify: bun test

Streaming + transcripts

Live feed (tool ✓/✗, thinking, text tail), framed overlay (m minimize, double-esc cancel), full transcript partitioned by harness.

outputs/<harness>/<ts>-<mode>.md

Configurable transport

Every harness runs over its native CLI's stdout by default. opencode also speaks ACP, opt-in per harness; devin is ACP-only.

harnesses.opencode.transport: "acp"

Cost-aware

Tokens, context% and spend flow into pi footer stats via tool Usage. Per-harness modelAliases, /delegate status spend rollup.

economy / balanced / max

Harnesses

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.

Usage

// 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

Modes

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.

Fan out to multiple harnesses

One task, every harness, concurrently

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 the auth flow · /delegate claude,codex plan the migration

One overlay, per-harness rows

╭─ ⠋ 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 & project trust

One key in pi's own settings.json

Config lives under the delegate key in ~/.pi/agent/settings.jsondefaultHarness, maxBudgetUsd, maxConcurrent, modelAliases, per-harness harnesses.<name>.model / .transport. Legacy claudeDelegate auto-migrates.

/delegate config · /delegate config init · /delegate status

Project trust — security fix in 0.6.0

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.

/delegate status → reports trust + skipped templates

Migration

pi-claude-delegate → pi-harness-delegate
claude_delegatedelegate { harness:claude} · /claude alias still works · claudeDelegate config auto-migrates · transcripts stay readable
pi install npm:pi-harness-delegate