1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
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.
|