feat(watch): quick actions — kill pane, abort turn, copy prompt, help overlay#34
Merged
Conversation
… overlay
Promote `muxa watch` from a read-only picker into a command center
without leaving the table. Four new keybindings act on the currently-
selected row:
c — copy the agent's `last_prompt` to the system clipboard
(pbcopy / wl-copy / xclip in order, with a `/tmp/muxa-clip-*.txt`
fallback when none are present).
K — kill the pane via `tmux kill-pane -t <pane_id>`. Capital so a
fat-fingered `k` (move cursor up) can't blow up a pane.
R — abort the current turn by sending Ctrl-C to the pane. Also
capital. Spec originally framed this as "restart"; reduced
to "abort" because we don't reliably know the original launch
command across Claude / Codex / Gemini wrappers.
? — toggle a help overlay listing every keybinding.
Destructive actions (`K`, `R`) gate on a y/N confirm popup that
defaults to "No" — only `y` / `Y` / Enter accept; Esc / Tab / arrow
keys / any other character cancels. The popup is a centred ratatui
rect over the table, mirroring the existing `p` preview-popup pattern.
Action dispatch is split: a `QuickAction` enum + `dispatch_quick_action`
helper that takes a `&mut dyn Effects` so unit tests can record calls
without ever shelling out to tmux or the clipboard binaries. Outcome
lands in a ~2 s transient footer hint (`✔ killed pane main:2.0`,
`✗ kill-pane failed: …`, `✔ copied prompt via pbcopy`).
Disabled actions (e.g. `K` on a paneless agent row, `c` on a row with
no `last_prompt`) surface a one-line "not applicable" hint instead of
silently doing nothing — avoids the "I pressed the key, nothing
happened" failure mode.
Tests cover the action selection logic (`kill_action_disabled_for_paneless_row`,
`copy_action_uses_last_prompt`), the confirm popup state machine
(`confirm_popup_y_proceeds`, `_n_cancels`, `_esc_tab_arrow_all_cancel`,
`_enter_proceeds`), and the help overlay (`help_overlay_lists_every_binding`
snapshot).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ith feat/webhook-sink
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
Promote
muxa watchfrom a read-only picker into a command center.Power users can now act on a selected agent row without leaving the
TUI:
c— copy the agent'slast_promptto the system clipboard(
pbcopy→wl-copy→xclipin order, falling back to/tmp/muxa-clip-<ts>.txtwhen none are present).K— kill the pane viatmux kill-pane -t <pane_id>.R— abort the current turn by sending Ctrl-C to the pane.?— toggle a help overlay listing every keybinding.Keybindings
cKR?K/Rare capital — Shift required so accidentalk(cursor up)or
r(refresh) presses don't blow up a pane or interrupt an agent.Safety
No. Only
y/Y/ Enter accept;n, Esc, Tab, arrow keys,q, even the same key that opened it — anything else cancels.Kon a paneless agent,con a row with nolast_prompt) surface a one-line "not applicable" hint in thefooter rather than silently doing nothing.
(
✔ killed pane main:2.0,✗ kill-pane failed: …,✔ copied prompt via pbcopy).Design choices
QuickActionenum is whathandle_eventreturns; a separatedispatch_quick_actionhelper executes it via a&mut dyn Effectstrait. Unit tests inject a
RecorderEffectsstub instead ofshelling out to tmux / xclip — fast, hermetic, and lets us cover
the success / failure / fallback paths.
centered_rect+Clear+Paragraphpattern as the existingpreview overlay.
Ris "abort current turn", not "restart". The spec calledfor re-launching the original command after Ctrl-C, but we don't
reliably know that command across the Claude / Codex / Gemini
wrappers. Pragmatic version is just to send Ctrl-C; users can
retype the launch.
Test plan
cargo build --workspacecargo test --workspace(15 new tests, all passing)cargo clippy --workspace --all-targets -- -D warningscargo fmt --all -- --checkmuxa watch, navigate to a Claude row, press?and verify the overlay lists every bindingKon a pane-bearing row → confirm popup appears→ press
n→ popup closes, pane survivesKagain → pressy→ pane dies, footer shows✔ killed pane …for ~2 scon a row with a prompt → footer shows✔ copied prompt via …; verify clipboard contains the promptKon a paneless row → footer showskill: no tmux pane on this row🤖 Generated with Claude Code