|
| 1 | +/** |
| 2 | + * Centralized defaults registry for Roo Code settings. |
| 3 | + * |
| 4 | + * IMPORTANT: These defaults should be applied at READ time (when consuming state), |
| 5 | + * NOT at WRITE time (when saving settings). This ensures: |
| 6 | + * - Users who haven't customized a setting inherit future default improvements |
| 7 | + * - Storage only contains intentional user customizations, not copies of defaults |
| 8 | + * - "Reset to Default" properly removes settings from storage (sets to undefined) |
| 9 | + * |
| 10 | + * Pattern: |
| 11 | + * - On save: pass `undefined` to remove a setting from storage (reset to default) |
| 12 | + * - On read: apply defaults using `value ?? settingDefaults.settingName` |
| 13 | + */ |
| 14 | + |
| 15 | +import { DEFAULT_CHECKPOINT_TIMEOUT_SECONDS } from "./global-settings.js" |
| 16 | + |
| 17 | +/** |
| 18 | + * Default values for all settings that can be reset to default. |
| 19 | + * |
| 20 | + * These values are the source of truth for defaults throughout the application. |
| 21 | + * When a setting is undefined in storage, these defaults should be applied |
| 22 | + * at consumption time. |
| 23 | + */ |
| 24 | +export const settingDefaults = { |
| 25 | + // Browser settings |
| 26 | + browserToolEnabled: true, |
| 27 | + browserViewportSize: "900x600", |
| 28 | + remoteBrowserEnabled: false, |
| 29 | + screenshotQuality: 75, |
| 30 | + |
| 31 | + // Audio/TTS settings |
| 32 | + soundEnabled: true, |
| 33 | + soundVolume: 0.5, |
| 34 | + ttsEnabled: true, |
| 35 | + ttsSpeed: 1.0, |
| 36 | + |
| 37 | + // Diff/Editor settings |
| 38 | + diffEnabled: true, |
| 39 | + fuzzyMatchThreshold: 1.0, |
| 40 | + |
| 41 | + // Checkpoint settings |
| 42 | + enableCheckpoints: false, |
| 43 | + checkpointTimeout: DEFAULT_CHECKPOINT_TIMEOUT_SECONDS, |
| 44 | + |
| 45 | + // Terminal settings |
| 46 | + terminalOutputLineLimit: 500, |
| 47 | + terminalOutputCharacterLimit: 50_000, |
| 48 | + terminalShellIntegrationTimeout: 30_000, |
| 49 | + |
| 50 | + // Context management settings |
| 51 | + maxOpenTabsContext: 20, |
| 52 | + maxWorkspaceFiles: 200, |
| 53 | + showRooIgnoredFiles: false, |
| 54 | + enableSubfolderRules: false, |
| 55 | + maxReadFileLine: -1, |
| 56 | + maxImageFileSize: 5, |
| 57 | + maxTotalImageSize: 20, |
| 58 | + maxConcurrentFileReads: 5, |
| 59 | + |
| 60 | + // Diagnostic settings |
| 61 | + includeDiagnosticMessages: true, |
| 62 | + maxDiagnosticMessages: 50, |
| 63 | + writeDelayMs: 1000, |
| 64 | + |
| 65 | + // Auto-approval settings |
| 66 | + alwaysAllowFollowupQuestions: false, |
| 67 | + |
| 68 | + // Prompt enhancement settings |
| 69 | + condensingApiConfigId: "", |
| 70 | + includeTaskHistoryInEnhance: true, |
| 71 | + |
| 72 | + // UI settings |
| 73 | + reasoningBlockCollapsed: true, |
| 74 | + enterBehavior: "send" as const, |
| 75 | + |
| 76 | + // Environment details settings |
| 77 | + includeCurrentTime: true, |
| 78 | + includeCurrentCost: true, |
| 79 | + maxGitStatusFiles: 0, |
| 80 | + |
| 81 | + // Language settings |
| 82 | + language: "en" as const, |
| 83 | + |
| 84 | + // MCP settings |
| 85 | + mcpEnabled: true, |
| 86 | + |
| 87 | + // Indexing settings |
| 88 | + codebaseIndexEnabled: false, |
| 89 | + codebaseIndexQdrantUrl: "http://localhost:6333", |
| 90 | + codebaseIndexEmbedderProvider: "openai" as const, |
| 91 | + codebaseIndexEmbedderBaseUrl: "", |
| 92 | + codebaseIndexEmbedderModelId: "", |
| 93 | + codebaseIndexEmbedderModelDimension: 1536, |
| 94 | + codebaseIndexOpenAiCompatibleBaseUrl: "", |
| 95 | + codebaseIndexBedrockRegion: "us-east-1", |
| 96 | + codebaseIndexBedrockProfile: "", |
| 97 | + codebaseIndexSearchMaxResults: 100, |
| 98 | + codebaseIndexSearchMinScore: 0.4, |
| 99 | + codebaseIndexOpenRouterSpecificProvider: "", |
| 100 | +} as const |
| 101 | + |
| 102 | +/** |
| 103 | + * Type representing all setting keys that have defaults. |
| 104 | + */ |
| 105 | +export type SettingWithDefault = keyof typeof settingDefaults |
| 106 | + |
| 107 | +/** |
| 108 | + * Helper function to get a setting value with its default applied. |
| 109 | + * Use this when reading settings from storage. |
| 110 | + * |
| 111 | + * @param key - The setting key |
| 112 | + * @param value - The value from storage (may be undefined) |
| 113 | + * @returns The value if defined, otherwise the default |
| 114 | + * |
| 115 | + * @example |
| 116 | + * const browserToolEnabled = getSettingWithDefault('browserToolEnabled', storedValue) |
| 117 | + */ |
| 118 | +export function getSettingWithDefault<K extends SettingWithDefault>( |
| 119 | + key: K, |
| 120 | + value: (typeof settingDefaults)[K] | undefined, |
| 121 | +): (typeof settingDefaults)[K] { |
| 122 | + return value ?? settingDefaults[key] |
| 123 | +} |
| 124 | + |
| 125 | +/** |
| 126 | + * Applies defaults to a partial settings object. |
| 127 | + * Only applies defaults for settings that are undefined. |
| 128 | + * |
| 129 | + * @param settings - Partial settings object |
| 130 | + * @returns Settings object with defaults applied for undefined values |
| 131 | + */ |
| 132 | +export function applySettingDefaults<T extends Partial<Record<SettingWithDefault, unknown>>>( |
| 133 | + settings: T, |
| 134 | +): T & typeof settingDefaults { |
| 135 | + const result = { ...settings } as T & typeof settingDefaults |
| 136 | + |
| 137 | + for (const key of Object.keys(settingDefaults) as SettingWithDefault[]) { |
| 138 | + if (result[key] === undefined) { |
| 139 | + ;(result as Record<SettingWithDefault, unknown>)[key] = settingDefaults[key] |
| 140 | + } |
| 141 | + } |
| 142 | + |
| 143 | + return result |
| 144 | +} |
0 commit comments