# Settings reference

> AppSettings and electron-store keys in claudette-settings: theme, fonts, QMD, ultra plan, reminders, GStack, Foundry, focus tasks, customModels, and autoRouterConfig defaults.

- Repository: Parcha-ai/build
- GitHub: https://github.com/Parcha-ai/build
- Human docs: https://grok-wiki.com/public/docs/parcha-ai-build-bea5702b371b
- Complete Markdown: https://grok-wiki.com/public/docs/parcha-ai-build-bea5702b371b/llms-full.txt

## Source Files

- `src/shared/types/index.ts`
- `src/main/services/settings.service.ts`
- `src/main/ipc/settings.ipc.ts`
- `src/renderer/components/settings/SettingsDialog.tsx`
- `SECURITY.md`

---

---
title: "Settings reference"
description: "AppSettings and electron-store keys in claudette-settings: theme, fonts, QMD, ultra plan, reminders, GStack, Foundry, focus tasks, customModels, and autoRouterConfig defaults."
---

Build persists user preferences in a single `electron-store` file named `claudette-settings.json` under Electron `userData`. The `AppSettings` object lives at the nested key `settings`; several API credentials and provider keys are stored at the top level of the same file. `SettingsService` merges partial updates, applies `DEFAULT_SETTINGS` on first launch, and exposes read/write through IPC (`settings:get`, `settings:set`, `settings:reset`).

## Storage location

| Environment | `userData` path | Settings file |
|-------------|-----------------|---------------|
| Production (macOS) | `~/Library/Application Support/Build` | `claudette-settings.json` |
| Dev (`./scripts/dev.sh`) | `/tmp/grep-build-dev` (via `GREP_DEV_USER_DATA`) | Same filename, isolated from production |

On first launch after a rename from older app bundles, `migrateFromGrepBuild()` copies `claudette-settings.json` (and related store files) from legacy `G-Build` or `Grep Build` directories into the current `userData` folder.

<Info>
Dev builds never write into production `userData` when started through `./scripts/dev.sh`. The script optionally seeds dev settings from production only when dev files are missing.
</Info>

## File layout

Most product toggles and structured config are nested under `settings`. Sensitive keys used by harness services are often stored at the root of the same JSON file for direct `store.get('anthropicApiKey')` access.

```text
claudette-settings.json
├── settings: AppSettings          ← SettingsService.getSettings() / setSettings()
├── anthropicApiKey                ← SETTINGS_GET/SET_API_KEY helpers
├── githubToken
├── googleApiKey
├── foundryApiKey                  ← duplicate of settings.foundryApiKey possible
├── openAiApiKey                   ← audio / realtime
├── elevenLabsApiKey               ← voice / TTS
└── audioSettings: AudioSettings   ← separate nested object (AudioService)
```

```mermaid
flowchart LR
  subgraph renderer [Renderer]
    SD[SettingsDialog]
    TS[task.store]
    AS[audio.store]
  end
  subgraph ipc [IPC preload]
    API["window.electronAPI.settings"]
  end
  subgraph main [Main process]
    SS[SettingsService]
    AR[auto-router.service]
    CS[claude.service]
  end
  subgraph disk [userData]
    FILE["claudette-settings.json"]
  end
  SD --> API
  TS --> API
  AS --> API
  API --> SS
  SS --> FILE
  AR --> FILE
  CS --> FILE
```

## AppSettings (`settings` object)

Type: `AppSettings` in `src/shared/types/index.ts`. Defaults: `DEFAULT_SETTINGS` in `src/main/services/settings.service.ts`. Updates are shallow-merged: `setSettings(partial)` reads current `settings`, spreads `partial`, and writes back.

### Appearance and editor

| Field | Type | Default | Notes |
|-------|------|---------|-------|
| `theme` | `'dark' \| 'light' \| 'system'` | `'dark'` | Defined on `AppSettings`; not exposed in **Settings → General** today |
| `fontSize` | `number` | `14` | Same — no settings UI binding found |
| `fontFamily` | `string` | `'JetBrains Mono, Menlo, Monaco, monospace'` | Same — terminal/editor use hard-coded fonts in components |

### Session bootstrap

| Field | Type | Default | Notes |
|-------|------|---------|-------|
| `defaultSetupScript` | `string` | Bash template (npm/pip install) | Docker session setup script |
| `autoStartContainer` | `boolean` | `true` | Auto-start container on session create |

### QMD semantic search

| Field | Type | Default | UI | Behavior |
|-------|------|---------|-----|----------|
| `qmdEnabled` | `boolean` | `false` | General tab toggle | Opt-in global flag; per-project prefs live in separate store `claudette-qmd.json` |

<Warning>
`SettingsService` persists `qmdEnabled` under `settings.qmdEnabled`. `claude.service` also reads a top-level `qmdEnabled` key when attaching the QMD MCP server. If QMD does not activate after enabling the toggle, verify both nested and root keys in `claudette-settings.json` or align reads to `settings.qmdEnabled`.
</Warning>

### Ultra Plan and plan approval

| Field | Type | Default | UI |
|-------|------|---------|-----|
| `ultraPlanMode` | `boolean` | `false` | General → Ultra Plan Mode |
| `showClearContextOnPlanAccept` | `boolean` | unset (UI treats as `false`) | General → Clear Context on Plan Accept |

When `ultraPlanMode` is true, Claude Agent SDK hooks after successful `ExitPlanMode` can decompose approved plans into structured tasks.

### Reminders and reviews

| Field | Type | Default | UI / runtime |
|-------|------|---------|--------------|
| `lunchReminderEnabled` | `boolean` | `false` | General; status bar countdown in `App.tsx` |
| `lunchReminderTime` | `string` (HH:MM) | `'12:00'` | Used only when lunch reminder enabled |
| `bedtimeReminderEnabled` | `boolean` | `false` | General; 5-minute snooze in status bar |
| `bedtimeReminderTime` | `string` (HH:MM) | `'23:00'` | Used only when bedtime reminder enabled |
| `dailyReviewEnabled` | `boolean` | `true` | General |
| `dailyReviewTime` | `string` (HH:MM) | `'09:00'` | Morning review prompt when enabled |
| `bedtimeTaskReviewEnabled` | `boolean` | `true` | General; runs ~30 minutes before configured bedtime |

### GStack

| Field | Type | Default | UI |
|-------|------|---------|-----|
| `gstackEnabled` | `boolean` | `false` | **No Settings dialog toggle** |

When `true`, `claude.service` appends GStack routing instructions from `gstack.service` into the system prompt. Session-level GStack modes (`Session.gstackMode`) and the chat **G** launcher work independently of this flag.

### Foundry (Azure-hosted Claude)

| Field | Type | Default | UI (API Keys tab) |
|-------|------|---------|-------------------|
| `foundryEnabled` | `boolean` | `false` | Toggle |
| `foundryBaseUrl` | `string?` | — | Base URL (debounced save) |
| `foundryApiKey` | `string?` | — | API key field |
| `foundryDefaultSonnetModel` | `string?` | — | Model ID fields |
| `foundryDefaultHaikuModel` | `string?` | — | |
| `foundryDefaultOpusModel` | `string?` | — | |

When enabled, Claude runs set `ANTHROPIC_FOUNDRY_*` environment variables and route model availability through Foundry defaults.

### Focus tasks

| Field | Type | Default | Persisted by |
|-------|------|---------|--------------|
| `focusTasks` | `FocusTask[]` | `[]` | `task.store` via `settings.set` |
| `focusModeEnabled` | `boolean` | `false` | Task list UI |
| `focusModeActiveTaskId` | `string?` | — | Active task in focus mode |

`FocusTask` shape: `id`, `title`, `order`, `status` (`pending` \| `active` \| `done`), optional `sessionId`, `createdAt`, `completedAt`, optional `subtasks[]`.

### Custom proxy models

| Field | Type | Default | UI |
|-------|------|---------|-----|
| `customModels` | `CustomModelConfig[]` | `[]` | API Keys → Custom models |

`CustomModelConfig`: `id`, `name`, `modelId`, `baseUrl`, `apiKey`, optional `description`. Entries need `id`, `apiKey`, `baseUrl`, and `modelId` for Auto Build credential checks.

### Harness API keys (nested in `settings`)

| Field | Type | UI tab |
|-------|------|--------|
| `cursorApiKey` | `string?` | API Keys |
| `deepseekApiKey` | `string?` | API Keys (OpenCode / DeepSeek) |
| `geminiApiKey` | `string?` | API Keys |

### Onboarding and analytics (optional)

| Field | Type | Default | Notes |
|-------|------|---------|-------|
| `onboardingSkipped` | `boolean?` | — | Set when user skips API key onboarding |
| `posthogApiKey` | `string?` | — | Optional; `analytics.service` also reads env fallbacks |
| `posthogHost` | `string?` | — | Defaults to `https://us.i.posthog.com` when key present |

### Legacy / duplicate typed fields

`AppSettings` also declares `anthropicApiKey?` and `githubToken?`, but live reads for Anthropic/GitHub in main process prefer **top-level** store keys (see below).

## Top-level keys in `claudette-settings`

These sit beside `settings`, not inside it:

| Key | Access | Purpose |
|-----|--------|---------|
| `anthropicApiKey` | `SettingsService.getApiKey()` / `setApiKey()` | Primary Claude API key |
| `githubToken` | `getGitHubToken()` / `setGitHubToken()` | GitHub integration |
| `googleApiKey` | `getGoogleApiKey()` / `setGoogleApiKey()` | Gemini / Google harness |
| `foundryApiKey` | `getFoundryApiKey()` / `setFoundryApiKey()` | Foundry auth (may mirror `settings.foundryApiKey`) |
| `openAiApiKey` | `audio.service`, `realtime.service` | Transcription / Realtime |
| `elevenLabsApiKey` | `audio.service`, `elevenlabs-voice.service` | Voice mode / TTS |
| `audioSettings` | `AudioService` | Voice, Ralph Loop, Computer Use (see below) |

<Note>
Report security issues per [SECURITY.md](SECURITY.md): API keys stay on disk locally and are sent only to configured providers. Optional PostHog requires an explicit key in settings or environment.
</Note>

## `autoRouterConfig`

Optional field on `AppSettings`: `autoRouterConfig?: AutoRouterConfig`. Saved from **Settings → Auto Build** via `autoBuildConfigFromState()` in `SettingsDialog.tsx`. Runtime resolution merges saved values with `DEFAULT_CONFIG` in `auto-router.service.ts`.

### Runtime defaults (`DEFAULT_CONFIG`)

Used when no user overrides exist:

| Field | Default |
|-------|---------|
| `enabled` | `true` |
| `planModel` | `claude-sonnet-4-6` |
| `buildModel` | `codex:gpt-5.5` |
| `verifyModel` | `codex:gpt-5.5` |
| `refineModel` | `cursor:composer-2.5` |
| `fallbackModel` | `claude-sonnet-4-6` |
| `costAware` | `true` |
| `costThresholdPercent` | `80` (not exposed in Settings UI) |

Tier-specific `*Effort`, `*Speed`, `*Workflow`, `*BudgetUsd`, and `*Verification` fields are omitted until set in the UI (empty / `auto` in the dialog means “omit from saved JSON”).

### Settings UI defaults (before first save)

| Tier | Default model (UI) |
|------|-------------------|
| plan | `claude-sonnet-4-6` |
| build | `codex:gpt-5.5` |
| verify | `codex:gpt-5.5` |
| refine | `cursor:composer-2.5` |
| fallback | `claude-sonnet-4-6` |

Policy UI defaults: effort `''` (Default), speed/workflow/verification `'auto'`, budget `''`.

`costAware` defaults to `true` in the Auto Build tab. Custom categories use ids outside `plan`, `build`, `verify`, `refine`, `fallback` and match on `keywords` during routing.

Legacy configs may store tier models inside `categories[]` with fixed ids; `migrateAutoBuildModels()` promotes those into `planModel` / `buildModel` / etc. when loading the dialog.

For routing behavior, orchestration, and verification scripts, see the dedicated Auto Build configuration page.

## Audio settings (`audioSettings`)

Separate nested object, not part of `AppSettings`:

| Field | Default (high level) |
|-------|----------------------|
| `voiceModeEnabled` | `true` |
| `ralphLoopEnabled` | `false` |
| `computerUseEnabled` | `false` |
| `maxComputerUseIterations` | `20` |
| `selectedVoice` / `voiceSettings` | ElevenLabs Rachel preset |
| `voiceTriggerWord` | `'please'` |

Managed through `window.electronAPI.audio` IPC; Ralph Loop and Computer Use toggles appear under **Settings → General** (Just Build It Mode section).

## IPC and preload API

| Channel | Handler | Returns / effect |
|---------|---------|------------------|
| `settings:get` | `SettingsService.getSettings()` | Full `AppSettings` |
| `settings:set` | `setSettings(partial)` | Shallow merge into `settings` |
| `settings:reset` | `resetSettings()` | Restore `DEFAULT_SETTINGS` |
| `settings:get-api-key` | top-level `anthropicApiKey` | string (empty if missing) |
| `settings:set-api-key` | top-level write | |
| `settings:get-google-api-key` | top-level `googleApiKey` | |
| `settings:set-google-api-key` | top-level write | |

Renderer usage:

```typescript
await window.electronAPI.settings.get();
await window.electronAPI.settings.set({ qmdEnabled: true });
await window.electronAPI.settings.setApiKey('sk-...');
await window.electronAPI.settings.reset();
```

## Settings dialog tabs

| Tab | Persists to |
|-----|-------------|
| **General** | `qmdEnabled`, reminders, ultra plan, daily/bedtime reviews; audio flags via `audio` IPC |
| **Auto Build** | `autoRouterConfig` (models, costAware, tier policy, custom categories) |
| **API Keys** | Top-level Anthropic/OpenAI/Google/ElevenLabs keys; nested Foundry, Cursor, DeepSeek, Gemini, `customModels` |
| **Releases** | Read-only release notes |

Changes auto-save with debounced text fields (500 ms) for secrets and URLs.

## Related electron-store files

Not in `claudette-settings`, but commonly edited alongside settings:

| File | Purpose |
|------|---------|
| `claudette-sessions.json` | Session records |
| `claudette-qmd.json` | QMD collections and per-project enable/disable |
| `claudette-mcp-servers.json` | Installed MCP servers |
| `claudette-analytics.json` | Local usage events |
| `grep-auth` (separate store name) | GitHub OAuth tokens |

## Reset and inspection

- **In app:** no full reset button in the dialog; use `settings:reset` from devtools or custom tooling to restore `DEFAULT_SETTINGS` (does not clear top-level API keys unless you delete them separately).
- **On disk:** quit Build, edit or remove `claudette-settings.json` under the correct `userData` path, restart.

<Steps>
<Step title="Confirm which data directory is active">
Production uses `~/Library/Application Support/Build`. Dev uses `/tmp/grep-build-dev` when launched via `./scripts/dev.sh`.
</Step>
<Step title="Back up the file">
Copy `claudette-settings.json` before manual edits.
</Step>
<Step title="Verify nested vs top-level keys">
API keys for Claude should exist at `anthropicApiKey` (root). Product toggles belong under `settings`.
</Step>
</Steps>

## Related pages

<CardGroup>
<Card title="Configure API keys and providers" href="/configure-providers">
Anthropic, OpenAI, Google, Foundry, Cursor, DeepSeek, and custom proxy setup beyond the raw store keys.
</Card>
<Card title="Auto Build configuration" href="/auto-build-configuration">
Full `AutoRouterConfig` routing semantics, tiers, and `verify:auto-router:*` scripts.
</Card>
<Card title="Semantic search (QMD)" href="/semantic-search-qmd">
Project preferences in `claudette-qmd.json` and indexing workflow.
</Card>
<Card title="IPC and preload bridge" href="/ipc-bridge">
How `settings:*` channels map to `window.electronAPI.settings`.
</Card>
<Card title="Installation" href="/installation">
Production vs dev `userData` separation and first-run migration.
</Card>
</CardGroup>
