Skip to content

Latest commit

 

History

History
91 lines (66 loc) · 5.08 KB

File metadata and controls

91 lines (66 loc) · 5.08 KB

tmux runtime backend

tmux is Firstmate's verified reference runtime backend and the fully supported baseline for secondmate homes. configuration.md owns shared backend selection and metadata semantics.

Setup

Install tmux with brew install tmux or your platform package manager. The universal harness and toolchain requirements are in configuration.md.

tmux is the hard default when no explicit setting or runtime auto-detection selects another backend. Select it explicitly with local config/backend containing tmux, with FM_BACKEND=tmux for one launch, or by asking Firstmate to use tmux. An explicit selection is also the opt-out from Herdr or cmux runtime auto-detection.

No provisioning is required before the first task.

Watching the crew

For the best visible experience, launch the primary harness inside a tmux session:

tmux new -s firstmate

Crew tasks become windows in that session. tmux display-message -p '#S' prints its name. If the primary harness runs outside tmux, Firstmate creates or reuses a detached session named firstmate:

tmux attach -t firstmate

Each task window is named fm-<id>.

tmux list-windows -t <session-name>
tmux select-window -t <session-name>:fm-<id>

Typing into an attached task window is authoritative direct intervention. Routine supervision does not require attachment: bin/fm-peek.sh <id> captures a bounded tail and FM_HOME=<home> bin/fm-send.sh <id> '<text>' steers the recorded endpoint.

Verify setup by spawning a small task and confirming its fm-<id> window appears in the selected session.

Current behavior and safety

A target-existence check proves only that the pane exists. The deeper tmux agent-liveness probe first verifies exact window membership, then reads #{pane_current_command} to distinguish a running harness process from a bare idle shell. It classifies recognized Claude, Codex, OpenCode, Pi, pi-signed, Grok, and Kimi process names as alive, common shells as dead, an authoritatively absent window as missing, unreadable state as unreadable, and every other process as ambiguous. Only dead and missing authorize recovery because a false dead result could launch a duplicate agent.

The verified Pi Launcher path reports the exact foreground command pi-launcher for both pi and pi-signed, while direct executable identities pi, pi-signed, and Pi remain accepted exactly. Similar or prefixed process names are not accepted through those exact Pi-family entries.

Agent liveness and composer safety are separate checks. For a bordered composer, the tmux reader locates the complete box structurally and classifies every content row through the shared ANSI and ghost handling in bin/fm-composer-lib.sh. Real text on any content row is pending, while only an unambiguous box with every row empty is proven empty. Unreadable, incomplete, or structurally ambiguous boxes fail closed, and panes without a bordered composer retain the compatible cursor-row classification. The shared classifier accepts a shell glyph as an empty agent composer only inside a verified bordered composer. A bare shell prompt is unknown, so away-mode escalation is never injected into a dead shell.

Rendered busy detection is also harness-scoped. Task metadata selects only that harness's verified signature, so output from one harness cannot make another harness appear busy. The exact selection contract and safety rationale live in architecture, while the signatures live in the harness-adapters skill.

bin/fm-tmux-lib.sh owns exact type-and-submit mechanics. It types a message once and retries Enter only until the composer clears. Only a proven empty composer is a positive delivery acknowledgement. Text left in established structure remains pending, text in ambiguous structure remains unproven, and unreadable or unsafe state remains unknown. fm-send.sh reports every unconfirmed verdict as a failure instead of retyping or assuming delivery.

OpenCode 1.18.4 has one busy-queue exception. While OpenCode is mid-turn, Enter queues the message but leaves its text visible until the turn completes. After the normal retry budget, only structurally proven pending text in a provably busy pane is accepted as queued, while an idle pane remains pending as a genuine swallowed Enter. Ambiguous pending text never receives the busy-queue conversion. tests/fm-tmux-submit-busy.test.sh covers busy and idle panes with proven, ambiguous, and cleared composers.

Limits and regression entry points

  • tmux is the reference path and supports secondmate homes.
  • The OpenCode busy-queue exception is tmux-specific; Herdr retains its separately documented gap.
tests/fm-backend-tmux-smoke.test.sh
tests/fm-composer-ghost.test.sh
tests/fm-kimi-harness.test.sh
tests/fm-tmux-submit-busy.test.sh
tests/fm-bootstrap.test.sh

verification/runtime-backends.md records the active foreground-process and submit evidence.