---
name: team-tile-spawn
description: One-shot bootstrap of N maw-tile-spawned blank panes into a TeamCreate team — each pane cd's into a target oracle/repo and boots claude.exe with TeamCreate flags via `maw run`, then receives a mission via SendMessage. Use when user says "team-tile-spawn", "tile a team", "spawn N teammates with missions", or wants the all-maw verb chain (vs raw tmux split-window).
argument-hint: <team-name> <role@cwd:color:#mission> [<role@cwd:color:#mission>...]
---

# /team-tile-spawn — All-Maw Team Bootstrap

Validated 2026-05-20 via live experiment in [[ψ/lab/buddy-mom-demo/plan.md]] + [[ψ/ralph/55-teammate-message-wire]]. The cleanest path from "blank window" → "N TeamCreate teammates working in parallel with missions in different oracle paths" using ONLY maw verbs + Claude Code tools.

Replaces the raw-tmux-split path in `ψ/ralph/scripts/team-tile/team-tile.ts` which hit seam #3 (raw-spawn panes invisible to `maw run`). This skill uses `maw tile N` first — those panes ARE addressable via the canonical `<session>:<window>.<pane-idx>` form.

**Updated 2026-05-20**: After maw-js #1837 landed, `maw tile [N] [--path <dir>] [--cmd <cmd>]` does spawn + cd + run in a single verb. The earlier `maw tile` + `maw run` two-step is now one step per pane.

## When to use

- User says "team-tile-spawn", "tile a team", "spawn N teammates", "boot N readers in parallel"
- You want N parallel claude.exe teammates each in a different oracle/repo with missions
- All-maw-verbs is the goal (vs raw tmux split-window)

## When NOT to use

- One-off solo agent → use `Agent` tool directly
- Parallel reads in same repo with no peer messaging → use parallel `Agent` calls
- Single conversation-level subagents → use built-in `/team-agents` or mother's `/team-talk`

## Preflight

```bash
[ -n "$TMUX" ] || { echo "✗ not in tmux"; exit 1; }
[ -n "$CLAUDE_SESSION_ID" ] || { echo "✗ CLAUDE_SESSION_ID unset (need parent uuid)"; exit 1; }
which maw rtk bun || { echo "✗ tools missing"; exit 1; }
```

Also verify `TeamCreate` + `SendMessage` are loaded (use `ToolSearch select:TeamCreate,SendMessage`).

## Argument format

```
/team-tile-spawn <team-name> <member-spec> [<member-spec>...]
```

Member spec: `<role>@<cwd>[:<color>][:#<mission>]`

- `<role>` — the agent name, becomes `--agent-name` + `--agent-id <role>@<team>`
- `<cwd>` — absolute path the pane will `cd` into before booting claude
- `<color>` — optional: red|green|yellow|blue|purple|cyan|magenta|white (rotates if omitted)
- `#<mission>` — optional: initial mission sent via SendMessage after boot

Example:
```
/team-tile-spawn mom-demo \
  mother-reader@/opt/Code/github.com/Soul-Brews-Studio/mother-oracle:magenta:#"read ψ/lab/boy-method/dna-full-list.md and reply with surprising patterns" \
  buddy-reader@/opt/Code/github.com/Soul-Brews-Studio/maw-plugin-registry:cyan:#"read plugins/buddy/lib.ts and reply with design notes"
```

## Recipe (8 steps)

### 1. Parse args + preflight

Extract `<team-name>` and the list of member specs. Validate cwd paths exist. Pick colors for any unspecified.

### 2. `maw tile N` — spawn N blank zsh panes

```bash
rtk maw tile <N>   # where N = number of members
```

The panes appear with tmux indices 1..N in the current window. **They are addressable via `<session>:<window-idx>.<pane-idx>` from `maw ls -v`.**

### 3. Layout: main-vertical (optional, but pretty)

```bash
tmux select-layout main-vertical
```

Puts lead-pane on the left, tile-panes stacked on the right. Skip if you prefer the default tile layout.

### 4. `TeamCreate({team_name: "..."})` — lead-side, from your Claude session

```
TeamCreate({
  team_name: "<team>",
  description: "<one-line purpose>",
  agent_type: "researcher"
})
```

This writes `~/.claude/teams/<team>/config.json` with the lead as the sole initial member. Teammates will be addressable by role-name once they boot with the matching `--agent-name` flag.

### 5. Capture each tile pane's canonical address

```bash
# tile panes are in the current window, indices 1..N
# canonical addr: <session>:<window-idx>.<pane-idx>
SESSION=$(tmux display-message -p '#{session_name}')
WINDOW=$(tmux display-message -p '#{window_index}')
# pane idx 0 is the lead pane; tiles start at 1
```

### 6. `maw run` each tile pane with the bootstrap command

For each member at pane idx `i`:

```bash
CMD="cd <cwd> && env CLAUDECODE=1 CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 \
  $CLAUDE_BIN \
  --agent-id <role>@<team> \
  --agent-name <role> \
  --team-name <team> \
  --agent-color <color> \
  --parent-session-id $CLAUDE_SESSION_ID \
  --model sonnet \
  --dangerously-skip-permissions"

rtk maw run $SESSION:$WINDOW.$i "$CMD"
```

Where `$CLAUDE_BIN` resolves to `~/.nvm/versions/node/v24.15.0/lib/node_modules/@anthropic-ai/claude-code/bin/claude.exe` (or wherever claude.exe lives on this machine).

### 7. Wait for boots (8-12s) then verify

```bash
sleep 10
rtk maw peek $SESSION:$WINDOW.<i>   # should show claude.exe + agent identity in status bar
```

### 8. SendMessage each mission (if specified)

For each member with a `#<mission>` clause:

```
SendMessage({
  to: "<role>",
  summary: "<5-10 word gist>",
  message: "<full mission text>"
})
```

The message lands in `~/.claude/teams/<team>/inboxes/<role>.json` and is wrapped as `<teammate-message>` XML when delivered to the teammate's next turn.

## Cleanup recipe

```bash
# In the lead Claude session, after teammates finish:
SendMessage({to: "<role>", message: {type: "shutdown_request"}})   # for each teammate
# wait for shutdown_approved replies
TeamDelete({})                                # removes ~/.claude/teams/<team>/

# Tmux cleanup — kill teammate panes (they exit on shutdown_approved, but extras)
# Use absolute pane idx from `tmux list-panes`
tmux kill-pane -t <session>:<window>.<idx>
```

## Failure modes

| Symptom | Likely cause | Fix |
|---|---|---|
| `maw run <addr>` fails: "not in agents map" | Wrong address format | Use `<session>:<window-idx>.<pane-idx>` from `maw ls -v`, NOT raw `%pane-id` |
| Teammate boots but isn't in `config.json` members | TeamCreate was called AFTER spawn | OK if just using SendMessage — addressing is by agent-id env, not membership. See [[ψ/ralph/55-teammate-message-wire]] for the 5-seam model. |
| `--parent-session-id` rejected | Missing `$CLAUDE_SESSION_ID` env | Pass UUID explicitly or set the env in your shell |
| Auth seam — teammate boots but can't reach API | Foreign-pane direnv didn't load | The tile pane should inherit your env; if not, prefix the command with `direnv allow && eval "$(direnv export zsh)"` (mother's book ch.9) |
| Teammate replies but pane doesn't exit on shutdown_approved | `shutdown_approved` ≠ process kill | Use `tmux kill-pane` after — see the 6th seam from buddy-team session 2026-05-20 |

## The verb chain

```
maw tile N → tmux select-layout → TeamCreate → maw run × N → SendMessage × N
```

All maw verbs except TeamCreate + SendMessage (Claude tools — those run from your Claude session, not from shell).

## Related

- [[ψ/lab/buddy-mom-demo/plan.md]] — the live experiment that validated this pattern
- [[ψ/ralph/55-teammate-message-wire]] — wire format + 5-seam visibility model
- [[ψ/ralph/56-mother-oracle-team-architect]] — mother's `team-talk` skill + `bridge-spawn.ts` (the cross-session variant)
- [[ψ/ralph/49-buddy-team]] — buddy plugin context
- maw-js issue #1837 — when `maw new --path --cmd` lands, this skill collapses further
- maw-js issue (proposed) — `maw tile --path --cmd` ergonomic ask for the non-team case

ARGUMENTS: $ARGUMENTS
