Running tray: background commands read in words, not shell

Merged
TE
2d ago
+950-19

Leo, 2026-11-03, on the running tray above the composer showing raw shell lines (glaeda-gh wait run manaflow-ai/cmux/41762593154 --until done --timeout 3000 2>..., python3 -c "import time; time.sleep(560)"; ...):

we should be able to parse these more... like instead of raw things, we should be able to deterministically/heuristically have stuff

What changes

A background command's tray line is now named, in this order:

  1. The call's own description. Claude's Bash description was already used when the transcript had the call loaded; a process whose call was not loaded (an older page, a long wait) fell back to the shell line. acpmux now keeps description on the process record (claude_stdio sends it on the shell's running update, hub/processes.rs stores and lists it, docs/background-processes.md), and the web side reads it from the registry. Codex sends no such field, so its commands use the rules.

  2. A declarative rule table, webviews/src/agent-session/acpmux/session-info/commandRules.ts (COMMAND_RULES: program, icon, and a reader that gives a pane string, its values and an optional link). Seed rules:

    • glaeda-gh wait run|pr → "Waiting on cmux checks" / "Waiting on cmux#34769 checks", linking the run or PR
    • gh pr merge N → "Merging #N" ("Merging cmux#N" with -R, linked); gh pr checks N --watch, gh pr create, gh run watch
    • cmux-ci test --setup playwright → "Fleet tests · Playwright"; cmux-ci test -- cargo test -p X → "Fleet tests · cargo test X"; cmux-ci run --key …-34769-… → "Fleet run for #34769"; cmux-ci compile-check
    • sleep N and python3 -c "import time; time.sleep(N)" → "Waiting 9m 20s"
    • git push, cargo test|build -p X, bun test FILE, xcodebuild -scheme S test|build

    Before matching, the command is cut to the one program that does the work: comments (# fg-ok), cd X &&, export/assignment steps, env/timeout N/nohup/nice wrappers, redirections, pipes (| tail -5) and later steps. One linear pass, quotes and $(...) kept whole.

  3. Its program and main argument (bun run dev, python3 merge_freeze.py, make), after #34679's commandWorkLabel for a line with command substitutions.

Builds on #34679 (merged while this was open): a setup step's substitution is still named before the rule's words, so SHA=$(git rev-parse HEAD); cmux-ci run … reads "git rev-parse HEAD · Fleet run" (it read "git rev-parse HEAD · cmux-ci run"); #34679's tray and gallery expectations change to that. A substitution inside the program's own arguments (--key x-$(date +%s)) is part of what the rule reads. commandLabel itself is unchanged.

Takes back #34679: only the outer operation's words in its two tray expectations ("cmux-ci run" → "Fleet run"), since the rule names it better; its substitution naming stays.

The raw command stays the line's tooltip, and the expanded tail now starts with it. A line whose rule names a run or pull request gets an "Open on GitHub" link in its tail. The per-row elapsed time is unchanged. New strings are in Localizable.xcstrings with every locale.

Gallery: agent-pane.subagent-tray → command-words (the commands from the screenshot, opened; its play checks the labels).

Tests

  • webviews/test/command-rules.test.ts: table-driven over real commands from the screenshot and agent transcripts, plus description precedence, the registry description, the program cutting and a linear-time check.
  • webviews/test/subagent-tray.test.tsx: the undescribed nice bun test line now reads "Running tests".
  • acpmux: the_running_update_carries_the_calls_description, a_description_round_trips_and_is_left_out_when_absent.

Observed / Not run

  • Fleet (cmux-ci test) at the pushed head: bun run check green, check:design-tokens green, 164 tests pass across command-rules, subagent-tray*, background-tasks-open, session-info*, summary-background-work and agent-pane-workflow-progress; strings-build-output passes.
  • acpmux on the fleet: cargo test -p acpmux --lib -- background_output process_index, 9 passed, including both new tests.
  • Review follow-up fixed: xcodebuild … clean/archive falls back instead of reading Building. Left as a follow-up: a background acpmux send keeps its send label ahead of its call's description, as before.
  • Not run: a gallery capture of command-words (the advisory gallery run covers it) or a DEV build.

Changelog

Changed: Background commands in the running tray read in words ("Waiting on cmux#34769 checks", "Fleet tests · Playwright", "Waiting 9m 20s") instead of the raw shell line, which stays in the tooltip.

🤖 Generated with Claude Code

Agent session: agent session