@mporenta/pi-cmux-orchestrator
Pi extension for orchestrating visible, interactive Pi workers in cmux terminal surfaces.
Package details
Install @mporenta/pi-cmux-orchestrator from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@mporenta/pi-cmux-orchestrator- Package
@mporenta/pi-cmux-orchestrator- Version
0.1.1- Published
- Jul 18, 2026
- Downloads
- 293/mo · 23/wk
- Author
- pi-porenta
- License
- MIT
- Types
- extension
- Size
- 41.1 KB
- Dependencies
- 0 dependencies · 3 peers
Pi manifest JSON
{
"extensions": [
"./index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
@mporenta/pi-cmux-orchestrator
A Pi package that lets a parent Pi session create and supervise visible, interactive Pi workers in cmux terminal surfaces. Workers stay human-observable and can be prompted, inspected, stopped, or handed over between the orchestrator and a person.
Use it as the visible transport and topology layer for multi-agent coding workflows: the orchestrator owns routing, the workers do the work in their own cmux surfaces, and a human can step into any surface at any time. It does not, by itself, enforce a workflow — the orchestrator's prompts supply the durable handoffs, completion sentinels, and verification described under Building multi-agent workflows.
Requirements
- macOS with cmux installed and running
cmuxavailable onPATHpiavailable onPATH- A parent Pi session launched inside a cmux terminal surface (so
CMUX_WORKSPACE_IDis set), unless every worker is spawned withlayout: "new-workspace"
Install
pi install npm:@mporenta/pi-cmux-orchestrator
For project-local installation:
pi install -l npm:@mporenta/pi-cmux-orchestrator
Try the package without installing it:
pi -e npm:@mporenta/pi-cmux-orchestrator
After installation, restart Pi. When developing from an auto-discovered extension directory, /reload reloads the extension.
First prompts to try
- “Spawn a Pi worker to review the current changes.”
- “List the Pi workers and show their ownership and liveness.”
- “Ask the worker to run the targeted tests, then report its latest result.”
- “Spawn a builder and a separate verifier in a new workspace, then route the verifier’s verdict back to me.”
Tools
| Tool | Purpose |
|---|---|
spawn_pi_worker |
Start a visible interactive Pi worker in the same or a new cmux workspace. |
send_worker_prompt |
Send a follow-up or steering prompt to an orchestrator-owned worker. |
list_workers |
List worker ownership, cmux surface, and liveness state. |
stop_worker |
Gracefully stop a worker and optionally close its cmux surface. |
get_worker_result |
Retrieve the worker's latest result. |
release_worker |
Return a human-taken worker to orchestrator ownership. |
Tool parameters
spawn_pi_worker—name?,cwd?(defaults to the parent session cwd),prompt?(delivered once the worker is online),layout?("same-workspace"default, or"new-workspace"),waitForOnline?(defaults totrue; the call blocks up to 30s for the worker to connect back). Returns{ success: true, worker }or a typed failure withreason(not_in_cmux,cmux_error,shell_readiness_timeout,worker_online_timeout).send_worker_prompt—workerId,prompt,deliverAs?("followUp"default, queued after the current turn, or"steer"to interrupt). A prompt to a human-owned worker is deferred, not delivered ({ deferred: true }).list_workers— no parameters. Returns every known worker with itsstate,owner,cmuxSurfaceId,cmuxWorkspaceId, and last heartbeat.stop_worker—workerId,closeSurface?(defaults tofalse; leaves the surface open for inspection unless set).get_worker_result—workerId. Returns the latest result inline up to 8 KB; larger results are written to a file under the run directory and returned as{ resultId, path }.release_worker—workerId. Clears human ownership so the orchestrator may prompt the worker again.
How it works
The parent extension starts a local Unix-domain socket server under the system temporary directory (pi-cmux-orchestrator-<sessionId>/parent.sock). It creates cmux terminal surfaces, waits for each shell to become ready, and launches a child pi process with worker-specific environment variables. Workers connect back to the parent over the local socket and exchange lifecycle events — online, heartbeat (every 5s), status, result, offline — while staying visible in cmux.
Worker records are persisted as custom session entries, so list_workers and results survive a /reload of the parent session; previously live workers are marked stale on restore until they heartbeat again.
Worker lifecycle
A worker moves through these state values (visible via list_workers):
| State | Meaning |
|---|---|
pending |
Surface created and pi launched; waiting for the worker to connect back. |
online |
Connected and idle. |
busy |
Running a turn, a tool, or a delivered prompt. |
stale |
No heartbeat for ≥15s; may recover on the next heartbeat. |
presumed_dead |
No heartbeat for ≥30s. |
offline |
Cleanly stopped or its session shut down. |
failed |
Configuration or connection error; inspect the visible surface. |
Ownership and human handoff
A worker is orchestrator-owned until interactive input is detected directly in its cmux surface, at which point it becomes human-owned. The orchestrator will not prompt a human-owned worker — prompts are deferred — until release_worker returns it to orchestrator ownership. This is what keeps a person able to take over any surface without the orchestrator fighting them for control.
Building multi-agent workflows
The orchestrator supplies transport; a durable, trustworthy workflow comes from the prompts you route through it. When designing one, apply the building-cmux-agent-workflows skill:
- Choose the smallest honest topology. A single narrow lane wants three roles — lead, builder, verifier. Keep the lead (this orchestrator session) as the sole routing authority; never route by whichever surface happens to be focused. Capture each
workerId→ surface reference at spawn time (spawn_pi_workerreturns it,list_workersre-lists it). - Write durable handoffs, not scrollback. Have workers read and write files —
.team/REQUEST.md,PLAN.md,ACCEPTANCE.md, round-scoped logs, patches — so state outlives any single terminal. Terminal output is evidence transport, not the source of truth. - Dispatch narrowly. Give each worker its role, allowed paths, exact validation commands, a completion sentinel, and a prohibition on unrelated edits, all in the spawn
promptor asend_worker_promptfollow-up. - Wait by event, then read once.
get_worker_resultreturns a worker's settled assistant text — treat its arrival as a doorbell, then confirm the agreed sentinel and required artifacts actually exist before accepting completion. Ask each role to print one machine-readable final line, e.g.CMUX-WORK-DONE: <role> | <PASS|FAIL> | <round> | <summary>. - Verify independently. Spawn a separate verifier that re-reads the original request and runs fresh checks; a builder running its own tests is not independent verification.
- Bound the revision loop. On
FAIL,send_worker_promptthe exact evidence back to the responsible builder. Stop after a fixed round/time limit or on repeated unchanged failure, and report the blocker instead of looping. - Tear down safely. Preserve reports and patches, then
stop_workeronly the surfaces this workflow owns. PasscloseSurface: false(the default) when a human may still want to inspect a surface; never close or steal focus from a surface you do not own.
Configuration
The extension configures workers internally through these environment variables; users normally do not need to set them:
PI_CMUX_ORCH_ROLE— set toworkerin spawned sessions; unset (parent) sessions register the tools.PI_CMUX_ORCH_WORKER_ID— the worker's stable id.PI_CMUX_ORCH_PARENT_SOCKET— path to the parent's Unix socket.PI_CMUX_ORCH_RUN_DIR— per-session run directory for sockets and result overflow files.
It also reads cmux's own CMUX_WORKSPACE_ID and CMUX_SURFACE_ID to decide placement and to report each worker's surface.
Security and permissions
Pi packages run with the installing user's full system permissions. This extension:
- runs
cmuxcommands to create, inspect, focus, and close terminal surfaces; - starts local
piworker processes (each inheriting the parent environment); - sends text and key events to cmux surfaces;
- creates Unix sockets and transient runtime files under the system temporary directory;
- sends prompts and receives agent output over a local Unix socket;
- inherits the parent environment and therefore may expose available credentials to worker Pi processes.
It does not intentionally contact a remote service itself, but Pi workers may use configured model providers and tools. Review worker prompts and cmux surfaces before granting access to sensitive repositories or credentials.
Remove the package with:
pi remove npm:@mporenta/pi-cmux-orchestrator
Troubleshooting
- Not running in cmux (
not_in_cmux): launch the parent Pi session from a cmux terminal surface, or spawn withlayout: "new-workspace". cmuxorpinot found: ensure both executables are on thePATHinherited by Pi.- Shell never becomes ready (
shell_readiness_timeout): the surface's shell did not echo the readiness marker within 10s; inspect the surface for a slow or blocked shell profile. - Worker does not come online (
worker_online_timeout): inspect its visible surface; startup waits are bounded to 30s and the surface may show an authentication or configuration error. - Worker cannot be prompted: check
list_workers; ifownerishuman,release_workerit before prompting. - Worker shows
staleorpresumed_dead: it stopped heartbeating; read its surface, thenstop_workerand respawn if needed.
Development
npm install
npm run typecheck
npm run pack:dry-run
pi -e ./index.ts
License
MIT