diff options
Diffstat (limited to '.opencode')
| -rw-r--r-- | .opencode/skill/tui-iteration/SKILL.md | 287 |
1 files changed, 287 insertions, 0 deletions
diff --git a/.opencode/skill/tui-iteration/SKILL.md b/.opencode/skill/tui-iteration/SKILL.md new file mode 100644 index 0000000..d28f0a7 --- /dev/null +++ b/.opencode/skill/tui-iteration/SKILL.md @@ -0,0 +1,287 @@ +--- +name: tui-iteration +description: Iteratively develop and refine Terminal User Interfaces (TUIs) by using tmux to spawn, observe, and interact with a running TUI process. Use this skill when asked to build, debug, or visually refine a TUI application — any time you need to "see" what the terminal renders and react to it, the way Playwright lets a browser agent iterate on web UI. +--- + +This skill lets you act as a TUI design agent: launch a TUI in a controlled tmux pane, capture its rendered output, send keystrokes to interact with it, observe the result, and iterate — all from the CLI. The tmux pane is your "browser tab"; `capture-pane` is your "screenshot". + +--- + +## Core Concept + +TUIs render to a virtual terminal buffer. `tmux` holds that buffer in memory at all times, even when the pane is not visible. You can: + +1. **Spawn** a tmux session/pane and run the TUI inside it. +2. **Capture** the current rendered state (text + ANSI color codes) as a snapshot. +3. **Send** keystrokes or input to drive the TUI. +4. **Repeat** — capture → evaluate → send → capture — until the UI looks right. + +This is the TUI equivalent of Playwright's `page.screenshot()` + `page.click()` loop. + +--- + +## Setup + +### Create a dedicated session + +```bash +tmux new-session -d -s tui-dev -x 220 -y 50 +``` + +- `-d` — detached (runs in background, no need to attach) +- `-s tui-dev` — session name; use this name in all subsequent commands +- `-x 220 -y 50` — terminal dimensions (columns × rows); set to match your target environment + +### Run the TUI in that session + +```bash +tmux send-keys -t tui-dev 'python my_tui.py' Enter +# or +tmux send-keys -t tui-dev 'cargo run' Enter +# or any other start command +``` + +Give the process a moment to render before capturing: + +```bash +sleep 0.5 +``` + +--- + +## Capturing State ("Taking a Screenshot") + +### Plain text capture + +```bash +tmux capture-pane -t tui-dev -p +``` + +Prints the current pane content to stdout as plain text. Good for reading layout, text content, and cursor position. + +### Capture with ANSI color codes preserved + +```bash +tmux capture-pane -t tui-dev -p -e +``` + +The `-e` flag includes escape sequences for colors and styling. Pipe to a file if you want to save a snapshot: + +```bash +tmux capture-pane -t tui-dev -p -e > snapshot.txt +``` + +Render that snapshot back to your terminal to visually inspect it: + +```bash +cat snapshot.txt +``` + +### Capture a scrollback window (not just the visible area) + +```bash +tmux capture-pane -t tui-dev -p -S -100 +``` + +`-S -100` captures 100 lines above the visible area. Useful if the TUI printed startup logs. + +### Save to a named tmux buffer (instead of stdout) + +```bash +tmux capture-pane -t tui-dev -b my-snapshot +tmux show-buffer -b my-snapshot +``` + +--- + +## Sending Input ("Clicking / Typing") + +### Type text + +```bash +tmux send-keys -t tui-dev 'hello world' '' +# Note: omitting Enter means no newline — useful for text fields +``` + +### Press Enter + +```bash +tmux send-keys -t tui-dev '' Enter +``` + +### Arrow keys and navigation + +```bash +tmux send-keys -t tui-dev '' Up +tmux send-keys -t tui-dev '' Down +tmux send-keys -t tui-dev '' Left +tmux send-keys -t tui-dev '' Right +``` + +### Special keys + +```bash +tmux send-keys -t tui-dev '' Tab +tmux send-keys -t tui-dev '' Escape +tmux send-keys -t tui-dev '' BSpace # Backspace +tmux send-keys -t tui-dev '' DC # Delete +tmux send-keys -t tui-dev '' Home +tmux send-keys -t tui-dev '' End +tmux send-keys -t tui-dev '' PPage # Page Up +tmux send-keys -t tui-dev '' NPage # Page Down +tmux send-keys -t tui-dev '' F1 # Function keys F1–F12 +``` + +### Control sequences + +```bash +tmux send-keys -t tui-dev 'q' '' # Just the letter q (quit in many TUIs) +tmux send-keys -t tui-dev '' C-c # Ctrl+C +tmux send-keys -t tui-dev '' C-d # Ctrl+D (EOF) +tmux send-keys -t tui-dev '' C-z # Ctrl+Z (suspend) +``` + +### Hex / raw escape sequences (advanced) + +```bash +# Send Escape then [ then A (same as Up arrow in many terminals) +tmux send-keys -t tui-dev $'\x1b[A' '' +``` + +--- + +## Targeting Specific Panes + +If your session has multiple windows or panes: + +```bash +# target syntax: session:window.pane +tmux send-keys -t tui-dev:0.0 '' Enter # session tui-dev, window 0, pane 0 +tmux capture-pane -t tui-dev:1.0 -p # window 1, pane 0 +``` + +List all panes to find the right target: + +```bash +tmux list-panes -a +``` + +--- + +## Resize the Terminal (Test Responsive Layouts) + +```bash +tmux resize-window -t tui-dev -x 80 -y 24 # classic 80×24 +tmux resize-window -t tui-dev -x 120 -y 40 # wider +``` + +After resizing, most TUI frameworks emit a `SIGWINCH` and redraw automatically. Capture again after ~200ms. + +--- + +## The Iteration Loop + +This is the core workflow. Repeat until satisfied: + +``` +1. send-keys → trigger an action or type input +2. sleep 0.2 → give the TUI time to redraw +3. capture-pane -p -e → observe the new state +4. evaluate → does it look right? any errors visible? +5. go to 1 +``` + +Example shell loop for automated checking: + +```bash +# Press Down 5 times and snapshot each state +for i in $(seq 1 5); do + tmux send-keys -t tui-dev '' Down + sleep 0.15 + echo "--- Step $i ---" + tmux capture-pane -t tui-dev -p +done +``` + +--- + +## Reading the Captured Output + +When you receive the text from `capture-pane -p`, look for: + +- **Borders and box-drawing characters** (`─`, `│`, `╭`, `╰`, `┌`, `└`, etc.) — indicate panels, modals, popups +- **Highlighted / reversed rows** — often indicated by `[7m` in ANSI output (reverse video = selected item) +- **Color shifts** — `[32m` green, `[31m` red, `[33m` yellow — often encode status +- **Cursor position** — `tmux display-message -t tui-dev -p '#{cursor_x},#{cursor_y}'` +- **Blank regions** — unexpected whitespace may mean a rendering bug or layout overflow + +To strip ANSI codes for pure text analysis: + +```bash +tmux capture-pane -t tui-dev -p -e | sed 's/\x1b\[[0-9;]*m//g' +``` + +--- + +## Useful Diagnostic Commands + +```bash +# What is currently running in the pane? +tmux display-message -t tui-dev -p '#{pane_current_command}' + +# Get pane dimensions +tmux display-message -t tui-dev -p '#{pane_width}x#{pane_height}' + +# Get cursor position +tmux display-message -t tui-dev -p 'cursor: #{cursor_x},#{cursor_y}' + +# Is the pane still alive? +tmux list-panes -t tui-dev -F '#{pane_id} #{pane_dead} #{pane_current_command}' + +# Watch the pane live (attach briefly) +tmux attach -t tui-dev +# Detach again with: Ctrl+B then D +``` + +--- + +## Teardown + +Kill the TUI process without destroying the session: + +```bash +tmux send-keys -t tui-dev '' C-c +``` + +Kill the whole session when done: + +```bash +tmux kill-session -t tui-dev +``` + +--- + +## Workflow Summary + +| Goal | Command | +|------|---------| +| Create session | `tmux new-session -d -s tui-dev -x 220 -y 50` | +| Start TUI | `tmux send-keys -t tui-dev 'CMD' Enter` | +| Snapshot (plain) | `tmux capture-pane -t tui-dev -p` | +| Snapshot (with color) | `tmux capture-pane -t tui-dev -p -e` | +| Send keystroke | `tmux send-keys -t tui-dev '' Down` | +| Type text | `tmux send-keys -t tui-dev 'text' ''` | +| Resize terminal | `tmux resize-window -t tui-dev -x W -y H` | +| Cursor position | `tmux display-message -t tui-dev -p '#{cursor_x},#{cursor_y}'` | +| Kill process | `tmux send-keys -t tui-dev '' C-c` | +| Kill session | `tmux kill-session -t tui-dev` | + +--- + +## Tips + +- **Always `sleep` after `send-keys`** before capturing. TUIs need a render cycle. 100–300ms is usually enough; animations may need longer. +- **Prefer `-e` captures when debugging visual issues** — color is often load-bearing information in TUIs (errors in red, selection in reverse video, etc.). +- **Use a wide session** (`-x 220`) by default. Many TUI layout bugs only appear at narrow widths; you can always resize down to test. +- **Scrollback is truncated** — `capture-pane` only sees the visible buffer plus scrollback history. If the TUI clears the screen on launch, earlier output is gone. +- **Mouse events** can be sent via `tmux send-keys` using raw escape sequences, but most TUI iteration tasks don't need them — keyboard navigation is sufficient. |
