feat(bin): orchestrator dashboard layout with swappable worker watch panes and reference picker#114
Open
MerpGoaterman wants to merge 6 commits into
Open
Conversation
…panes Add fm-layout.sh to arrange the firstmate window into a left command column (orchestrator chat top 2/3, terse active-worker summary bottom 1/3) and a right 2/3 column of three stacked worker watch slots. Watch slots are read-only capture-pane mirrors of live worker windows, so workers keep running untouched; the orchestrator pane stays focused and is never replaced or obscured. Workers are discovered from state/*.meta (live windows only; secondmates and stale metas excluded) with a terse repo + feature label. Slots autofill from the first active workers and any worker can be swapped into any slot via a reliable keyboard picker popup (fm-layout-pick.sh); right-click reassignment is offered as an opt-in, documented best-effort path given tmux's server-global key tables. arrange is safe to re-run: it rebuilds only its own viewer panes, never kills a worker or unrecognized pane, refuses worker windows and windows with unexpected panes, and never spawns work to fill a slot. Keybindings are opt-in and runtime-only (never ~/.tmux.conf). Covered by tests/fm-layout.test.sh (real tmux on a private socket): discovery, label truncation, assign/clear/reject, geometry, idempotent re-run, refusals, and rendered summary/mirror content.
… document tmux 3.1 requirement
Add a #-style worker picker to the dashboard. `fm-layout.sh bind` wires `prefix #` to a tmux display-menu of live workers (keyboard 1-9/arrows and mouse-clickable, like an @// picker); choosing one types that worker's reference straight into the composer pane via send-keys, so the captain stops hand-copying terminal targets. A bare # typed in a composer cannot be intercepted reliably - agent TUIs expose no custom-trigger hook, cmux's shortcuts only rebind its own actions (and its control socket is password-gated), and trapping literal # at the tmux root table would hijack every # keystroke. So this uses a prefix chord, documented with the full feasibility rationale. New subcommands: `ref` (open the picker, -p pane / -c client / --print) and `insert-ref -p <pane> -w <window>` (validate the worker is live, then type its reference). FM_LAYOUT_REF_FORMAT selects target|window|select; the same reference shows in each watch pane header. cmux's `cmux send` is documented as an optional delivery path. Covered by tests/fm-layout.test.sh (ref formats, ref --print listing/exclusion, insert-ref typing into a pane, dead-worker rejection). Based on the PR kunchenguid#110 dashboard branch; ships as its own PR.
…ref to window form
… agreement note for window default
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
The developer (the orchestrator/captain) asked for a durable worker-reference shortcut for their Firstmate terminal dashboard, framed as a follow-up to already-completed orchestrator dashboard work. The desired UX was that typing # would open a picker of the current worker list, similar to @ or / pickers in agent composers, so the captain could write messages that reference and route to a selected worker without manually copying terminal targets. They asked the agent to first investigate feasibility across cmux/OpenCode/Codex/Claude terminal contexts, and if direct interception of # in agent composers was not possible, to implement the closest practical workflow: a command/shortcut/picker that lists current workers by short, human-readable names and inserts or sends the selected worker reference, with documentation. They explicitly required keeping worker names short and readable, doing the work cleanly on a separate branch/PR rather than mixing unsafe state into the finished dashboard PR, and reporting feasibility, implementation, and validation clearly. Across the broader session the developer also wanted off-screen workers made visible, and directed clearing the blocking PR and updating no-mistakes to v1.31.2 so validation could proceed.
What Changed
bin/fm-layout.sh,bin/fm-layout-lib.sh, andbin/fm-watch-pane.shto build a tmux orchestrator dashboard whose side panes watch live workers and can be swapped between them, surfacing off-screen workers without leaving the composer.bin/fm-layout-pick.shlists current workers by short, human-readable names andfm-layout.shinserts the selected reference (or sends it) into the composer pane, bound to aprefix-key chord; the reference format defaults to the shortfm-<id>window form and is configurable viaFM_LAYOUT_REF_FORMAT.tests/fm-layout.test.shplus documentation indocs/orchestrator-layout.md,docs/configuration.md,docs/scripts.md, and the README.Risk Assessment
✅ Low: Well-bounded, additive tmux-layout tooling with no behavior changes to existing supervision code; both prior-round errors are verifiably fixed, the new worker-reference path is read-only toward workers and well-tested, and helpers are bash-3.2 safe.
Testing
Ran the full
tests/fm-layout.test.shsuite against a real tmux (8/8 pass) and additionally drove the feature manually to produce reviewer-visible CLI/tmux transcripts: the picker listing workers by short readable names with the secondmate excluded, the selected reference being typed live into a composer pane mid-message, the dead-worker safety path typing nothing, the empty-picker not crashing on the system bash 3.2 (the review fix), and theprefix #chord being wired bybind. This is a tmux/terminal CLI surface with no rendered web/graphical UI, so evidence is captured as tmux pane captures and command transcripts rather than screenshots - that is the actual end-user surface here. All checks passed and the working tree was left clean.Evidence: Picker lists current workers by short names (secondmate excluded)
$ fm-layout.sh ref --print -p %composer 1 firstmate:fm-api-audit-p7 fm-api-audit-p7 2 firstmate:fm-cache-bug-z2 fm-cache-bug-z2 3 firstmate:fm-login-fix-k3 fm-login-fix-k3 (secondmate fm-triage-dd excluded)Evidence: Selected reference typed into the composer pane mid-message
composer reads: please rebase fm-login-fix-k3 onto main and rerun CI (short readable worker ref inserted mid-message with a trailing space; no hand-copied tmux target)Evidence: Dead-worker safety: nothing typed for a non-live worker
Evidence: bind wires the prefix # chord
bound: prefix+O = arrange/refresh, prefix+P = pick worker, prefix+# = insert worker reference bind-key -T prefix # run-shell ".../bin/fm-layout.sh ref -p '#{pane_id}' -c '#{client_name}'"Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 3 issues found → auto-fixed ✅
bin/fm-layout-pick.sh:38- fm-layout-pick.sh iteratesfor row in "${WORKERS[@]}"(lines 38 and 52) underset -u. On bash 3.2.57 (the macOS default shell this branch's prior commit explicitly hardened for), iterating an empty array withset -uaborts withWORKERS[@]: unbound variable(verified directly on the system bash). When no workers are live, the empty-workers branch at line 34 prints its message but does not exit, so control falls into the line-38 loop and the picker crashes before it can show "0) clear this slot" or read a choice. The picker is documented as the dependable path that "works on any tmux/terminal". Fix mechanically with the safe expansion"${WORKERS[@]+"${WORKERS[@]}"}"on both loops, or exit/guard after the empty message.bin/fm-layout.sh:50-bindmapsprefix #(KEY_REF default#), which overrides tmux's built-inprefix #= list-buffers binding, andunbindleaves#unbound rather than restoring the default. The in-code comment "Opt-in prefix keys (capitals, not default tmux bindings)" applies to O/P but not to#, which is a tmux default. This is an opt-in, documented tradeoff; noting for awareness.bin/fm-layout.sh:51- The worker-reference picker defaults to FM_LAYOUT_REF_FORMAT=target, inserting the fullfirstmate:fm-<long-id>tmux target into the composer. The captain's stated requirement emphasized short, human-readable names; the inserted token is the routing target, not the readable label shown in the menu. This is configurable (windowformat yields the shorterfm-<id>) and documented, so flagging only to confirm the default matches intent.🔧 Fix: fix bash 3.2 empty-picker crash, default worker-ref to window form
✅ Re-checked - no issues remain.
✅ **Test** - passed
✅ No issues found.
bash tests/fm-layout.test.sh(8/8 ok, including the worker-reference picker block: ref formats,ref --printlisting/exclusion,insert-reftyping into a real composer pane, dead-worker rejection)Manual end-to-end on a private tmux socket:fm-layout.sh ref --print -p %composerlists 3 live workers by short names, excludes the secondmateManual:fm-layout.sh insert-ref -p <composer> -w firstmate:fm-login-fix-k3insertsfm-login-fix-k3mid-message into a live composer pane (captured:please rebase fm-login-fix-k3 onto main and rerun CI)Manual:insert-reftargeting a non-live worker (fm-ghost-xx) types nothingManual on bash 3.2.57:fm-layout.sh ref --printwith zero workers exits 0 with no output (review-fix for the empty-array crash)Manual:fm-layout.sh bindfrom inside tmux reports theprefix+#binding andtmux list-keysconfirms theprefix #chord runsfm-layout.sh ref✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.