Skip to content

Commit 1c69e6b

Browse files
committed
docs: Add recipes page with 6 composable workflow patterns
why: Tool docs explained atoms but never showed molecules. The send_keys → wait_for_text → capture_pane pattern — the fundamental workflow — appeared nowhere as a complete sequence. what: - Run a command and capture output (the core pattern + race condition warning) - Start a service and wait for readiness (Playwright/web server use case) - Search for errors across all panes (two-phase: search broad, capture narrow) - Set up a multi-pane workspace (create, split, layout, label) - Interrupt a hung command (Ctrl-C with enter=false) - Clean capture without prior output (clear, send, wait, capture) - Added to "Use it" toctree between tools/index and configuration
1 parent a854473 commit 1c69e6b

2 files changed

Lines changed: 157 additions & 0 deletions

File tree

docs/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ clients
9393
:caption: Use it
9494
9595
tools/index
96+
recipes
9697
configuration
9798
```
9899

docs/recipes.md

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
(recipes)=
2+
3+
# Recipes
4+
5+
Composable workflow patterns showing how to combine tools. Each recipe shows the tool sequence, why each step matters, and a common mistake to avoid.
6+
7+
## Run a command and capture output
8+
9+
The fundamental workflow. Most agent interactions follow this pattern.
10+
11+
```json
12+
{"tool": "send_keys", "arguments": {"keys": "make test", "pane_id": "%0"}}
13+
```
14+
15+
```json
16+
{"tool": "wait_for_text", "arguments": {"pattern": "\\$\\s*$", "pane_id": "%0", "regex": true}}
17+
```
18+
19+
```json
20+
{"tool": "capture_pane", "arguments": {"pane_id": "%0", "start": -50}}
21+
```
22+
23+
**Why each step matters:**
24+
- `send_keys` sends the command but returns immediately — it does not wait for completion
25+
- `wait_for_text` blocks until the shell prompt returns (the `$` regex), confirming the command finished
26+
- `capture_pane` reads the result after the command has completed
27+
28+
```{warning}
29+
Do not call `capture_pane` immediately after `send_keys`. There is a race condition — you may capture the terminal *before* the command produces output. Always use `wait_for_text` between them.
30+
```
31+
32+
## Start a service and wait for readiness
33+
34+
Use when you need a background service running before proceeding — web servers, databases, build watchers.
35+
36+
```json
37+
{"tool": "split_window", "arguments": {"session_name": "dev", "direction": "right"}}
38+
```
39+
40+
The new pane's `pane_id` is in the response. Use it for the remaining steps:
41+
42+
```json
43+
{"tool": "send_keys", "arguments": {"keys": "npm run dev", "pane_id": "%1"}}
44+
```
45+
46+
```json
47+
{"tool": "wait_for_text", "arguments": {"pattern": "Local:.*http://localhost", "pane_id": "%1", "regex": true, "timeout": 30}}
48+
```
49+
50+
Now the server is ready — run tests in the original pane:
51+
52+
```json
53+
{"tool": "send_keys", "arguments": {"keys": "npx playwright test", "pane_id": "%0"}}
54+
```
55+
56+
**Common mistake:** Using a fixed `sleep` instead of `wait_for_text`. Server startup times vary — `wait_for_text` adapts automatically.
57+
58+
## Search for errors across all panes
59+
60+
Find which pane has an error without knowing where to look.
61+
62+
```json
63+
{"tool": "search_panes", "arguments": {"pattern": "error", "session_name": "dev"}}
64+
```
65+
66+
The response lists every pane with matching lines. Then capture the full context from each match:
67+
68+
```json
69+
{"tool": "capture_pane", "arguments": {"pane_id": "%2", "start": -100}}
70+
```
71+
72+
**Why two steps:** `search_panes` is fast — it uses tmux's built-in filter for plain text patterns and never captures full pane content. Once you know *which* pane has the error, `capture_pane` gets the full context.
73+
74+
**Common mistake:** Using `list_panes` to find errors. `list_panes` only searches metadata (names, IDs, current command) — not terminal content.
75+
76+
## Set up a multi-pane workspace
77+
78+
Create a structured development layout with labeled panes.
79+
80+
```json
81+
{"tool": "create_session", "arguments": {"session_name": "workspace"}}
82+
```
83+
84+
```json
85+
{"tool": "split_window", "arguments": {"session_name": "workspace", "direction": "right"}}
86+
```
87+
88+
```json
89+
{"tool": "split_window", "arguments": {"session_name": "workspace", "direction": "below"}}
90+
```
91+
92+
```json
93+
{"tool": "select_layout", "arguments": {"session_name": "workspace", "layout": "main-vertical"}}
94+
```
95+
96+
Label each pane for later identification:
97+
98+
```json
99+
{"tool": "set_pane_title", "arguments": {"pane_id": "%0", "title": "editor"}}
100+
```
101+
102+
```json
103+
{"tool": "set_pane_title", "arguments": {"pane_id": "%1", "title": "server"}}
104+
```
105+
106+
```json
107+
{"tool": "set_pane_title", "arguments": {"pane_id": "%2", "title": "tests"}}
108+
```
109+
110+
Then start processes in each:
111+
112+
```json
113+
{"tool": "send_keys", "arguments": {"keys": "vim .", "pane_id": "%0"}}
114+
```
115+
116+
```json
117+
{"tool": "send_keys", "arguments": {"keys": "npm run dev", "pane_id": "%1"}}
118+
```
119+
120+
## Interrupt a hung command
121+
122+
Recover when a command is stuck or waiting for input.
123+
124+
```json
125+
{"tool": "send_keys", "arguments": {"keys": "C-c", "pane_id": "%0", "enter": false}}
126+
```
127+
128+
```json
129+
{"tool": "wait_for_text", "arguments": {"pattern": "\\$\\s*$", "pane_id": "%0", "regex": true, "timeout": 5}}
130+
```
131+
132+
**Why `enter: false`:** Ctrl-C is a tmux key name, not text to type. Setting `enter: false` prevents sending an extra Enter keystroke after the interrupt signal.
133+
134+
**If the interrupt fails** (process ignores Ctrl-C), use `kill_pane` to destroy the pane and `split_window` to get a fresh one.
135+
136+
## Clean capture (no prior output)
137+
138+
Get a clean capture without output from previous commands.
139+
140+
```json
141+
{"tool": "clear_pane", "arguments": {"pane_id": "%0"}}
142+
```
143+
144+
```json
145+
{"tool": "send_keys", "arguments": {"keys": "pytest -x", "pane_id": "%0"}}
146+
```
147+
148+
```json
149+
{"tool": "wait_for_text", "arguments": {"pattern": "passed|failed|error", "pane_id": "%0", "regex": true, "timeout": 60}}
150+
```
151+
152+
```json
153+
{"tool": "capture_pane", "arguments": {"pane_id": "%0"}}
154+
```
155+
156+
**Why clear first:** Without clearing, `capture_pane` returns the visible viewport which may include output from prior commands. Clearing ensures you only capture output from the command you just ran.

0 commit comments

Comments
 (0)