# Chatbox Admin & Developer Guide

This guide documents Chatbox (Community Edition) for administrators, architects,
and developers: how it is built, how it stores and protects data, how its
subsystems fit together, and how to deploy and operate every part of it
(including the web build, mobile builds, and the team-sharing proxy). For
end-user instructions, see the companion **User Guide**.

---

## 1. Executive Summary

**What it is.** Chatbox is a cross-platform AI chat **client** built on Electron.
The same TypeScript/React codebase compiles to a **desktop app** (Windows,
macOS, Linux), a **web app**, and **mobile apps** (iOS/Android via Capacitor). It
connects to 20+ AI providers, stores all user data locally, and adds image
generation, retrieval-augmented knowledge bases, web search, MCP tooling, and
reusable "Copilot" assistants.

**Architecture in one line.** A standard three-process Electron layout
(`main` / `preload` / `renderer`) plus a `shared` layer, where the **renderer is
the product** (a React SPA routed by file-based TanStack Router) and the **main
process** provides OS integration, persistent storage, the knowledge-base
database, and MCP stdio transport. The same renderer runs in a browser (web
build) or a WebView (mobile build) behind platform abstractions.

**Key technical facts every operator should know:**

| Area | Fact |
|------|------|
| Runtime | Electron 26, React 18, TypeScript 5.8 |
| Build | `pnpm` + `electron-vite` (Vite 7) + `electron-builder`; Capacitor 7 for mobile |
| AI layer | Vercel **AI SDK** (`ai`, `@ai-sdk/*`) — one SDK, many providers |
| State | `jotai` + `zustand` + `@tanstack/react-query` |
| UI | Mantine + MUI + Tailwind, with a `chatbox-*` design-token system |
| Config store | `electron-store` JSON in `userData`, auto-backed-up every 10 min |
| Knowledge base | libSQL vector store via **Mastra** (`@mastra/libsql`, `@mastra/rag`) |
| Security posture | `webSecurity: false`; `contextBridge` exposes a generic `invoke` |
| Telemetry | Google Analytics 4 + Sentry + Plausible (all opt-out) |
| Updates | `electron-updater`, releases hosted on Cloudflare R2 |
| License | GPLv3 (Community Edition) |

> [!IMPORTANT]
> Chatbox is a **client application, not a server**. There is no backend to
> deploy for the app itself, no listening port, no multi-user mode, and no
> central database. The only deployable server component is the optional
> **team-sharing** proxy ([§11](#11-team-sharing-deployment)). The "Chatbox AI"
> cloud service is a first-party SaaS the client can call, not part of this repo.

---

## 2. Architecture

### 2.1 Process model

```
                         Electron application
 ┌─────────────────────────────────────────────────────────────────┐
 │  MAIN process (Node.js)            src/main/                      │
 │   • BrowserWindow lifecycle, tray, global shortcuts, menu        │
 │   • electron-store config + auto-backup        (store-node.ts)    │
 │   • auto-update (electron-updater)             (app-updater.ts)   │
 │   • proxy, auto-launch, deep links, file parsing                 │
 │   • Knowledge Base: libSQL DB + RAG worker  (knowledge-base/)    │
 │   • MCP stdio transport                        (mcp/)            │
 │            ▲                                                       │
 │            │ ipcMain.handle(...)  ◄── contextBridge "invoke"      │
 │            ▼                                                       │
 │  PRELOAD            src/preload/index.ts                          │
 │   • exposes window.electronAPI = { invoke, on* listeners }       │
 │            ▲                                                       │
 │            │ window.electronAPI                                   │
 │            ▼                                                       │
 │  RENDERER (Chromium)               src/renderer/   ← THE PRODUCT  │
 │   • React 18 SPA, TanStack file-based router                      │
 │   • jotai/zustand stores, react-query                            │
 │   • Vercel AI SDK calls go straight to provider APIs            │
 └─────────────────────────────────────────────────────────────────┘

 SHARED   src/shared/  — types, defaults, provider registry, model
                          classes, errors; imported by every process.
```

The four source roots:

| Root | Role |
|------|------|
| `src/main` | Electron main process (Node). OS integration + KB DB + MCP. |
| `src/preload` | The `contextBridge` shim — the only renderer→main door. |
| `src/renderer` | The React application — UI, routing, stores, model calls. |
| `src/shared` | Cross-process code: types, defaults, provider/model registry, errors, file-extension tables. |

> [!NOTE]
> Unusually for an Electron app, **the renderer talks to AI providers
> directly** over HTTP using the Vercel AI SDK — model traffic does **not** flow
> through the main process. The main process is used for OS-level work, the
> config store, the knowledge-base database, and launching stdio MCP servers.
> This is why `webSecurity` is disabled (see [§9](#9-security-analysis)).

### 2.2 The renderer route tree = the feature map

Chatbox uses **file-based routing** (`@tanstack/react-router`); the generated
`src/renderer/routeTree.gen.ts` is the authoritative page list. The top-level
routes are the app's features:

| Route | Feature |
|-------|---------|
| `/` | Home / new conversation (model selector, Copilot picker, input box) |
| `/session/$` | A chat or picture conversation |
| `/copilots` | Copilot gallery & management |
| `/image-creator` | Image generation workspace |
| `/guide` | First-run onboarding |
| `/about` | About / links / version |
| `/settings/*` | Settings panels (see below) |
| `/dev`, `/task` | Developer/internal pages |

Settings sub-routes (`src/renderer/routes/settings/`), which double as the config
surface:

`chatbox-ai`, `provider` (+ `provider/$providerId`), `default-models`,
`web-search`, `mcp`, `knowledge-base`, `document-parser`, `chat`, `hotkeys`,
`general`. The `mcp` and `knowledge-base` panels are gated behind
`featureFlags` in `src/renderer/utils/feature-flags.ts`.

### 2.3 State management

- **`jotai`** atoms (`src/renderer/stores/atoms/`) for fine-grained reactive
  state (current session id, remote config, etc.), with `jotai-immer`/`optics`.
- **`zustand`** stores (`settingsStore`, `uiStore`, `authInfoStore`,
  `onboardingStore`, `chatStore`/`sessionActions`) for app/settings/UI state.
- **`@tanstack/react-query`** for async/server data (model registry, remote
  copilots, blobs).

Settings and onboarding stores hydrate from persistent storage on boot
(`initSettingsStore()`, `initOnboardingStore()` in `routes/__root.tsx`).

### 2.4 Platform abstraction

`src/renderer/platform/` abstracts everything platform-specific behind one
interface so the same renderer runs on desktop, web, and mobile. Concrete
implementations include `DesktopFileStorage`, `LocalStorage`, `SQLiteStorage`,
`MobileSQLiteStorage`, `IndexedDBStorage`, plus exporters and loggers
(`web_platform.ts`, `desktop_platform.ts`, `test_platform.ts`). Build-time
flags (`CHATBOX_BUILD_PLATFORM`, `CHATBOX_BUILD_TARGET`) select the
implementation; `platform.type` is `'desktop' | 'web' | 'mobile'`.

---

## 3. Requirements

### 3.1 Runtime (end users)

| Platform | Requirement |
|----------|-------------|
| Windows | Windows 10/11, x64 or ARM64 |
| macOS | Intel or Apple Silicon (universal builds: arm64 + x64) |
| Linux | AppImage or `.deb`, x64 or ARM64 |
| Web | Any modern Chromium/Firefox/Safari browser |
| Mobile | iOS (App Store) / Android (Play or APK) |

### 3.2 Build (developers)

| Tool | Version (from `package.json` `engines`) |
|------|------|
| Node.js | `>=20.0.0 <23.0.0` |
| pnpm | `>=10.17.0` (pinned `packageManager: pnpm@10.33.0`) |
| Electron | `^26.6.10` |
| TypeScript | `^5.8.3` |
| Capacitor (mobile) | `^7.0.0` |

> [!NOTE]
> The pnpm workspace enforces **supply-chain hygiene**: `pnpm-workspace.yaml`
> sets `minimumReleaseAge: 10080` (10080 minutes = 7 days), so only packages
> published at least a week ago are installed.

---

## 4. Build & Distribution

### 4.1 Build commands

All builds go through `electron-vite` (config: `electron.vite.config.ts`), which
compiles the three targets (`main`, `preload`, `renderer`).

| Command | Purpose |
|---------|---------|
| `pnpm dev` (`pnpm start`) | Run in development (electron-vite dev) |
| `pnpm dev:web` | Renderer-only web dev (`DEV_WEB_ONLY=true`) |
| `pnpm build` | Build all three targets |
| `pnpm build:web` | Web build (`CHATBOX_BUILD_PLATFORM=web`) + strip sourcemaps |
| `pnpm package` | Build + `electron-builder` installer for current OS |
| `pnpm package:all` | Build installers for Windows + macOS + Linux |
| `pnpm mobile:ios` / `mobile:android` | Build + `cap sync` + open native IDE |
| `pnpm test` | `vitest run` |
| `pnpm lint` / `format` / `check` | Biome lint / Biome format / `tsc --noEmit` |

Build flavor is driven by environment variables consumed in
`electron.vite.config.ts`:

| Variable | Effect |
|----------|--------|
| `CHATBOX_BUILD_PLATFORM` | `web` / `ios` / `android` / unset (desktop) |
| `CHATBOX_BUILD_TARGET` | `mobile_app` for Capacitor builds |
| `CHATBOX_BUILD_CHANNEL` | e.g. `google_play` (affects store-review behavior) |
| `USE_LOCAL_API` / `USE_BETA_API` | Point at local/beta Chatbox AI backend |
| `USE_LOCAL_CHATBOX` / `USE_BETA_CHATBOX` | Point at local/beta web endpoints |
| `SENTRY_AUTH_TOKEN` / `SENTRY_RELEASE` / `SENTRY_DIST` | Enable Sentry sourcemap upload |
| `DEV_PORT` | Renderer dev server port (default 1212) |

The renderer build splits vendor chunks (`vendor-ai` for `ai`/`@ai-sdk`,
`vendor-ui` for Mantine/Tabler, `vendor-charts` for mermaid/d3) to control
bundle size and build memory.

### 4.2 Packaging matrix (`electron-builder.yml`)

| Target | Arch | Output | Signing |
|--------|------|--------|---------|
| Windows | x64, arm64 | NSIS installer (`${productName}-${version}-Setup.exe`) | `custom_win_sign.js`, SHA-256 |
| macOS | arm64, x64 | DMG (distribution) | hardened runtime + entitlements; notarize via `afterSign` hook (`notarize.js`) |
| Linux | x64, arm64 | AppImage + `.deb` | — |

- `appId`: `xyz.chatboxapp.app`; `productName`: `Chatbox`.
- ASAR packaging is on; native bits are unpacked (`**/*.{node,dll}` and the
  whole `node_modules/libsql/**`). An `afterPack` hook (`patch-libsql.cjs`)
  patches libSQL for packaged builds.
- **Releases are published to Cloudflare R2** (S3-compatible) under
  `bucket: chatbox`, `path: /releases`, with the channel set by the
  `UPDATE_CHANNEL` env var.

### 4.3 Auto-update

`src/main/app-updater.ts` wires `electron-updater`:

- On launch (if **Automatic updates** is on) it checks immediately, then
  **every hour**.
- It tries a **list of mirror feed URLs** in order until one responds:
  `chatboxai.app`, `api.chatboxai.app`, `api.ai-chatbox.com`,
  `api.chatboxapp.xyz`, `api.chatboxai.com` (each at `/api/auto_upgrade`).
- If **Beta updates** is enabled, it switches to the `beta` channel and disables
  downgrades.
- When an update is downloaded, the renderer is notified (`update-downloaded`)
  and the user can apply it via the `install-update` IPC call
  (`autoUpdater.quitAndInstall()`).

> [!NOTE]
> AppImage and app-store builds typically rely on external updaters; for those,
> direct users to GitHub Releases.

---

## 5. Configuration & Data Storage

### 5.1 Where data lives

Everything is under Electron's `userData` directory (e.g.
`%APPDATA%\Chatbox` on Windows, `~/Library/Application Support/Chatbox` on
macOS, `~/.config/Chatbox` on Linux):

| Path | Contents |
|------|----------|
| `config.json` | `electron-store` data: `settings`, `configs` (incl. `uuid`), `configVersion` |
| `config-backup-<ISO>.json` | Rolling auto-backups (every 10 min) |
| `databases/chatbox_kb.db` | libSQL knowledge-base DB + vector index |
| log file (electron-log default) | Diagnostic logs |

Browser (web) and mobile builds use IndexedDB / SQLite via the platform
abstraction instead of `config.json`.

### 5.2 The config store and its self-healing

`src/main/store-node.ts` is the durability core:

- On startup it validates `config.json`. If invalid, it walks the newest backup
  files and restores the latest valid one.
- `electron-store` is created with `clearInvalidConfig: true`.
- `autoBackup()` runs every 10 minutes (and re-arms on power resume / pauses on
  suspend), keeping recent valid backups and pruning old ones.
- Large binary values (avatars, background images, generated images) are stored
  as **blobs** via separate IPC (`getStoreBlob`/`setStoreBlob`/...), not inside
  `config.json`.

### 5.3 Settings schema (defaults)

`src/shared/defaults.ts` defines the authoritative defaults. Notable values:

| Key | Default |
|-----|---------|
| `theme` | System | `language` | `en` | `fontSize` | `14` |
| `spellCheck` | `true` | `autoGenerateTitle` | `true` |
| `enableMarkdownRendering` / `LaTeX` / `Mermaid` | `true` |
| `autoPreviewArtifacts` | `false` | `autoCollapseCodeBlock` | `true` |
| `pasteLongTextAsAFile` | `true` |
| `autoCompaction` | `true` | `compactionThreshold` | `0.6` |
| `autoLaunch` | `false` | `autoUpdate` | `true` | `betaUpdate` | `false` |
| `allowReportingAndTracking` | `true` (opt-out) |
| default chat session | provider `chatbox-ai`, model `chatboxai-4`, unlimited context |
| default picture session | provider `chatbox-ai`, model `DALL-E-3`, vivid, 1 image |
| web search | provider `build-in` (Chatbox AI) |
| document parser | unset → desktop defaults to `local`, mobile/web to `chatbox-ai` |

Default shortcuts (`settings.shortcuts`): quick toggle `Alt+\``, focus input
`mod+i`, web-browsing `mod+e`, new chat `mod+n`, new picture `mod+shift+n`,
session nav `mod+tab`/`mod+shift+tab`, refresh context `mod+r`, search `mod+k`,
send `Enter`, send-without-reply `Ctrl+Enter`.

### 5.4 Environment variables

There is **no `.env`-style runtime config for end users.** The environment
variables in [§4.1](#41-build-commands) are **build-time** flags. Runtime
behavior toggles that do exist are minimal:

| Variable | Used by | Effect |
|----------|---------|--------|
| `NODE_ENV` | main/renderer | `development` enables debug menus & devtools |
| `DEBUG_PROD` | main | Force debug behavior in a production build |
| `START_MINIMIZED` | main | Start the window minimized |
| `COMPUTERNAME` | main | Windows device-name source |

> [!IMPORTANT]
> **Negative knowledge — things that do NOT exist:** no system-wide config file
> (no `/etc/chatbox/`, no registry policy keys), no HTTP API exposed by the app,
> no webhooks, no plugin system with arbitrary code (extensibility is via MCP),
> and no telemetry that includes message content. Don't document or configure
> knobs that aren't here.

### 5.5 Import / export & migration

`src/renderer/routes/settings/general.tsx` implements streaming JSON export of
selected data (`Settings`, `Conversations`, `My Copilots`, optionally
`API KEY & License`). When **keys are not included**, the exporter strips
`apiKey`/`accessKey`/`secretKey`/`sessionToken`/`licenseKey`/`licenseDetail`.
Import runs `migrateOnData()` (see `stores/migration.ts`) to upgrade older
exports, then **relaunches** the app. Schema evolution is tracked by
`configVersion`.

---

## 6. Provider & Model Architecture

### 6.1 Provider registry

Providers are registered into a `Map` via side-effect imports in
`src/shared/providers/index.ts` (import order determines UI order, with Chatbox
AI first). The registry API (`src/shared/providers/registry.ts`):
`defineProvider`, `getProviderDefinition`, `getAllProviders`,
`getSystemProviders`, `hasProvider`.

Each `ProviderDefinition` carries: `id`, `name`, `type`
(`ModelProviderType`: `OpenAI` | `Claude` | `Gemini` | `OpenAIResponses`),
`urls`, `defaultSettings` (apiHost/apiPath/models), an optional
`modelsDevProviderId` (for [models.dev](https://models.dev) enrichment),
`curatedModelIds`, and a `createModel()` factory.

**Built-in providers** (22): `chatbox-ai`, `openai`, `openai-responses`,
`gemini`, `claude`, `deepseek`, `qwen`, `qwen-portal`, `minimax`, `moonshot`,
`siliconflow`, `openrouter`, `ollama`, `lmstudio`, `azure`, `groq`, `xai`,
`mistral-ai`, `perplexity`, `volcengine`, `chatglm`, `github-copilot`,
`bedrock`.

### 6.2 Model instantiation

`getModel(settings, globalSettings, config, dependencies)`
(`src/shared/providers/index.ts`) resolves the provider definition and calls its
`createModel()`. For **custom** providers, `createCustomProviderModel()`
(`utils.ts`) instantiates one of `CustomOpenAI`, `CustomClaude`, `CustomGemini`,
or `CustomOpenAIResponses` based on the chosen API type. Model metadata
(capabilities like `vision` / `tool_use` / `reasoning`, context window, max
output) is enriched from the **model registry** (`src/shared/model-registry`,
which snapshots models.dev data in `snapshot.generated.ts`).

API host/path normalization helpers (`src/shared/utils`) keep endpoints
consistent: `normalizeOpenAIApiHostAndPath`, `normalizeClaudeHost`,
`normalizeGeminiHost`, `normalizeAzureEndpoint`, `normalizeOpenAIResponsesHostAndPath`.

### 6.3 The AI call layer

The actual chat/stream/tool-call logic uses the **Vercel AI SDK** (`ai` +
`@ai-sdk/*`) under `src/renderer/packages/model-calls`, `model-context`,
`context-management`, `token-estimation`, `tools`, and `web-search`. Model
abstractions and the error hierarchy live in `src/shared/models`
(`abstract-ai-sdk.ts`, `errors.ts`).

### 6.4 OAuth

Some providers support OAuth (`src/shared/oauth`); when an OAuth token is active,
the provider's default API host is used and `resolveEffectiveApiKey()` resolves
the credential. Provider import/OAuth deep links arrive via
`chatbox://provider/import`.

---

## 7. Knowledge Base (RAG) Internals

Implemented entirely in the **main process** under `src/main/knowledge-base/`.

### 7.1 Storage

- **libSQL** file DB at `userData/databases/chatbox_kb.db`, accessed through
  Mastra's `LibSQLVector` (`@mastra/libsql`). The same client serves both
  relational tables and the vector index (a single client to avoid corruption).
- **Schema:**

  ```sql
  knowledge_base(id, name, embedding_model, rerank_model, vision_model,
                 document_parser, provider_mode, created_at)
  kb_file(id, kb_id, filename, filepath, mime_type, file_size,
          chunk_count, total_chunks, status, error, parser_type,
          use_remote_parsing, parsed_remotely, processing_started_at, created_at)
  ```

  Schema upgrades are applied as idempotent `ALTER TABLE ... ADD COLUMN`
  statements (errors ignored when the column already exists).
- Vector index per KB is named `kb_{kbId}`.

### 7.2 Ingestion pipeline

A background **worker loop** (`startWorkerLoop`) polls every **3 s** for
`pending` files and processes them:

1. **Parse** via the parser router (`parsers/`): `local`, `chatbox-ai` (cloud),
   or `mineru`. The effective parser comes from the KB's `document_parser` config
   (or a forced `chatbox-ai` when the user retried "with server parsing").
2. **Chunk** with Mastra `MDocument` — strategy `recursive`, size **512**,
   overlap **50**.
3. **Embed** in batches of **50** via `embedMany` (AI SDK) using the KB's
   embedding model.
4. **Upsert** vectors with metadata (`text`, `fileId`, `filename`, `chunkIndex`)
   into the libSQL vector index.
5. Track progress in `chunk_count`/`total_chunks` so processing is **resumable**
   from the last completed chunk.

File state machine: `pending → processing → done | failed | paused`. Files
processing for > 5 min are marked `failed` (timeout); interrupted files left in
`processing` are reset to `paused` on next launch (manual resume). Per-file
limit is **100 MB** (server parser limit is 50 MB).

### 7.3 Retrieval

`searchKnowledgeBase(kbId, query)` embeds the query, runs a vector
`query({ topK: 20 })`, then — if a rerank model is configured —
`rerank(..., { topK: 5 })` to return the best passages. Failures fall back to the
raw vector results.

### 7.4 IPC surface

The KB exposes a clean IPC API (`ipc-handlers.ts`), all input-validated:
`kb:list`, `kb:create`, `kb:update`, `kb:delete`, `kb:file:list`,
`kb:file:count`, `kb:file:list-paginated`, `kb:file:get-metas`,
`kb:file:read-chunks`, `kb:file:upload`, `kb:search`, `kb:file:retry`,
`kb:file:pause`, `kb:file:resume`, `kb:file:delete`. Deletes run in a transaction
that removes rows **and** the vector index together.

> [!TIP]
> The KB system reports failures to Sentry with rich tags (component, operation,
> kbId, filename). When diagnosing ingestion problems, the `operation` tag
> (`file_parsing`, `document_chunking`, `generate_embeddings`,
> `vector_storage`, `image_ocr_processing`) tells you exactly which stage failed.

---

## 8. MCP (Model Context Protocol)

Chatbox is an MCP **host** built on `@modelcontextprotocol/sdk` and
`@ai-sdk/mcp`.

- **Main process** (`src/main/mcp/`) provides the **stdio transport**
  (`ipc-stdio-transport`): it spawns local MCP server processes and bridges their
  events to the renderer over channels named
  `mcp:stdio-transport:{transportId}:{event}` (the preload registers listeners
  via `addMcpStdioTransportEventListener`). All transports are closed on
  `will-quit`.
- **Renderer** (`src/renderer/packages/mcp/`) manages server configs and tool
  invocation; **Settings → MCP** has **built-in** and **custom** server sections.
  Custom servers may be stdio (desktop) or remote (HTTP/SSE).
- Config persists in `settings.mcp = { servers, enabledBuiltinServers }`.
- Install-by-link: `chatbox://mcp/install?server=<base64>` opens the MCP settings
  pre-filled.

> [!CAUTION]
> A stdio MCP server is an arbitrary local executable run with the user's
> privileges. In managed deployments, treat the MCP server list as a
> **code-allowlist** and review configurations distributed via `chatbox://` deep
> links before approving them.

---

## 9. Security Analysis

Chatbox follows a **client-trusts-itself** model. Document it honestly rather
than expecting a hardened sandbox.

### 9.1 Renderer security posture

From `src/main/main.ts` `createWindow()`:

- `webSecurity: false` — **disabled on purpose** so the renderer can call
  arbitrary provider APIs cross-origin (the AI SDK runs in the renderer). This is
  the central trade-off: it removes the browser's same-origin protection for the
  app's web content.
- `allowRunningInsecureContent: false`.
- `contextBridge.exposeInMainWorld('electronAPI', { invoke, ...listeners })` —
  the preload exposes a **generic `ipcRenderer.invoke`**, so the renderer can
  call any IPC channel. There is no per-channel allowlist or `validateSender`
  check.
- External links are opened in the system browser (`setWindowOpenHandler` →
  `shell.openExternal`, `action: 'deny'`), preventing in-app navigation to remote
  origins.
- Single-instance lock (`requestSingleInstanceLock`) routes second-launch deep
  links to the existing window.

> [!WARNING]
> Because `webSecurity` is off and `invoke` is generic, the renderer is a
> trust boundary: any code running in it (including content rendered from model
> output) executes with the app's privileges. Mitigations in place are loading
> only local app content, denying new-window navigation, and not enabling
> `@electron/remote`. Operators distributing Chatbox should rely on **code
> signing** (Windows custom signer, macOS hardened runtime + notarization) to
> guarantee binary integrity.

### 9.2 Credentials & secrets

- API keys, license keys, and cloud tokens are stored in `config.json` (local,
  unencrypted) and in blob storage for binary assets. They never leave the device
  except to the provider you call.
- Exports **strip secrets by default** unless the user explicitly includes
  "API KEY & License" ([§5.5](#55-import--export--migration)).

### 9.3 Telemetry & privacy

Three optional analytics paths exist; all are governed by
`allowReportingAndTracking` (Settings → General → Error Reporting):

| System | Where | Data |
|--------|-------|------|
| Google Analytics 4 | `src/main/analystic-node.ts` (Measurement Protocol) | App/version/platform events keyed by the install `uuid` |
| Sentry | `@sentry/node` (main) + `@sentry/react` (renderer) | Crash/exception reports with operation tags |
| Plausible | web build (`data-domain` swapped to `web.chatboxai.app`) | Page analytics |

> [!NOTE]
> Telemetry is **opt-out** (`allowReportingAndTracking` defaults to `true`) and
> is described to users as "anonymous error data and events." Message content is
> not part of these payloads. For privacy-sensitive deployments, instruct users
> to disable it, or build with telemetry tokens unset.

### 9.4 Network

- A user-configurable **proxy** (`socks5://...` etc.) is applied to the whole
  Electron session (`src/main/proxy.ts`, `session.setProxy`).
- A per-provider **"Improve Network Compatibility" (`useProxy`)** flag exists for
  hosts that need it (note the known mobile gap for custom Anthropic hosts,
  issue #3739).

---

## 10. Operations

### 10.1 Logs

`electron-log` writes to the platform default log path. Users can **Export Logs**
(Settings → General → Diagnostic Logs); the renderer calls the `exportLogs` /
`clearLogs` IPC handlers. The renderer can also push structured log lines into
the main log via `appLog`.

### 10.2 Backups

The config auto-backup ([§5.2](#52-the-config-store-and-its-self-healing)) is the
primary safety net. For full portability use the JSON export/import. The
knowledge-base DB (`databases/chatbox_kb.db`) is **not** included in the JSON
export — back it up at the filesystem level if KB contents are critical.

### 10.3 Deep-link & instance handling

The app registers the `chatbox://` scheme (dev: `chatbox-dev://`) and handles:
`chatbox://mcp/install`, `chatbox://provider/import`, and an auth callback.
Deep links arriving via second-instance launch (Windows/Linux) or `open-url`
(macOS) are routed to the renderer with `navigate-to`.

### 10.4 OS integration toggles

Tray icon (show/hide + quit), global show/hide hotkey, **launch at startup**
(`auto-launch`), window-state persistence (size/position/maximized/fullscreen),
and native theme sync are all managed in the main process.

---

## 11. Team-Sharing Deployment

`team-sharing/` ships a small reverse-proxy so a team can share one upstream
OpenAI-style API key without handing out the secret. It is a **Caddy** server:

- `team-sharing/main.sh` substitutes `<HOST>` and `<KEY>` into a `Caddyfile`
  template and runs `caddy run`.
- Configure via environment: `HOST` (defaults to `:80`) and `KEY` (the shared
  access key).
- Deploy it (Docker/host) somewhere your team can reach, then each member sets
  their provider's **API Host** to the proxy URL and authenticates with the
  shared `KEY`.

See `team-sharing/README.md` in the repo for the exact `Caddyfile` and Docker
instructions.

> [!IMPORTANT]
> The proxy holds the **real** upstream API key. Run it over HTTPS, restrict
> network access to your team, and rotate `KEY` periodically. This is the only
> network-listening component associated with Chatbox.

---

## 12. Repository Structure

```
chatbox/
├── src/
│   ├── main/                 Electron main process
│   │   ├── main.ts           Window/tray/shortcuts/IPC entry
│   │   ├── store-node.ts     electron-store + auto-backup
│   │   ├── app-updater.ts    electron-updater
│   │   ├── proxy.ts, autoLauncher.ts, deeplinks.ts, file-parser.ts
│   │   ├── knowledge-base/    libSQL DB + RAG worker + IPC
│   │   ├── mcp/               stdio transport
│   │   └── adapters/          sentry, etc.
│   ├── preload/index.ts      contextBridge shim
│   ├── renderer/             React SPA (THE PRODUCT)
│   │   ├── routes/            TanStack file-based routes (feature map)
│   │   ├── packages/          model-calls, mcp, web-search, tools, token-estimation, …
│   │   ├── platform/          desktop/web/mobile storage & exporters
│   │   ├── stores/            jotai atoms + zustand stores
│   │   ├── components/, modals/, i18n/
│   │   └── routeTree.gen.ts   (generated)
│   └── shared/               types, defaults, providers/, models/, model-registry/, oauth/
├── team-sharing/             Caddy proxy for shared API keys
├── electron.vite.config.ts   3-target build config
├── electron-builder.yml      packaging/signing/publish (R2)
├── biome.json                lint + format
├── tailwind.config.js, postcss.config.js
└── package.json
```

---

## 13. Code Quality & Conventions

- **Tooling:** Biome 2.0 (`biome.json`) for lint + format — single quotes, no
  semicolons, 2-space indent, 120-col width. (A legacy `.eslintrc.js` remains.)
  Type-check with `pnpm check` (`tsc --noEmit`).
- **Testing:** `vitest` (node env) for unit tests (`*.test.ts` next to sources)
  and integration tests under `test/integration` (`test:integration`,
  `test:file-conversation`, `test:model-provider`). MSW (`msw`) mocks HTTP.
- **Path aliases:** `@` → `src/renderer`, `@shared` → `src/shared`.
- **Patches:** `patches/` carries pnpm patches for `libsql`,
  `mdast-util-gfm-autolink-literal`, and `@ai-sdk/deepseek`; some deps are version-
  pinned via `pnpm.overrides`.
- **Pre-commit:** Husky + lint-staged run Biome format on staged JS/TS.

---

## 14. Potential Improvements

These are observations from the source, not defects:

- **Tighten the IPC boundary.** The preload exposes a generic `invoke`; moving to
  an explicit per-channel API (and adding `validateSender`) would shrink the
  renderer's trust surface ([§9.1](#91-renderer-security-posture)).
- **Re-evaluate `webSecurity: false`.** Where provider calls could be proxied
  through the main process, re-enabling web security would restore same-origin
  protections for the app shell.
- **Include the KB database in backups.** The JSON export covers settings, chats,
  and copilots but not `chatbox_kb.db`; an integrated KB export/import would make
  migrations complete.
- **Encrypt secrets at rest.** API/license keys sit in plaintext `config.json`;
  OS keychain integration (or `safeStorage`) would harden stored credentials.
- **Surface MCP/remote-transport errors more clearly.** Several open issues
  (#3725, #3728) point to confusing failures for remote/HTTPS MCP servers.

---

## 15. Quick Reference

**Build:** `pnpm install && pnpm dev` · package: `pnpm package` /
`pnpm package:all` · web: `pnpm build:web` · mobile: `pnpm mobile:ios|android`.

**Key paths (userData):** `config.json`, `config-backup-*.json`,
`databases/chatbox_kb.db`, electron-log file.

**Source roots:** `src/main` (Node) · `src/preload` (bridge) · `src/renderer`
(SPA) · `src/shared` (types/providers/models).

**Providers (22):** chatbox-ai, openai, openai-responses, gemini, claude,
deepseek, qwen, qwen-portal, minimax, moonshot, siliconflow, openrouter, ollama,
lmstudio, azure, groq, xai, mistral-ai, perplexity, volcengine, chatglm,
github-copilot, bedrock (+ custom OpenAI/Claude/Gemini/Responses).

**KB pipeline:** parse (local/chatbox-ai/mineru) → chunk (recursive 512/50) →
embed (batch 50) → libSQL vector upsert → query topK 20 → rerank topK 5.

**Security flags:** `webSecurity:false`, generic `invoke` via contextBridge,
telemetry opt-out (`allowReportingAndTracking`), session-wide proxy support.

**Distribution:** electron-builder → NSIS / DMG / AppImage+deb (x64+arm64),
published to Cloudflare R2; `electron-updater` with hourly mirror-feed checks.

---

_Generated June 2026 from chatboxai/chatbox at 9c1db31. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
