npm.io
0.6.1 • Published 1 month agoCLI

xcode-build-queue

Licence
MIT
Version
0.6.1
Deps
1
Size
104 kB
Vulns
0
Weekly
0

xbq — Xcode Build Queue

Serial build queue for Xcode projects with git worktrees.

Problem

Running multiple Claude Code sessions on the same Xcode project requires separate repos, each needing its own SPM resolution and DerivedData (~8GB+ per copy). This tool eliminates that duplication by routing all builds through a single "main" repo.

How It Works

┌──────────────┐   ┌──────────────┐    ┌──────────────┐
│ Claude Code  │   │ Claude Code  │    │ Claude Code  │
│ (worktree A) │   │ (worktree B) │    │ (worktree C) │
└──────┬───────┘   └──────┬───────┘    └──────┬───────┘
       │ snapshot         │ snapshot          │ snapshot
       └──────────────────┼───────────────────┘
                          ▼
               ┌────────────────────┐
               │ xbq (serial queue) │
               │                    │
               │ checkout snapshot  │
               │ (detached HEAD)    │
               │ build/test via     │
               │ Xcode MCP or       │
               │ xcodebuild         │
               └────────┬───────────┘
                        ▼
                  ┌───────────┐
                  │ Main Repo │  ← single DerivedData
                  │ (warm)    │  ← SPM already resolved
                  └───────────┘
  • Claude Code sessions edit code in lightweight git worktrees (code only, no builds)
  • When they need to build/test, they run xbq build or xbq test
  • xbq creates a snapshot commit of all changes and checks it out via detached HEAD in the main repo
  • Jobs run serially to prevent DerivedData corruption
  • Results are returned to the requesting session
  • Each worktree gets a CLAUDE.md that tells Claude Code to use xbq

Installation

npm install -g xcode-build-queue
From GitHub
npm install -g github:a-ulkhan/xbq
From source
git clone https://github.com/a-ulkhan/xbq.git
cd xbq
make install

Setup

# Configure (point to your main Xcode repo)
xbq init ~/path/to/your/project

# Start the daemon
xbq daemon start
Optional: git-restore-mtime

For best incremental build performance after branch switches:

pip3 install git-restore-mtime

Fleet Management

Manage multiple parallel Claude sessions across worktrees with templates and session tracking.

# Launch a code-review session for an MR
xbq fleet launch -t code-review --mr 4521

# Launch a feature session for a Jira ticket
xbq fleet launch -t feature --ticket MOBI-12345

# Launch with a custom name and prompt
xbq fleet launch my-experiment -p "refactor the auth module"

# Check all fleet sessions
xbq fleet status
# WORKTREE              STATUS     TASK                    SINCE
# code-review-mr-4521   active     Review MR !4521         12m
# feature-mobi-12345    active     feature MOBI-12345      8m

# Stop a session
xbq fleet stop code-review-mr-4521
Templates

Templates are user-managed JSON files in ~/.bq/fleet/templates/. Three defaults are seeded on xbq init:

Template Use case Placeholders
code-review MR review {mr}
feature New feature {ticket}
bugfix Bug fix {ticket}

Manage templates via CLI:

# List all templates
xbq fleet templates list

# Create a custom template
xbq fleet templates create refactor --prompt "Refactor {ticket}: ..."

# Edit an existing template in $EDITOR
xbq fleet templates edit bugfix

# Delete a template
xbq fleet templates delete refactor

# Re-seed defaults (only if templates directory is empty)
xbq fleet templates seed

Template JSON format (~/.bq/fleet/templates/bugfix.json):

{
  "name": "bugfix",
  "prompt_prefix": "Fix Jira ticket {ticket}:\n1) Fetch ticket\n2) Trace root cause\n3) Fix\n4) Build + test\n5) Commit",
  "permissions": ["Read", "Grep", "Glob"]
}

Use {ticket} and {mr} as placeholders — they are substituted from --ticket and --mr flags. The permissions field is optional.

Quick Start

Start a new parallel session
# Create a worktree + launch Claude Code (all-in-one)
xbq session my-feature

# With an initial prompt (auto-submitted to Claude Code)
xbq session my-feature -p "implement login screen"

# Or create worktree only (e.g. to open in a new terminal)
xbq worktree new my-feature

# Auto-named session (timestamp-based)
xbq session

xbq session / xbq worktree new:

  1. Creates a git worktree branching from the default branch
  2. Auto-injects xbq instructions into the worktree's CLAUDE.md
  3. Optionally launches Claude Code in the worktree
  4. With -p, passes the prompt directly to Claude Code so it starts working immediately
Build and test from a worktree
# Build (changes are captured automatically via diff — no commit needed)
xbq build

# Run tests
xbq test

# With specific destination
xbq build --destination "platform=iOS Simulator,name=iPhone 16,OS=26.2"

# Specific scheme/test plan
xbq test --scheme MyScheme --test-plan All

# Run only specific test classes
xbq test --only-testing PaysAppUnitTests/BankDetailsPresenterTests

# Run specific test methods
xbq test --only-testing PaysAppUnitTests/BankDetailsPresenterTests/testValidInput

# Multiple targeted tests
xbq test --only-testing PaysAppUnitTests/BankDetailsPresenterTests PaysAppTransferSDKTests/IBANGeneratorTests

# Force xcodebuild backend
xbq build --backend xcodebuild

# Legacy branch mode (for pushed branches)
xbq build --branch feature/my-branch

Worktree Management

# List all worktrees
xbq worktree list

# Clean up merged and stale worktrees (>7 days, no uncommitted changes)
xbq worktree clean

# Force remove all non-main worktrees
xbq worktree clean --force

# Custom age threshold
xbq worktree clean --days 3
Cleanup rules
Condition Action
Branch merged into default branch Removed automatically
Stale (>7d) with no uncommitted changes Removed automatically
Active with uncommitted work Kept (unless --force)

Tip: add to crontab for automatic cleanup:

0 9 * * * xbq worktree clean

Claude Code Integration

Every worktree created by xbq gets a CLAUDE.md that instructs Claude Code to:

  • NEVER run xcodebuild directly in the worktree
  • NEVER use Xcode MCP build/test tools directly
  • ALWAYS use xbq build / xbq test (changes are captured automatically)

This is automatic — no manual setup needed per session.

To manually manage the Claude integration:

# Inject xbq instructions into an existing project's CLAUDE.md
xbq setup-claude /path/to/worktree

# Remove xbq instructions
xbq setup-claude --remove /path/to/worktree

The injection is idempotent (safe to run multiple times) and uses HTML markers to update in place.

Queue Management

# Check daemon and queue status
xbq status

# View recent job results
xbq logs

# View a specific job's full log
xbq logs 20260323-101530-abc123

# Clean old results and logs (default: 7 days)
xbq clean

Daemon

xbq daemon start      # Start in background
xbq daemon stop       # Stop
xbq daemon status     # Check status + queue info
xbq daemon start -f   # Foreground (for debugging)

The daemon auto-starts when you enqueue a job if it's not already running.

Backends

Xcode MCP (default)

Uses Xcode 26.3+'s native MCP server (xcrun mcpbridge). Requires Xcode to be running with the project open. Provides richer diagnostics.

xcodebuild (fallback)

Standard CLI build tool. Works headless, no Xcode GUI needed. Auto-selected when mcpbridge is unavailable.

If MCP fails, xbq automatically falls back to xcodebuild (configurable).

Configuration

Manage settings via xbq config:

# List all settings
xbq config list

# Get a specific value
xbq config get backend

# Set a value
xbq config set backend xcodebuild
xbq config set default_destination "platform=iOS Simulator,name=iPhone 16,OS=18.0"
xbq config set xcodebuild_fallback false
Available keys
Key Type Default Description
main_repo string "" Path to main Xcode repo
workspace string "" Xcode workspace name
default_scheme string "" Default build scheme
default_test_scheme string "" Scheme for test jobs (falls back to default_scheme if empty)
default_test_plan string "" Default test plan
default_destination string platform=iOS Simulator,name=iPhone 16 Simulator destination
backend mcp | xcodebuild mcp Build backend
xcodebuild_fallback boolean true Fall back to xcodebuild if MCP fails
git_restore_mtime boolean true Restore file timestamps for incremental builds

Config is stored at ~/.bq/config.json. Workspace, scheme, and backend are auto-detected during xbq init.

All Commands

Command Description
xbq init [path] First-time setup — set main repo path
xbq session [name] [-p prompt] Create worktree + start Claude Code
xbq worktree new [name] Create a new worktree
xbq worktree list List all worktrees
xbq worktree clean Remove merged/stale worktrees
xbq fleet status Show all fleet sessions and their state
xbq fleet launch [name] Create a tracked worktree session from a template
xbq fleet stop <name> Mark a fleet session as stopped
xbq fleet templates list List available fleet templates
xbq fleet templates create <name> Create a new template
xbq fleet templates edit <name> Open a template in $EDITOR
xbq fleet templates delete <name> Delete a template
xbq fleet templates seed Seed default templates
xbq build Enqueue a build job
xbq test Enqueue a test job
xbq status Show daemon + queue status
xbq logs [job-id] View build logs / recent results
xbq daemon start|stop|status Manage the queue daemon
xbq setup-claude [dir] Inject/update xbq instructions in CLAUDE.md
xbq config list Show all config values
xbq config get <key> Get a config value
xbq config set <key> <value> Set a config value
xbq clean Clean old results and logs
Common flags
Flag Commands Description
-p, --prompt <prompt> session, fleet launch Initial prompt for Claude Code
-t, --template <name> fleet launch Template: code-review, feature, bugfix
--mr <iid> fleet launch GitLab MR IID (for code-review template)
--ticket <key> fleet launch Jira ticket key (for feature/bugfix template)
-b, --branch <branch> build, test Branch to build (optional in worktree)
-s, --scheme <scheme> build, test Xcode scheme override
-d, --destination <dest> build, test Simulator destination
--test-plan <plan> test Test plan name
-o, --only-testing <ids...> test Run only specific test identifiers (Target/Class or Target/Class/method)
--backend <backend> build, test Force mcp or xcodebuild
--timeout <seconds> build, test Job timeout (default: 1800)

Requirements

  • Node.js >= 18
  • Xcode 26.3+ (for MCP backend) or any Xcode (for xcodebuild backend)
  • git
  • Optional: git-restore-mtime (pip3 install git-restore-mtime)