-
Notifications
You must be signed in to change notification settings - Fork 2.8k
settings refactor #10928
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
settings refactor #10928
Changes from all commits
c853feb
3b85990
88e9777
6c36806
c038fa5
f3d1c12
e3fef81
22055b8
988b1f6
4a71b09
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,152 @@ | ||
| import { describe, expect, it } from "vitest" | ||
| import { settingDefaults, getSettingWithDefault } from "../defaults.js" | ||
| import { DEFAULT_CHECKPOINT_TIMEOUT_SECONDS, DEFAULT_WRITE_DELAY_MS } from "../global-settings.js" | ||
|
|
||
| describe("settingDefaults", () => { | ||
| it("should have all expected default values", () => { | ||
| // Auto-approval settings (all default to false for safety) | ||
| expect(settingDefaults.autoApprovalEnabled).toBe(false) | ||
| expect(settingDefaults.alwaysAllowReadOnly).toBe(false) | ||
| expect(settingDefaults.alwaysAllowReadOnlyOutsideWorkspace).toBe(false) | ||
| expect(settingDefaults.alwaysAllowWrite).toBe(false) | ||
| expect(settingDefaults.alwaysAllowWriteOutsideWorkspace).toBe(false) | ||
| expect(settingDefaults.alwaysAllowWriteProtected).toBe(false) | ||
| expect(settingDefaults.alwaysAllowBrowser).toBe(false) | ||
| expect(settingDefaults.alwaysAllowMcp).toBe(false) | ||
| expect(settingDefaults.alwaysAllowModeSwitch).toBe(false) | ||
| expect(settingDefaults.alwaysAllowSubtasks).toBe(false) | ||
| expect(settingDefaults.alwaysAllowExecute).toBe(false) | ||
| expect(settingDefaults.alwaysAllowFollowupQuestions).toBe(false) | ||
| expect(settingDefaults.requestDelaySeconds).toBe(0) | ||
| expect(settingDefaults.followupAutoApproveTimeoutMs).toBe(0) | ||
| expect(settingDefaults.commandExecutionTimeout).toBe(0) | ||
| expect(settingDefaults.preventCompletionWithOpenTodos).toBe(false) | ||
| expect(settingDefaults.autoCondenseContext).toBe(false) | ||
| expect(settingDefaults.autoCondenseContextPercent).toBe(50) | ||
|
|
||
| // Browser settings | ||
| expect(settingDefaults.browserToolEnabled).toBe(true) | ||
| expect(settingDefaults.browserViewportSize).toBe("900x600") | ||
| expect(settingDefaults.remoteBrowserEnabled).toBe(false) | ||
| expect(settingDefaults.screenshotQuality).toBe(75) | ||
|
|
||
| // Audio/TTS settings | ||
| expect(settingDefaults.soundEnabled).toBe(true) | ||
| expect(settingDefaults.soundVolume).toBe(0.5) | ||
| expect(settingDefaults.ttsEnabled).toBe(true) | ||
| expect(settingDefaults.ttsSpeed).toBe(1.0) | ||
|
|
||
| // Checkpoint settings | ||
| expect(settingDefaults.enableCheckpoints).toBe(false) | ||
| expect(settingDefaults.checkpointTimeout).toBe(DEFAULT_CHECKPOINT_TIMEOUT_SECONDS) | ||
|
|
||
| // Terminal settings | ||
| expect(settingDefaults.terminalOutputLineLimit).toBe(500) | ||
| expect(settingDefaults.terminalOutputCharacterLimit).toBe(50_000) | ||
| expect(settingDefaults.terminalShellIntegrationTimeout).toBe(30_000) | ||
| expect(settingDefaults.terminalShellIntegrationDisabled).toBe(false) | ||
| expect(settingDefaults.terminalCommandDelay).toBe(0) | ||
| expect(settingDefaults.terminalPowershellCounter).toBe(false) | ||
| expect(settingDefaults.terminalZshClearEolMark).toBe(false) | ||
| expect(settingDefaults.terminalZshOhMy).toBe(false) | ||
| expect(settingDefaults.terminalZshP10k).toBe(false) | ||
| expect(settingDefaults.terminalZdotdir).toBe(false) | ||
| expect(settingDefaults.terminalCompressProgressBar).toBe(false) | ||
|
|
||
| // Context management settings | ||
| expect(settingDefaults.maxOpenTabsContext).toBe(20) | ||
| expect(settingDefaults.maxWorkspaceFiles).toBe(200) | ||
| expect(settingDefaults.showRooIgnoredFiles).toBe(false) | ||
| expect(settingDefaults.enableSubfolderRules).toBe(false) | ||
| expect(settingDefaults.maxReadFileLine).toBe(-1) | ||
| expect(settingDefaults.maxImageFileSize).toBe(5) | ||
| expect(settingDefaults.maxTotalImageSize).toBe(20) | ||
| expect(settingDefaults.maxConcurrentFileReads).toBe(5) | ||
|
|
||
| // Diagnostic settings | ||
| expect(settingDefaults.diagnosticsEnabled).toBe(false) | ||
| expect(settingDefaults.includeDiagnosticMessages).toBe(true) | ||
| expect(settingDefaults.maxDiagnosticMessages).toBe(50) | ||
| expect(settingDefaults.writeDelayMs).toBe(DEFAULT_WRITE_DELAY_MS) | ||
|
|
||
| // Prompt enhancement settings | ||
| expect(settingDefaults.includeTaskHistoryInEnhance).toBe(true) | ||
|
|
||
| // UI settings | ||
| expect(settingDefaults.reasoningBlockCollapsed).toBe(true) | ||
| expect(settingDefaults.historyPreviewCollapsed).toBe(false) | ||
| expect(settingDefaults.enterBehavior).toBe("send") | ||
| expect(settingDefaults.hasOpenedModeSelector).toBe(false) | ||
|
|
||
| // Environment details settings | ||
| expect(settingDefaults.includeCurrentTime).toBe(true) | ||
| expect(settingDefaults.includeCurrentCost).toBe(true) | ||
| expect(settingDefaults.maxGitStatusFiles).toBe(0) | ||
|
|
||
| // Language settings | ||
| expect(settingDefaults.language).toBe("en") | ||
|
|
||
| // MCP settings | ||
| expect(settingDefaults.mcpEnabled).toBe(true) | ||
| expect(settingDefaults.enableMcpServerCreation).toBe(false) | ||
|
|
||
| // Rate limiting | ||
| expect(settingDefaults.rateLimitSeconds).toBe(0) | ||
|
|
||
| // Indexing settings | ||
| expect(settingDefaults.codebaseIndexEnabled).toBe(false) | ||
| expect(settingDefaults.codebaseIndexQdrantUrl).toBe("http://localhost:6333") | ||
| expect(settingDefaults.codebaseIndexEmbedderProvider).toBe("openai") | ||
| expect(settingDefaults.codebaseIndexEmbedderBaseUrl).toBe("") | ||
| expect(settingDefaults.codebaseIndexEmbedderModelId).toBe("") | ||
| expect(settingDefaults.codebaseIndexEmbedderModelDimension).toBe(1536) | ||
| expect(settingDefaults.codebaseIndexOpenAiCompatibleBaseUrl).toBe("") | ||
| expect(settingDefaults.codebaseIndexBedrockRegion).toBe("us-east-1") | ||
| expect(settingDefaults.codebaseIndexBedrockProfile).toBe("") | ||
| expect(settingDefaults.codebaseIndexSearchMaxResults).toBe(100) | ||
| expect(settingDefaults.codebaseIndexSearchMinScore).toBe(0.4) | ||
| expect(settingDefaults.codebaseIndexOpenRouterSpecificProvider).toBe("") | ||
| }) | ||
|
|
||
| it("should be immutable (readonly)", () => { | ||
| // TypeScript should prevent this at compile time, but we can verify the type | ||
| const defaultsCopy = { ...settingDefaults } | ||
| expect(defaultsCopy.browserToolEnabled).toBe(settingDefaults.browserToolEnabled) | ||
| }) | ||
| }) | ||
|
|
||
| describe("getSettingWithDefault", () => { | ||
| it("should return the value when defined (matching type)", () => { | ||
| // Test with values that match the default type | ||
| expect(getSettingWithDefault("browserToolEnabled", true)).toBe(true) | ||
| expect(getSettingWithDefault("soundVolume", 0.5)).toBe(0.5) | ||
| expect(getSettingWithDefault("maxOpenTabsContext", 20)).toBe(20) | ||
| expect(getSettingWithDefault("enterBehavior", "send")).toBe("send") | ||
| }) | ||
|
|
||
| it("should return the default when value is undefined", () => { | ||
| expect(getSettingWithDefault("browserToolEnabled", undefined)).toBe(true) | ||
| expect(getSettingWithDefault("soundVolume", undefined)).toBe(0.5) | ||
| expect(getSettingWithDefault("maxOpenTabsContext", undefined)).toBe(20) | ||
| expect(getSettingWithDefault("enterBehavior", undefined)).toBe("send") | ||
| expect(getSettingWithDefault("mcpEnabled", undefined)).toBe(true) | ||
| expect(getSettingWithDefault("showRooIgnoredFiles", undefined)).toBe(false) | ||
| }) | ||
|
|
||
| it("should demonstrate reset-to-default pattern", () => { | ||
| // This test demonstrates the ideal "reset to default" pattern: | ||
| // When a user resets a setting, we store `undefined` (not the default value) | ||
| // When reading, we apply the default at consumption time | ||
|
|
||
| // Simulating reading from storage where value is undefined (reset state) | ||
| const storedValue = undefined | ||
| const effectiveValue = getSettingWithDefault("browserToolEnabled", storedValue) | ||
|
|
||
| // User sees the default value | ||
| expect(effectiveValue).toBe(true) | ||
|
|
||
| // If the default changes in the future (e.g., to false), | ||
| // users who reset their setting would automatically get the new default | ||
| // because they stored `undefined`, not `true` | ||
| }) | ||
| }) |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,176 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Centralized defaults registry for Roo Code settings. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * IMPORTANT: These defaults should be applied at READ time (when consuming state), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * NOT at WRITE time (when saving settings). This ensures: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * - Users who haven't customized a setting inherit future default improvements | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * - Storage only contains intentional user customizations, not copies of defaults | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * - "Reset to Default" properly removes settings from storage (sets to undefined) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Pattern: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * - On save: pass `undefined` to remove a setting from storage (reset to default) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * - On read: apply defaults using `value ?? settingDefaults.settingName` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { DEFAULT_CHECKPOINT_TIMEOUT_SECONDS, DEFAULT_WRITE_DELAY_MS } from "./global-settings.js" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Default values for all settings that can be reset to default. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * These values are the source of truth for defaults throughout the application. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * When a setting is undefined in storage, these defaults should be applied | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * at consumption time. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * IMPORTANT: Every setting that has a default value MUST be listed here. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * The clearDefaultSettings() function uses this registry to remove default | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * values from storage on every startup. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export const settingDefaults = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // ===== Auto-approval settings ===== | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // All auto-approval settings default to false for safety | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| autoApprovalEnabled: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| alwaysAllowReadOnly: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| alwaysAllowReadOnlyOutsideWorkspace: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| alwaysAllowWrite: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| alwaysAllowWriteOutsideWorkspace: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| alwaysAllowWriteProtected: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| alwaysAllowBrowser: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| alwaysAllowMcp: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| alwaysAllowModeSwitch: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| alwaysAllowSubtasks: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| alwaysAllowExecute: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| alwaysAllowFollowupQuestions: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| requestDelaySeconds: 0, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| followupAutoApproveTimeoutMs: 0, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| commandExecutionTimeout: 0, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| preventCompletionWithOpenTodos: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| autoCondenseContext: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| autoCondenseContextPercent: 50, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // ===== Browser settings ===== | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| browserToolEnabled: true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| browserViewportSize: "900x600", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| remoteBrowserEnabled: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| screenshotQuality: 75, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // ===== Audio/TTS settings ===== | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| soundEnabled: true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| soundVolume: 0.5, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ttsEnabled: true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ttsSpeed: 1.0, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // ===== Checkpoint settings ===== | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| enableCheckpoints: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| checkpointTimeout: DEFAULT_CHECKPOINT_TIMEOUT_SECONDS, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // ===== Terminal settings ===== | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| terminalOutputLineLimit: 500, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| terminalOutputCharacterLimit: 50_000, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| terminalShellIntegrationTimeout: 30_000, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| terminalShellIntegrationDisabled: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| terminalCommandDelay: 0, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| terminalPowershellCounter: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| terminalZshClearEolMark: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| terminalZshOhMy: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| terminalZshP10k: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| terminalZdotdir: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| terminalCompressProgressBar: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // ===== Context management settings ===== | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| maxOpenTabsContext: 20, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| maxWorkspaceFiles: 200, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| showRooIgnoredFiles: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| enableSubfolderRules: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| maxReadFileLine: -1, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| maxImageFileSize: 5, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| maxTotalImageSize: 20, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| maxConcurrentFileReads: 5, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // ===== Diagnostic settings ===== | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| diagnosticsEnabled: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| includeDiagnosticMessages: true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| maxDiagnosticMessages: 50, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| writeDelayMs: DEFAULT_WRITE_DELAY_MS, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // ===== Prompt enhancement settings ===== | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| includeTaskHistoryInEnhance: true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // ===== UI settings ===== | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| reasoningBlockCollapsed: true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| historyPreviewCollapsed: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| enterBehavior: "send" as const, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| hasOpenedModeSelector: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // ===== Environment details settings ===== | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| includeCurrentTime: true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| includeCurrentCost: true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| maxGitStatusFiles: 0, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // ===== Language settings ===== | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| language: "en" as const, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // ===== MCP settings ===== | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| mcpEnabled: true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| enableMcpServerCreation: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // ===== Rate limiting ===== | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| rateLimitSeconds: 0, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // ===== Indexing settings ===== | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| codebaseIndexEnabled: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| codebaseIndexQdrantUrl: "http://localhost:6333", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| codebaseIndexEmbedderProvider: "openai" as const, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| codebaseIndexEmbedderBaseUrl: "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| codebaseIndexEmbedderModelId: "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| codebaseIndexEmbedderModelDimension: 1536, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| codebaseIndexOpenAiCompatibleBaseUrl: "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| codebaseIndexBedrockRegion: "us-east-1", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| codebaseIndexBedrockProfile: "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| codebaseIndexSearchMaxResults: 100, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| codebaseIndexSearchMinScore: 0.4, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| codebaseIndexOpenRouterSpecificProvider: "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } as const | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Type representing all setting keys that have defaults. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export type SettingWithDefault = keyof typeof settingDefaults | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Helper function to get a setting value with its default applied. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Use this when reading settings from storage. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param key - The setting key | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param value - The value from storage (may be undefined) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @returns The value if defined, otherwise the default | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @example | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * const browserToolEnabled = getSettingWithDefault('browserToolEnabled', storedValue) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export function getSettingWithDefault<K extends SettingWithDefault>( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| key: K, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| value: (typeof settingDefaults)[K] | undefined, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ): (typeof settingDefaults)[K] { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return value ?? settingDefaults[key] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Applies defaults to a partial settings object. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Only applies defaults for settings that are undefined. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @param settings - Partial settings object | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * @returns Settings object with defaults applied for undefined values | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export function applySettingDefaults<T extends Partial<Record<SettingWithDefault, unknown>>>( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| settings: T, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ): T & typeof settingDefaults { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const result = { ...settings } as T & typeof settingDefaults | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (const key of Object.keys(settingDefaults) as SettingWithDefault[]) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (result[key] === undefined) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ;(result as Record<SettingWithDefault, unknown>)[key] = settingDefaults[key] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return result | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+164
to
+176
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor naming mismatch:
Suggested change
Fix it with Roo Code or mention @roomote and request a fix. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor API mismatch: the PR summary mentions an
applySettingsDefaults()helper, but the exported helper isapplySettingDefaults()(singular) and currently unused. If any callers import the plural name, it will fail at build time; consider renaming or adding a compat alias.Fix it with Roo Code or mention @roomote and request a fix.