pi-tmux-orchestrator
Pi extension, skill, and dependency-free Python CLI for coordinating coding agents in tmux
Package details
Install pi-tmux-orchestrator from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-tmux-orchestrator- Package
pi-tmux-orchestrator- Version
0.8.1- Published
- Aug 20, 2026
- Downloads
- 951/mo · 826/wk
- Author
- revazi
- License
- MIT
- Types
- extension, skill
- Size
- 525.7 KB
- Dependencies
- 0 dependencies · 0 peers
Pi manifest JSON
{
"extensions": [
"./extensions/tmux-orchestrator.js"
],
"skills": [
"./SKILL.md"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
Pi Tmux Orchestrator
A Pi extension, skill, and dependency-free Python CLI for coordinating coding agents in monitorable tmux grids.
Demo

Native Pi TUI workers remain directly steerable while the broker dashboard shows workflow, role, model, usage, context, and recent metadata state.
What it provides
- One implementer with normal Pi coding tools
- One independent reviewer with read/verification tools
- Optional technical probe, Playwright tester, and Django expert
- One event-driven owner-only Unix-socket broker per run
- An adaptive broker/status dashboard for workflow, role, model, usage, context, and recent metadata events
- The same worker-bridge protocol for interactive TUI and headless RPC workers
- Native worker output in TUI panes and assistant/tool input/tool output visibility in RPC panes
- Parent Pi supervision with event-driven final structured reports and attention alerts
- Assignment-boundary context resets with bounded parent capsules, coalesced latest-per-role run state, and complete Pi history
- Bounded typed reports through a terminating Pi tool
- No Markdown handoffs, readiness markers, mailbox payload files, relay polling, lifecycle sleeps, or tmux key injection in newly started runs
- Metadata-only SQLite state, durable Pi sessions, idempotent command IDs, and
crash-
uncertainsemantics - User-configurable provider/model/thinking policy for every role, including Pi custom providers, with exact natural-language overrides through the model tool
- Actual provider token/cost accounting when Pi exposes it, plus context pressure and soft budgets
- A versioned JSON CLI and tmux-independent Supervisor API v2
- A persistent project-neutral controller Pi session
- Explicit project trust, one-writer policy, bounded output, and confirmations for restart/stop
Grid
┌──────────────────────────────┬──────────────────────────────┐
│ Implementer │ Reviewer │
│ configured provider/model │ configured provider/model │
│ configured thinking │ configured thinking │
├──────────────────────────────┼──────────────────────────────┤
│ Optional probe │ Optional Playwright tester │
│ configured provider/model │ configured provider/model │
│ configured thinking │ configured thinking │
├──────────────────────────────┼──────────────────────────────┤
│ Optional Django expert │ Broker + status │
│ configured provider/model │ state, roles, models, usage │
│ configured thinking │ recent metadata events │
└──────────────────────────────┴──────────────────────────────┘
Tmux hosts and displays the broker and workers. It is not the coordination transport.
The broker pane is an event-driven terminal dashboard rather than a log tail.
It prioritizes session identity and workflow state/round, then transport and
protocol, per-role connection/lifecycle/assignment/model/thinking/actual usage,
soft-budget pressure, and a bounded recent metadata event rail. Green denotes
healthy/success, cyan active work, yellow attention or budget pressure, red
failure/uncertainty, and dim text secondary metadata. Full, compact, and narrow
layouts adapt to the pane without wrapping. State changes and supported
SIGWINCH resize notifications repaint TTYs in place and restore cursor state;
NO_COLOR, TERM=dumb, non-TTY, and non-UTF-8 outputs
have plain safe fallbacks. The dashboard never renders workflow or provider
bodies and never polls to refresh. See the reviewable
broker dashboard design for the wireframe,
hierarchy, semantic tokens, breakpoints, and intentional omissions.
Architecture
bin/pi-tmux-agents is a thin executable. The authoritative standard-library
implementation is pi_tmux_orchestrator/:
- CLI/controller/tmux host control
- strict manifests and private storage
- framed broker protocol and metadata-only SQLite state machine
- focused dependency-free broker dashboard presentation
- broker clients and TUI/RPC worker supervision
- role system prompts and worker bridge
- retained-run Supervisor API
The extension delegates orchestration control actions as bounded argument arrays to the Python JSON CLI, reads only bounded model metadata from Pi's current registry, and owns the parent-session observer/presentation bridge. For Pi-started runs, the invoking parent Pi keeps an authenticated read-only broker observer: tmux panes provide live worker visibility, while structured completion/attention reports return to the parent for decisions. The broker is the only current-run metadata writer. Pi owns conversation durability. Reviewer roles inspect the shared worktree directly instead of receiving copied diffs or logs.
See coordination protocol v1 for schemas, role ACLs, authentication, lifecycle, report limits, acknowledgements, retry, crash recovery, and token accounting.
Requirements
- Pi available as
pi - Python 3.11+
- tmux 3.2+; tmux 3.5+ recommended
- Node 22.19+ for package verification
- Ruff 0.11.11 for repository development checks only
Recommended tmux 3.5+ configuration:
set -g extended-keys on
set -g extended-keys-format csi-u
Installation
pi install npm:pi-tmux-orchestrator
One run without installation:
pi -e npm:pi-tmux-orchestrator
Reviewed Git commit or local checkout:
pi install git:github.com/revazi/pi-tmux-orchestrator@<reviewed-full-commit>
pi install /absolute/path/to/pi-tmux-orchestrator
Pi packages execute with the current user's permissions. Inspect source before installation. This package has no runtime dependency tree and is MIT licensed.
If an old installation uses the removed scoped npm identity:
pi remove npm:@revazi/pi-tmux-orchestrator
pi install npm:pi-tmux-orchestrator
Start from Pi
The package exposes:
/orchestrator-help/orchestrator-about/orchestrator-doctor/orchestrator-models [query]/orchestrator-start [task]/orchestrator-list/orchestrator-status [session]/orchestrator-watch [session]/orchestrator-attach [session]/orchestrator-send [session]/orchestrator-stop [session]- Short aliases:
/or-help,/or-about,/or-doctor,/or-models,/or-start,/or-list,/or-status,/or-watch,/or-attach,/or-send, and/or-stop /orchestrateand/orchestrationscompatibility aliases
The /or-* aliases use the exact same handlers, confirmations, selectors, and
safety boundaries as their canonical /orchestrator-* commands.
At interactive Pi startup, the extension makes one best-effort, time-bounded
request to the public npm registry. If a newer release exists, it shows a
non-blocking warning with pi update npm:pi-tmux-orchestrator. /or-about
shows the installed version, latest npm version, update command, and project
links. Set PI_TMUX_ORCHESTRATOR_DISABLE_UPDATE_NOTICE=1 to disable startup
notices. Update checks are skipped in orchestration worker and controller
sessions.
Worker model configuration
Pi's own provider authentication and models.json remain authoritative. The
orchestrator never reads or copies provider credentials. Configure global
worker defaults outside project repositories in
~/.pi/agent/tmux-orchestrator.json (or under PI_CODING_AGENT_DIR):
{
"version": 1,
"defaults": {
"provider": "anthropic",
"model": "claude-sonnet-4-6",
"thinking": "high"
},
"roles": {
"reviewer": {
"provider": "google",
"model": "gemini-3.1-pro-preview",
"thinking": "medium"
},
"probe": {
"thinking": "low"
}
}
}
The file is read for every new start. defaults applies to every role and
roles overrides individual roles. Only
provider, model, and thinking are accepted; credential or endpoint fields
are rejected. Set PI_TMUX_ORCHESTRATOR_CONFIG to an absolute path to keep the
file elsewhere. Precedence is: explicit CLI/model-tool role override, role
configuration, global configuration, then packaged fallback defaults.
Natural-language requests are supported by the tmux_orchestrator tool. For
example, users can ask Pi to “use my current model for every worker,” “use
Anthropic model X with high thinking for the implementer,” or “use configured
models.” Pi can call the metadata-only models action to resolve exact IDs; the
same catalogue is available with /or-models [query]. The tool must not invent
provider/model IDs. Explicit CLI equivalents remain available:
pi-tmux-agents start --task-file /tmp/task.md \
--implementer-provider anthropic \
--implementer-model claude-sonnet-4-6 \
--implementer-thinking high \
--reviewer-provider google \
--reviewer-model gemini-3.1-pro-preview \
--reviewer-thinking medium
When a session argument is omitted, status, watch, attach, send, and
stop list valid running orchestrations in a Pi selector showing session and
project. Choosing one passes its exact session name to the authoritative CLI;
providing a session argument still bypasses the picker.
The tmux_orchestrator model tool provides bounded doctor, list, status,
watch, attach, start, and send actions. Start requires interactive
confirmation. The Pi session that invokes start is the parent supervisor; a
run creates only the detached worker grid and does not start another parent Pi,
parent window, or controller. New runs are watched automatically. watch
subscribes that invoking Pi to lifecycle/final updates without changing the
terminal. attach (or /orchestrator-attach SESSION) switches its existing
tmux client into the worker grid after ensuring observation. Use normal tmux
pane keys to select a subagent and type directly into its native Pi editor.
Press the tmux prefix followed by L to detach from the grid and return to the
same invoking Pi; the orchestration keeps running and can be reattached.
Native Pi TUI workers are the interactive default, preserving Pi's highlighting,
tool rendering, and input field in every subagent pane. Plain RPC panes remain
an explicit headless automation option only. The parent receives visible
lifecycle/report-received progress and a triggered structured update when the
broker reaches ready, needs_attention, or uncertain. Parent project trust
is never inherited by child Pi sessions; child --approve needs separate
confirmation. For natural-language starts, the parent can synthesize an optional
structured contextCapsule from its existing conversation without another
model call. The capsule carries only task-relevant current state, settled
decisions, constraints, acceptance criteria, paths, evidence, open questions,
and out-of-scope items—never the complete parent transcript.
Start from the terminal
cat > /tmp/pi-agent-task.md <<'TASK'
Implement the requested change, add focused tests, run verification, and stop
after independent review approval.
TASK
cat > /tmp/pi-agent-context.md <<'CONTEXT'
### Current state
A focused branch already contains the reviewed scaffolding.
### Decisions already made
- Preserve broker-v1 as the only workflow transport.
### Acceptance criteria
- Add focused regressions and preserve metadata-only durable state.
CONTEXT
pi-tmux-agents start \
--project "$PWD" \
--task-file /tmp/pi-agent-task.md \
--context-capsule-file /tmp/pi-agent-context.md \
--attach
The context capsule is limited to 12 KiB, transferred through a private file, and deleted after baseline delivery. Its body is excluded from SQLite, status, registries, dashboards, and the Supervisor API. The live broker retains the rendered per-role baseline only in memory so a confirmed worker handover can replay it; the worker Pi session retains every delivery in its complete JSONL history.
Add specialists:
pi-tmux-agents start \
--project "$PWD" \
--task-file /tmp/pi-agent-task.md \
--with-probe --probe-task-file /tmp/pi-agent-probe.md \
--with-playwright --playwright-task-file /tmp/pi-agent-playwright.md \
--with-django-expert --django-task-file /tmp/pi-agent-django.md
Use --rpc-workers only when plain headless RPC event panes are explicitly
needed for automation. They render assistant progress plus bounded tool inputs
and outputs, but they do not reproduce Pi's native interactive editor or visual
presentation. Native TUI is the default and is the required presentation for
full visual navigation and direct subagent input. Both presentations use the
same broker and bridge; --rpc-workers is not a legacy coordination mode.
Use --approve-project only after inspecting and trusting the target project.
RPC workers otherwise apply Pi's saved/global trust behavior and cannot display
startup trust dialogs.
Event-driven workflow
- Bridges connect and authenticate independently.
- Broker stores the task plus optional bounded parent context capsule in each Pi session without waking idle roles.
- Only implementer and optional initial probe are triggered.
- Implementer submits a bounded
implementationreport throughorchestrator_report; the tool terminates the turn. - Enabled specialists inspect the worktree and submit typed evidence.
- Broker replaces prior evidence deliveries with one bounded run-state capsule containing only the latest accepted report per role, then wakes reviewer exactly once. Updates for a role already working are coalesced until its next assignment.
- Each newly accepted assignment emits one metadata-only
context_boundaryevent. That boundary changes the projection policy used on every provider request: the worker keeps the baseline, latest run state, assignment, direct messages, and all assistant/tool turns from the new assignment while pruning only prior-assignment assistant/tool turns. - A confirmed role restart advances a broker generation, replays the in-memory baseline, and materializes the latest coalesced run state—including an update deferred during the active assignment—before recovering that assignment. A failed local respawn or interrupted replacement recovery is
uncertain. approvedmarks the workflow ready without an acknowledgement-only worker turn.- An attached parent observer shows lifecycle and report-received progress, then returns the latest structured role reports when the run is ready or requires intervention.
Idle workers end their turns. They do not sleep or poll. A parent with an
attached observer also ends its turn and relies on broker updates instead of
sleeping or repeatedly polling status/tmux. Non-terminal updates remain
non-triggering while steering an already-active parent before its next model
step; terminal updates may trigger parent reasoning. A worker settling without
a report becomes waiting/needs attention rather than entering an unlimited
reminder loop. Pi invokes the worker context-projection hook for every provider
request, but its pruning policy changes only at a distinct assignment boundary.
Repeated projections retain every assistant/tool turn from the current
assignment, and Pi's durable worker session history remains intact. A deterministic two-round
synthetic regression currently reduces serialized provider-visible message
characters from 99,170 to 8,678 (91.2%) and enforces a minimum 50% reduction in
CI. This is a reproducible character metric, not provider token acceptance; real
token usage remains provider-reported and visible in the dashboard/Supervisor API.
Manage grids
pi-tmux-agents list
pi-tmux-agents status SESSION
pi-tmux-agents attach SESSION
pi-tmux-agents send SESSION --role implementer --message-file /tmp/message.txt
pi-tmux-agents send SESSION --role reviewer --delivery follow-up \
--command-id 0123456789abcdef0123456789abcdef \
--message-file /tmp/review-message.txt
pi-tmux-agents abort SESSION --role implementer
pi-tmux-agents restart SESSION --role implementer --yes
pi-tmux-agents stop SESSION --yes
When the invoking Pi is already inside tmux, /orchestrator-attach SESSION
performs the exact client switch without replacing or stopping that Pi. Prefix
then L detaches the client from the grid by returning it to the invoking Pi;
it does not stop the workers. Attach and detach can be repeated while the run is
live.
Acknowledgement means acceptance, not completion. Matching role/action/delivery
command IDs deduplicate; conflicting reuse is rejected. Confirmed restart
respawns the worker process and reopens its exact Pi session ID, preserving the
conversation and complete JSONL history. A failed respawn or crash in an
unprovable delivery or replacement-handover window becomes uncertain; there is
no exactly-once claim.
Supervisor API v2
pi-tmux-agents --json supervisor capabilities
pi-tmux-agents --json supervisor sessions
pi-tmux-agents --json supervisor runs SESSION
pi-tmux-agents --json supervisor snapshot SESSION --run RUN_ID
pi-tmux-agents --json supervisor events SESSION --run RUN_ID \
--cursor implementer=0 --cursor reviewer=0 --limit 50
pi-tmux-agents --json supervisor command SESSION --run RUN_ID \
--role reviewer --command-id COMMAND_ID
Retained-state reads do not query tmux and never infer liveness from retained
PIDs. Host runtime is reported as not_observed. Snapshot/status include role
lifecycle, workflow round/state, actual provider usage totals when available,
and context pressure without workflow payload bodies.
Durable state and compatibility
Run state is private and external to target repositories:
~/.pi/agent/orchestrations/<session>/<run>/
Files are retained for manifests, authentication, complete Pi JSONL sessions, metadata-only SQLite, and a transient startup payload deleted after broker ingestion. Baselines, bounded latest-per-role evidence, and rolling run-state bodies needed for a confirmed handover remain only in live broker memory and Pi sessions. Attached-parent report bodies are likewise ephemeral in broker memory and become durable only in Pi sessions; none enter SQLite, status, journals, registries, or Supervisor API output. Newly started workers never create or poll task/handoff/review/specialist payload files or readiness markers.
Retained 0.4.x runs remain readable and operable through compatibility code.
Every 0.5.0 start creates manifest v3 with coordination: "broker-v1"; there
is no selectable legacy fallback.
Token policy
The bridge sums actual Pi/provider-reported input, output, cache-read, cache-write, optional reasoning tokens, and cost across complete durable history. It separately exposes current provider-context occupancy when Pi makes it available. Missing data remains unavailable; the orchestrator does not invent estimates.
Structural savings include no waiting turns, no polling, no copied diffs/logs, one reviewer wake after all evidence, no approval acknowledgement turn, and terminating report calls. Soft role/run budgets warn before additional work. No budget can stop an already-started provider response at an exact token.
Persistent controller
pi-tmux-agents controller start
pi-tmux-agents controller status
pi-tmux-agents controller attach
pi-tmux-agents controller stop --confirm
The optional controller uses stable Pi session ID
pi-tmux-orchestrator-controller-v1, a private project-neutral workspace, and
no edit/write tools. It exists only after an explicit controller start; a
normal orchestration never creates it. It can serve as the parent Pi for
cross-project runs; the invoking project Pi is the interactive parent otherwise.
Every target project must be explicit. Duplicate or unmarked reserved tmux names
are refused.
Safety model
- One writer; independent read-only reviewers retain
bashand are not an OS sandbox. - Exact tmux targets; existing sessions are never replaced.
- Private canonical non-symlink state paths and strict schemas.
- Owner-only local socket with per-role and control authentication.
- Role-specific structured report ACLs and bounded frames/fields.
- Metadata-only status, SQLite, journals, registries, and Supervisor API.
- No Pi/provider credential access or copying.
- No synthetic-as-production acceptance claims.
- Explicit trust, restart, abort, and stop boundaries.
- Failure ambiguity is
uncertain, never blind replay.
See SECURITY.md and usage reference.
JSON CLI
Place --json before or after a public command for one schema-v1 envelope:
{"schema_version":"1","command":"status","success":true,"data":{},"error":null}
The outer JSON envelope remains version 1; Supervisor API versioning is independent. Payload bodies are never returned.
Author and license
Created and maintained by Revaz Zakalashvili. Contact: revaz.zakalashvili@gmail.com. Licensed under the MIT License.
Development
python -m pip install ruff==0.11.11
scripts/test.sh
Checks are model-free and isolate package/Pi/npm state from real authentication.