Help us improve
Share bugs, ideas, or general feedback.
Debug interactive CLIs, REPLs, TUIs, watchers, and long-running terminal processes using tmux to preserve live state, send controlled input, and capture evidence. Use when commands hang, wait for input, or behave differently in a real terminal.
npx claudepluginhub esonhugh/marketplace --plugin detectiveHow this skill is triggered — by the user, by Claude, or both
Slash command
/macos-control-bypasser:interactive-cli-systemic-debuggingThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Use tmux as an observation lab for interactive terminal programs. Preserve the live process, inspect real screen state, send controlled input, capture evidence, and change one variable at a time.
Automates interactive terminal programs (REPLs, debuggers, TUIs) via PTY. Start sessions, type text/keystrokes, wait for screen stability, snapshot output, and manage multiple sessions.
Runs interactive CLI tools (vim, git rebase -i, REPLs) via tmux detached sessions with send-keys and capture-pane for programmatic control when standard bash piping fails.
Renders a prepared tmux layout for operator-side observability of session side-channels (STATE.md tail, CI watch, events.jsonl tail). Default 4-pane layout or debug layout. Read-only — coordinator chat stays in original terminal.
Share bugs, ideas, or general feedback.
Use tmux as an observation lab for interactive terminal programs. Preserve the live process, inspect real screen state, send controlled input, capture evidence, and change one variable at a time.
Interactive CLI failures often disappear when forced into a single Bash call because prompts, timing, ANSI rendering, stdin state, and background output matter. tmux keeps those signals visible and makes the debugging loop reproducible.
Apply this workflow for:
Do not use tmux for a simple deterministic command that exits quickly and has complete stdout/stderr evidence. Run the command normally instead.
Before starting tmux, write down:
If the target is unclear, ask one focused question or inspect the project enough to identify the command.
Use a descriptive, collision-resistant name:
tmux new-session -d -s cli-debug-<topic> -x 120 -y 40
Prefer a stable 120x40 viewport unless the bug is size-dependent. For size bugs, record the chosen dimensions.
Send commands exactly as a user would type them:
tmux send-keys -t cli-debug-<topic> '<command>' Enter
Avoid piping input or adding flags that change interactivity unless that is the hypothesis being tested.
Capture the pane before sending more input:
tmux capture-pane -p -t cli-debug-<topic> -S -200
Read the captured output as evidence. Look for prompts, partial lines, cursor position clues, warnings, stack traces, progress states, and whether the process is waiting for input.
Send one input at a time, then recapture:
tmux send-keys -t cli-debug-<topic> 'help' Enter
tmux capture-pane -p -t cli-debug-<topic> -S -200
For special keys, use tmux key names:
tmux send-keys -t cli-debug-<topic> C-c
tmux send-keys -t cli-debug-<topic> Escape
tmux send-keys -t cli-debug-<topic> Down Enter
Wait for the program to react before the next input. If timing matters, use short sleeps only as observation delays, not as proof of correctness.
When an observation matters, save it to a file:
tmux capture-pane -p -t cli-debug-<topic> -S -1000 > /tmp/cli-debug-<topic>.log
Reference saved logs or relevant excerpts when explaining findings. Evidence should support every conclusion about what happened.
Keep separate panes or sessions for comparisons:
tmux split-window -h -t cli-debug-<topic>
tmux list-panes -t cli-debug-<topic>
tmux send-keys -t cli-debug-<topic>.1 '<variant-command>' Enter
Confirm pane IDs with tmux list-panes before targeting a specific pane. Change only one factor per run: environment variable, terminal size, command flag, input sequence, dependency version, config file, or code change. If two things changed, the result cannot identify the cause.
For each debugging pass, record:
Stop when the root cause is identified, the issue is reproduced reliably, or the next step requires user input.
| Need | Command |
|---|---|
| Create detached session | tmux new-session -d -s <name> -x 120 -y 40 |
| Run a command | tmux send-keys -t <name> '<command>' Enter |
| Capture recent output | tmux capture-pane -p -t <name> -S -200 |
| Capture full scrollback | tmux capture-pane -p -t <name> -S - |
| Send Ctrl-C | tmux send-keys -t <name> C-c |
| Resize session | tmux resize-window -t <name> -x <cols> -y <rows> |
| Split pane | tmux split-window -h -t <name> |
| List panes | tmux list-panes -t <name> |
| Kill session | tmux kill-session -t <name> |
Capture first. If the screen shows a prompt or cursor after a partial line, the process may be waiting for input rather than hung. Test with harmless input such as Enter, ?, or help only when appropriate for the program.
If no screen change occurs, check process state from outside tmux with ordinary diagnostic commands, then return to tmux for user-visible behavior.
Treat prompts as a state machine. Capture each state, send exactly one answer, and capture the next state. Do not paste a whole script of answers until the prompt sequence is known.
Record terminal size, $TERM, color mode, and whether the program uses alternate screen mode. Use tmux resizing to reproduce layout issues. Send named keys through tmux rather than embedding escape sequences by hand.
Start the watcher in tmux, capture the ready state, trigger one external change, then capture the reaction. Keep the watcher alive while editing or running client commands in another pane or normal shell.
Run repeated attempts in fresh sessions or panes with the same viewport and environment. Save logs per attempt. Compare the earliest divergence rather than only the final error.
| Mistake | Better approach |
|---|---|
Running the CLI in one Bash call and guessing why it hung | Start it in tmux and capture the live pane |
| Sending multiple inputs before observing | Send one input, capture, then decide |
| Treating lack of output as proof of a freeze | Check whether the program is waiting for input or drawing in alternate screen mode |
| Changing flags, env, code, and terminal size at once | Change one variable per pass |
| Losing evidence after the session scrolls | Save capture-pane output when it matters |
| Leaving sessions running after debugging | Kill sessions once evidence is saved, unless the user needs them kept alive |
When reporting results, include:
Avoid claiming a fix works until the relevant behavior has been reproduced and observed in tmux or another appropriate verification path.