From iterm
iTerm2 pane management for splitting, listing, and closing panes within existing tabs from macOS host or Linux container environments.
npx claudepluginhub manifoldlogic/claude-code-plugins --plugin itermThis skill uses the workspace's default tool permissions.
**Last Updated:** 2026-02-19
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Generates original PNG/PDF visual art via design philosophy manifestos for posters, graphics, and static designs on user request.
Last Updated: 2026-02-19
Plugin: iterm
Scripts Location: plugins/iterm/skills/pane-management/scripts/
The pane-management skill provides iTerm2 pane management capabilities for Claude Code, enabling automated splitting, listing, and closing of panes within existing terminal tabs from both macOS host environments and Linux containers (via SSH tunneling).
Key Capabilities:
Important: This skill splits panes within an existing iTerm2 window. It will not create a new window if none exists. Use the tab-management skill to create new tabs or windows first.
When to Use This Skill vs Tab Management:
| Use Pane Management | Use Tab Management |
|---|---|
| Side-by-side code and terminal output | Separate workspaces for different repos |
| Monitoring logs alongside development | Spawning Claude agents in isolated tabs |
| Running tests while editing | Opening new worktree environments |
| Quick reference pane (docs, git log) | Need full-width terminal workspace |
| Comparing output from two commands | Creating new windows |
| Batch close related panes by name pattern | Close tabs by name pattern |
| Inventory panes across windows/tabs (JSON) | List tabs across windows (JSON) |
/Applications/iTerm.appiterm:open-tab first if no window is available.host.docker.internal with mounted SSH keysHOST_USER environment variable set in devcontainer.jsonSee the tab-management SKILL.md section "Container Mode Requirements" for full SSH setup, HOST_USER configuration, and profile details.
See the tab-management SKILL.md section "Host Mode Requirements" for details.
This skill sources iterm-utils.sh from the tab-management skill directory. If iterm-utils.sh cannot be sourced, the script exits with code 3. See the tab-management SKILL.md for verification commands and utility details.
| Skill | Description | Key Flags |
|---|---|---|
iterm:split-pane | Split current session into a new pane with direction, profile, command, and name options | -d direction, -p profile, -c command, -n name |
iterm:list-panes | List all panes across windows and tabs in table or JSON format with optional filtering | -f format (table/json), -w window filter, -t tab filter, --dry-run |
iterm:close-pane | Close panes by substring pattern matching on session names with confirmation prompts | <pattern> argument, --force, -w window filter, -t tab filter |
iterm:send-text | Send arbitrary text to a specific pane by number, with optional submit (CR) or no-newline modes | -p pane number, --submit, --no-newline, --dry-run |
User Request
├─ Need a separate workspace or full-width terminal?
│ └─ Yes → Use tab-management skill (iterm:open-tab)
├─ Need to create a window first (none exist)?
│ └─ Yes → Use tab-management skill (iterm:open-tab)
│ (pane-management requires an existing window)
└─ Want side-by-side panes in the current tab?
└─ Yes → Use pane-management skill
├─ Create a new pane?
│ └─ Use iterm:split-pane — which direction?
│ ├─ "right", "side by side", "beside" → -d vertical
│ └─ "below", "under", "stacked", "bottom" → -d horizontal
├─ See current pane layout?
│ └─ Use iterm:list-panes
│ ├─ Quick visual check → default table format
│ └─ Programmatic parsing → -f json
├─ Remove a pane?
│ └─ Use iterm:close-pane <pattern>
│ ├─ Preview first → --dry-run "pattern"
│ ├─ With confirmation → "pattern"
│ └─ Automated (no prompts) → --force "pattern"
├─ Send text to an existing pane?
│ └─ Use iterm:send-text -p PANE "text"
│ ├─ Shell command (standard newline) → default (no flag)
│ ├─ Claude Code session (needs Enter) → --submit
│ └─ Partial text (no newline) → --no-newline
The -d flag for iterm-split-pane.sh accepts only two values: vertical and horizontal. The terminology follows iTerm2 convention where vertical means the divider is vertical (panes appear side by side, left/right) and horizontal means the divider is horizontal (panes appear stacked, top/bottom).
| Natural Language | Flag Value | Visual Result |
|---|---|---|
| "right", "to the right" | vertical | New pane appears to the right |
| "left", "to the left" | vertical | New pane appears to the right (splits always add right/below) |
| "below", "under", "underneath" | horizontal | New pane appears below |
| "above", "over", "on top" | horizontal | New pane appears below (splits always add below) |
| "side by side", "alongside", "beside" | vertical | Panes arranged left and right |
| "stacked", "top and bottom", "one above the other" | horizontal | Panes arranged top and bottom |
Important clarifications:
This table maps common user requests to exact script invocations. Every command listed has been verified against the script source.
| User Says | Mapped To | Notes |
|---|---|---|
| "split right" | iterm-split-pane.sh -d vertical | Default direction is already vertical; -d vertical is explicit |
| "split below" | iterm-split-pane.sh -d horizontal | Horizontal divider creates top/bottom layout |
| "split and run my tests" | iterm-split-pane.sh -c "npm test" | Uses default vertical direction; adjust command as needed |
| "split right and run tests in watch mode" | iterm-split-pane.sh -d vertical -c "npm test -- --watch" | Combine direction and command |
| "split below and start the dev server" | iterm-split-pane.sh -d horizontal -c "npm run dev" | Horizontal split with command execution |
| "split with the ZSH profile" | iterm-split-pane.sh -p ZSH | Profile name must match an iTerm2 profile exactly |
| "split and name it Logs" | iterm-split-pane.sh -n Logs | Sets the pane title for identification |
| "open a pane below with Devcontainer profile running build" | iterm-split-pane.sh -d horizontal -p Devcontainer -c "npm run build" -n "Build" | All flags combined |
| "split right and navigate to my project" | iterm-split-pane.sh -d vertical -c "cd /workspace/repos/my-project" | Use -c with cd for directory navigation, not -d |
| "preview the split without doing it" | iterm-split-pane.sh --dry-run -d vertical | Dry-run shows generated AppleScript |
| User Says | Mapped To | Notes |
|---|---|---|
| "show me all panes" | iterm-list-panes.sh | Default table format; shows Window, Tab, Pane, Name columns |
| "list panes in window 1" | iterm-list-panes.sh -w 1 | Window index is 1-based |
| "list panes as JSON" | iterm-list-panes.sh -f json | JSON output for programmatic parsing |
| "show panes in window 1, tab 2 as JSON" | iterm-list-panes.sh -w 1 -t 2 -f json | Filters combine with AND logic |
| "what panes are in tab 3" | iterm-list-panes.sh -t 3 | Tab filter across all windows |
| User Says | Mapped To | Notes |
|---|---|---|
| "close the test pane" | iterm-close-pane.sh "test" | Substring match on session name (case-sensitive) |
| "force close all agent panes" | iterm-close-pane.sh --force "agent" | Skips confirmation prompt for multiple matches |
| "close panes matching 'worker' in window 2" | iterm-close-pane.sh -w 2 "worker" | Pattern is a positional argument after options |
| "preview which panes would be closed for 'dev'" | iterm-close-pane.sh --dry-run "dev" | Dry-run shows AppleScripts without executing |
| "close the Logs pane in window 1, tab 1" | iterm-close-pane.sh -w 1 -t 1 "Logs" | Combined window and tab filter with pattern |
| User Says | Mapped To | Notes |
|---|---|---|
| "send 'ls' to pane 2" | iterm-send-text.sh -p 2 "ls" | Default mode appends newline; standard shell command execution |
| "send a command to the Claude pane" | iterm-send-text.sh -p 2 --submit "your-command" | Use --submit for Claude Code panes; CR submits without literal newline in buffer |
| "start claude in pane 3" | iterm-send-text.sh -p 3 --submit "claude" | Sends "claude" + CR to properly launch Claude Code in that pane |
| "type without pressing enter in pane 1" | iterm-send-text.sh -p 1 --no-newline "partial" | Use --no-newline for fine-grained input control |
| "what pane number is the dev server" | iterm-list-panes.sh | List panes first to find the target pane number, then use -p |
| "preview what would be sent to pane 2" | iterm-send-text.sh -p 2 --dry-run "hello" | Dry-run shows generated AppleScript without executing |
| User Says | Mapped To | Notes |
|---|---|---|
| "spawn an agent in a new pane" | spawn-agent.sh --pane | Uses default vertical direction and current directory |
| "spawn agent to the right to investigate auth" | spawn-agent.sh --pane --direction vertical /workspace/repos/project "investigate auth" | Positional args: worktree path then task description |
| "spawn agent below in a horizontal split" | spawn-agent.sh --pane --direction horizontal | Direction only applies when --pane is set |
| User Says | Resolution | Notes |
|---|---|---|
| "open a terminal" | Use tab-management skill (iterm-open-tab.sh) | Creates a separate workspace in a new tab; pane-management splits within existing tab |
| "run something on the side" | Use pane-management skill (iterm-split-pane.sh -d vertical) | "On the side" implies side-by-side layout within the current tab |
| "I need another shell" | Depends on context: tab-management for isolated workspace, pane-management for quick side panel | Ask the user whether they want an independent tab or a split pane |
| "put the logs somewhere I can see them" | Use pane-management skill (iterm-split-pane.sh -d horizontal -c "tail -f logs") | "Somewhere I can see" suggests visible alongside current work, i.e., a pane |
Goal: Spawn a Claude agent in an adjacent pane so you can continue working in your current session while the agent handles a separate task.
Steps:
Split the current session vertically to create a side-by-side layout:
iterm-split-pane.sh -d vertical -n "Agent: auth fix"
In the new pane, start a Claude agent with a task:
iterm-split-pane.sh -d vertical -c "cd /workspace/repos/my-project && echo 'investigate the auth timeout in src/auth.ts' | claude --dangerously-skip-permissions" -n "Agent: auth fix"
Outcome: The agent runs in the right pane working on the auth investigation while you continue editing in the left pane. The pane title "Agent: auth fix" makes it easy to identify later.
Goal: See test output continuously in a split pane while editing code in the main pane.
Steps:
Split horizontally to create a stacked layout with tests running below:
iterm-split-pane.sh -d horizontal -c "cd /workspace/repos/my-project && npm test -- --watch" -n "Tests"
The test watcher starts immediately in the bottom pane. As you save files in the top pane, test results update automatically below.
Outcome: Tests run in the bottom pane in watch mode. The top pane remains your primary editing workspace. The pane title "Tests" identifies the pane in listings.
Goal: Create a 3-pane layout in a single tab with editing space, test output, and log tailing.
Steps:
Split vertically to create a right-side pane for test output:
iterm-split-pane.sh -d vertical -c "cd /workspace/repos/my-project && npm test -- --watch" -n "Tests"
Split the new pane horizontally to add a log tail below it:
iterm-split-pane.sh -d horizontal -c "tail -f /workspace/repos/my-project/logs/app.log" -n "Logs"
Verify the layout by listing panes in the current tab:
iterm-list-panes.sh -t 1
Outcome: Three panes in one tab: the original editing pane on the left, tests in the top-right, and logs in the bottom-right. Each pane has a descriptive title visible in the listing.
Goal: See the current pane organization across all windows and tabs to understand what is running where.
Steps:
List all panes in table format for a quick visual overview:
iterm-list-panes.sh
Output:
Window Tab Pane Name
1 1 1 Devcontainer
1 1 2 Tests
1 1 3 Logs
1 2 1 claude-code-plugins
List panes in the current tab as JSON for programmatic use:
iterm-list-panes.sh -w 1 -t 1 -f json
Filter to a specific window to see only its panes:
iterm-list-panes.sh -w 1
Outcome: You can see every pane's window index, tab index, pane index, and session name. JSON output is useful for scripting; table output gives a quick visual check. Filters narrow the view to specific windows or tabs.
Goal: Close multiple agent panes that have finished their work, keeping only the main development pane.
Steps:
List panes to see which ones match the agent naming pattern:
iterm-list-panes.sh
Output:
Window Tab Pane Name
1 1 1 Devcontainer
1 1 2 Agent: auth fix
1 1 3 Agent: test refactor
1 2 1 claude-code-plugins
Preview which panes would be closed using dry-run:
iterm-close-pane.sh --dry-run "Agent:"
Close all agent panes (skip confirmation since you already previewed):
iterm-close-pane.sh --force "Agent:"
Outcome: Both "Agent: auth fix" and "Agent: test refactor" panes are closed. The main "Devcontainer" pane and the "claude-code-plugins" tab remain open. Panes are closed in reverse order to prevent index shifting issues.
Goal: Use the spawn-agent.sh wrapper to spawn a Claude agent in a split pane with a single command, instead of manually building the split and agent command.
Steps:
Spawn an agent in a vertical split pane with a task description:
spawn-agent.sh --pane --direction vertical /workspace/repos/my-project "investigate the failing CI pipeline"
Or spawn an agent in a horizontal split for a stacked layout:
spawn-agent.sh --pane --direction horizontal /workspace/repos/my-project "refactor the database connection pool"
Spawn an agent in a pane using defaults (vertical direction, current directory):
spawn-agent.sh --pane
Outcome: The wrapper delegates to iterm-split-pane.sh with the correct flags, builds the Claude command with the task description piped in, and sets the pane name from the task. The agent starts running in the new pane immediately. If the plugin script is unavailable, spawn-agent.sh falls back to its built-in AppleScript implementation.
Goal: Set up a 3-pane layout with Claude Code sessions running in two new panes while the main pane remains available for work.
Steps:
List current panes to confirm the starting state:
iterm-list-panes.sh
Split vertically to create pane 2 on the right:
iterm-split-pane.sh -d vertical -n "Claude Agent 1"
Split pane 2 horizontally to create pane 3 below it:
iterm-split-pane.sh -d horizontal -n "Claude Agent 2"
Send "claude" to pane 2 with --submit to properly launch Claude Code there:
iterm-send-text.sh -p 2 --submit "claude"
Send "claude" to pane 3 with --submit:
iterm-send-text.sh -p 3 --submit "claude"
Outcome: Three panes in one tab -- main pane on the left, two Claude Code sessions on the right. Using --submit ensures the claude command is submitted correctly (the pane handles it as Enter/Return, not a literal newline). Without --submit, the newline appended by standard write text would be treated as a literal newline character in the Claude Code input buffer, causing the command to fail.
Splits the current iTerm2 session into a new pane with support for direction selection, profile specification, command execution, and pane naming.
Usage:
iterm-split-pane.sh [OPTIONS]
Options:
| Flag | Long Form | Description | Default |
|---|---|---|---|
-d | --direction DIR | Split direction: vertical or horizontal | vertical |
-p | --profile PROFILE | iTerm2 profile name | Devcontainer |
-c | --command CMD | Command to run in the new pane | (none) |
-n | --name NAME | Set pane title | (profile default) |
--dry-run | Show AppleScript without executing | (false) | |
-h | --help | Display help information |
Flag Clarification:
-d sets the split direction (vertical or horizontal), NOT the working directory. This is different from -d in the tab-management script (which sets the directory). To navigate to a directory in the new pane, use -c "cd /path".-c sets a command to execute in the new pane. This can include navigation commands like cd /path/to/dir.Examples:
# Split vertically with default Devcontainer profile
iterm-split-pane.sh
# Split horizontally
iterm-split-pane.sh -d horizontal
# Split with custom profile and title
iterm-split-pane.sh -p "Custom Profile" -n "My Pane"
# Split and run a command in the new pane
iterm-split-pane.sh -c "git status"
# Navigate to a directory in the new pane
iterm-split-pane.sh -c "cd /workspace/repos/my-project"
# Preview AppleScript without executing
iterm-split-pane.sh --dry-run -d horizontal -n "Test Pane"
# All options combined
iterm-split-pane.sh -d vertical -p "Development" -c "npm test" -n "Test Runner"
Purpose: List all panes across windows and tabs with optional filtering.
Usage:
iterm-list-panes.sh [OPTIONS]
Flags:
| Flag | Long Form | Description | Default |
|---|---|---|---|
-f | --format FORMAT | Output format: table or json | table |
-w | --window INDEX | Filter to specific window (1-based) | (all windows) |
-t | --tab INDEX | Filter to specific tab (1-based) | (all tabs) |
--dry-run | Show AppleScript without executing | (false) | |
-h | --help | Show help message |
Output Formats:
table (default): ASCII table with columns Window, Tab, Pane, Name. Names longer than 30 characters are truncated with ....
Window Tab Pane Name
1 1 1 Devcontainer
1 1 2 Tests
1 2 1 claude-code-plugins
2 1 1 System Monitor
json: Nested JSON object with windows array containing tabs arrays containing panes arrays. Each pane has index and name fields.
{
"windows": [
{
"index": 1,
"tabs": [
{
"index": 1,
"panes": [
{"index": 1, "name": "Devcontainer"},
{"index": 2, "name": "Tests"}
]
}
]
}
]
}
Examples:
# List all panes in default table format
iterm-list-panes.sh
# List panes in window 1 only
iterm-list-panes.sh -w 1
# List panes as JSON for programmatic parsing
iterm-list-panes.sh -f json
# List panes in window 1, tab 2 (filters combine with AND logic)
iterm-list-panes.sh -w 1 -t 2
# List panes in tab 3 across all windows
iterm-list-panes.sh -t 3
# JSON output filtered to a specific window
iterm-list-panes.sh --format json --window 1
# Preview AppleScript without executing
iterm-list-panes.sh --dry-run
Exit Codes:
See the Exit Codes section below. This script uses codes 0 (success), 1 (connection failure), 2 (iTerm2 unavailable), and 3 (invalid arguments).
Purpose: Close panes matching a pattern in their session name.
Usage:
iterm-close-pane.sh [OPTIONS] <pattern>
Arguments:
| Argument | Required | Description |
|---|---|---|
pattern | Yes | String to match in pane session name (case-sensitive, substring match) |
Flags:
| Flag | Long Form | Description | Default |
|---|---|---|---|
-w | --window INDEX | Limit to specific window (1-based) | (all windows) |
-t | --tab INDEX | Limit to specific tab (1-based) | (all tabs) |
--force | Skip confirmation prompt for multiple matches | (interactive) | |
--dry-run | Show what would be closed without executing | (false) | |
-h | --help | Show help message |
Confirmation Flow:
Found N matching panes. Close them all? [y/N]:--force to bypass the confirmation prompt (useful for automation and scripting)Behavior:
"agent" matches "Agent: auth" only if the casing matches exactly.iterm-close-pane.sh "worktree: feature"EXIT_NO_MATCH) is returned when no panes match the provided patternExamples:
# Close panes with "agent:" in session name
iterm-close-pane.sh "agent:"
# Force close without confirmation prompt
iterm-close-pane.sh --force "cleanup"
# Close panes matching "test" in window 1 only
iterm-close-pane.sh -w 1 "test"
# Close panes matching "worker" in tab 2 only
iterm-close-pane.sh -t 2 "worker"
# Close panes in window 2, tab 1 with pattern
iterm-close-pane.sh --force -w 2 -t 1 "worktree: feature"
# Preview which panes would be closed (dry-run)
iterm-close-pane.sh --dry-run "feature-branch"
Exit Codes:
See the Exit Codes section below. This script uses codes 0 (success), 1 (connection failure), 2 (iTerm2 unavailable), 3 (invalid arguments), and 4 (no panes match pattern).
Purpose: Send text to a specific pane identified by its 1-based pane number.
Usage:
iterm-send-text.sh -p PANE [--submit | --no-newline] [--dry-run] [-h] <text>
Arguments:
| Argument | Required | Description |
|---|---|---|
<text> | Yes | Text to send to the target pane (must be non-empty) |
Flags:
| Flag | Long Form | Description | Default |
|---|---|---|---|
-p | --pane PANE | Target pane number (1-based session index) | (required) |
--submit | Send text without newline, then send CR (ASCII 13) to simulate Enter | (false) | |
--no-newline | Send text without any trailing newline | (false) | |
--dry-run | Show AppleScript without executing | (false) | |
-h | --help | Show help message |
Flag Clarification:
-p in iterm-send-text.sh means --pane, NOT --profile. This differs from iterm-split-pane.sh where -p means --profile.--submit and --no-newline are mutually exclusive. Using both together exits with code 3.write text "text" which appends a standard newline -- works for shell commands, not for Claude Code sessions.--submit uses write text "text" without newline + write text (ASCII character 13) without newline -- correct for Claude Code sessions.Text Modes:
| Mode | When to Use | AppleScript Behavior |
|---|---|---|
| Default (no flag) | Shell commands | write text "text" -- appends newline |
--submit | Claude Code sessions | write text "text" without newline + write text (ASCII character 13) without newline |
--no-newline | Partial input / advanced control | write text "text" without newline |
Examples:
# Send shell command to pane 2 (standard newline)
iterm-send-text.sh -p 2 "npm test"
# Send command to Claude Code session in pane 3 (use --submit)
iterm-send-text.sh -p 3 --submit "claude"
# Send text without trailing newline to pane 1
iterm-send-text.sh -p 1 --no-newline "partial input"
# Preview the AppleScript without sending
iterm-send-text.sh -p 2 --dry-run --submit "claude"
# Find pane numbers first, then send
iterm-list-panes.sh
iterm-send-text.sh -p 2 --submit "claude --dangerously-skip-permissions"
Exit Codes:
See the Exit Codes section below. This script uses codes 0 (success), 1 (connection failure), 2 (iTerm2 unavailable or no windows), and 3 (invalid arguments or invalid pane number).
The script automatically detects whether it is running on the macOS host or inside a container and adapts its execution strategy. This detection uses the shared iterm-utils.sh from the tab-management skill.
osascript (~100ms latency)host.docker.internal (~500ms latency)Pane-specific difference: Pane operations require an existing window and will not create one. In both modes, the script targets the first window in its AppleScript. If no window exists, the script returns "NO_WINDOWS" (exit code 2). Use iterm:open-tab to create a window first.
See the tab-management SKILL.md section "Execution Contexts" for the complete detection logic diagram, host/container mode details, and behavior comparison table.
Codes 0-4 are defined in iterm-utils.sh (shared across all iterm skills). Code 4 is used exclusively by iterm-close-pane.sh.
| Code | Constant | Description | Used By |
|---|---|---|---|
| 0 | EXIT_SUCCESS | Operation completed successfully | All scripts |
| 1 | EXIT_CONNECTION_FAIL | SSH connection to host failed | All scripts (container mode) |
| 2 | EXIT_ITERM_UNAVAILABLE | iTerm2 not running or not accessible | All scripts |
| 3 | EXIT_INVALID_ARGS | Invalid arguments or configuration | All scripts |
| 4 | EXIT_NO_MATCH | No panes matched the specified pattern | iterm-close-pane.sh |
Example Error Handling:
#!/bin/bash
if iterm-close-pane.sh --force "agent:"; then
echo "Panes closed successfully"
else
exit_code=$?
case $exit_code in
1) echo "Connection failed - check SSH config" ;;
2) echo "iTerm2 not available" ;;
3) echo "Invalid arguments" ;;
4) echo "No panes matched pattern" ;;
*) echo "Unknown error: $exit_code" ;;
esac
exit $exit_code
fi
"NO_WINDOWS" returned
The script returns "NO_WINDOWS" instead of splitting a pane. No iTerm2 windows are open. Unlike tab-management (which can create new windows), pane-management requires an existing window to split within.
Solution:
iterm-open-tab.sh -d /workspace
iterm-split-pane.sh -d vertical
"Invalid direction" (exit code 3)
The -d flag received a value other than vertical or horizontal. A common mistake is passing a directory path to -d (which sets direction, not directory).
Solution:
vertical or horizontal with -d:
iterm-split-pane.sh -d vertical
iterm-split-pane.sh -d horizontal
-c with a cd command:
iterm-split-pane.sh -c "cd /workspace/repos/my-project"
"Profile not found" / AppleScript execution failed (exit code 1)
The profile specified with -p does not exist in iTerm2, or AppleScript permissions have not been granted.
Solution:
--dry-run to inspect generated AppleScript:
iterm-split-pane.sh --dry-run -d vertical -p "Devcontainer"
Empty output / No panes found
The list command returns no rows or an empty table. This occurs when no iTerm2 windows are open, or when the applied filters exclude all panes.
Solution:
iterm-list-panes.sh
Filter not matching expected panes
The -w or -t filter returns fewer panes than expected or none at all. Window and tab indices are 1-based. Using a 0-based index or an index that exceeds the window/tab count returns no results.
Solution:
iterm-list-panes.sh
-w 1 -t 2 shows only panes in window 1 AND tab 2JSON output issues
If JSON output appears malformed or truncated, the most likely cause is an iTerm2 session name containing special characters that interfere with the delimiter parsing.
Solution:
iterm-list-panes.sh -f table
iterm-list-panes.sh -f json
Exit code 4: No panes matched pattern
The pattern provided to iterm-close-pane.sh does not match any pane session names. Pattern matching is case-sensitive substring match, not regex.
Solution:
iterm-list-panes.sh
"Agent" does not match "agent"--dry-run to preview what would be matched:
iterm-close-pane.sh --dry-run "your-pattern"
Last pane closes the entire tab
When the last pane in a tab is closed, the tab itself closes. If it is the last tab in a window, the window closes. This is expected iTerm2 behavior, not a bug.
Solution:
iterm-list-panes.sh -w 1 -t 1
Confirmation prompt blocks automation
When multiple panes match the pattern, the script prompts for confirmation interactively. This blocks non-interactive scripts and automation pipelines.
Solution:
--force flag to bypass the confirmation prompt:
iterm-close-pane.sh --force "agent:"
--force"INVALID_PANE" returned (exit code 3)
The pane number specified with -p does not exist in the current tab. The count of sessions in the current tab is less than the requested pane number.
Solution:
iterm-list-panes.sh
Pane column value from the output as the -p argument-w and -t filters with iterm-list-panes.sh to see pane numbers in a specific tabCommand sent but not executed in Claude Code pane
Text was sent but the command was not submitted -- it appears as text in the input buffer without executing.
Solution:
--submit instead of the default mode:
iterm-send-text.sh -p 2 --submit "your-command"
write text "text" which appends a newline (\n, ASCII 10). Claude Code treats \n as a literal newline in the input buffer, not as Enter/Return. The --submit mode sends \r (ASCII 13) instead, which iTerm2 interprets as Enter.Text sent to wrong pane
The text appeared in an unexpected pane.
Solution:
iterm-list-panes.sh to confirm pane numbers before sendingiterm-list-panes.sh since new panes get the next sequential indexFor SSH connectivity, HOST_USER configuration, iterm-utils.sh sourcing failures, and AppleScript permission issues, see the tab-management SKILL.md Troubleshooting section. These infrastructure issues are shared across tab and pane management skills and are documented in detail there.
Each operation from container mode incurs ~500ms SSH overhead:
Optimization: For batch operations, consider running from host mode when possible.
When splitting multiple panes rapidly:
# Add small delay between pane splits to avoid race conditions
for cmd in "npm test" "npm run dev" "git log --follow -p"; do
iterm-split-pane.sh -d vertical -c "$cmd"
sleep 0.3 # 300ms delay prevents iTerm2 race conditions
done
The script always targets first window in its AppleScript for multi-window safety. This means:
For agent workflows and concurrent task monitoring:
When to Use Tabs Instead:
Use the tab-management skill to create additional tabs when pane limits are reached.
The devcontainer spawn-agent.sh script supports spawning Claude agents directly in panes:
Flags:
--pane: Spawn agent in a new pane instead of a new tab--direction <vertical|horizontal>: Specify split direction (requires --pane)Example:
# Spawn agent in vertical pane (right side)
spawn-agent.sh --pane --direction vertical
Behavior:
spawn-agent.sh detects the iterm plugin and delegates to iterm-split-pane.shYou can mix pane and tab management in workflows:
Example: Multi-Agent Workflow
iterm-open-tab.sh -n "Agents"spawn-agent.sh --pane --direction verticaliterm-split-pane.sh -d horizontalAfter completing agent work:
iterm-list-panes.shiterm-close-pane.sh "Agent:"iterm-close-tab.sh "Agents"Skills:
Scripts:
References: