l-swarm-local-confirm
Check out multiple PRs as git worktrees, assign unique sequential ports (40000+), launch dev servers, and report all localhost URLs for simultaneous Port range 40000-40099 avoids macOS ephemeral port ...
Swarm Local Confirm
Check out multiple PRs as git worktrees with unique ports, launch dev servers for all, and give the user localhost URLs for simultaneous visual confirmation.
Prerequisites
- Must be run from the repo root (not from inside a worktree)
- The repo must be clean (no uncommitted changes) or changes must be stashed
Step 1: Parse Input
The user provides PR numbers, branch names, or hints. Parse these to identify target PRs.
Examples of valid input:
1100 1101 1102— PR numbers#1100 #1101 #1102— PR numbers with hashnoci/top-page-v1 noci/top-page-v2— branch namesall noci— keyword meaning “all open PRs withnoci/prefix”
Handling “all noci” keyword
If the user says all noci or similar:
gh pr list --state open --json number,headRefName --jq '.[] | select(.headRefName | startswith("noci/")) | "\(.number) \(.headRefName)"'
Resolving PR numbers to branches
For each PR number:
gh pr view <PR_NUMBER> --json headRefName,title --jq '"\(.headRefName)\t\(.title)"'
Collect all into a list: WORKTREES=( "branch1" "branch2" ... )
Report the list to the user before proceeding:
Found N PRs to confirm:
#1100 noci/top-page-v1 — "Top page design: grid layout"
#1101 noci/top-page-v2 — "Top page design: hero banner"
#1102 noci/top-page-v3 — "Top page design: minimal"
Step 2: Checkout Worktrees
For each branch, create a worktree using the project’s init script:
pnpm run init-worktree <branch-name>
This creates worktrees/<branch-name>/ with proper env file symlinks.
If the worktree already exists, skip creation and reuse it.
Important: The branch name may contain / (e.g., noci/top-page-v1). The init-worktree script handles this — it creates the worktree using the branch name as the directory name under worktrees/.
If the init-worktree script doesn’t support slashes in directory names, fall back to manual worktree creation:
SAFE_NAME=$(echo "<branch-name>" | tr '/' '-')
git worktree add "worktrees/$SAFE_NAME" "<branch-name>"
Then symlink env files manually following the same pattern as the init script.
Step 3: Assign Unique Ports and Patch package.json
Starting from port 40000, assign each worktree a unique port sequentially.
For each worktree at index i (0-based):
PORT=$((40000 + i))
In each worktree, add a dev-local-wt script to package.json that:
- Runs
_prepare(build public directory) - Sets up local image symlinks
- Kills any process on the assigned port
- Starts the Astro dev server on the unique port
Use node to patch the package.json (safer than sed for JSON):
cd worktrees/<name>
node -e "
const fs = require('fs');
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
const PORT = $PORT;
pkg.scripts['dev-local-wt'] = 'pnpm run _prepare && pnpm setup:local-images && (lsof -ti:' + PORT + ' | xargs kill -9 2>/dev/null || true) && astro dev --port ' + PORT + ' --host localhost';
fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
"
Do NOT commit these changes. They are temporary local-only tweaks.
Step 4: Install Dependencies
Run pnpm install in each worktree if node_modules doesn’t exist or is stale.
Since all worktrees share the same lockfile, a simple check is:
cd worktrees/<name>
if [ ! -d "node_modules" ]; then
pnpm install
fi
Step 5: Launch Dev Servers
Launch all dev servers in the background. Use pnpm dev-local-wt in each worktree:
cd worktrees/<name>
pnpm dev-local-wt &
Use the Bash tool with run_in_background: true for each, or launch them all in a single script.
Wait a few seconds for servers to start, then verify each is responding:
curl -s -o /dev/null -w "%{http_code}" http://localhost:<PORT>/
Step 6: Report URLs to User
Present all URLs in a clear table format:
All dev servers are running! Open these URLs to compare:
| PR | Branch | Port | URL |
|----|--------|------|-----|
| #1100 | noci/top-page-v1 | 40000 | http://localhost:40000/ |
| #1101 | noci/top-page-v2 | 50001 | http://localhost:50001/ |
| #1102 | noci/top-page-v3 | 50002 | http://localhost:50002/ |
To stop all servers:
kill $(lsof -ti:40000,50001,50002) 2>/dev/null
If specific pages are relevant (e.g., top page prototypes), include direct paths:
Top page comparison:
http://localhost:40000/
http://localhost:50001/
http://localhost:50002/
Cleanup
When the user is done, provide a cleanup command:
# Kill all dev servers
for port in $(seq 40000 <last_port>); do
lsof -ti:$port | xargs kill -9 2>/dev/null
done
# Remove worktrees (optional — user decides)
# git worktree remove worktrees/<name>
Do NOT auto-cleanup. Let the user decide when they’re done.
Error Handling
- If a worktree checkout fails (e.g., branch conflicts), skip it and report the error
- If a dev server fails to start, report which one failed and continue with the rest
- If
pnpm installfails, trypnpm install --frozen-lockfileas fallback - Always report partial successes — even if only 2 of 5 servers start, that’s useful