feat(skills): Add 'Use when / Don't use when' routing blocks (#14521)

* feat(skills): add 'Use when / Don't use when' blocks to skill descriptions

Based on OpenAI's Shell + Skills + Compaction best practices article.

Key changes:
- Added clear routing logic to skill descriptions
- Added negative examples to prevent misfires
- Added templates/examples to github skill
- Included Blake's specific setup notes for openhue

Skills updated:
- apple-reminders: Clarify vs Clawdbot cron
- github: Clarify vs local git operations
- imsg: Clarify vs other messaging channels
- openhue: Add device inventory, room layout
- tmux: Clarify vs exec tool
- weather: Add location defaults, format codes

Reference: https://developers.openai.com/blog/skills-shell-tips

* fix(skills): restore metadata and generic CLI examples

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
Blakeshannon
2026-02-17 18:28:20 -06:00
committed by GitHub
parent 6b5199ba2a
commit 9cce40d123
6 changed files with 525 additions and 232 deletions

View File

@@ -5,131 +5,149 @@ metadata:
{ "openclaw": { "emoji": "🧵", "os": ["darwin", "linux"], "requires": { "bins": ["tmux"] } } }
---
# tmux Skill (OpenClaw)
# tmux Session Control
Use tmux only when you need an interactive TTY. Prefer exec background mode for long-running, non-interactive tasks.
Control tmux sessions by sending keystrokes and reading output. Essential for managing Claude Code sessions.
## Quickstart (isolated socket, exec tool)
## When to Use
**USE this skill when:**
- Monitoring Claude/Codex sessions in tmux
- Sending input to interactive terminal applications
- Scraping output from long-running processes in tmux
- Navigating tmux panes/windows programmatically
- Checking on background work in existing sessions
## When NOT to Use
**DON'T use this skill when:**
- Running one-off shell commands → use `exec` tool directly
- Starting new background processes → use `exec` with `background:true`
- Non-interactive scripts → use `exec` tool
- The process isn't in tmux
- You need to create a new tmux session → use `exec` with `tmux new-session`
## Example Sessions
| Session | Purpose |
| ----------------------- | --------------------------- |
| `shared` | Primary interactive session |
| `worker-2` - `worker-8` | Parallel worker sessions |
## Common Commands
### List Sessions
```bash
SOCKET_DIR="${OPENCLAW_TMUX_SOCKET_DIR:-${CLAWDBOT_TMUX_SOCKET_DIR:-${TMPDIR:-/tmp}/openclaw-tmux-sockets}}"
mkdir -p "$SOCKET_DIR"
SOCKET="$SOCKET_DIR/openclaw.sock"
SESSION=openclaw-python
tmux -S "$SOCKET" new -d -s "$SESSION" -n shell
tmux -S "$SOCKET" send-keys -t "$SESSION":0.0 -- 'PYTHON_BASIC_REPL=1 python3 -q' Enter
tmux -S "$SOCKET" capture-pane -p -J -t "$SESSION":0.0 -S -200
tmux list-sessions
tmux ls
```
After starting a session, always print monitor commands:
```
To monitor:
tmux -S "$SOCKET" attach -t "$SESSION"
tmux -S "$SOCKET" capture-pane -p -J -t "$SESSION":0.0 -S -200
```
## Socket convention
- Use `OPENCLAW_TMUX_SOCKET_DIR` (legacy `CLAWDBOT_TMUX_SOCKET_DIR` also supported).
- Default socket path: `"$OPENCLAW_TMUX_SOCKET_DIR/openclaw.sock"`.
## Targeting panes and naming
- Target format: `session:window.pane` (defaults to `:0.0`).
- Keep names short; avoid spaces.
- Inspect: `tmux -S "$SOCKET" list-sessions`, `tmux -S "$SOCKET" list-panes -a`.
## Finding sessions
- List sessions on your socket: `{baseDir}/scripts/find-sessions.sh -S "$SOCKET"`.
- Scan all sockets: `{baseDir}/scripts/find-sessions.sh --all` (uses `OPENCLAW_TMUX_SOCKET_DIR`).
## Sending input safely
- Prefer literal sends: `tmux -S "$SOCKET" send-keys -t target -l -- "$cmd"`.
- Control keys: `tmux -S "$SOCKET" send-keys -t target C-c`.
- For interactive TUI apps like Claude Code/Codex, this guidance covers **how to send commands**.
Do **not** append `Enter` in the same `send-keys`. These apps may treat a fast text+Enter
sequence as paste/multi-line input and not submit; this is timing-dependent. Send text and
`Enter` as separate commands with a small delay (tune per environment; increase if needed,
or use `sleep 1` if sub-second sleeps aren't supported):
### Capture Output
```bash
tmux -S "$SOCKET" send-keys -t target -l -- "$cmd" && sleep 0.1 && tmux -S "$SOCKET" send-keys -t target Enter
# Last 20 lines of pane
tmux capture-pane -t shared -p | tail -20
# Entire scrollback
tmux capture-pane -t shared -p -S -
# Specific pane in window
tmux capture-pane -t shared:0.0 -p
```
## Watching output
- Capture recent history: `tmux -S "$SOCKET" capture-pane -p -J -t target -S -200`.
- Wait for prompts: `{baseDir}/scripts/wait-for-text.sh -t session:0.0 -p 'pattern'`.
- Attaching is OK; detach with `Ctrl+b d`.
## Spawning processes
- For python REPLs, set `PYTHON_BASIC_REPL=1` (non-basic REPL breaks send-keys flows).
## Windows / WSL
- tmux is supported on macOS/Linux. On Windows, use WSL and install tmux inside WSL.
- This skill is gated to `darwin`/`linux` and requires `tmux` on PATH.
## Orchestrating Coding Agents (Codex, Claude Code)
tmux excels at running multiple coding agents in parallel:
### Send Keys
```bash
SOCKET="${TMPDIR:-/tmp}/codex-army.sock"
# Send text (doesn't press Enter)
tmux send-keys -t shared "hello"
# Create multiple sessions
for i in 1 2 3 4 5; do
tmux -S "$SOCKET" new-session -d -s "agent-$i"
# Send text + Enter
tmux send-keys -t shared "y" Enter
# Send special keys
tmux send-keys -t shared Enter
tmux send-keys -t shared Escape
tmux send-keys -t shared C-c # Ctrl+C
tmux send-keys -t shared C-d # Ctrl+D (EOF)
tmux send-keys -t shared C-z # Ctrl+Z (suspend)
```
### Window/Pane Navigation
```bash
# Select window
tmux select-window -t shared:0
# Select pane
tmux select-pane -t shared:0.1
# List windows
tmux list-windows -t shared
```
### Session Management
```bash
# Create new session
tmux new-session -d -s newsession
# Kill session
tmux kill-session -t sessionname
# Rename session
tmux rename-session -t old new
```
## Sending Input Safely
For interactive TUIs (Claude Code, Codex, etc.), split text and Enter into separate sends to avoid paste/multiline edge cases:
```bash
tmux send-keys -t shared -l -- "Please apply the patch in src/foo.ts"
sleep 0.1
tmux send-keys -t shared Enter
```
## Claude Code Session Patterns
### Check if Session Needs Input
```bash
# Look for prompts
tmux capture-pane -t worker-3 -p | tail -10 | grep -E "|Yes.*No|proceed|permission"
```
### Approve Claude Code Prompt
```bash
# Send 'y' and Enter
tmux send-keys -t worker-3 'y' Enter
# Or select numbered option
tmux send-keys -t worker-3 '2' Enter
```
### Check All Sessions Status
```bash
for s in shared worker-2 worker-3 worker-4 worker-5 worker-6 worker-7 worker-8; do
echo "=== $s ==="
tmux capture-pane -t $s -p 2>/dev/null | tail -5
done
# Launch agents in different workdirs
tmux -S "$SOCKET" send-keys -t agent-1 "cd /tmp/project1 && codex --yolo 'Fix bug X'" Enter
tmux -S "$SOCKET" send-keys -t agent-2 "cd /tmp/project2 && codex --yolo 'Fix bug Y'" Enter
# When sending prompts to Claude Code/Codex TUI, split text + Enter with a delay
tmux -S "$SOCKET" send-keys -t agent-1 -l -- "Please make a small edit to README.md." && sleep 0.1 && tmux -S "$SOCKET" send-keys -t agent-1 Enter
# Poll for completion (check if prompt returned)
for sess in agent-1 agent-2; do
if tmux -S "$SOCKET" capture-pane -p -t "$sess" -S -3 | grep -q ""; then
echo "$sess: DONE"
else
echo "$sess: Running..."
fi
done
# Get full output from completed session
tmux -S "$SOCKET" capture-pane -p -t agent-1 -S -500
```
**Tips:**
- Use separate git worktrees for parallel fixes (no branch conflicts)
- `pnpm install` first before running codex in fresh clones
- Check for shell prompt (`` or `$`) to detect completion
- Codex needs `--yolo` or `--full-auto` for non-interactive fixes
## Cleanup
- Kill a session: `tmux -S "$SOCKET" kill-session -t "$SESSION"`.
- Kill all sessions on a socket: `tmux -S "$SOCKET" list-sessions -F '#{session_name}' | xargs -r -n1 tmux -S "$SOCKET" kill-session -t`.
- Remove everything on the private socket: `tmux -S "$SOCKET" kill-server`.
## Helper: wait-for-text.sh
`{baseDir}/scripts/wait-for-text.sh` polls a pane for a regex (or fixed string) with a timeout.
### Send Task to Session
```bash
{baseDir}/scripts/wait-for-text.sh -t session:0.0 -p 'pattern' [-F] [-T 20] [-i 0.5] [-l 2000]
tmux send-keys -t worker-4 "Fix the bug in auth.js" Enter
```
- `-t`/`--target` pane target (required)
- `-p`/`--pattern` regex to match (required); add `-F` for fixed string
- `-T` timeout seconds (integer, default 15)
- `-i` poll interval seconds (default 0.5)
- `-l` history lines to search (integer, default 1000)
## Notes
- Use `capture-pane -p` to print to stdout (essential for scripting)
- `-S -` captures entire scrollback history
- Target format: `session:window.pane` (e.g., `shared:0.0`)
- Sessions persist across SSH disconnects