Files
CherryHQ-cherry-studio/docs/references/data/preference-overview.md
fullex b40d863b0b refactor(quick-assistant): rename mini window to quick assistant
Unify the feature under its canonical name "Quick Assistant":

- Rename miniWindow.html → quickAssistant.html and
  windows/mini/ → windows/quickAssistant/ (via git mv to preserve history).
  The bounds file miniWindow-state.json is not migrated; users see default
  bounds once after upgrade.
- Collapse half-renamed QuickWindow/MiniWindow identifiers in
  QuickAssistantService and its callers (ShortcutService, TrayService,
  ShortcutService.test) onto QuickAssistant.
- Rename the Inputbar scope literal 'mini-window' → 'quick-assistant'.
  The Redux DEFAULT_TOOL_ORDER_BY_SCOPE keeps the legacy key behind a
  transitional Record<InputbarScope | 'mini-window', ToolOrder> annotation;
  both entries will be collapsed when Redux is removed.
- Rename i18n keys miniwindow.*, mini_window, show_mini_window to
  quickAssistant.*, quick_assistant, show_quick_assistant across all
  locales; synced via i18n:sync.
- Update lingering "mini window" wording in docs and comments.

Legacy 'mini_window' literals intentionally retained in the v2
ShortcutMappings migrator (identifies Redux-persisted old keys) and in
v1 Redux store files (to be removed with Redux).
2026-04-18 10:36:27 -07:00

7.2 KiB

Preference System Overview

The Preference system provides centralized management for user configuration and application settings with cross-window synchronization.

Purpose

PreferenceService handles data that:

  • Is a user-modifiable setting that affects app behavior
  • Has a fixed key structure with stable value types
  • Needs to persist permanently until explicitly changed
  • Should sync automatically across all application windows

Key Characteristics

Fixed Key Structure

  • Predefined keys in the schema (users modify values, not keys)
  • Supports 158 configuration items
  • Nested key paths supported (e.g., app.theme.mode)

Atomic Values

  • Each preference item represents one logical setting
  • Values are typically: boolean, string, number, or simple array/object
  • Changes are independent (updating one doesn't affect others)

Cross-Window Synchronization

  • Changes automatically broadcast to all windows
  • Consistent state across main window, quick assistant, etc.
  • Conflict resolution handled by Main process

Update Strategies

Optimistic Updates (Default)

// UI updates immediately, then syncs to database
await preferenceService.set("app.theme.mode", "dark");
  • Best for: frequent, non-critical settings
  • Behavior: Local state updates first, then persists
  • Rollback: Automatic revert if persistence fails

Pessimistic Updates

// Waits for database confirmation before updating UI
await preferenceService.set("api.key", "secret", { optimistic: false });
  • Best for: critical settings (API keys, security options)
  • Behavior: Persists first, then updates local state
  • No rollback needed: UI only updates on success

Architecture Diagram

┌─────────────────────────────────────────────────────┐
│ Renderer Process                                    │
│ ┌─────────────────────────────────────────────────┐ │
│ │ usePreference Hook                              │ │
│ │ - Subscribe to preference changes               │ │
│ │ - Optimistic/pessimistic update support         │ │
│ └──────────────────────┬──────────────────────────┘ │
│                        ▼                            │
│ ┌─────────────────────────────────────────────────┐ │
│ │ PreferenceService (Renderer)                    │ │
│ │ - Local cache for fast reads                    │ │
│ │ - IPC proxy to Main process                     │ │
│ │ - Subscription management                       │ │
│ └──────────────────────┬──────────────────────────┘ │
└────────────────────────┼────────────────────────────┘
                         │ IPC
┌────────────────────────┼────────────────────────────┐
│ Main Process           ▼                            │
│ ┌─────────────────────────────────────────────────┐ │
│ │ PreferenceService (Main)                        │ │
│ │ - Full memory cache of all preferences          │ │
│ │ - SQLite persistence via Drizzle ORM            │ │
│ │ - Cross-window broadcast                        │ │
│ └──────────────────────┬──────────────────────────┘ │
│                        ▼                            │
│ ┌─────────────────────────────────────────────────┐ │
│ │ SQLite Database (preference table)              │ │
│ │ - scope + key structure                         │ │
│ │ - JSON value storage                            │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘

Main vs Renderer Responsibilities

Main Process PreferenceService

  • Source of truth for all preferences
  • Full memory cache for fast access
  • SQLite persistence via preference table
  • Broadcasts changes to all renderer windows
  • Handles batch operations and transactions

Renderer Process PreferenceService

  • Local cache for read performance
  • Proxies write operations to Main
  • Manages React hook subscriptions
  • Handles optimistic update rollbacks
  • Listens for cross-window updates

Statistics (Debug)

Main process provides getStats(details?) for debugging subscription status:

  • Returns total keys, main process subscriptions, and window subscriptions
  • Pass details=true for per-key breakdown
  • Warning: Resource-intensive, recommended for development only
import { application } from '@application'

const preferenceService = application.get('PreferenceService')
const stats = preferenceService.getStats(true);

Database Schema

Preferences are stored in the preference table:

// Simplified schema
{
  scope: string; // e.g., 'default', 'user'
  key: string; // e.g., 'app.theme.mode'
  value: json; // The preference value
  createdAt: number;
  updatedAt: number;
}

Preference Categories

Application Settings

  • Theme mode, language, font sizes
  • Window behavior, startup options

Feature Toggles

  • Show/hide UI elements
  • Enable/disable features

User Customization

  • Keyboard shortcuts
  • Default values for operations

Provider Configuration

  • AI provider settings
  • API endpoints and tokens

Usage Summary

For detailed code examples and API usage, see Preference Usage Guide.

Operation Hook Service Method
Read single usePreference(key) preferenceService.get(key)
Write single setPreference(value) preferenceService.set(key, value)
Read multiple usePreferences([...keys]) preferenceService.getMultiple([...keys])
Write multiple - preferenceService.setMultiple({...})