name: sim-pool description: "iOS simulator exclusive access management. Auto-triggers via PreToolUse hook before XcodeBuildMCP / ios-simulator tool calls. Prevents simulator conflicts between sessions."
Simulator Pool Management
Prevents simulator conflicts when multiple Claude Code sessions run in parallel on an iOS project.
How It Works
.claude/hooks/sim-pool-guard.shruns as PreToolUse hook, capturing all XcodeBuildMCP / ios-simulator tool calls (mcp__XcodeBuildMCP__.*,mcp__ios-simulator__.*)- Allowlist-based fail-closed: tools not explicitly listed are DENIED
- Each session gets an ephemeral simulator clone via
xcrun simctl clonefrom a golden image (APFS CoW) - For
ios-simulatortools: clone UDID auto-injected viaupdatedInput - For
XcodeBuildMCPbuild/test/run: first call DENIED with instructions to runsession_set_defaultspointing at clone
Guard Behavior
| Tool Category | Behavior |
|---|---|
Read-only tools (list_schemes, discover_projects, etc.) |
ALLOW immediately |
Clone-required tools (build, tap, take_screenshot, etc.) |
Ensure clone exists, then ALLOW with UDID injection |
session_set_defaults / session_use_defaults_profile with persist: true |
DENY (prevents cross-session pollution) |
| Unknown tools (not in any allowlist) | DENY with explanation (fail-closed) |
Golden Image Device Set Isolation
By default, golden image is in the default Device Set (risks accidental use by Xcode, Fastlane, simctl).
When SIM_GOLDEN_SET is configured:
- Golden operations use
xcrun simctl --set "$SIM_GOLDEN_SET"— invisible to defaultsimctl list - Clones via cross-set clone land in default Device Set for MCP compatibility
- Unset/empty: falls back to default Device Set
Ephemeral Clone Lifecycle
- Golden lazy init: First request boots
SIM_GOLDEN_NAME, waits for boot, shuts down, creates marker - Clone creation:
xcrun simctl clonecreatesatdd-kit-YYYYMMDDTHHMMSS-SESSION8. WithSIM_GOLDEN_SET: cross-set clone to default Device Set - Session lock: UDID and name stored in
$SESSION_DIR/$session_id - Orphan cleanup: Stale clones (past TTL) auto-deleted before new clone creation
Setup
Auto-configured on first iOS session or via /atdd-kit:setup-ios. See ${CLAUDE_PLUGIN_ROOT}/addons/ios/addon.yml.
Environment Overrides (Testing)
| Variable | Default | Purpose |
|---|---|---|
SIM_SESSION_DIR |
/tmp/claude-sim-sessions |
Session lock directory |
SIM_MARKER_DIR |
/tmp |
Golden init marker directory |
SIM_GOLDEN_NAME |
iPhone 17 Pro |
Golden image name |
SIM_GOLDEN_SET |
(empty) | Device Set path for golden image isolation. Empty = default Device Set |
SIM_DEFAULT_SET |
~/Library/Developer/CoreSimulator/Devices |
Device Set path for clones (cross-set clone destination) |
SIM_TTL_LOCAL |
7200 |
Local TTL in seconds (2h) |
SIM_TTL_CI |
2400 |
CI TTL in seconds (40min) |
SIM_CLONE_PREFIX |
atdd-kit- |
Clone name prefix |
Troubleshooting
- Clone not created: verify golden image exists (
xcrun simctl list devices availableor with--set "$SIM_GOLDEN_SET") - Stale clones: auto-cleaned on each new clone; manual:
xcrun simctl delete <udid> - Tool DENIED: check
READONLY_TOOLS/CLONE_REQUIRED_TOOLSinsim-pool-guard.sh - Golden in default list: set
SIM_GOLDEN_SETto a non-empty path