Skip to content

feat(bin): orchestrator dashboard layout with swappable worker watch panes and reference picker#114

Open
MerpGoaterman wants to merge 6 commits into
kunchenguid:mainfrom
MerpGoaterman:fm/worker-ref-shortcut-w4
Open

feat(bin): orchestrator dashboard layout with swappable worker watch panes and reference picker#114
MerpGoaterman wants to merge 6 commits into
kunchenguid:mainfrom
MerpGoaterman:fm/worker-ref-shortcut-w4

Conversation

@MerpGoaterman

Copy link
Copy Markdown

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

  • Added bin/fm-layout.sh, bin/fm-layout-lib.sh, and bin/fm-watch-pane.sh to 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.
  • Added a worker-reference shortcut: bin/fm-layout-pick.sh lists current workers by short, human-readable names and fm-layout.sh inserts the selected reference (or sends it) into the composer pane, bound to a prefix-key chord; the reference format defaults to the short fm-<id> window form and is configurable via FM_LAYOUT_REF_FORMAT.
  • Hardened the picker for the macOS bash 3.2 default shell (safe empty-array expansion so a zero-worker picker exits cleanly), and added tests/fm-layout.test.sh plus documentation in docs/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.sh suite 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 the prefix # chord being wired by bind. 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)

$ # --- The captain types `prefix #` in the orchestrator composer. The picker
$ #     lists current workers by short, human-readable names (like an @ / picker).
$ 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

$ # Each row: menu-key <TAB> tmux-target <TAB> reference token that gets typed.
$ #     Note the secondmate (fm-triage-dd) is excluded - only real workers listed.
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)

$ # Captain typed "please rebase ", opened the # picker, selected worker 3,
$ #     then kept typing. The composer now reads:

    ┌─ orchestrator composer ─────────────────────────────────┐
    │ please rebase fm-login-fix-k3 onto main and rerun CI
    └─────────────────────────────────────────────────────────┘

$ # The short, readable worker reference "fm-login-fix-k3" was inserted
$ #     mid-message (with a trailing space) - no hand-copying a tmux target.
Evidence: Dead-worker safety: nothing typed for a non-live worker
$ # Safety: selecting/targeting a worker that is no longer live types nothing.
$ fm-layout.sh insert-ref -p %composer -w firstmate:fm-ghost-xx
composer after (no "fm-ghost-xx" appears):
    please rebase fm-login-fix-k3 onto main and rerun CI
    please rebase fm-login-fix-k3 onto main and rerun CI
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}'"

$ fm-layout.sh bind   (run from inside the firstmate tmux session)
bound: prefix+O = arrange/refresh, prefix+P = pick worker, prefix+# = insert worker reference

$ tmux list-keys | grep "fm-layout.sh ref"   # the prefix # chord is now live:
bind-key  -T prefix  \#  run-shell ".../bin/fm-layout.sh ref -p '#{pane_id}' -c '#{client_name}'"

# Captain presses `prefix #` in the orchestrator composer -> picker opens ->
# pick a worker -> its short reference is typed into the composer.

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 iterates for row in &#34;${WORKERS[@]}&#34; (lines 38 and 52) under set -u. On bash 3.2.57 (the macOS default shell this branch's prior commit explicitly hardened for), iterating an empty array with set -u aborts with WORKERS[@]: 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 &#34;${WORKERS[@]+&#34;${WORKERS[@]}&#34;}&#34; on both loops, or exit/guard after the empty message.
  • ℹ️ bin/fm-layout.sh:50 - bind maps prefix # (KEY_REF default #), which overrides tmux's built-in prefix # = list-buffers binding, and unbind leaves # 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 full firstmate:fm-&lt;long-id&gt; 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 (window format yields the shorter fm-&lt;id&gt;) 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 --print listing/exclusion, insert-ref typing into a real composer pane, dead-worker rejection)
  • Manual end-to-end on a private tmux socket: fm-layout.sh ref --print -p %composer lists 3 live workers by short names, excludes the secondmate
  • Manual: fm-layout.sh insert-ref -p &lt;composer&gt; -w firstmate:fm-login-fix-k3 inserts fm-login-fix-k3 mid-message into a live composer pane (captured: please rebase fm-login-fix-k3 onto main and rerun CI)
  • Manual: insert-ref targeting a non-live worker (fm-ghost-xx) types nothing
  • Manual on bash 3.2.57: fm-layout.sh ref --print with zero workers exits 0 with no output (review-fix for the empty-array crash)
  • Manual: fm-layout.sh bind from inside tmux reports the prefix+# binding and tmux list-keys confirms the prefix # chord runs fm-layout.sh ref
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

…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.
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant