bun dw — Dev Worktrees
Run isolated, parallel Autumn dev stacks per git worktree. Each agent gets its own Neon DB branch, Redis (Dragonfly), SQS (ElasticMQ), portless HTTPS aliases, and tmux-wrapped dev server — no port collisions, no cross-contamination.
When to use it
| You are | Run |
|---|---|
| In the canonical (main) worktree | bun dev |
| In a parallel agent worktree (direct) | bun dw |
| Spawned by Conductor/Superset | already done — bun dw identify to find your stack |
Prerequisites
Most auto-install on first run:
- Neon CLI —
neonctl(logs in via OAuth on first use) - psql — for DDL against new branches
- Docker + Compose — spins Dragonfly + ElasticMQ per worktree
- Stripe CLI — used by the dev server for webhooks
- tmux — headless dev wrapping for agent worktrees
- portless —
npm install -g @portless/clifor HTTPS aliases - emulate —
npm install -g @kelby/emulatefor Google OAuth locally
Lifecycle
bun dw # provision (if first run) → start dev
bun dw setup # provision only (no dev server)
bun dw run # start dev server only (must already be provisioned)
bun dw identify # discover your URLs / ports / tmux session
bun dw attach # jump into tmux to watch logs interactively
bun dw logs # tail last 2000 lines without attaching
bun dw reset # nuke DB branch + containers → re-provision
bun dw teardown # full cleanup of this worktree
bun dw teardown --all # full cleanup of every agent worktree
bun dw disable # rename .env.local -> .env.local.disabled (fall back to canonical env)
bun dw enable # rename .env.local.disabled -> .env.local
bun dw admin # set the better-auth global role to 'admin' for every user in this worktree's DB
Subcommands
bun dw (no args)
Registers the current worktree, provisions a Neon branch (first-run only), ensures Docker compose services, writes .env.local files, kills stale ports, and starts the dev server.
bun dw
Worktree #1 runs inline; worktree #N>1 spawns in a detached tmux session when stdout is not a TTY.
bun dw setup
Provisions the current worktree (Neon branch, Docker compose stack, env files) but does not start the dev server. Use when the orchestrator already owns the dev-server pane.
bun dw setup
bun dw run
Starts the dev server in the current provisioned worktree. Fails if the worktree hasn't been registered yet. Always runs inline (never uses tmux) so the orchestrator's Run button owns the process.
bun dw run
bun dw identify
Prints your stack's URLs and tmux session. Example output:
Worktree #3 (/Users/amianthus/Documents/Code/Autumn OSS/sirtenzin-autumn)
Branch: dw-wt-3-a1b2c3d
Server URL: https://wt3-api.localhost
Vite URL: https://wt3.localhost
Tmux session: dw-wt-3
Server port: 8280
Vite port: 3200
DW_WORKTREE_NUM=3
DW_SERVER_URL=https://wt3-api.localhost
DW_VITE_URL=https://wt3.localhost
DW_TMUX_SESSION=dw-wt-3
DW_SERVER_PORT=8280
DW_VITE_PORT=3200
Machine-parseable KEY=value pairs are emitted after the blank line for eval-ing in shells.
bun dw list
Shows all registered worktrees with ports and age.
bun dw list
# 1 | (canonical) | server :8080 vite :3000 | 0d | /Users/.../main
# 3 | dw-wt-3-a1b2c3d | server :8280 vite :3200 | 2d | /Users/.../wt3
bun dw reset
Tears down only this worktree's DB branch, Docker compose stack, and env files, then re-provisions from scratch. Use when your DB is corrupt or you need a clean slate.
bun dw reset
bun dw logs
Dumps the last 2000 lines from your tmux pane without attaching.
bun dw logs
bun dw attach
Attaches your terminal to the worktree's tmux session. Detach with Ctrl+B then D.
bun dw attach
bun dw disable
Renames each managed .env.local to .env.local.disabled so tooling falls back to the canonical (infisical-injected) env. Useful when a test or script needs the canonical env without nuking your worktree provisioning.
bun dw disable
bun dw enable
Inverse of disable — restores each .env.local.disabled to .env.local.
bun dw enable
bun dw admin
Sets the better-auth global user role to admin for every row in the user table of this worktree's DB, granting the superuser scope locally (the /admin routes + impersonation). Org membership roles (member table) are left untouched.
bun dw admin
Targets databaseUrl from the registry entry for the current worktree, falling back to DATABASE_URL. Refuses to run against production via the shared assertNotProductionDb guard (connection strings containing us-east-2).
bun dw teardown
Full cleanup of the current worktree: deletes Neon branch, unregisters portless aliases, kills tmux session, removes Docker compose stack, removes .env.local files, and deletes the registry entry. If no other agent worktrees remain, also stops emulate + portless daemons.
bun dw teardown
Refuses to teardown worktree #1 (canonical).
bun dw teardown --all
Same as above, but for every registered agent worktree. Leaves worktree #1 untouched.
bun dw teardown --all
URL & port allocation
| Worktree | Server URL | Vite URL | Tmux session | Server port | Vite port |
|---|---|---|---|---|---|
| #1 (canonical) | http://localhost:8080 |
http://localhost:3000 |
(none, inline) | 8080 | 3000 |
| #N (N>1) | https://wtN-api.localhost |
https://wtN.localhost |
dw-wt-N |
8080 + (N-1)*100 |
3000 + (N-1)*100 |
Direct ports are useful for curl when you don't want HTTPS cert hassles.
Common workflows
"I'm a fresh agent — where is my stack?"
bun dw identify
"I want to query my own server"
eval $(bun dw identify | grep '^DW_')
curl -k $DW_SERVER_URL/health
"I broke my DB — start over"
bun dw reset
"I'm done — clean up"
bun dw teardown
Gotchas
- Canonical worktree (#1) is special. It runs
bun devinline, has no tmux session, and cannot be torn down or reset viabun dw. - Branch names follow
dw-wt-N-<hash>(e.g.dw-wt-3-a1b2c3d). They are created from thedw-templateNeon branch. - Env files are managed.
bun dwwritesserver/.env.local,vite/.env.local, andapps/checkout/.env.localwith the per-worktreeDATABASE_URL. Don't commit them. - Registry lives at
~/.autumn-worktrees.json. It tracks worktree numbers, branch names, and last-used timestamps. Deleting it orphans Neon branches and Docker containers. - Portless HTTPS requires the
portlessdaemon. If aliases aren't resolving, checkportless proxy status. - Emulate (Google OAuth) is shared across all worktrees and starts automatically when needed.
How Conductor / Superset use this
Both orchestrators read a config.json in their respective dotdir (.conductor/config.json, .superset/config.json) that declares:
{
"setup": ["bun dw setup"],
"run": ["bun dw run"],
"teardown": ["bun dw teardown"]
}
setupruns once when the workspace is created. It provisions the Neon branch, Docker compose stack, and env files, then returns without blocking on the dev server.runis restartable via the orchestrator's Run button. It owns its own terminal pane and starts the dev server inline (no tmux daemon).teardownruns automatically when the workspace is deleted.
As an agent landing in that worktree, you don't need to provision anything — just run bun dw identify to learn your environment.