cmux-tui: status indicators (loading fields, owned auto-clear, terminal busy, cmux status)
Status indicators, daemon and CLI side (plans/cmux-next/status-indicators.md section 5; spec decisions U5-U9). The app only renders; these are the facts it renders.
What changes
-
workspace_status.settakes optionalstate(busy|success|error|waiting|info),progress,style,ttl_ms,owner {pid, terminal, agent_session},target_terminal,exit_code,duration_ms. Stored in the additive tableworkspace_status_meta(state/status_meta.rs). Callers that send only text, icon and color are unchanged, and their request fingerprint is the same as before. -
The daemon removes an owned entry in its own commit (
workspace_status.auto_clear, astate_upsertof the workspace status) when:- its TTL passes: one expiry thread sleeps until the earliest deadline, with backoff after a failed commit;
- its owner terminal exits: the session host's exit subscription;
- its owner process exits: kqueue
NOTE_EXITor pidfd.
A process owner must be running, is accepted only from a trusted local connection (
server.rs), and is recorded with the machine id and the kernel start time, so a reused pid never stands in for it. Watches resume at daemon start (state/status_owners.rs). -
terminal-activity-v1: terminal records carryextra.busy {since_ms}while a shell command runs between OSC 133 C and D. A new prompt clears stale OSC 9;4 progress. An exited terminal publishes neither (terminal_activity.rs). The client applies the "show after N s" setting. -
CLI (
cli/status.rs,cli/command/state/status_flags.rs):workspace status settakes--state,--progress 0.4|40%,--style,--ttl 30s,--pid,--owner terminal|none,--target-terminal,--exit-codeand--duration-ms.- New shorthand
cmux status set [KEY] --label T | clear [KEY] [--all] | list | run [--label] [--badge-ttl 8s] -- CMD. runmarks the entry busy, owned by its own pid, and runs CMD with the terminal's stdio. It forwards signals that another process sent, then records success or error with the exit code and duration. It exits with CMD's status, and re-raises CMD's terminating signal so a shell loop around it stops too.- The CLI never sends a notification. The app decides, from the duration and the terminal's visibility.
-
Catalog fields and binding descriptors are updated. The transport coverage test exercises every new field.
The owner's three changes from #16174 are applied:
- the daemon validates owners;
- the owner decides auto-clear in the same commit, with its own transaction;
- terminal facts sit on the terminal record, and waits go under the terminal noun.
Not in this PR
cmux status wait KEY, andcmux terminal <term> wait --until idle|prompt. Both need a new connection-owned wait op.exitandoutputalready exist asterminal <t> process waitandterminal <t> screen wait --pattern.- Agent-session-end auto-clear.
busyis not restored after a daemon restart: it shows idle until the next OSC 133 mark.- A terminal-owner watch holds the daemon while it blocks.
Verification (Blacksmith Testbox, Linux)
cargo test --lockedfor the whole workspace: all pass exceptsession_shutdown_exits_an_interactive_detached_owner_client. That test flakes on the base commit too (1 of 6 failed there).cargo clippy -p cmux-tui-core -p cmux-tui --all-targets -D warningsis clean.cargo fmt --checkis clean for this diff. The remaining diffs are incmux-tasksfrom the base branch.- End to end with a built daemon:
cmux status run --label Tests --badge-ttl 2s -- sh -c 'sleep 2; exit 3'shows busy with a pid owner while it runs, then error with exit code 3 and duration 2001 ms. The CLI exits 3, and the entry is gone after 2 s.printf '\e]9;4;1;40\a\e]133;C\a'in a terminal showsextra {busy: {since_ms}, progress: {state: normal, value: 40}}.
- A review subagent checked correctness against OWNERSHIP-PRINCIPLES. Its findings are fixed in 152e55e0161.
- macOS kqueue code is not run on the box (UNVERIFIED there).
๐ค Generated with Claude Code
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.
Summary by cubic
Adds loading-indicator metadata to workspace status entries with daemon-side auto-clear, plus a cmux status CLI and terminal busy facts from OSC 133 marks. Entries written by older clients (text/icon/color only) are unaffected, and the new data is stored in an additive table that older binaries ignore.
Status entries and auto-clear
workspace_status.setaccepts optionalstate,progress,style,ttl_ms,owner(pid, terminal, agent session),target_terminal,exit_code, andduration_ms, persisted in a newworkspace_status_metatable.- The daemon removes owned entries itself when the TTL passes (one expiry thread), the owner terminal exits, or the owner process exits, using kqueue/pidfd; process owners are recorded with their kernel start time and accepted only from trusted local connections.
- Busy state is not restored after a daemon restart โ the terminal shows idle until the next OSC 133 mark.
CLI and terminal facts
- New
cmux status set | clear | list | run:runmarks the entry busy and owned by its own pid, runs the command with the terminal's stdio, records success or error with exit code and duration, propagates the child's exit status and signals, and keeps the entry for a configurable badge TTL (default 8s). workspace status setgains matching flags (--state,--progress,--style,--ttl,--pid,--owner,--target-terminal,--exit-code,--duration-ms).- Terminal records publish
extra.busy {since_ms}between OSC 133 C and D; exited terminals publish neither busy nor progress. A new prompt clears stale OSC 9;4 progress.