Skip to content
CADCAMFUN
Docs

Documentation

Architecture

Execution boundaries, request flow, persistence, and extension points across the desktop, sidecar, mobile companion, and documentation site.

Processes and trust boundaries

Tauri owns native window integration, secure credential commands, menus, updates, and sidecar lifecycle. Its webview runs the SolidJS application. The compiled Bun sidecar opens the database and serves HTTP on 127.0.0.1 with an operating-system-assigned port. The frontend does not open SQLite.

The sidecar's entry point is apps/sidecar/src/main.ts. It creates the HTTP server, builds the application layers, probes /api/health, and then prints a JSON readiness event containing the chosen port. Logs are routed to stderr so stdout remains available for the shell protocol.

The mobile companion reaches an explicitly paired desktop gateway. Its native transport and device credentials are separate from the desktop webview's loopback connection. The documentation Worker is a separate deployment and has no implicit connection to a user's desktop.

Library dependencies

@cadcamfun/core contains CAD, drawing, and CAM computation. It depends on Effect for schemas and boundary integration; algorithmic loops are ordinary TypeScript. @cadcamfun/api imports core types and schemas to declare HTTP inputs, outputs, errors, and streams.

@cadcamfun/db owns the application database service, schema, and migration logic. The sidecar combines it with core, API, AI, plugin SDK, VCS, and workflow packages. Its repositories use the database service; handlers delegate to repositories and services.

The desktop imports both @cadcamfun/api and @cadcamfun/core. It uses the API at runtime through an Effect client and uses core geometry in CAD/CAM features and the viewport. Mobile depends on the API package and wraps companion requests in its client. The standalone nikcli plugin discovers the running application's action catalogue over HTTP rather than importing backend implementations.

HTTP request lifecycle

  1. The webview obtains the sidecar connection from the native shell.
  2. apps/desktop/src/app/client.ts builds an Effect HttpApi client with bearer authorization and an optional account session token. packages/api/src/client.ts supplies a reusable contract client for other consumers.
  3. apps/sidecar/src/layers.ts assembles ServedApi, handlers, authorization, CORS, and shared service layers.
  4. The handler validates contract inputs, resolves services, performs computation or persistence, and returns the declared success or error representation. Streaming endpoints preserve their declared stream protocol.

CORS permits Tauri production origins and HTTP loopback origins used in development. It does not replace authorization. The API exposes several response envelope styles; consumers must follow each endpoint's schema rather than assume every response has the same shape.

Service lifecycle and storage

Effect layers acquire the database and shared services within the application scope. The database layer creates its parent directory, enables WAL and foreign keys, optionally applies migrations, and wraps query failures with an operation name. Finalization attempts a truncating WAL checkpoint and closes the SQLite handle.

The DatabaseLive layer selects dataDir/cadcamfun.db. A migration folder must be supplied to apply migrations at startup. AI credentials, plugin state, VCS objects, workflow execution, and file storage are handled through their respective service interfaces; storage details are described on their module pages.

The local Studio in packages/web/script/studio-server.ts is an additional Bun process. It opens a configured existing application database directly and serves authenticated overview data on loopback port 4396. Its development proxy and cookie sessions are independent of the Tauri sidecar connection.

Live project events (pull requests, commits, workflow runs, and assistant session phases) are published through an in-process event service. A new subscriber first receives up to the 20 most recent matching events and then live ones, optionally filtered by project and event type (apps/sidecar/src/services/live-events.ts).

Extension boundaries

There are two plugin integrations. The application plugin SDK defines manifests, capabilities, activation, and host contracts. The nikcli bridge exposes registered CAD/CAM actions to an external assistant. Installing a plugin through an HTTP registry route is a separate operation from activating a module in the runtime host.

Workflow parsing and scheduling live in packages/workflow. Service-backed steps are registered by sidecar layers, while pure project and CAM steps can run with their supplied inputs. VCS computes object hashes, diffs, merges, and GitHub transport operations in its library; sidecar services connect those operations to project persistence.

The web documentation assistant retrieves rendered documentation and can publish guide artifacts when storage is configured. It answers documentation questions; it does not inherit the CAD/CAM application's local project access.

Connection and credential boundaries

CredentialPurposeBoundary
Application bearer tokenAdmit the local application to protected sidecar routes.Generated/supplied for the sidecar launch; the webview obtains it through the native connection.
x-session-tokenSelect the account acting behind the admitted application.An absent, invalid, expired, or orphaned session falls back to the local profile.
Companion device tokenAdmit an individually paired phone to gateway routes.Checked by the separate HTTPS gateway and its method/path allow-list.
AI bridge tokenExpose permitted actions for a single project to an external agent.Admits the two action bridge endpoints and enforces read or read/write scope.
Provider API keyAuthenticate outbound model calls.Managed by the sidecar credential service; not a substitute for application authorization.
GitHub tokenPerform a requested mirror operation.Provided for that call through x-github-token; not project snapshot data.

Authorization is layered. Passing the bearer middleware does not prove ownership of a particular drawing or project; handlers and repositories check those resources. Pairing similarly does not turn the phone into an unrestricted sidecar client. Consult the specific endpoint and companion policy before choosing a credential.

The authorization adapter is apps/sidecar/src/http/authorization.ts. Companion and bridge decisions live in their own services. Keeping those paths separate lets a lost device or an integration token be revoked without replacing an AI provider's secret.

Failure isolation

Failures before the readiness event belong to sidecar initialization: configuration, database upgrade, service construction, or HTTP startup. Failures after readiness may be specific to a provider, filesystem operation, endpoint, or client session. The shell's lifecycle and the webview's connection-retry budget are distinct; inspect both when a restart changes the listening port.

A disconnected AI stream does not necessarily stop its server-side conversation. Recover the session state before resending an editing instruction. A failed workflow does not roll back its triggering commit. An unsuccessful remote push does not erase local history. These distinctions prevent a network failure from being handled as though a persistent operation never occurred.

For a failing API request, record its method, path, status, endpoint ID, and relevant non-secret identifiers. Compare the running /api/openapi.json with the documentation contract snapshot when client and server versions differ. Avoid troubleshooting with a token from a previous sidecar launch.

Architecture snapshot by source path

AreaWhere it livesWhat to read first
Desktop shell (Rust)apps/desktop/src-tauri/src/sidecar.rs (supervisor), commands.rs, updater.rs, menu.rs, tray.rs, secrets.rs
Desktop UIapps/desktop/src/app/, features/ (cad, cam, ai, chat, projects, toolpaths, plugins, …), viewport/, shared/
Sidecar entryapps/sidecar/src/main.tsReady handshake, layers in layers.ts, configuration in config.ts
HTTP handlersapps/sidecar/src/http/One file per group, e.g. toolpath-generator.ts, ai.ts, kv.ts
Services and repositoriesapps/sidecar/src/services/, repos/cam-program.ts, companion.ts, auth-tokens.ts, storage.ts
Contractpackages/api/src/index.ts, groups/, errors.ts, client.ts
Kernelpackages/core/src/cad/history.ts, cad/sketch.ts, cam/kernel/, cam/post/
Assistantpackages/ai/src/actions/, tools/, nikcli/, prompts/
Storagepackages/db/src/index.ts, upgrade.ts, schema.ts
Historypackages/vcs/, packages/workflow/Repository API, merge, workflow schema
Companionapps/mobile/app/ routes, lib/ connection and pairing

Trace: from launch to first request

  1. Tauri starts and the supervisor in sidecar.rs generates a random token.
  2. It spawns sidecar-<triple> with CADCAMFUN_TOKEN, CADCAMFUN_DATA_DIR and CADCAMFUN_MIGRATIONS_DIR.
  3. The sidecar reads its configuration, opens SQLite (WAL, foreign keys), backs up and migrates if needed, and builds its service layers.
  4. It binds 127.0.0.1 on an ephemeral port and prints a JSON ready line on stdout. The supervisor waits up to 60 s for it.
  5. The supervisor emits sidecar-status { state: "ready", port }; the webview calls get_sidecar_endpoint for { baseUrl, token }.
  6. The webview builds ApiClient.layer({ baseUrl, token }) and starts loading projects.

If the sidecar exits, the supervisor restarts it once and announces the new port; a second failure leaves the status at failed. On quit, the supervisor writes the shutdown line, waits 2 s, and then reaps the process; the database layer checkpoints the WAL as its scope closes.

Trace: a manufacture request

  1. The CAM workspace captures the drawing elements and stock and calls POST /api/toolpaths/manufacture.
  2. The bearer middleware admits the request; the body is decoded against CamKernelRequest.
  3. runKernelRequest in services/cam-program.ts calls cam.kernel.jobOfSnapshot; preparation issues become a 400.
  4. cam.kernel.runJob plans or follows operations, computes cutting data, generates toolpaths, posts NC for the machine's dialect and replays it on voxel stock to evaluate claims.
  5. The result is decoded against CamKernelResult and returned. Nothing is stored until the client saves a toolpath with a portable document, at which point the sidecar reruns the captured request and compares.

In 3D

Workspace dependency graph Drag to orbit · scroll to zoom · right-drag to pan
All 13 workspace packages from their package.json files; each line is a workspace:* dependency (17 in total). Rows are dependency depth: packages with no workspace dependencies at the front, the sidecar, which depends on 8 of them, at the back. Orange boxes are apps.