Documentation
Runtime configuration
Choose the process, data directory, credential type, and integration settings that actually control each runtime.
Configuration owners
The sidecar reads environment configuration through AppConfigService in apps/sidecar/src/config.ts. A layer reads those values when it is constructed and passes an AppConfig value to the services that need it. Changing a parent shell variable does not mutate an already-running service.
Tauri supplies its own launch token and application data/migration paths when starting the child. Browser preview uses Vite-side connection variables. Mobile stores a paired desktop connection and device credentials. The documentation site has separate Worker bindings and an independent local Studio process. They do not share a universal configuration file.
Configure the owner of the behavior you intend to change. For example, setting the CLI migration URL does not redirect the native desktop database, and configuring the documentation assistant does not supply the desktop AI provider credentials.
Start an isolated sidecar
CADCAMFUN_TOKEN=local-development-token \
CADCAMFUN_DATA_DIR=/tmp/cadcamfun-config-example \
CADCAMFUN_MIGRATIONS_DIR="$PWD/packages/db/drizzle" \
CADCAMFUN_AI_HOST=direct \
CADCAMFUN_AI_OFFLINE=1 \
bun --no-env-file apps/sidecar/src/main.ts This uses a disposable directory and an example development token. Choose an appropriate token for your own process. The server binds loopback on an assigned port; read that port from its ready event. Keep stdin open because closing it signals shutdown. The command deliberately passes settings explicitly and disables Bun's automatic environment-file loading.
For the normal native loop, use bun run desktop:dev. It prepares the sidecar binary and migrations before launching Tauri, which owns the resulting process connection. Do not start a second manual sidecar and assume the native webview will attach to it.
Required connection and storage settings
| Setting | Default | Behavior |
|---|---|---|
CADCAMFUN_TOKEN | Required | Redacted application bearer credential for protected local API routes. |
CADCAMFUN_DATA_DIR | Required | Root of sidecar-managed local state. The database is cadcamfun.db beneath it. |
CADCAMFUN_MIGRATIONS_DIR | Absent | Migration directory passed to the database layer. Without it, opening the database does not create or upgrade application tables. |
CADCAMFUN_APP_URL | Absent in config | Base URL supplied to account link integrations. The relevant service decides its fallback. |
CADCAMFUN_DEBUG_LINKS | False | Enables development response fields for account links in handlers that support them. |
The data directory is a storage root, not an HTTP bind address. The main server's listener is fixed to 127.0.0.1 with an ephemeral port. Companion networking uses its own explicitly enabled HTTPS gateway; changing a URL setting does not make the loopback listener public.
Keep the configured migration directory aligned with the binary. Startup can fail before readiness when a migration cannot be planned, backed up, or applied. The database reference explains transaction and backup behavior; a missing table after omitting migrations is a configuration issue rather than proof that the project was deleted.
The application token is read as a redacted value and never appears in configuration logs. Every setting on this page is read once, in apps/sidecar/src/config.ts; a changed value takes effect only after the sidecar restarts.
AI host and connectivity
| Setting | Default | Behavior |
|---|---|---|
CADCAMFUN_AI_HOST | nikcli | Select nikcli or direct. The direct host does not add the embedded persistent tool loop and specialist scheduler. |
CADCAMFUN_AI_OFFLINE | False | Disables network provider-catalogue loading and the live web-search handler. It is not a local model implementation. |
CADCAMFUN_AI_MINIMAX_BASE_URL | Absent | Optional trimmed endpoint override for the embedded MiniMax configuration. |
Provider keys are managed by the credential API and persisted by the AI service at <dataDir>/ai/credentials.json. They are not supplied by inventing an undocumented environment variable for every provider. Use the provider/model status endpoints to establish what is configured and the AI guide for supported direct-model routing.
Offline mode does not turn a cloud provider call into an offline answer. A configured direct or embedded model can still require its provider connection for inference. The local-first product retains local projects without a model connection; that storage property is distinct from offline AI inference.
Operator policy is loaded from <dataDir>/ai/policy.json. The embedded host isolates its own working/configuration directories below the application's AI storage. Policy, credentials, session context, and provider-catalogue cache have different purposes; copying one file does not reconstruct a conversation's entire runtime.
Account and billing integrations
| Setting | Use | When absent |
|---|---|---|
STRIPE_SECRET_KEY | Outbound Stripe API authentication. | Paid checkout and billing portal integration are unavailable. |
STRIPE_WEBHOOK_SECRET | Verify signed Stripe webhook payloads. | The webhook handler refuses ingestion without verification configuration. |
STRIPE_PRICE_BASIC, STRIPE_PRICE_PRO, STRIPE_PRICE_ENTERPRISE | Price IDs for paid plans. Blank values are ignored. | A missing mapping cannot identify a configured checkout price for that plan. |
CRON_SECRET | Additional shared credential for cron maintenance. | No extra cron secret is required by that guard; application bearer admission still applies. |
ADMIN_EMAIL | Administrator identity used by account/service policy. | The local installation's profile retains the local administrative behavior implemented by its services. |
These settings configure integrations; they do not establish that a remote account, price, subscription, or webhook delivery exists. Check the operation's actual failure and running service status. Do not infer that a table's presence means the related hosted feature is fully configured.
The AppConfig interface also contains test-injection hooks such as a replacement model factory and Stripe API base. They are not environment variables read by this production configuration layer. Keep test hooks out of deployment instructions unless the running host explicitly exposes them.
The billing trial route starts a 14-day PRO trial (TRIAL_DAYS in apps/sidecar/src/repos/billing-repo.ts, used by http/billing.ts). The available plans are FREE, BASIC, PRO, and ENTERPRISE; only the three paid plans take a STRIPE_PRICE_* setting.
Logs and telemetry
OTEL_EXPORTER_OTLP_ENDPOINT enables the sidecar's OTLP/HTTP trace, metric, and log exporters. Without a non-blank endpoint, this optional telemetry layer is disabled. The exporter code builds the signal-specific endpoints; configure a collector that supports those signals.
Normal sidecar logging is separate from telemetry export. Stdout carries the JSON readiness/error protocol consumed by the shell, while logs are directed to stderr. When diagnosing startup, retain the first relevant error and its operation context rather than expect the application window to contain every initialization detail.
Do not include launch tokens, provider keys, session tokens, or full credential files in diagnostic bundles. Source paths, method/status, endpoint IDs, non-secret project IDs, and the failed database operation usually provide a safer and more useful starting point.
Client configuration
A browser-only desktop preview uses the fake in-memory API when VITE_SIDECAR_URL is absent. To connect it to a manually started sidecar, set that URL and VITE_SIDECAR_TOKEN before starting Vite. The packaged Tauri path obtains its connection from the shell instead.
VITE_SIDECAR_URL=http://127.0.0.1:READY_PORT \
VITE_SIDECAR_TOKEN=local-development-token \
bun run --filter @cadcamfun/desktop dev Replace the port placeholder. Vite settings belong to the frontend development process; changing them does not restart or reconfigure the sidecar. Browser access is subject to the sidecar's loopback/Tauri CORS policy and normal bearer admission.
Mobile pairing stores its desktop address, certificate fingerprint, and device token through the mobile application. Changing the desktop's launch token is not a normal way to pair a phone. Use the pairing procedure and revoke individual devices when needed.
Database path selection
| Process | Selection rule |
|---|---|
| Native desktop sidecar | Tauri-supplied application data directory, then cadcamfun.db. |
| Manual sidecar | CADCAMFUN_DATA_DIR/cadcamfun.db. |
| Database migration CLI | DATABASE_URL, removing an initial file:; otherwise process-relative ./data/cadcamfun.db. |
Root db:migrate wrapper | Runs the DB package script, so the default resolves within packages/db. |
| Documentation Studio | CADCAMFUN_DB, then DATABASE_URL, then repository-root data/cadcamfun.db. The file must exist. |
An empty project list can therefore mean that you opened another valid database. Record the process and absolute selected path before changing migrations or copying data. An account session can also change which resources are visible without changing the file.
Apply and verify a change
- Identify the owner process and current storage path. Preserve needed data before changing storage or migrations.
- Stop that process cleanly and update its explicit launch configuration or native setting.
- Start it again and wait for its actual readiness result. Resolve the new connection instead of reusing an old port.
- Check a public health call and an admitted protected call.
- Verify the specific behavior: the intended project appears, the provider status changes, the gateway becomes reachable, or the configured telemetry collector receives the expected signal.
Presence of a configured value is not the same as a working external integration. Read the service result after making a change. Configuration values with a default should be distinguished from optional values for which the receiving service decides its fallback.
Configuration diagnosis
If initialization fails before ready, inspect required settings, migration availability, directory access, and the first layer-construction error. If health succeeds but a protected call fails, check the token type and current process. If a provider fails while projects work, inspect AI configuration rather than reset the database.
If Studio is unavailable on the hosted site, its production API intentionally returns 503; start its local Bun process against the selected existing file. If the documentation assistant is unavailable, inspect Worker bindings or its configured nikcli backend. Neither diagnosis requires replacing desktop credentials.
Source evidence: apps/sidecar/src/config.ts, layers.ts, main.ts, observability.ts, services/ai.ts, packages/db/src/migrate.ts, and packages/web/script/studio-server.ts.
Every sidecar setting in one table
AppConfigService is the only place in the sidecar that reads the environment. The table lists every variable it reads, in the order it reads them. Optional values that are empty or whitespace are treated as absent where noted.
| Variable | Type | Default | Used by |
|---|---|---|---|
CADCAMFUN_TOKEN | redacted string | required | Bearer middleware for every protected route |
CADCAMFUN_DATA_DIR | string | required | Database, AI storage, plugins, companion, uploads |
CADCAMFUN_MIGRATIONS_DIR | string | absent | Database layer; absent means no schema is created |
CADCAMFUN_APP_URL | string | absent | Links in account e-mails (the legacy NEXTAUTH_URL) |
CADCAMFUN_DEBUG_LINKS | boolean | false | Echo reset and magic links in responses (development only) |
CADCAMFUN_AI_OFFLINE | boolean | false | No provider-catalogue download and no live web search |
CADCAMFUN_AI_HOST | nikcli | direct | nikcli | Assistant host; any other value fails startup |
CADCAMFUN_AI_MINIMAX_BASE_URL | string, trimmed | absent | MiniMax endpoint for the embedded host |
STRIPE_WEBHOOK_SECRET | string | absent | Without it, Stripe webhooks are refused |
STRIPE_SECRET_KEY | redacted string | absent | Without it, paid checkout and the billing portal are unavailable |
STRIPE_PRICE_BASIC, _PRO, _ENTERPRISE | string, trimmed | absent | Price id per paid plan; blank values are ignored |
CRON_SECRET | string | absent | Shared secret for /api/cron/*; without it the route is open to the local app |
ADMIN_EMAIL | string | absent | Administrator e-mail; by default the local profile administers its own installation |
OTEL_EXPORTER_OTLP_ENDPOINT | string, trimmed | absent | OTLP/HTTP collector base URL; telemetry is off without it |
The reported application version is fixed in code (6.0.0), not read from the environment.
Invalid values stop startup
A missing required variable, or a value that does not parse (for example CADCAMFUN_AI_HOST=local), fails the configuration layer. The sidecar then prints an error instead of its ready line, and the desktop reports the startup failure.
Variables read outside the sidecar config
| Variable | Reader | Purpose |
|---|---|---|
DATABASE_URL | packages/db migrate script and drizzle-kit | Target for db:migrate / db:generate; a leading file: is stripped. Default ./data/cadcamfun.db relative to packages/db. |
CADCAMFUN_DB, then DATABASE_URL | Web Studio server (packages/web/script/studio-server.ts) | Database the local Studio opens; default data/cadcamfun.db at the repository root. |
NIKCLI_LOCALE, NIKCLI_LANGUAGE, NIKCLI_REGION | Embedded assistant host | Override the assistant's language and region. |
LC_ALL, LC_MESSAGES, LANG, LANGUAGE, TZ | Embedded assistant host | System locale and time-zone detection when no override is set. |
The desktop shell passes exactly three variables to the sidecar it launches: CADCAMFUN_TOKEN (a new random token per launch), CADCAMFUN_DATA_DIR (the application data directory) and CADCAMFUN_MIGRATIONS_DIR (the bundled migrations). Anything else must be present in the environment the desktop app itself was started with.
What lives in the data directory
cadcamfun.db SQLite database (+ -wal / -shm while running)
backups/ pre-migration snapshots, newest five kept
auth-secret signing secret for account session tokens (0600)
auth-revoked.json revoked session tokens
ai/
credentials.json provider API keys (owner-readable only)
policy.json operator policy for the assistant
skills/ user skills
session-owners/ which account owns which assistant session
nikcli/ isolated working and config dirs of the embedded host
plugins/ assistant plugins loaded at startup
plugins-registry/ installed marketplace plugin files
companion/ gateway TLS cert.pem and key.pem (0600)
storage/ file storage for library import/export, entity I/O and plugins
uploads/profiles/ profile pictures
downloads/ files served by /api/download
waitlist.json local waitlist entries Directories are created on first use, so a fresh installation contains only the ones its features have touched. Back up the whole directory with the application stopped: the database, credentials, auth secret and companion keys belong together. Paired companion devices are stored in the key-value table of the database, not in companion/.
Treat the directory as secret
ai/credentials.json, auth-secret and the companion private key are credentials. Do not commit a development data directory or attach it to bug reports.
Example configurations
export CADCAMFUN_TOKEN=dev-$(openssl rand -hex 16)
export CADCAMFUN_DATA_DIR="$(mktemp -d)"
export CADCAMFUN_MIGRATIONS_DIR="$PWD/packages/db/drizzle"
export CADCAMFUN_AI_HOST=direct
export CADCAMFUN_AI_OFFLINE=true
bun --no-env-file apps/sidecar/src/main.ts export CADCAMFUN_APP_URL=http://localhost:4321
export CADCAMFUN_DEBUG_LINKS=true # reset/magic links appear in responses export OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318 export STRIPE_SECRET_KEY=sk_test_...
export STRIPE_WEBHOOK_SECRET=whsec_...
export STRIPE_PRICE_PRO=price_... Never set CADCAMFUN_DEBUG_LINKS outside development: it puts account links in HTTP responses.