Documentation
Local development
Choose the API process, data directory, and client mode explicitly.
Development processes
A full desktop development session runs a Rust shell, a Bun sidecar, and Vite. The shell supplies native features and supervises the sidecar; Vite supplies webview assets and hot reload. bun run desktop:dev prepares the binary and migration resources before starting those processes.
For faster screen work, run the desktop dev script alone. App.tsx selects the in-memory preview API only outside Tauri and only when VITE_SIDECAR_URL is absent. Preview failures for unsupported API collections are expected to return 501. Use a live sidecar for persistence, authorization, streaming AI, and server services.
CADCAMFUN_TOKEN=local-development-token CADCAMFUN_DATA_DIR=/tmp/cadcamfun-development CADCAMFUN_MIGRATIONS_DIR="$PWD/packages/db/drizzle" bun --no-env-file apps/sidecar/src/main.ts The token above is an example for an isolated local development process. Choose your own value. Keep stdin open: closing it stops the sidecar. The server prints one JSON ready event with its ephemeral port after /api/health responds; logs go to stderr.
VITE_SIDECAR_URL=http://127.0.0.1:43111 VITE_SIDECAR_TOKEN=local-development-token bun run --filter @cadcamfun/desktop dev Replace port 43111 with the ready-event port and use the token supplied to that sidecar before running. Vite uses port 1420 with strict port selection, matching the Tauri development URL. The sidecar allows browser CORS origins on HTTP localhost/loopback and the supported Tauri origins; it still requires the appropriate authorization for protected routes.
Data directories and migrations
The sidecar opens <CADCAMFUN_DATA_DIR>/cadcamfun.db. Tauri chooses its own application data directory and passes it to the child. A manual process uses the directory you provide. These databases are independent even when their filename is identical.
The CLI migration script reads DATABASE_URL and otherwise uses ./data/cadcamfun.db relative to its working directory. Root db:migrate runs inside packages/db. Choose an absolute file URL for deliberate CLI operations; do not infer the target from a relative filename shown in a log.
DATABASE_URL=file:/tmp/cadcamfun-cli/cadcamfun.db bun run db:migrate Schema changes originate in packages/db/src/schema.ts. Run bun run db:generate, review the generated migration, and apply it to an isolated database first. The sidecar uses CADCAMFUN_MIGRATIONS_DIR when provided; packaged builds stage the generated directory as a resource.
The database layer enables WAL and foreign keys. When an existing file needs a migration, the upgrade path creates a backup beside it under backups/ and retains the latest five matching automatic backups. First creation, an unchanged schema, and in-memory databases do not create an upgrade backup. Preserve data independently before manual recovery operations.
Targeted checks
bun run --filter @cadcamfun/core typecheck
bun test packages/core
bun run --filter @cadcamfun/desktop typecheck
bun test apps/desktop/src/viewport
bun run --cwd packages/web check
bun run --cwd packages/web build Select checks by the boundary changed. Pure geometry changes need geometry assertions; API contract changes need generated-client checks and affected handlers; persistence changes need repository and migration tests; UI interaction changes need the relevant component and runtime flow. The root test script includes packages, apps, and scripts.
Native shell checks run from apps/desktop/src-tauri with cargo clippy --all-targets -- -D warnings and cargo test. Stage the target sidecar and migrations first, since Tauri's build context includes those resources. Operating-system integration tests can require a native desktop and keychain.
Runtime configuration
apps/sidecar/src/config.ts owns the sidecar configuration layer. Required inputs are CADCAMFUN_TOKEN and CADCAMFUN_DATA_DIR. CADCAMFUN_MIGRATIONS_DIR selects migration resources. The default AI host is nikcli; CADCAMFUN_AI_HOST=direct selects direct calls, and CADCAMFUN_AI_OFFLINE supports offline/test operation.
Optional configuration includes the application URL and development auth links, Stripe credentials and price identifiers, administrator/cron settings, and OTEL_EXPORTER_OTLP_ENDPOINT. Billing is unavailable without the relevant provider configuration; telemetry export is off without its collector endpoint. Supply only the inputs needed for your flow.
Browser endpoint variables are Vite configuration, not sidecar configuration. A companion pairing contains a different token and HTTPS address. A standalone action-bridge token has its own scope and lifetime. Do not substitute these credentials for each other.
Use explicit process configuration or application settings. The sample sidecar command disables Bun's environment-file loading. Never print actual tokens, model keys, pairing links, or signing material in logs or documentation examples.
Effect and resource ownership
The repository pins Effect to 4.0.0-rc.112. Services use Context.Service, implementations are supplied through layers, and operations return typed Effects. Use the installed effect/ai-docs/src documentation when changing this API, including its unstable HTTP modules.
Decode external input at boundaries. Map foreign exceptions into typed errors, preserve stable error tags, and let a scoped layer own database handles, workers, streams, and server resources. The sidecar's shutdown flow handles a parent shutdown event, stdin closure, and runtime interruption; logs and protocol stdout have different destinations.
Core CAD/CAM calculations remain plain functions in computational hot paths. Wrapping validation at the boundary does not require putting every geometry operation inside an Effect. Use the core geometry unit conventions and perform display/export conversions at the appropriate edge. Drawing angles use radians; some feature parameters and CAM rotary-axis values explicitly use degrees.
Startup troubleshooting
- Vite port occupied: free port 1420 or stop the existing development server; strict port mode does not silently choose another port.
- Boot keeps retrying: inspect the sidecar ready/error output and migration path. The app re-resolves the endpoint while its connection budget remains.
- Server exits immediately: check required configuration and whether the launching process closed stdin.
- Projects missing: confirm the data directory, API endpoint, and whether the app is using the fake client.
- 401 responses: verify the client is using the token of the current process rather than a previous launch.
- 501 in browser preview: use a real sidecar for that API collection.
- Native context build fails: stage the sidecar binary and migration resources for the correct target.
Documentation and companion development
bun run --cwd packages/web start runs Astro alone. bun run --cwd packages/web dev starts Astro plus the local Studio API. The documentation check validates the route index; the build validates Astro compilation and prerendering.
For iOS, bun run --cwd apps/mobile start starts Metro for a custom development client. bun run --cwd apps/mobile ios builds/runs the native app; build exports JavaScript only. Native pinning requires the local Swift module and cannot run in Expo Go.
bun scripts/build.ts --help lists the release pipeline's options. --only=resources restages migrations without rebuilding, and --dry-run prints the plan without writing anything.
Process configuration reference
| Variable | Default/requirement | Use |
|---|---|---|
CADCAMFUN_TOKEN | Required | Bearer token supplied by the shell or development launcher. |
CADCAMFUN_DATA_DIR | Required | Sidecar database and application service state. |
CADCAMFUN_MIGRATIONS_DIR | Optional | Folder of generated migrations. The database layer skips migrations when no folder is supplied. |
CADCAMFUN_AI_HOST | nikcli | nikcli embedded host or direct AI calls. |
CADCAMFUN_AI_OFFLINE | False | Offline/test AI operation; not a local substitute model. |
CADCAMFUN_AI_MINIMAX_BASE_URL | Unset | Optional embedded-host MiniMax endpoint override. |
CADCAMFUN_APP_URL | Unset | Application origin used in authentication links. |
CADCAMFUN_DEBUG_LINKS | False | Development auth responses can expose reset/magic links. |
OTEL_EXPORTER_OTLP_ENDPOINT | Unset | Enables telemetry export when configured. |
VITE_SIDECAR_URL, VITE_SIDECAR_TOKEN | Unset | Browser webview connection; both are needed for a real sidecar. |
DATABASE_URL | CLI-specific default | Database migration/generation tool target, independent of sidecar configuration. |
Boolean inputs are decoded by Effect configuration, not arbitrary string truthiness. Use explicit true/false values. Unknown AI host literals fail decoding. Supply configuration before creating the process; changing a parent terminal variable does not update an already running sidecar.
Use Studio against an explicit database
The local Studio API listens on loopback port 4396. Its path precedence is CADCAMFUN_DB, then DATABASE_URL with a file: prefix removed, then repository-root data/cadcamfun.db. This differs from the database package's default CLI working-directory path. It opens only an existing database and does not create/migrate one automatically.
DATABASE_URL=file:/tmp/cadcamfun-studio/cadcamfun.db bun run db:migrate
CADCAMFUN_DB=/tmp/cadcamfun-studio/cadcamfun.db bun run --cwd packages/web dev The first command initializes the file. The second starts Studio plus Astro against that path. A fresh migrated schema does not contain a user/password session merely because it exists; Studio sign-in requires a suitable account. Its authenticated requests use the Studio session cookie and return 401 without a valid session.
When the file is missing, the Studio API returns 503 with the selected path. When Astro runs without the companion Studio process, proxied /studio/api requests cannot reach port 4396. Documentation pages themselves can be developed with packages/web start without starting Studio.
Implementation anchors: packages/web/script/dev.ts, script/studio-server.ts, astro.config.mjs, packages/db/src/migrate.ts, and apps/sidecar/src/config.ts.
A repeatable development loop
- Choose a disposable sidecar data directory and explicit migration folder.
- Start the sidecar in an interactive terminal and record the port from its ready event.
- Start Vite in another terminal with the matching URL/token, or open the native app with its supervised sidecar.
- Reproduce one action and inspect its response and persisted state.
- For backend changes, restart the sidecar, update the browser endpoint if its port changed, and repeat the action.
- Stop the process with its normal interrupt or parent shutdown path so resources finalize.
The sidecar drains HTTP scopes briefly, checkpoints WAL, and closes SQLite on normal scoped shutdown. Killing a process without that path can interrupt in-flight work. A source edit does not replace the compiled binary already supervised by Tauri; rebuild the sidecar when testing compiled behavior.
For compiled-runtime validation, scripts/smoke-sidecar.ts can run a selected binary with an isolated home/data directory and offline AI. It measures readiness/health/action behavior and exercises a kernel job. Without --binary it first compiles a temporary executable, so plan for the build cost; its result is separate from source-level tests.
Which process runs where
| Command | Starts | Data directory | Database |
|---|---|---|---|
bun run desktop:dev | Compiled sidecar + Tauri dev window | Application data directory chosen by Tauri | <dataDir>/cadcamfun.db |
Manual sidecar (bun apps/sidecar/src/main.ts) | Sidecar only, on an ephemeral loopback port | CADCAMFUN_DATA_DIR | <dataDir>/cadcamfun.db |
bun run db:migrate | Migration script | — | DATABASE_URL or packages/db/data/cadcamfun.db |
bun run --filter @cadcamfun/web studio | Local Studio | — | CADCAMFUN_DB, DATABASE_URL or data/cadcamfun.db |
bun run --filter @cadcamfun/web dev | Docs site | — | — |
Four different database defaults
These entry points do not share a default path. Set the path explicitly when you need two tools to look at the same file.
Inner loop by change type
| You changed | Run |
|---|---|
Kernel code in packages/core | bun test packages/core |
A contract in packages/api | bun run generate, bun run generate:check, the sidecar tests, then the docs generate:api-reference |
| A sidecar handler or service | bun test apps/sidecar |
| The schema | bun run db:generate, commit the new migration folder, bun scripts/build.ts --only=resources |
Rust in src-tauri | cargo clippy and cargo test in apps/desktop/src-tauri |
| Docs pages | bun run typecheck and bun run build in packages/web |