Command reference
Root commands for development, databases, Rackspace schemas, and verification
Run these aliases from the repository root. Operator aliases run the CLI directly, and each
command runs its own prerequisites. For example, pnpm db:seed applies migrations before it adds
seed data. Prompts read from your terminal. Run pnpm cli --help to list every CLI command, and
add --help after a command to see its flags. Each executable loads its own environment.
Getting started describes owner-local
files. Operator commands live in the CLI. Use NODE_ENV=production pnpm db:migrate to read only supplied variables.
Explicit NODE_ENV wins; otherwise CI selects production and local use selects development.
The CLI README defines the complete mode and file policy.
Setup and development
| Command | Purpose |
|---|---|
pnpm install | Install the workspace dependencies |
pnpm dev:setup | Apply migrations, add seed data, and create the local accounts |
pnpm rsdb:seed | Load the local Rackspace databases with synthetic data |
pnpm auth:bootstrap-development | Create or repair the local administrator and impersonation users |
pnpm auth:bootstrap-preview | Create the preview administrator from PREVIEW_ADMIN_* values |
pnpm auth:create-admin | Create a system administrator; prompts ask for missing values |
pnpm dev | Start every app, Drizzle Studio, and foreground Maildev |
pnpm maildev:start | Start background Maildev without the apps |
pnpm maildev:stop | Stop the repository-owned background Maildev process |
pnpm add:component | Add a Shadcn component to the shared interface package |
pnpm api:list-projects | List one organization's Projects through the HTTP API and SDK |
pnpm dev:setup is for a new development environment. It runs db:migrate, db:seed, and
auth:bootstrap-development in order, and it runs rsdb:seed. The local administrator values are
in the tracked apps/cli/.env.development file. Do not use them outside local development.
pnpm dev:setup runs rsdb:seed only after the other setup steps pass.
[!CAUTION]
pnpm rsdb:seeddrops the localmi_property_valueandtredis_global_dynamicdatabases and theconcourse_localaccount, and then creates them again. Local changes to that data are lost.
pnpm rsdb:seed needs MySQL 8.0 or 8.4 on this machine. It loads their committed tables, creates the
concourse_local runtime account for connections from this machine only, and adds synthetic Global
Dynamic users and property value projects through the Services. Running it again gives the same
result. The RSDB checks
describe the root connection settings.
Before it changes data, the seed makes these checks:
- The root connection uses a loopback address.
- The server reports this machine's host name. A tunnel or proxy on a loopback address to another server fails this check.
- The server is the one that MIDOT reads:
RACKSPACE_MYSQL_HOSTandRACKSPACE_MYSQL_PORTinapps/cliandapps/midot. IfRSDB_TEST_MYSQL_*selects another server, set the same host and port inapps/cli/.env.localandapps/midot/.env.local.
The seed creates these Global Dynamic accounts:
| User name | Password | Account |
|---|---|---|
local-admin | local-admin-password | Super user. The same password is its administrator password. |
local-user | local-user-password | Michigan user with full TREDIS access. Can sign in to MIDOT. |
local-legacy | local-legacy-password | User whose profile dates are legacy zero dates |
Each user has one calculated and one new property value project.
pnpm auth:bootstrap-preview is for the preview database workflow. It reads PREVIEW_ADMIN_EMAIL,
PREVIEW_ADMIN_NAME, and PREVIEW_ADMIN_PASSWORD from the environment. The
deployment runbook says where those values come from.
pnpm api:list-projects reads CONCOURSE_BASE_URL and CONCOURSE_SESSION_TOKEN and takes an
optional --organization <id> and --status archived. The
SDK guide says how to get
a session token.
Before you run pnpm dev, stop background Maildev. The development command owns its own foreground
Maildev process.
Database operations
| Command | Purpose |
|---|---|
pnpm db:migrate | Apply the committed migrations to the development database |
pnpm db:generate | Write a migration for a schema change |
pnpm db:diff | Report a schema change that has no migration |
pnpm db:seed | Apply migrations, then add seed data or reuse it |
pnpm db:reset | Recreate the development database after a typed confirmation |
pnpm db:clear | Erase the rows in the tables that the seed command manages |
CAUTION: pnpm db:reset erases the complete development database. Type reset only when you
intend to erase its data.
CAUTION: pnpm db:clear erases the tables that the seed command manages. Make sure that
TURSO_DATABASE_URL points at the intended database before you run it.
The database package guide describes the migration workflow.
Rackspace schemas
| Command | Purpose |
|---|---|
pnpm rackspace:schema generate --config <config-path> | Generate Rackspace schema snapshots through the VPN |
pnpm rackspace:schema verify | Check the committed snapshots without a database connection |
Run generate from an interactive terminal on the approved VPN. Add --database <name> once for
each database to skip the database list. The
Rackspace operations page has the protected configuration shape and
the review steps.
Checks and tests
| Command | Purpose |
|---|---|
pnpm check | Run lint rules and compiler checks for every workspace |
pnpm lint:fix | Apply the safe Oxlint corrections |
pnpm lint:boundaries | Check the package boundaries and relative import depth |
pnpm lint:dead | Report unused files, dependencies, and exports with Knip |
pnpm format | Format the workspace |
pnpm format:check | Check the formatting |
pnpm test | Run the cacheable unit tests |
pnpm test:integration | Run the SQLite and MySQL integration tests |
pnpm e2e | Run or restore the complete acceptance lifecycle |
pnpm e2e:full | Ignore the E2E cache and run the complete lifecycle |
pnpm build | Build every app with Turbopack |
pnpm verify | Run the complete merge gate |
pnpm ci:local | Run the CI workflow under act and sign off the commit (Local CI) |
After a small change, run the focused command for the files that you changed. Before a merge, or
after a change that crosses several areas, run pnpm verify. Turbo restores each completed task
from the local or remote cache.
pnpm verify schedules two Turbo runs. Each task loads only its owner’s applicable files.
The first run includes combined checks, package boundaries, dead code, and formatting. The second
run starts only when the first run passes. It includes unit tests, migration diff, builds, SQLite
and MySQL integrations, and acceptance tests. The virtual
verify:build task selects ordinary builds except for Concourse, where it selects build:test.
Concourse tests use .next-test; its production build uses .next.
Verification selects the DB, Auth, Services, API, CLI, RSDB, and application integration suites as
separate tasks.
They form a serial chain and cache successful results from isolated fixtures.
pnpm test:integration --force reruns them. pnpm e2e does not repeat integration coverage.
Repository test scopes own isolated database files. The browser lifecycle uses its fixed acceptance database.
The MySQL suites use isolated databases on local MySQL, so they can run alongside the acceptance
lifecycle.
The root package.json script verify defines this task selection.
The acceptance suite uses one fixed SQLite file in each checkout. It also uses fixed ports on the
machine: Next 3100, Maildev 1125 and 1180, OIDC 8180, and SAML 8280. The Vitest global setup starts
scripts/e2e-server.ts. That script removes leftover SQLite files, migrates the fixed database,
serves Next, and removes the database when it stops. Do not run two acceptance suites at the same
time on one machine, even from separate worktrees. The @concourse/auth and @concourse/email unit
tests use the same ports. If a forced stop leaves SQLite files behind, the next run removes them
before migration.
Remote cache
Developers can share cache results through the Conveyal Vercel Remote Cache. Authenticate and link this checkout from the repository root:
turbo login
turbo link --scope=conveyalTurbo stores the login and the link outside the tracked source files. Do not commit Turbo
credentials or .turbo/config.json.
CI exchanges its GitHub OIDC token for short-lived cache access. It does not use a Vercel personal access token or a cache-signature secret.
Combined checks
pnpm check runs the lint rules and compiler checks. The first step of the CI checks job also
checks package boundaries, dead code, and formatting. To get the same result as that step, also run
pnpm lint:boundaries, pnpm lint:dead, and pnpm format:check, or run pnpm verify.
To check one workspace, use pnpm exec turbo run check --filter=<package-name>. Turbo also runs
route generation and retained compiler tasks. A direct workspace check script runs only Oxlint
and does not run these dependencies.
Oxlint checks source types and lint rules together. Next.js apps retain full compiler checks for
generated route validators. Concourse also retains its separate server and E2E compiler projects.
The root, sdk, and midot also run a check:types compiler task. It compiles their imported
configuration modules together with their own files.
These tasks use the check:types prefix.
Turbo invalidates a workspace check when imported workspace source changes. Root checks include
workspace inputs because root tests import workspace modules.
Next.js builds retain framework type checks and route generation ordering without a lint prerequisite.
The virtual DB and RSDB build gates retain their complete checks.
pnpm verify finishes the source checks before it starts the builds. next build removes its
output folder, including the generated route types that the compiler checks read.
The Oxlint guide owns the lint scope. The TypeScript guide owns compiler configuration.