| name | description | allowed-tools |
|---|---|---|
session |
Start a new Claude session in a WezTerm pane with an initial prompt. Use when user says "start a session", "new claude session", "spawn claude with prompt", "power session" (bypasses permissions), "start a swarm", "swarm session", "coordinated sessions", or wants to run claude with a starting task in a new pane. Swarm mode enables multiple sessions to coordinate via shared state files. |
Bash(wezterm:*), Bash(mkdir:*), Bash(cat:*), Bash(printf:*), Bash(date:*), Bash(basename:*), Bash(jq:*) |
- Current directory name: !
basename "$PWD" - Timestamp: !
date +%Y%m%d-%H%M%S - WEZTERM_PANE: !
echo $WEZTERM_PANE
Spawn a new Claude Code session in a WezTerm pane with context from the current conversation.
- User wants to delegate a subtask to another Claude instance
- Current task has a parallelizable component
- User wants to explore a tangent without losing current context
- Breaking a complex task into concurrent sessions
If user says "power session", add --dangerously-skip-permissions flag:
printf 'claude --dangerously-skip-permissions "$(cat /tmp/claude-session-prompt.md)"\n' | wezterm cli send-text --pane-id "$NEW_PANE"This bypasses all permission checks. Only use in trusted directories.
Use the dynamic context values above to create prompt files:
# Pattern: /tmp/claude-sessions/<cwd>-<timestamp>-<purpose>.md
mkdir -p /tmp/claude-sessions
PROMPT_FILE="/tmp/claude-sessions/${CWD_NAME}-${TIMESTAMP}-${PURPOSE}.md"Where CWD_NAME and TIMESTAMP come from the Dynamic Context section above, and PURPOSE is a descriptive slug for the task.
Run once to create the BSP split helper:
cat > /tmp/bsp-split.sh << 'SCRIPT'
#!/bin/bash
# BSP Split: Find largest pane IN CURRENT TAB and bisect it
# Get current pane from WEZTERM_PANE env var (set by WezTerm for shells)
if [ -z "$WEZTERM_PANE" ]; then
echo "Error: WEZTERM_PANE not set" >&2
exit 1
fi
# Get tab ID for current pane
CURRENT_TAB=$(wezterm cli list --format json | jq -r --arg pane "$WEZTERM_PANE" '
.[] | select(.pane_id == ($pane | tonumber)) | .tab_id
')
# Get largest pane in current tab only
LARGEST=$(wezterm cli list --format json | jq -r --arg tab "$CURRENT_TAB" '
map(select(.tab_id == ($tab | tonumber) and .is_zoomed == false)) |
sort_by(-(.size.rows * .size.cols)) |
.[0] |
"\(.pane_id) \(.size.cols) \(.size.rows)"
')
PANE_ID=$(echo "$LARGEST" | awk '{print $1}')
COLS=$(echo "$LARGEST" | awk '{print $2}')
ROWS=$(echo "$LARGEST" | awk '{print $3}')
RATIO=$(echo "$COLS $ROWS" | awk '{printf "%.2f", $1/$2}')
if (( $(echo "$RATIO > 2.0" | bc -l) )); then
wezterm cli split-pane --pane-id "$PANE_ID" --right
else
wezterm cli split-pane --pane-id "$PANE_ID" --bottom
fi
SCRIPT
chmod +x /tmp/bsp-split.sh# 1. Setup prompt file with structured name
mkdir -p /tmp/claude-sessions
CWD_NAME=$(basename "$PWD")
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
PURPOSE="task-name"
PROMPT_FILE="/tmp/claude-sessions/${CWD_NAME}-${TIMESTAMP}-${PURPOSE}.md"
# 2. Write prompt
cat > "$PROMPT_FILE" << 'EOF'
## Context
[Summary of relevant conversation context]
## Task
[What this new session should accomplish]
EOF
# 3. BSP split and run claude
NEW_PANE=$(/tmp/bsp-split.sh)
printf 'claude "$(cat %s)"\n' "$PROMPT_FILE" | wezterm cli send-text --pane-id "$NEW_PANE"# Setup
mkdir -p /tmp/claude-sessions
CWD_NAME=$(basename "$PWD")
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
# Create prompt files with structured names
TASKS=("write-tests" "fix-auth" "add-logging" "refactor-utils")
for i in "${!TASKS[@]}"; do
PROMPT_FILE="/tmp/claude-sessions/${CWD_NAME}-${TIMESTAMP}-${TASKS[$i]}.md"
cat > "$PROMPT_FILE" << EOF
## Task
${TASKS[$i]}
EOF
PROMPT_FILES+=("$PROMPT_FILE")
done
# Spawn all with BSP layout
for PROMPT_FILE in "${PROMPT_FILES[@]}"; do
NEW_PANE=$(/tmp/bsp-split.sh)
printf 'claude "$(cat %s)"\n' "$PROMPT_FILE" | wezterm cli send-text --pane-id "$NEW_PANE"
doneFor just one additional session without BSP:
mkdir -p /tmp/claude-sessions
PROMPT_FILE="/tmp/claude-sessions/$(basename $PWD)-$(date +%Y%m%d-%H%M%S)-quick.md"
cat > "$PROMPT_FILE" << 'EOF'
## Task
[Task here]
EOF
PANE_ID=$(wezterm cli split-pane)
printf 'claude "$(cat %s)"\n' "$PROMPT_FILE" | wezterm cli send-text --pane-id "$PANE_ID"Use printf ... | wezterm cli send-text for newlines.
# CORRECT - printf pipe
printf 'command\n' | wezterm cli send-text --pane-id "$PANE_ID"
# WRONG - literal \n gets sent
wezterm cli send-text --pane-id "$PANE_ID" "command\n"When spawning multiple sessions that need to coordinate, use swarm mode. Sessions can track each other's progress via shared state files.
- "start a swarm", "swarm session", "coordinated sessions"
- Or when spawning 2+ related sessions
Add to your project's .claude/settings.json or globally to ~/.claude/settings.json:
{
"hooks": {
"SessionStart": ["bun run $HOME/.claude/plugins/claude-swarm/scripts/SessionStart.ts"],
"UserPromptSubmit": ["bun run $HOME/.claude/plugins/claude-swarm/scripts/UserPromptSubmit.ts"],
"Stop": ["bun run $HOME/.claude/plugins/claude-swarm/scripts/Stop.ts"]
}
}This enables automatic:
- Child registration in manifest on session start
- Progress tracking and sibling status injection
- Completion status updates on session end
CLAUDE_SWARM_ID- Unique swarm identifierCLAUDE_SWARM_DIR- Path to shared state directoryCLAUDE_PARENT_SESSION- Parent's session ID (use$CLAUDE_SESSION_ID)CLAUDE_SESSION_ROLE- "parent" or "child"CLAUDE_SESSION_PURPOSE- Task description for this session
./sessions/<swarm-id>/
├── manifest.json # All sessions in this swarm
├── parent-<id>.md # Parent session status
├── child-<id>-1.md # Child session 1 status
└── child-<id>-2.md # Child session 2 status
# Generate swarm ID
SWARM_ID="$(basename $PWD)-$(date +%Y%m%d-%H%M%S)"
SWARM_DIR="./sessions/$SWARM_ID"
mkdir -p "$SWARM_DIR"
# Create manifest
cat > "$SWARM_DIR/manifest.json" << EOF
{
"swarm_id": "$SWARM_ID",
"created_at": "$(date -Iseconds)",
"swarm_dir": "$SWARM_DIR",
"parent": {
"session_id": "${CLAUDE_SESSION_ID:-parent}",
"purpose": "Coordinate tasks",
"status": "running"
},
"children": []
}
EOF
echo "Swarm initialized: $SWARM_ID"# Create prompt file
PURPOSE="write-tests"
PROMPT_FILE="/tmp/claude-sessions/${CWD_NAME}-${TIMESTAMP}-${PURPOSE}.md"
cat > "$PROMPT_FILE" << 'EOF'
## Context
You are part of a coordinated swarm session.
## Your Task
Write unit tests for the auth module.
## Coordination
- Update your progress in: $CLAUDE_SWARM_DIR/child-$CLAUDE_SESSION_ID.md
- Check sibling progress: ls $CLAUDE_SWARM_DIR/*.md
EOF
# Spawn with environment variables
NEW_PANE=$(/tmp/bsp-split.sh)
printf 'CLAUDE_SWARM_ID=%s CLAUDE_SWARM_DIR=%s CLAUDE_SESSION_ROLE=child CLAUDE_SESSION_PURPOSE="%s" CLAUDE_PARENT_SESSION=%s claude "$(cat %s)"\n' \
"$SWARM_ID" "$SWARM_DIR" "$PURPOSE" "${CLAUDE_SESSION_ID:-parent}" "$PROMPT_FILE" \
| wezterm cli send-text --pane-id "$NEW_PANE"# Setup swarm
SWARM_ID="$(basename $PWD)-$(date +%Y%m%d-%H%M%S)"
SWARM_DIR="./sessions/$SWARM_ID"
mkdir -p "$SWARM_DIR"
CWD_NAME=$(basename "$PWD")
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
# Initialize manifest
cat > "$SWARM_DIR/manifest.json" << EOF
{
"swarm_id": "$SWARM_ID",
"created_at": "$(date -Iseconds)",
"swarm_dir": "$SWARM_DIR",
"parent": {
"session_id": "${CLAUDE_SESSION_ID:-parent}",
"purpose": "Coordinate parallel tasks",
"status": "running"
},
"children": []
}
EOF
# Define tasks
TASKS=("write-tests" "fix-auth" "add-logging")
# Spawn each child
for PURPOSE in "${TASKS[@]}"; do
PROMPT_FILE="/tmp/claude-sessions/${CWD_NAME}-${TIMESTAMP}-${PURPOSE}.md"
cat > "$PROMPT_FILE" << EOF
## Swarm Context
- Swarm ID: $SWARM_ID
- Your Role: child
- Your Purpose: $PURPOSE
- Siblings: ${TASKS[*]}
## Instructions
1. Focus on YOUR assigned task: $PURPOSE
2. Update your progress file: \$CLAUDE_SWARM_DIR/child-\$CLAUDE_SESSION_ID.md
3. Check sibling status: cat \$CLAUDE_SWARM_DIR/*.md
4. When complete, update status to "completed"
## Task
$PURPOSE
EOF
NEW_PANE=$(/tmp/bsp-split.sh)
printf 'CLAUDE_SWARM_ID=%s CLAUDE_SWARM_DIR=%s CLAUDE_SESSION_ROLE=child CLAUDE_SESSION_PURPOSE="%s" CLAUDE_PARENT_SESSION=%s claude "$(cat %s)"\n' \
"$SWARM_ID" "$SWARM_DIR" "$PURPOSE" "${CLAUDE_SESSION_ID:-parent}" "$PROMPT_FILE" \
| wezterm cli send-text --pane-id "$NEW_PANE"
done# List all session status files
ls $CLAUDE_SWARM_DIR/*.md
# Read all sibling progress
for f in $CLAUDE_SWARM_DIR/*.md; do
echo "=== $(basename $f) ==="
cat "$f"
echo
done
# Check manifest for session list
cat $CLAUDE_SWARM_DIR/manifest.json | jq .# Add completed item
cat >> $CLAUDE_SWARM_DIR/child-$CLAUDE_SESSION_ID.md << EOF
- [x] Completed: <task description>
EOF
# Update status to completed
# (The hooks system does this automatically on Stop)- BSP = Binary Space Partitioning (always splits largest pane)
- Ratio > 2.0 = split right, else split bottom
- Use
<< 'EOF'(quoted) to prevent variable expansion in prompts - Swarm mode uses
./sessions/directory in the project root - Environment variables are passed inline before the
claudecommand