Skip to content

CLI & scripts

Subspace ships as a pnpm monorepo with a small set of root scripts that wrap the thin shell helpers under scripts/. This page documents the ones you’ll actually type; see Self-hosting for a first-boot walkthrough and Backup and restore for the doctor drills.

pnpm check  typecheck + lint + unit tests

The quality gate: tsc -b --pretty, eslint ., then vitest run. Run this before closing out any change.

pnpm dev  server + web, one Ctrl-C

Starts the server (tsx watch on :4780) and the web SPA (vite HMR on :5180) against your real home ($SUBSPACE_HOME or ~/Subspace). Vite proxies /trpc and /ws to the server; other routes (/files, /pty, /blobs) must be hit on :4780 directly. Wraps scripts/dev.sh.

pnpm dev:sandbox  throwaway home + fake providers

Same dev loop, but against a disposable home (/tmp/subspace-dev) with PROVIDERS=fake and SUBSPACE_SEED=mock-world. This is the safe default for local iteration: it never touches ~/Subspace. Add --fresh (via scripts/dev.sh --sandbox --fresh) to wipe the sandbox home first. Log in as alice@example.com through the dev-login form.

pnpm e2e [spec…] [-g pattern]  Playwright web suite

Runs the Playwright web suite on an auto-picked free port, so it’s safe to run alongside a dev server or another parallel agent’s e2e run. Pass spec name fragments to filter (pnpm e2e outliner tables), -g pattern for a Playwright --grep passthrough, or --port 4810 to pin the port explicitly. --desktop and --extension switch to the Electron and MV3 suites, each on a fixed home/port (4795 and 4791): only one run of each at a time.

pnpm psql [-c 'sql']  psql into a running server's embedded Postgres

Opens psql against the unix socket of a running server’s embedded Postgres, using the bundled binaries so no system psql is required. --home /tmp/subspace-dev targets an explicit home; --e2e [port] targets an e2e throwaway home (/tmp/subspace-e2e-<port>, default port 4780). Connection facts: superuser subspace, database postgres, port 5432 (socket-namespaced, so every home reuses it safely).

pnpm build:workflows  rebuild the WDK agent bundle

Compiles the agent workflow source into the standalone bundle the agent engine actually executes. Required after any edit to a workflow definition: workflows are never run from source. e2e configs rebuild automatically; a long-lived pnpm dev server does not auto-rebuild, so restart it after running this.

Other root scripts you’ll use less often:

Script Purpose
pnpm build tsc -b: build every workspace package.
pnpm typecheck tsc -b --pretty alone.
pnpm lint eslint . alone.
pnpm test vitest run alone (unit + embedded-Postgres integration tests).
pnpm test:watch vitest in watch mode.
pnpm format / pnpm format:check prettier --write . / prettier --check ..
pnpm doctor Runs @subspace/server’s doctor script directly (see below).
pnpm build:plugin-demo Builds the e2e plugin-demo fixture (Lane B workflow bundle) via the plugin SDK CLI.

The server package’s operational CLI, reachable as pnpm doctor -- <flags> from the repo root or pnpm doctor <flags> from the server package.

Terminal window
subspace doctor --restore-drill [--keep]
subspace doctor --pg-upgrade [--old-root PATH] [--current-root PATH]
–restore-drill

Fetches the latest WAL-G backup into a temporary, isolated, read-only Postgres cluster, replays archived WAL, hashes and downloads every referenced blob (from the local store or the blob replica), and OKF-parses every live page to catch corruption. Requires a configured WAL-G repository (see Environment variables). Pass --keep to leave the scratch cluster on disk for inspection instead of cleaning it up. Runs monthly on a schedule automatically; attempts and failures audit into ops.backup_runs. See Backup and restore.

–pg-upgrade

Upgrades an existing home’s Postgres major version in place, backing up first. --old-root / --current-root override the detected Postgres installation roots when the automatic detection needs a hint (for example a manual binary layout). Prints “Postgres upgrade not required” and exits cleanly when the home is already current.

Run from apps/server (or via corepack pnpm --filter @subspace/server <script> from the root):

Script Purpose
start Boots the embedded Postgres + server on :4780.
dev tsx watch server only (what pnpm dev wraps).
reindex Rebuilds the search index from scratch. Boots the embedded Postgres like the server does, so stop the running server first.
doctor The CLI documented above.
build:workflows The WDK bundle rebuild documented above.

Root pnpm scripts are thin wrappers over these; read them directly when you need the exact flags or are debugging a script itself.

Script What it does
scripts/dev.sh Backs pnpm dev / pnpm dev:sandbox. Refuses to start if port 4780 is already bound (fails fast instead of silently colliding with another server). --server-only skips vite, for when you’re serving the built SPA from the server itself.
scripts/e2e.sh Backs pnpm e2e. Picks a free port in the 4800-4899 range with random jitter (so two agents launched in the same second still diverge), or accepts --port to pin one. Keys the e2e home to the chosen port (/tmp/subspace-e2e-<port>) so parallel runs never share state. --desktop/--extension switch to the fixed-home Electron/MV3 configs.
scripts/psql.sh Backs pnpm psql. Resolves the bundled vendor/pg-<platform>-<arch>/native/bin/psql, falling back to a system psql if the vendored binary is missing. Errors clearly if no Postgres socket exists for the target home (the server for that home isn’t running).
scripts/pg-upgrade-rehearsal.sh Rehearses a Postgres major-version upgrade end to end against a scratch copy, ahead of running subspace doctor --pg-upgrade for real.
scripts/merge-app-static.sh Merges built static assets for packaging.