# Pane

> Tmux pane lifecycle management. Split, capture, send to, close, and list tmux panes by writing JSON request files. A PostToolUse hook executes the tmux operations automatically.

- Skill: `collinthefarmer/pane` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add collinthefarmer/pane`
- Raw SKILL.md: https://api.skillmd.com/api/skills/collinthefarmer/pane/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: collinthefarmer (https://skillmd.com/u/collinthefarmer)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/collinthefarmer/pane

---


# Pane — Tmux Pane Management via File Protocol

Manage tmux panes by writing JSON request files. A Claude Code hook detects the writes and executes the tmux operations — no Bash needed.

## Runtime Paths

Read `~/.claude/skills/runtime.json` to get the `runtime_dir` value. All paths are under `<runtime_dir>/claude-panes/`.

| Path | Direction | Purpose |
|------|-----------|---------|
| `requests/pane-split.json` | Write | Split a new pane |
| `requests/pane-close.json` | Write | Close a pane |
| `requests/pane-send.json` | Write | Send input to a pane |
| `requests/pane-capture.json` | Write | Capture pane content |
| `results/pane-split.json` | Read | Split result (pane_id, session) |
| `results/pane-capture.txt` | Read | Captured pane text |
| `registry/<session>.json` | Read | Current pane registry |

## Commands

### Split

Write to `requests/pane-split.json`:
```json
{
  "name": "myskill/renderer",
  "direction": "h",
  "size": 50,
  "cmd": "python3 my-script.py",
  "cwd": "/optional/working/dir"
}
```

| Field | Default | Description |
|-------|---------|-------------|
| `name` | (required) | Logical pane name, namespaced by skill |
| `direction` | `"v"` | `"v"` vertical, `"h"` horizontal |
| `size` | `50` | Percentage of parent pane |
| `cmd` | (none) | Command to run in the pane |
| `cwd` | inherited | Working directory |

Read result from `results/pane-split.json`:
```json
{"pane_id": "%42", "name": "myskill/renderer", "session": "my-session"}
```

### Close

Write to `requests/pane-close.json`:
```json
{"name": "myskill/renderer", "force": false}
```

### Send

Write to `requests/pane-send.json`:
```json
{"name": "myskill/renderer", "text": "C-c", "keys": true}
```

| Field | Default | Description |
|-------|---------|-------------|
| `text` | (required) | Text or key names to send |
| `keys` | `false` | Interpret as tmux key names |
| `literal` | `false` | Send literally, no interpretation |

### Capture

Write to `requests/pane-capture.json`:
```json
{"name": "myskill/renderer", "lines": 20, "clean": true}
```

Read result from `results/pane-capture.txt` (plain text).

### List

No request needed. Read the registry directly:
`registry/<session>.json`

## Pane Registry

Each session has a JSON file in the `registry/` directory:
```json
{
  "session": "my-session",
  "panes": [
    {"name": "graph/latency", "pane_id": "%42", "created_at": "...", "command": "...", "direction": "h", "size": 50}
  ]
}
```

Pane names are scoped by skill (`graph/renderer`, `tests/runner`). Duplicate names within a session are rejected.

## Dependencies

- tmux (required)
- python3 (for registry JSON operations)
- Claude Code hooks configured (run `setup.sh` once)

