feat(tui): opt-in cmux tab auto-rename reflecting loop state - #102
Open
jitokim wants to merge 1 commit into
Open
feat(tui): opt-in cmux tab auto-rename reflecting loop state#102jitokim wants to merge 1 commit into
jitokim wants to merge 1 commit into
Conversation
The captain runs many cmux tabs and renames each by hand to the task. fleetops
already knows each loop's state, goal, and (since v0.9.0) what it's delegating to
a subagent — so it can write that to the cmux tab strip, killing the manual step.
This is "fleetops goes to where the captain already looks (the tab strip)" rather
than "make the captain open fleetops" (see .notes/pivot.md).
First slice — opt-in, cmux-only, fail-closed:
- `--rename-tabs` flag, default OFF. Observation stays pure unless opted in.
- New optional `control.TabTitler` interface (mirrors TerminalOpener/TTYLocator),
implemented by cmuxController only: `cmux rename-tab --surface <ref> -- <title>`
(same-workspace; title positional after `--`). The exec goes through an
injectable `cmuxTabRunner` seam defaulting to runWithTimeout (5s bound), so it
is unit-tested without a live cmux and a wedged cmux can never hang a tick.
- Title composer (pure): glyph + state token (StateString, includes stall slug) +
short DisplayLabel truncated to ~18 cols; delegation wins ("▸deleg code-reviewer").
- Presentation-sync driver on the scan tick: debounced (per-session last-title
ledger, advanced only on a CONFIRMED write — ambiguous/failed writes retry next
tick), and only for unambiguously-mapped cmux loops (reuses the actuation
ambiguity refusal — ambiguous ⇒ skip, never rename a guessed tab).
- Honesty: delegation is detected only against claude.formatDelegating's
authoritative boundaries, so a raw tail literally starting with "delegating…"
can't fabricate a delegation on the tab.
ResolveActuationTarget was refactored (extracted tierOneAAcross/tierOneBAcross) so
tab-title resolution reuses the exact tier-1a/1b locate + ambiguity rule instead of
reimplementing it — behavior-preserving (all pre-existing ResolveActuationTarget
tests unchanged and green). Not routed through internal/control/actuate: a tab
rename writes terminal chrome, not a keystroke into the session.
Tests: go test ./... -race green (20 pkgs); new tests cover argv/error, resolver
ambiguity/tty/non-cmux, composer table, driver gate/debounce/mixed-batch.
NOT YET VERIFIED against a live cmux binary (none on this box): that `rename-tab`
exists with `--surface <ref>` + positional title, that omitting `--window` scopes
to the caller's workspace, and that a bad surface ref exits non-zero. This is the
merge gate — confirm with `cmux rename-tab --help` before merging.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: jitokim <pigberger70@gmail.com>
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.
Summary
The captain runs many cmux tabs and renames each by hand to the task name (his workflow, step 4). fleetops already knows each loop's state, goal, and — since v0.9.0 — what subagent it's delegating to. So it can write that to the cmux tab strip, killing the manual step. This is the first concrete step of the pivot: "fleetops goes to where the captain already looks (the tab strip)" rather than "make the captain open fleetops." (Full rationale:
.notes/pivot.md.)First slice — opt-in, cmux-only, fail-closed
--rename-tabsflag, default OFF. Observation stays pure unless opted in.control.TabTitlerinterface (mirrorsTerminalOpener/TTYLocator), implemented bycmuxControlleronly:cmux rename-tab --surface <ref> -- <title>(same-workspace; title positional after--). Exec goes through an injectablecmuxTabRunnerseam defaulting torunWithTimeout(5s bound) — unit-tested without a live cmux, and a wedged cmux can never hang the 3s tick.StateString, includes stall slug) + shortDisplayLabel(~18 cols). Delegation wins:▸deleg code-reviewer. Examples:◆GATE auth-mw·⏸STALL rate-limit fx·✗DRIFT auth-mw.claude.formatDelegating's authoritative boundaries, so a raw tail literally starting with "delegating…" can't fabricate a delegation on the tab.Design decisions
ResolveActuationTarget(extractedtierOneAAcross/tierOneBAcross) so tab-title resolution reuses the exact tier-1a/1b locate + ambiguity rule instead of reimplementing it. Behavior-preserving — all 14 pre-existingResolveActuationTargettests unchanged and green (independently verified).internal/control/actuate: a tab rename writes terminal chrome, not a keystroke into the session — it has no Delivered/Tier2/DeliveryUnknown outcome space, so folding it into that Verdict/Dispatch seam would violate its switch-totality design. It borrows that seam's discipline (ambiguity refusal, bounded exec), not its types.테스트 결과
go test ./... -race: 20/20 packages ✅New tests: cmux argv/error propagation + default-seam-is-bounded, resolver ambiguity/tty/non-cmux/no-match, composer table (per state + truncation + delegation precedence + prose-negative), driver gate-off/debounce/mixed-batch.
go vet/gofmtclean.Review trail
Design (architect, pivot §5.1) → implement → developer self-run deep review (fixed honesty W1: prose can't fake delegation) → independent quality gate: PASSED, actuation refactor verified behavior-preserving against untouched test suite, Critical 0.
This box has no cmux binary, so every test asserts what fleetops builds, not what cmux accepts. Before merging, confirm on a machine with cmux:
cmux rename-tab --help— the subcommand exists with--surface <ref>+ positional title after--.--windowscopes to the caller's workspace.Then run
fleetops --rename-tabsand watch a tab update. Until that's confirmed, do not merge (terminal write on sessions fleetops didn't spawn).Out of v1 (follow-ups)
Cross-workspace rename (needs
workspace:ref capture), tmux/iTerm2/orca titlers (same interface), restore-on-exit (cmux has no clear-to-default today).🤖 Generated with Claude Code