Orca–Pi orchestration (OP1.1 / JEF-5 scaffold + OP1.2 / JEF-6 Pi agent
profiles + OP1.3 / JEF-7 deterministic Pi argv launcher + OP1.6 / JEF-10
default scout/worker/reviewer profiles + OP1.7 / JEF-11 profile management
UX + OP1.4 / JEF-8 supervised worker adapter + OP1.5 / JEF-9 compact
Pi-facing orchestration CLI/skill): a thin Orca plugin
plus a separately testable companion orca-pi CLI/library.
Orca owns Runs/Tasks/Dispatches/worktrees and completion; orca-pi is a thin
Pi-facing wrapper that never couples orchestration logic to Orca's
experimental plugin-worker internals.
Ownership boundary: JEF-7 owns ResolvedPiProfile → ProcessSpec and the
redacted launch-spec formatter; JEF-11 owns CLI commands,
provenance/display presentation, validation UX, and the Orca sidebar, and
consumes JEF-7's formatter via injection rather than implementing another one.
- Thin Orca plugin (
packages/orca-plugin/) — contributes UI/config/ skills/commands where supported. It performs no process spawning: the plugin worker's capability model is still evolving (stablyai/orca#15637), so unrestricted Nodechild_processaccess inside the plugin is explicitly not a long-term dependency. - Companion
orca-piCLI/library (packages/cli/+packages/core/) — owns version reporting,doctordiagnostics, profile loading, deterministic Pi argv construction (OP1.3 / JEF-7), supervised Pi worker launches (OP1.4 / JEF-8), and the compact Pi-facing orchestration surface (OP1.5 / JEF-9:spawn/status/send/wait/stopplus theorca-pi-orchestrationskill). All Orca calls use the publicorcaCLI (--json).
orca-pi/
├── packages/
│ ├── core/ # version + doctor + manifest validator + profiles + launcher + supervised adapter + compact orchestration (no Electron)
│ ├── cli/ # `orca-pi` executable (thin wrapper over core)
│ ├── pi-rpc/ # SNC1.1 Pi RPC contract proofs (LF-only JSONL, fixtures, compatibility matrix)
│ ├── structured-bridge/ # SNC1.3 hot-swappable external structured-session bridge (dev seam + mock + Pi mapping) + SNC1.4 Pi-backed provider (pi --mode rpc text chat)
│ └── orca-plugin/ # Orca manifest, panel/skill/command contributions
├── profiles/ # Pi agent profile schema docs + defaults + examples (OP1.2 / JEF-6 + OP1.6 / JEF-10)
├── prompts/ # Default scout/worker/reviewer role prompts (OP1.6 / JEF-10)
├── scripts/ # skill-size regression guard (OP1.5 / JEF-9)
├── docs/ # targeted Orca plugin API/version notes + manual evals
└── README.md
Core/CLI code is testable without Electron/Orca Desktop: doctor and the CLI
run() entry take an injected ProcessRunner, and unit tests use fake
executables.
- Node.js
>= 18and npm. - Orca Desktop with the
orcaCLI on PATH (CLI overview). - Pi coding agent with the
piCLI on PATH (coding-agent README).
This scaffold was developed against Orca app 1.4.196 and Pi 0.84.4.
See docs/ORCA_PLUGIN_API.md for the targeted plugin API/version and for
how to re-validate against a new Orca release.
npm install
npm run build # tsc -b → packages/*/dist
npm run typecheck # tsc -b --verbose
npm run lint # eslint .
npm test # vitest runGitHub Actions workflow .github/workflows/ci.yml runs on every pull
request targeting main and on pushes to main (single stable verify
job, contents: read). To reproduce CI locally, run from the repo root
with Node 22:
npm ci
npm run build
npm test
npm run lintRun the CLI from source after building:
node packages/cli/dist/main.js --version
node packages/cli/dist/main.js doctor
node packages/cli/dist/main.js doctor --json
node packages/cli/dist/main.js profiles list
node packages/cli/dist/main.js profile show scout
node packages/cli/dist/main.js profile inspect scout --project-root .
node packages/cli/dist/main.js profile inspect scout --project-root . --context-summary
node packages/cli/dist/main.js profile validate
node packages/cli/dist/main.js profile path
node packages/cli/dist/main.js status --json
node scripts/check-skill-size.mjs
node packages/cli/dist/main.js github auth status --identity reviewer
node packages/cli/dist/main.js github auth status --profile worker
node packages/cli/dist/main.js github identity doctor --repo 44madfire/orca-pi
node packages/cli/dist/main.js github setup --identity worker --repo 44madfire/orca-pi
node scripts/setup-github-apps.mjs --repo 44madfire/orca-pi
node packages/cli/dist/main.js github review --identity reviewer --pr https://github.com/octo/hello-world/pull/123 --verdict request-changes --body @/tmp/review.md
node packages/cli/dist/main.js github check start --identity reviewer --repo octo/hello-world --sha <head-sha>
node packages/cli/dist/main.js github check complete --identity reviewer --repo octo/hello-world --sha <head-sha> --verdict approve --summary "No blocking findings."Or link it globally for the orca-pi name:
npm link --workspaces=false ./packages/cli
orca-pi --version
orca-pi doctororca-pi --versionprints the release version (0.1.0).orca-pi doctorverifiesorcaandpiare on PATH and reports versions. It is strictly read-only: it only spawns<exe> --version(plusorca status --jsonas a fallback, sinceorca --versioncurrently prints usage without a version) and never mutates configuration.- Exit
0when both CLIs report versions; exit1with actionable install hints when either is missing or versionless.
- Exit
orca-pi --helpprints usage; unknown commands/flags exit2.orca-pi profiles list [--json]lists merged profiles with effective model/thinking/tool/skill counts plus user/project precedence and file locations. Exit0even when no profiles exist (with creation hints).orca-pi profile show <name> [--json] [--show-prompt]shows effective values plus provenance (built-in, user config, project config, inherited profile). Redacts large prompt bodies unless--show-prompt.orca-pi profile inspect <name> [--project-root <path>] [--cwd <path>] [--user-config <path>] [--project-config <path>] [--json] [--show-prompt] [--context-summary]prints JEF-11 presentation (provenance, context policy) plus JEF-7's deterministic Pi argv in redacted human-readable form (read-only, never launches Pi).--jsonprints structured{ profile, provenance, spec, … };--show-promptprints the full prompt text (default truncates to a preview + length).--context-summaryadds a context-budget estimate (prompt chars/words/lines, ~tokens, tool/skill/extension counts, context-file policy; heuristic, not provider billing). The display formatter is never used for execution — launching always uses the structured{ command, args, cwd, env }array.- Fresh installs expose built-in
scout,worker, andreviewer(model-agnostic defaults inpackages/core/src/profile/builtins.ts, mirrored inprofiles/scout.yaml/worker.yaml/reviewer.yamlandprompts/*.md). Override models while retaining role policy:profiles: { scout: { model: <fast-model> } }. Seeprofiles/README.mdanddocs/EVALS.mdfor role policy and manual evals. orca-pi profile validate [<name>] [--json]validates all (or one) profile with file/source/field diagnostics. Exit0when valid,1when invalid or unreadable.orca-pi profile path [--project|--user] [--json]prints the authoritative user/global and project locations (script-friendly with--project/--user). Never parses file contents, so it stays usable when config is malformed (recovery UX; content diagnostics belong tovalidate).orca-pi spawn <profile> (--task <spec>|--task-id <id>) [--worktree <policy>] [--identity <name>] [--json]resolves the role profile pre-launch (unknown profiles fail before any Orca effects) then launches an Orca-supervised Pi worker via JEF-8's adapter. Returns one frozen receipt (taskId,dispatchId,terminalHandle, worktree, Pi argv,githubIdentity).--worktreeiscurrent(default),new-child/new-top-level(require--name), or an existing selector (active,id:…,name:…,path:…).--identityis diagnostics/admin only and must match the profile'sgithubIdentity(cross-role overrides fail closed). The terminal command is prefixed per-process withORCA_PI_GITHUB_IDENTITY+ORCA_PI_PROFILEso agents inherit without repeating--identityand without touching global git/GH config. Exit1on profile/Orca failures.orca-pi status [--worker <dispatch|terminal>|--task <id>] [--json]inspects Orca Task/Dispatch state (never terminal-text inference). Barestatussweeps workers (plus tasks when a Run is bound). Exit0with a stable receipt; exit1for unknown workers/tasks.orca-pi send --worker <handle> --message <text> [--subject <text>] [--json]delivers coordinator follow-up mail (send --to dispatch:<id>), preserving provenance. Never sendsworker_done/heartbeat(worker-owned signals).orca-pi wait (--worker <handle>|--task <id>) [--timeout <duration>] [--json]polls Orca state with backoff untilcompleted/failedor timeout (500ms,30s,5m,1h; plain numbers mean seconds; default15m). Exit0oncompleted,1onfailed/timeout. Timeouts mean "still running", never failure.orca-pi stop --worker <handle> [--json]fences one worker terminal (worker-stop) idempotently (alreadyStoppedon repeats). It never marks the Task complete/failed — Orca owns completion; the observedtaskStatusis reported unchanged.
Compact orchestration keeps only minimal handle mappings
(<projectRoot>/.pi/orca-pi-workers.json, best-effort); Orca remains the
source of truth for completion/status.
- GitHub agent identities + automated review checks (OP1.9 / JEF-15 + OP1.12 worker/reviewer Apps):
Worker App (
orca-pi-worker[bot], Contents: write) creates/updates PRs while the dedicated Reviewer GitHub App (orca-pi-reviewer[bot], Contents: read) submits formalCOMMENT/REQUEST_CHANGES/APPROVEreviews and publishes the deterministicorca-pi/agent-reviewcheck (in_progress→success/failure) for branch protection/rulesets. Human (44madfire, including ChatGPT-assisted review) remains merge authority (no auto-merge).worker bot != reviewer bot != 44madfire, so worker PRs are approvable by both reviewer bot and human. Review/check writes fail closed: reviewer-only with installation-token proof (GET /installation/repositories, IAT-supported unlikeGET /user) for the trusted configured App login + distinct-from-PR-author guard before any POST (same-account PATs never write); worker pushes/PRs fail closed via the parallel worker App preflight;check startreuses the deterministic run (idempotent), review retries dedupe via response-state matching. Launch role is authoritative:githubIdentityfrom the resolved profile controls the effective actor (--profileor spawn-injectedORCA_PI_GITHUB_IDENTITYinherits; explicit--identitymust match the profile, no escalation). Worker git/GH writes run as the worker App via a scoped broker (per-processexecGH_TOKENwith Worker-App preflight / worktree-scopedsetup-gitempty-reset + helper, never--global;ghneedsexec,setup-gitcoversgitonly). Repository verification uses App JWT on the JWT-only installation endpoint. Seedocs/GITHUB_IDENTITIES.md.orca-pi github auth status [--identity <name>] [--profile <name>] [--json]— credential presence (source label + expiry, never values).orca-pi github review [--identity reviewer] [--profile <name>] --pr <url|number|owner/repo#n> --verdict <approve|request-changes|comment> --body <text|@file> [--repo <owner/repo>] [--json]orca-pi github check start|complete [--identity reviewer] [--profile <name>] --repo <owner/repo> --sha <sha> ...(idempotent: reuses the deterministic run for the SHA).orca-pi github doctor [--repo <owner/repo>] [--ambient <login>] [--json]/orca-pi github identity doctor— non-secret diagnostics (App login/ids, perms, expiry, distinctness).orca-pi github setup --identity <name> [--repo <owner/repo>]— idempotent non-secret App bootstrap steps (Apps require UI/admin; no secrets committed).orca-pi github mint --identity <name>— out-of-LLM installation-token mint/refresh via@octokit/auth-app(private key from..._PRIVATE_KEY_PATH, WSL/Windows aware; prints metadata only).orca-pi github exec [--identity <name>] [--profile <name>] -- <command...>— scoped broker (every worker exec preflights the Worker App; processGIT_CONFIG_*host override +GIT_SSH_COMMANDguard; reviewergit pushrefused).orca-pi github setup-git --identity worker [--path <repo-path>] [--host <host>]— worktree empty-resets + host helper (--worktreewithextensions.worktreeConfigauto-enable, never--global;gitonly,ghneedsexec).orca-pi github ssh-guard— internal SSH fail-closed guard (exit 128; worker pushes require HTTPS).- Profiles reference logical identities (
githubIdentity: worker|reviewer), never secrets; tokens resolve at runtime viaORCA_PI_GITHUB_<IDENTITY>_TOKEN(+ optional..._EXPIRES_AT) or App mint (..._APP_ID+..._PRIVATE_KEY_PATH+..._INSTALLATION_ID+..._LOGIN). Reviewer holds Contents: read only —githubIdentity: reviewerwithedit/writetools fails validation.
- Manifest:
packages/orca-plugin/orca-plugin.json(manifest v1:manifestVersion: 1,pluginApi: 1,engines.orca: ">=1.4.0", no capabilities). Install identity:44madfire.orca-pi. - Panels (
contributes.panels, declarative sandboxed HTML, no worker):orca-pi-status(panel.html) — plugin/CLI version plusorca-pi doctorand profile CLI pointers.orca-pi-profiles(panel/profiles.html, OP1.7 / JEF-11) — read-only Pi profiles sidebar: effective model/thinking, tool count, skill names/count, extension count, context-file policy, validation state. Live data comes fromorca-pi profiles list --json; without a supported host bridge the panel shows CLI fallback content. Conservative actions only: validate, show/open/copy config location, refresh/reload. Editing happens in config files — the panel keeps no local store.- Feature detection (
detectPanelSupport()insrc/panel.ts) reports read-only support vscli-onlyfallback; unsupported APIs degrade gracefully without blocking orchestration.
- No commands yet: manifest v1 treats action-less commands as worker
commands requiring a
mainentry, andactionaliases must come from the host's closed built-in list — so a command waits for a later ticket with a real worker or a suitable built-in action. - The plugin is declarative-only: no
mainworker entry,capabilities: []. - Skills (
skills/, installed through Orca's skill flow, not the plugin manifest — v1 has noskillscontribution point):orca-pi-doctor/SKILL.md(OP1.1) — read-onlydoctordiagnostics.orca-pi-orchestration/SKILL.md(OP1.5 / JEF-9) — compact Pi-facing orchestration: when to useorca-pi, the five semantic commands, role profiles, worktree policy, and Orca-authority rules. No model/tool lists, no full orchestration guide copy. Load in Pi viapi --skill packages/orca-plugin/skills/orca-pi-orchestration. Size: ~3.4KB (~840 tokens, 83 lines) vs upstreamorca skills get orchestration --full~42.5KB (~10.6k tokens, 440 lines) — ~8%. Guarded bynode scripts/check-skill-size.mjs(budget ≤6000 bytes / ≤1600 tokens).
- Dependency-free entry
src/index.ts(activate(),renderPluginStatus()) proves the artifact loads without Electron.
- Build:
npm run build. - In Orca, load the folder
packages/orca-plugin/via the development plugin loader (it must containorca-plugin.jsonat its root). - Verify Orca loads it and the
Orca-Pi Statuspanel appears, without destabilizing Orca. - In a terminal, verify
orca-pi doctorreports your Orca/Pi versions.
If your Orca build reports a manifest error, update
packages/core/src/pluginManifest.ts, orca-plugin.json, and
docs/ORCA_PLUGIN_API.md together — they are tested as a unit
(packages/orca-plugin/test/manifest.test.ts).
Profiles (OP1.2 / JEF-6) + deterministic launcher (OP1.3 / JEF-7) + defaults (OP1.6 / JEF-10) + management UX (OP1.7 / JEF-11)
- Built-in model-agnostic defaults (
scout,worker,reviewer) inpackages/core/src/profile/builtins.ts(fresh installs work with no config files), mirrored inprofiles/scout.yaml/worker.yaml/reviewer.yamlandprompts/*.md. Declarative overrides inprofiles/examples.yaml(copy to$PI_CODING_AGENT_DIR/profiles.yamlor<projectRoot>/.pi/profiles.yaml). - Schema/loader/resolver in
@orca-pi/core(packages/core/src/profile/):validateProfilesDocument,parseAndValidateProfilesText,mergeValidatedDocuments,resolveProfile→ one frozenResolvedPiProfile. Invalid config fails pre-launch with dotted-path diagnostics; seeprofiles/README.mdfor fields, precedence, and security rules. - Deterministic Pi argv launcher in
@orca-pi/core(packages/core/src/pi/):buildPiLaunch(resolved, { projectRoot, cwd })→ frozen{ command: "pi", args, cwd, env }(structured, no shell strings).systemPromptFileis read againstprojectRootand passed explicitly via--system-prompt; relative skill/extension paths resolve againstprojectRoot;cwdpreserves the Orca worktree selection; task text is never embedded (Orcadispatch --injectowns injection in JEF-8); lean profiles visibly emit--no-skills/--no-extensions/--no-context-filesthen only explicit--skill/--extensionentries;ephemeralemits--no-sessionwhilefreshemits no session flags and never resumes. Pi file-or-text contract: current Pi treats--system-prompt <value>as file-or-text (existsSync→ read file, else literal). Non-colliding prompts travel literally (common case, byte-identical); when the intended text equals an existing file incwd, the launcher materializes it to a deterministic content-addressed temp file and passes the temp path so Pi's file branch reads the exact intended text (seeprompt-transport.tsandpi-prompt-contract.test.ts). - Presentation (
packages/core/src/profile/presentation.ts, JEF-11): effective values plus per-field provenance, redacted prompt display (--show-promptreveals),toPanelModel()metadata-only sidebar model. Never loads skill/prompt file contents for metadata; shortens~in human output except in explicitprofile path.profile inspectwires the production preview asformatPiInspect(resolved, await buildPiLaunch(…))via asyncLaunchPreviewProviderinjection (JEF-11 never builds argv).
A Pi coordinator runs the normal worker lifecycle without loading Orca's
full orchestration guide — only orca-pi plus the orca-pi-orchestration
skill:
# 1. Scout (read-only inspection, evidence-backed handoff)
orca-pi spawn scout --task "Map the auth flow; cite files/symbols and uncertainties" --json
orca-pi wait --task <scout-task-id> --timeout 10m --json
# 2. Worker (bounded implementation)
orca-pi spawn worker --task "Implement the fix per the scout handoff; keep the diff scoped" --json
orca-pi send --worker <worker-dispatch> --message "Prefer approach X; see file Y for the pattern" --json
orca-pi wait --worker <worker-dispatch> --timeout 15m --json
# 3. Reviewer (independent evaluation, no edits)
orca-pi spawn reviewer --task "Review the diff for <worker-task-id> against acceptance criteria" --json
orca-pi wait --task <reviewer-task-id> --timeout 10m --json
# Fence a worker terminal when done (idempotent; never marks the Task complete)
orca-pi stop --worker <worker-dispatch> --json
# Inspect at any time (Orca-state only, never terminal text)
orca-pi status --worker <dispatch> --json
orca-pi status --task <task-id> --jsonOrca owns completion/status throughout: status/wait read
Task/Dispatch state, send is structured inbox mail (not injection),
and stop fences the terminal without completing the Task.
- No transcript parsing.
- No Orca core fork.
- No panel-local config store or undocumented filesystem/network bridge.
- No coordinator-side completion authority (Orca Task/Dispatch state only).
- No role-specific model/tool duplication outside profile config.
- Orca pluggable harness proposal:
https://github.com/stablyai/orca/issues/13306 - Orca plugin capability limitations:
https://github.com/stablyai/orca/issues/15637 - Orca CLI overview:
https://www.onorca.dev/docs/cli/overview - Pi coding-agent CLI:
https://github.com/up0to1/pi-mono/blob/main/packages/coding-agent/README.md