# Scripts - `bun run dev` — Starts contracts, server, and web in watch mode. - `bun run dev:share` — Also publishes the web port over HTTPS on this machine's tailnet. The startup pairing URL is built against the shared origin, and the mapping is removed on exit. - `bun run dev:pair` — Prints a fresh pairing URL for the running dev server, using its recorded state directory, port, and web origin. Add `--base-dir ` only when the server was started with `--home-dir`. - `bun run dev:seed` — Copies recent projects and threads from the shared home into the isolated dev database. Stop the server before running it, then restart. Tune the copy with `--threads` and `--activities`; it refuses to write to the shared home. - `vp run dev:server` — Starts just the WebSocket server. The server process runs on Bun (`@effect/platform-bun` + `BunPtyAdapter`), but task running uses `vp run`. - `vp run dev:web` — Starts just the Vite dev server for the web app. - Dev commands run from a linked **git worktree** default to that worktree's gitignored `.t3`, even when `T3CODE_HOME` is set, storing state in `/.t3/userdata`. Pass `--home-dir ` to choose another isolated directory explicitly. Submodules are not worktrees and keep the normal precedence. - From the **main checkout**, dev commands implicitly use `~/.t3/dev`, keeping development state separate from `~/.t3/userdata`. An explicit `--home-dir ` stores state under `/userdata`; the base directory remains available for caches, worktrees, and other shared data. - Web dev commands do not auto-open a browser. Open the one-time pairing URL printed by the server so the first browser navigation is authenticated. Set `T3CODE_NO_BROWSER=0` only when interactive auto-open is intentional. - Pass dev-runner flags directly after the root task name, for example: `vp run dev --home-dir /tmp/t3code-dev` - `vp run start` — Runs the production server (serves built web app as static files). - `vp run build` — Builds contracts, web app, and server. - `vp run typecheck` — Strict TypeScript checks for all packages. - `vp run test` — Runs workspace tests. - `node apps/server/scripts/t3-sqlite-state.ts --base-dir ...` — Inspects or seeds an isolated T3 SQLite database; writes create a private backup first. - `vp run dist:desktop:artifact -- --platform --target --arch ` — Builds a desktop artifact for a specific platform/target/arch. - `vp run dist:desktop:dmg` — Builds a shareable macOS `.dmg` into `./release`. - `vp run dist:desktop:dmg:x64` — Builds an Intel macOS `.dmg`. - `vp run dist:desktop:linux` — Builds a Linux AppImage into `./release`. - `vp run dist:desktop:win` — Builds a Windows NSIS installer into `./release`. ## Desktop `.dmg` packaging notes - Default build is unsigned/not notarized for local sharing. - The DMG build uses `assets/prod/black-macos-1024.png` as the production app icon source. - Desktop production windows load the bundled UI from `t3code://app/index.html` (not a `127.0.0.1` document URL). - Desktop packaging includes `apps/server/dist` (the `t3` backend) and starts it on loopback with an auth token for WebSocket/API traffic. - Your tester can still open it on macOS by right-clicking the app and choosing **Open** on first launch. - To keep staging files for debugging package contents, run: `vp run dist:desktop:dmg -- --keep-stage` - To allow code-signing/notarization when configured in CI/secrets, add: `--signed`. - Signed macOS builds also require `T3CODE_APPLE_TEAM_ID` and `T3CODE_MACOS_PROVISIONING_PROFILE`. The passkey RP domain is derived from `T3CODE_CLERK_PUBLISHABLE_KEY` unless `T3CODE_CLERK_PASSKEY_RP_DOMAINS` overrides it. - Windows `--signed` uses Azure Trusted Signing and expects: `AZURE_TRUSTED_SIGNING_ENDPOINT`, `AZURE_TRUSTED_SIGNING_ACCOUNT_NAME`, `AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE_NAME`, and `AZURE_TRUSTED_SIGNING_PUBLISHER_NAME`. - Azure authentication env vars are also required (for example service principal with secret): `AZURE_TENANT_ID`, `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`. ## Browser development `dev` and `dev:web` leave `VITE_HTTP_URL` and `VITE_WS_URL` unset so the browser resolves the backend from `window.location.origin`. Vite proxies `/api`, `/ws`, `/oauth`, and `/.well-known` to the server, allowing the same bundle to work from localhost or a tailnet hostname. Worktrees derive a preferred port offset from their path. The runner shifts both ports together when either is occupied or the web port is blocked by browsers, so treat the `[dev-runner]` output as authoritative. An isolated dev database starts empty. `bun run dev:seed` copies projection data only, clears the target event log, and resets every projector cursor to zero so later events are not skipped or replayed over unrelated projections. Because no live agent accompanies the copy, it also settles anything that would otherwise wait on one: sessions are stopped, running turns are interrupted, streaming messages are finished, pending interaction counts are cleared, and orphaned provider bindings are removed. Files backing copied image attachments are copied alongside the rows. The copy tolerates source/target migration drift and remains local because it includes real message bodies and host paths. `dev:seed` refuses to run while a server is using the target directory: it replaces the projections and event log that server is holding open, and it has no way to tell the running process its read model was swapped underneath it. Stop the server, seed, then start it again. Both source and target follow whichever state directory actually holds a database, so a main-checkout `bun run dev` — whose state lives in `~/.t3/dev` — is seedable without naming the directory. When a base directory holds both, the more recently written one wins, since that is the database the last server to run had open. The resolved path is printed in the summary. ## Running multiple dev instances Set `T3CODE_DEV_INSTANCE` to any value to deterministically shift all dev ports together. - Default ports: server `13773`, web `5733` - Shifted ports: `base + offset` (offset is hashed from `T3CODE_DEV_INSTANCE`) - Example: `T3CODE_DEV_INSTANCE=branch-a vp run dev:desktop` If you want full control instead of hashing, set `T3CODE_PORT_OFFSET` to a numeric offset.