Skip to content
CADCAMFUN
Docs

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

Interactive terminal at the repository root
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

SettingDefaultBehavior
CADCAMFUN_TOKENRequiredRedacted application bearer credential for protected local API routes.
CADCAMFUN_DATA_DIRRequiredRoot of sidecar-managed local state. The database is cadcamfun.db beneath it.
CADCAMFUN_MIGRATIONS_DIRAbsentMigration directory passed to the database layer. Without it, opening the database does not create or upgrade application tables.
CADCAMFUN_APP_URLAbsent in configBase URL supplied to account link integrations. The relevant service decides its fallback.
CADCAMFUN_DEBUG_LINKSFalseEnables 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

SettingDefaultBehavior
CADCAMFUN_AI_HOSTnikcliSelect nikcli or direct. The direct host does not add the embedded persistent tool loop and specialist scheduler.
CADCAMFUN_AI_OFFLINEFalseDisables network provider-catalogue loading and the live web-search handler. It is not a local model implementation.
CADCAMFUN_AI_MINIMAX_BASE_URLAbsentOptional 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

SettingUseWhen absent
STRIPE_SECRET_KEYOutbound Stripe API authentication.Paid checkout and billing portal integration are unavailable.
STRIPE_WEBHOOK_SECRETVerify signed Stripe webhook payloads.The webhook handler refuses ingestion without verification configuration.
STRIPE_PRICE_BASIC, STRIPE_PRICE_PRO, STRIPE_PRICE_ENTERPRISEPrice IDs for paid plans. Blank values are ignored.A missing mapping cannot identify a configured checkout price for that plan.
CRON_SECRETAdditional shared credential for cron maintenance.No extra cron secret is required by that guard; application bearer admission still applies.
ADMIN_EMAILAdministrator 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.

Browser using the manually started sidecar
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

ProcessSelection rule
Native desktop sidecarTauri-supplied application data directory, then cadcamfun.db.
Manual sidecarCADCAMFUN_DATA_DIR/cadcamfun.db.
Database migration CLIDATABASE_URL, removing an initial file:; otherwise process-relative ./data/cadcamfun.db.
Root db:migrate wrapperRuns the DB package script, so the default resolves within packages/db.
Documentation StudioCADCAMFUN_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

  1. Identify the owner process and current storage path. Preserve needed data before changing storage or migrations.
  2. Stop that process cleanly and update its explicit launch configuration or native setting.
  3. Start it again and wait for its actual readiness result. Resolve the new connection instead of reusing an old port.
  4. Check a public health call and an admitted protected call.
  5. 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.
VariableTypeDefaultUsed by
CADCAMFUN_TOKENredacted stringrequiredBearer middleware for every protected route
CADCAMFUN_DATA_DIRstringrequiredDatabase, AI storage, plugins, companion, uploads
CADCAMFUN_MIGRATIONS_DIRstringabsentDatabase layer; absent means no schema is created
CADCAMFUN_APP_URLstringabsentLinks in account e-mails (the legacy NEXTAUTH_URL)
CADCAMFUN_DEBUG_LINKSbooleanfalseEcho reset and magic links in responses (development only)
CADCAMFUN_AI_OFFLINEbooleanfalseNo provider-catalogue download and no live web search
CADCAMFUN_AI_HOSTnikcli | directnikcliAssistant host; any other value fails startup
CADCAMFUN_AI_MINIMAX_BASE_URLstring, trimmedabsentMiniMax endpoint for the embedded host
STRIPE_WEBHOOK_SECRETstringabsentWithout it, Stripe webhooks are refused
STRIPE_SECRET_KEYredacted stringabsentWithout it, paid checkout and the billing portal are unavailable
STRIPE_PRICE_BASIC, _PRO, _ENTERPRISEstring, trimmedabsentPrice id per paid plan; blank values are ignored
CRON_SECRETstringabsentShared secret for /api/cron/*; without it the route is open to the local app
ADMIN_EMAILstringabsentAdministrator e-mail; by default the local profile administers its own installation
OTEL_EXPORTER_OTLP_ENDPOINTstring, trimmedabsentOTLP/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

VariableReaderPurpose
DATABASE_URLpackages/db migrate script and drizzle-kitTarget for db:migrate / db:generate; a leading file: is stripped. Default ./data/cadcamfun.db relative to packages/db.
CADCAMFUN_DB, then DATABASE_URLWeb 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_REGIONEmbedded assistant hostOverride the assistant's language and region.
LC_ALL, LC_MESSAGES, LANG, LANGUAGE, TZEmbedded assistant hostSystem 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_DATA_DIR>/
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

Offline development with a throwaway database
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
Account e-mail testing
export CADCAMFUN_APP_URL=http://localhost:4321
export CADCAMFUN_DEBUG_LINKS=true      # reset/magic links appear in responses
Telemetry to a local collector
export OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318
Billing in test mode
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.

In 3D

Where configuration is read Drag to orbit · scroll to zoom · right-drag to pan
Processes at run time. The Tauri shell spawns the sidecar and waits for its {”event”:”ready”,”port”:N} line on stdout (sidecar.rs); the webview then talks HTTP to 127.0.0.1 on that port with the bearer token. The sidecar owns the SQLite database, the embedded nikcli AI host (CADCAMFUN_AI_HOST=nikcli, the default) and plugins; the mobile app reaches it through companion pairing.