# Tmux Worktree Session

> Spin up an isolated git worktree in its own tmux session — coding agent in one window, a shell in another, dev stack in a third — with the agent briefed and already working. Use for spinning up a worktree, starting a feature/branch/task in isolation, handing work to a fresh agent (Claude/Codex), or setting up an isolated tmux dev session.

- Skill: `steveclarke/tmux-worktree-session` (Agent Skill)
- Install (CLI): `npx skillmds@latest add steveclarke/tmux-worktree-session`
- Raw SKILL.md: https://api.skillmd.com/api/skills/steveclarke/tmux-worktree-session/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: steveclarke (https://skillmd.com/u/steveclarke)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/steveclarke/tmux-worktree-session

---


# tmux Worktree Session

Stand up a self-contained workspace: an isolated git worktree, a tmux session to
drive it, the dev stack running, and a fresh agent already working a briefing.
The human attaches and the work is already in motion.

**Composes** two skills: **tmux-orchestration** for safely driving panes, and
**handoff** for writing the briefing.

## Standard layout

```
Session: <Project>-<work>     (hyphenated, no spaces)
├── Window 1 "agent" → coding agent (Claude/Codex), cwd = worktree, given a
│                      kickoff prompt pointing at the briefing
├── Window 2 "cli"   → bare shell for tests and ad-hoc commands
└── Window 3 "dev"   → dev stack
```

Three windows, one thing each — no splits. The common shape; adapt it (no dev
stack, two agents, a logs window). Confirm if non-obvious. Don't add a git/lazygit
window unless the user asks for one.

## Inputs

Fill from context, don't interrogate:
- **Work name** → branch + session name. Prefer a PR/issue number if one exists.
- **Agent + mode** → Claude or Codex, fast/plan. Ask once if unsure.
- **Base branch** → usually the default; worktree tools often base on
  `origin/<default>`, which matters for step 1.

## Process

### 1. Write the briefing, commit it to the base branch first

Use **handoff** to write what the agent reads: mission, scoped task,
files/patterns, conventions, guardrails. A briefing, not a history.

If the worktree tool bases new trees on `origin/<default>`, commit and push the
briefing to the base branch *before* creating the worktree — otherwise it won't
be there for the agent.

### 2. Discover and run the worktree tool

Look (see cheatsheet), don't assume. Common: `bin/worktree add <name>`,
`bin/worktree add --pr 42`. Fallback: `git worktree add ../<repo>-<branch> -b <branch> origin/<default>`.

Creation often triggers a **full bootstrap** (deps, DB, secrets) that takes
**minutes** — don't assume it hung. It may **prompt for a secret** (1Password,
master key, env token): that's the **user's** to approve — surface it and wait,
never type credentials yourself. Run it in a visible pane and wait for a real
completion signal (append `; echo DONE_$?` and poll) before starting the dev
stack.

### 3. Discover dev-stack and test commands

Look (see cheatsheet). Prefer a **headless/detached** mode for your control
(e.g. process-compose `-D` + `status`/`logs`); a foreground TUI is fine for the
human to watch. Note the test runner — the cli window and agent need it.

### 4. Build the session

Mechanics via **tmux-orchestration**. Specifics that bite:
- Create it **detached** so the user's current session is untouched.
- **Hyphenated name, no spaces.**
- Window 1 `agent`: `cd` to worktree, launch agent; when its UI is ready,
  **buffer-paste** the kickoff, then Enter as a separate step. Keep it short —
  point at the briefing. Optionally hand it the sibling pane ids (cli, dev) so it
  can poll them itself via the tmux CLI.
- Window 2 `cli`: `cd` to worktree, bare shell for tests and ad-hoc commands.
- Window 3 `dev`: `cd` to worktree, run the dev stack.

Every window `cd`s into the worktree and needs the right toolchain (see
version-manager gotcha).

### 5. Verify and report

- Dev stack actually **healthy** (poll `status`/health), not just "started";
  read process logs if anything failed.
- Agent actually **started** (capture its pane, don't assume the paste landed).
- Report: `tmux attach -t <session>`.

## Gotchas

**Version managers don't activate in spawned shells (the big one).** A shell you
spawn programmatically (`tmux new-session`, non-login) often lacks the user's
version manager (mise/asdf/rbenv/nvm), so `ruby`/`node`/`python` silently falls
back to the system version and bootstrap fails (e.g. *"Could not find bundler"*).
- Detect: compare `ruby -v` etc. in your pane vs the user's. Mismatch = the smell.
- Fix interactive panes: put shims on PATH, e.g. mise
  `export PATH="$HOME/.local/share/mise/shims:$PATH"`.
- Fix the dev stack's child processes too. For **mise**, plain `mise activate` is
  a **no-op in non-interactive `bash -lc`** — use `mise activate <shell> --shims`
  or `mise exec --`. If the dev-stack config uses plain `mise activate`, that's a
  real bug for agent/CI use — flag it.

**Pane mechanics + safety → tmux-orchestration.** Pane-id targeting, never
writing to your own pane, read-before-write, buffer-pasting multi-line prompts,
Enter as a separate step — all of that lives there. Don't restate it; follow it.
Two things worth repeating here: **no spaces in session names** (`session:window`
targets mis-parse), and quit a dev TUI with its real key (process-compose `F10`),
not a guessed `Ctrl-C`.

## Discovery cheatsheet

| Need | Look for |
|------|----------|
| Worktree tool | `bin/worktree`, `script/worktree`, `DEVSTACK.md`, `just`/`make`, else `git worktree add` |
| Dev stack | `bin/dev`, `npm/pnpm dev`, `foreman`/`overmind`, `process-compose`, `docker compose`, `mise run dev`, project verbs |
| Test runner | `bin/rspec`, `pnpm test`, `pytest`, `go test`, `Makefile` |
| Toolchain | `.mise.toml`/`.tool-versions`/`.ruby-version`/`.nvmrc` — confirm the spawned shell uses it |

