@mporenta/pi-cmux-orchestrator

Pi extension for orchestrating visible, interactive Pi workers in cmux terminal surfaces.

Packages

Package details

extension

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
  • cmux available on PATH
  • pi available on PATH
  • A parent Pi session launched inside a cmux terminal surface (so CMUX_WORKSPACE_ID is set), unless every worker is spawned with layout: "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_workername?, cwd? (defaults to the parent session cwd), prompt? (delivered once the worker is online), layout? ("same-workspace" default, or "new-workspace"), waitForOnline? (defaults to true; the call blocks up to 30s for the worker to connect back). Returns { success: true, worker } or a typed failure with reason (not_in_cmux, cmux_error, shell_readiness_timeout, worker_online_timeout).
  • send_worker_promptworkerId, 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 its state, owner, cmuxSurfaceId, cmuxWorkspaceId, and last heartbeat.
  • stop_workerworkerId, closeSurface? (defaults to false; leaves the surface open for inspection unless set).
  • get_worker_resultworkerId. 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_workerworkerId. 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_worker returns it, list_workers re-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 prompt or a send_worker_prompt follow-up.
  • Wait by event, then read once. get_worker_result returns 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_prompt the 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_worker only the surfaces this workflow owns. Pass closeSurface: 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 to worker in 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 cmux commands to create, inspect, focus, and close terminal surfaces;
  • starts local pi worker 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 with layout: "new-workspace".
  • cmux or pi not found: ensure both executables are on the PATH inherited 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; if owner is human, release_worker it before prompting.
  • Worker shows stale or presumed_dead: it stopped heartbeating; read its surface, then stop_worker and respawn if needed.

Development

npm install
npm run typecheck
npm run pack:dry-run
pi -e ./index.ts

License

MIT