mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-19 09:33:53 +00:00
788 lines
22 KiB
TypeScript
788 lines
22 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2025 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import type {
|
|
MCPServerConfig,
|
|
BugCommandSettings,
|
|
TelemetrySettings,
|
|
AuthType,
|
|
ChatCompressionSettings,
|
|
} from '@google/gemini-cli-core';
|
|
import type { CustomTheme } from '../ui/themes/theme.js';
|
|
|
|
export interface SettingDefinition {
|
|
type: 'boolean' | 'string' | 'number' | 'array' | 'object';
|
|
label: string;
|
|
category: string;
|
|
requiresRestart: boolean;
|
|
default: boolean | string | number | string[] | object | undefined;
|
|
description?: string;
|
|
parentKey?: string;
|
|
childKey?: string;
|
|
key?: string;
|
|
properties?: SettingsSchema;
|
|
showInDialog?: boolean;
|
|
}
|
|
|
|
export interface SettingsSchema {
|
|
[key: string]: SettingDefinition;
|
|
}
|
|
|
|
export type MemoryImportFormat = 'tree' | 'flat';
|
|
export type DnsResolutionOrder = 'ipv4first' | 'verbatim';
|
|
|
|
/**
|
|
* The canonical schema for all settings.
|
|
* The structure of this object defines the structure of the `Settings` type.
|
|
* `as const` is crucial for TypeScript to infer the most specific types possible.
|
|
*/
|
|
export const SETTINGS_SCHEMA = {
|
|
// Maintained for compatibility/criticality
|
|
mcpServers: {
|
|
type: 'object',
|
|
label: 'MCP Servers',
|
|
category: 'Advanced',
|
|
requiresRestart: true,
|
|
default: {} as Record<string, MCPServerConfig>,
|
|
description: 'Configuration for MCP servers.',
|
|
showInDialog: false,
|
|
},
|
|
|
|
general: {
|
|
type: 'object',
|
|
label: 'General',
|
|
category: 'General',
|
|
requiresRestart: false,
|
|
default: {},
|
|
description: 'General application settings.',
|
|
showInDialog: false,
|
|
properties: {
|
|
preferredEditor: {
|
|
type: 'string',
|
|
label: 'Preferred Editor',
|
|
category: 'General',
|
|
requiresRestart: false,
|
|
default: undefined as string | undefined,
|
|
description: 'The preferred editor to open files in.',
|
|
showInDialog: false,
|
|
},
|
|
vimMode: {
|
|
type: 'boolean',
|
|
label: 'Vim Mode',
|
|
category: 'General',
|
|
requiresRestart: false,
|
|
default: false,
|
|
description: 'Enable Vim keybindings',
|
|
showInDialog: true,
|
|
},
|
|
disableAutoUpdate: {
|
|
type: 'boolean',
|
|
label: 'Disable Auto Update',
|
|
category: 'General',
|
|
requiresRestart: false,
|
|
default: false,
|
|
description: 'Disable automatic updates',
|
|
showInDialog: true,
|
|
},
|
|
disableUpdateNag: {
|
|
type: 'boolean',
|
|
label: 'Disable Update Nag',
|
|
category: 'General',
|
|
requiresRestart: false,
|
|
default: false,
|
|
description: 'Disable update notification prompts.',
|
|
showInDialog: false,
|
|
},
|
|
checkpointing: {
|
|
type: 'object',
|
|
label: 'Checkpointing',
|
|
category: 'General',
|
|
requiresRestart: true,
|
|
default: {},
|
|
description: 'Session checkpointing settings.',
|
|
showInDialog: false,
|
|
properties: {
|
|
enabled: {
|
|
type: 'boolean',
|
|
label: 'Enable Checkpointing',
|
|
category: 'General',
|
|
requiresRestart: true,
|
|
default: false,
|
|
description: 'Enable session checkpointing for recovery',
|
|
showInDialog: false,
|
|
},
|
|
},
|
|
},
|
|
enablePromptCompletion: {
|
|
type: 'boolean',
|
|
label: 'Enable Prompt Completion',
|
|
category: 'General',
|
|
requiresRestart: true,
|
|
default: false,
|
|
description:
|
|
'Enable AI-powered prompt completion suggestions while typing.',
|
|
showInDialog: true,
|
|
},
|
|
debugKeystrokeLogging: {
|
|
type: 'boolean',
|
|
label: 'Debug Keystroke Logging',
|
|
category: 'General',
|
|
requiresRestart: false,
|
|
default: false,
|
|
description: 'Enable debug logging of keystrokes to the console.',
|
|
showInDialog: true,
|
|
},
|
|
},
|
|
},
|
|
|
|
ui: {
|
|
type: 'object',
|
|
label: 'UI',
|
|
category: 'UI',
|
|
requiresRestart: false,
|
|
default: {},
|
|
description: 'User interface settings.',
|
|
showInDialog: false,
|
|
properties: {
|
|
theme: {
|
|
type: 'string',
|
|
label: 'Theme',
|
|
category: 'UI',
|
|
requiresRestart: false,
|
|
default: undefined as string | undefined,
|
|
description: 'The color theme for the UI.',
|
|
showInDialog: false,
|
|
},
|
|
customThemes: {
|
|
type: 'object',
|
|
label: 'Custom Themes',
|
|
category: 'UI',
|
|
requiresRestart: false,
|
|
default: {} as Record<string, CustomTheme>,
|
|
description: 'Custom theme definitions.',
|
|
showInDialog: false,
|
|
},
|
|
hideWindowTitle: {
|
|
type: 'boolean',
|
|
label: 'Hide Window Title',
|
|
category: 'UI',
|
|
requiresRestart: true,
|
|
default: false,
|
|
description: 'Hide the window title bar',
|
|
showInDialog: true,
|
|
},
|
|
hideTips: {
|
|
type: 'boolean',
|
|
label: 'Hide Tips',
|
|
category: 'UI',
|
|
requiresRestart: false,
|
|
default: false,
|
|
description: 'Hide helpful tips in the UI',
|
|
showInDialog: true,
|
|
},
|
|
hideBanner: {
|
|
type: 'boolean',
|
|
label: 'Hide Banner',
|
|
category: 'UI',
|
|
requiresRestart: false,
|
|
default: false,
|
|
description: 'Hide the application banner',
|
|
showInDialog: true,
|
|
},
|
|
hideFooter: {
|
|
type: 'boolean',
|
|
label: 'Hide Footer',
|
|
category: 'UI',
|
|
requiresRestart: false,
|
|
default: false,
|
|
description: 'Hide the footer from the UI',
|
|
showInDialog: true,
|
|
},
|
|
showMemoryUsage: {
|
|
type: 'boolean',
|
|
label: 'Show Memory Usage',
|
|
category: 'UI',
|
|
requiresRestart: false,
|
|
default: false,
|
|
description: 'Display memory usage information in the UI',
|
|
showInDialog: true,
|
|
},
|
|
showLineNumbers: {
|
|
type: 'boolean',
|
|
label: 'Show Line Numbers',
|
|
category: 'UI',
|
|
requiresRestart: false,
|
|
default: false,
|
|
description: 'Show line numbers in the chat.',
|
|
showInDialog: true,
|
|
},
|
|
accessibility: {
|
|
type: 'object',
|
|
label: 'Accessibility',
|
|
category: 'UI',
|
|
requiresRestart: true,
|
|
default: {},
|
|
description: 'Accessibility settings.',
|
|
showInDialog: false,
|
|
properties: {
|
|
disableLoadingPhrases: {
|
|
type: 'boolean',
|
|
label: 'Disable Loading Phrases',
|
|
category: 'UI',
|
|
requiresRestart: true,
|
|
default: false,
|
|
description: 'Disable loading phrases for accessibility',
|
|
showInDialog: true,
|
|
},
|
|
screenReader: {
|
|
type: 'boolean',
|
|
label: 'Screen Reader Mode',
|
|
category: 'UI',
|
|
requiresRestart: true,
|
|
default: false,
|
|
description:
|
|
'Render output in plain-text to be more screen reader accessible',
|
|
showInDialog: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
|
|
ide: {
|
|
type: 'object',
|
|
label: 'IDE',
|
|
category: 'IDE',
|
|
requiresRestart: true,
|
|
default: {},
|
|
description: 'IDE integration settings.',
|
|
showInDialog: false,
|
|
properties: {
|
|
enabled: {
|
|
type: 'boolean',
|
|
label: 'IDE Mode',
|
|
category: 'IDE',
|
|
requiresRestart: true,
|
|
default: false,
|
|
description: 'Enable IDE integration mode',
|
|
showInDialog: true,
|
|
},
|
|
hasSeenNudge: {
|
|
type: 'boolean',
|
|
label: 'Has Seen IDE Integration Nudge',
|
|
category: 'IDE',
|
|
requiresRestart: false,
|
|
default: false,
|
|
description: 'Whether the user has seen the IDE integration nudge.',
|
|
showInDialog: false,
|
|
},
|
|
},
|
|
},
|
|
|
|
privacy: {
|
|
type: 'object',
|
|
label: 'Privacy',
|
|
category: 'Privacy',
|
|
requiresRestart: true,
|
|
default: {},
|
|
description: 'Privacy-related settings.',
|
|
showInDialog: false,
|
|
properties: {
|
|
usageStatisticsEnabled: {
|
|
type: 'boolean',
|
|
label: 'Enable Usage Statistics',
|
|
category: 'Privacy',
|
|
requiresRestart: true,
|
|
default: true,
|
|
description: 'Enable collection of usage statistics',
|
|
showInDialog: false,
|
|
},
|
|
},
|
|
},
|
|
|
|
telemetry: {
|
|
type: 'object',
|
|
label: 'Telemetry',
|
|
category: 'Advanced',
|
|
requiresRestart: true,
|
|
default: undefined as TelemetrySettings | undefined,
|
|
description: 'Telemetry configuration.',
|
|
showInDialog: false,
|
|
},
|
|
|
|
model: {
|
|
type: 'object',
|
|
label: 'Model',
|
|
category: 'Model',
|
|
requiresRestart: false,
|
|
default: {},
|
|
description: 'Settings related to the generative model.',
|
|
showInDialog: false,
|
|
properties: {
|
|
name: {
|
|
type: 'string',
|
|
label: 'Model',
|
|
category: 'Model',
|
|
requiresRestart: false,
|
|
default: undefined as string | undefined,
|
|
description: 'The Gemini model to use for conversations.',
|
|
showInDialog: false,
|
|
},
|
|
maxSessionTurns: {
|
|
type: 'number',
|
|
label: 'Max Session Turns',
|
|
category: 'Model',
|
|
requiresRestart: false,
|
|
default: -1,
|
|
description:
|
|
'Maximum number of user/model/tool turns to keep in a session. -1 means unlimited.',
|
|
showInDialog: true,
|
|
},
|
|
summarizeToolOutput: {
|
|
type: 'object',
|
|
label: 'Summarize Tool Output',
|
|
category: 'Model',
|
|
requiresRestart: false,
|
|
default: undefined as
|
|
| Record<string, { tokenBudget?: number }>
|
|
| undefined,
|
|
description: 'Settings for summarizing tool output.',
|
|
showInDialog: false,
|
|
},
|
|
chatCompression: {
|
|
type: 'object',
|
|
label: 'Chat Compression',
|
|
category: 'Model',
|
|
requiresRestart: false,
|
|
default: undefined as ChatCompressionSettings | undefined,
|
|
description: 'Chat compression settings.',
|
|
showInDialog: false,
|
|
},
|
|
skipNextSpeakerCheck: {
|
|
type: 'boolean',
|
|
label: 'Skip Next Speaker Check',
|
|
category: 'Model',
|
|
requiresRestart: false,
|
|
default: false,
|
|
description: 'Skip the next speaker check.',
|
|
showInDialog: true,
|
|
},
|
|
},
|
|
},
|
|
|
|
context: {
|
|
type: 'object',
|
|
label: 'Context',
|
|
category: 'Context',
|
|
requiresRestart: false,
|
|
default: {},
|
|
description: 'Settings for managing context provided to the model.',
|
|
showInDialog: false,
|
|
properties: {
|
|
fileName: {
|
|
type: 'object',
|
|
label: 'Context File Name',
|
|
category: 'Context',
|
|
requiresRestart: false,
|
|
default: undefined as string | string[] | undefined,
|
|
description: 'The name of the context file.',
|
|
showInDialog: false,
|
|
},
|
|
importFormat: {
|
|
type: 'string',
|
|
label: 'Memory Import Format',
|
|
category: 'Context',
|
|
requiresRestart: false,
|
|
default: undefined as MemoryImportFormat | undefined,
|
|
description: 'The format to use when importing memory.',
|
|
showInDialog: false,
|
|
},
|
|
discoveryMaxDirs: {
|
|
type: 'number',
|
|
label: 'Memory Discovery Max Dirs',
|
|
category: 'Context',
|
|
requiresRestart: false,
|
|
default: 200,
|
|
description: 'Maximum number of directories to search for memory.',
|
|
showInDialog: true,
|
|
},
|
|
includeDirectories: {
|
|
type: 'array',
|
|
label: 'Include Directories',
|
|
category: 'Context',
|
|
requiresRestart: false,
|
|
default: [] as string[],
|
|
description:
|
|
'Additional directories to include in the workspace context. Missing directories will be skipped with a warning.',
|
|
showInDialog: false,
|
|
},
|
|
loadMemoryFromIncludeDirectories: {
|
|
type: 'boolean',
|
|
label: 'Load Memory From Include Directories',
|
|
category: 'Context',
|
|
requiresRestart: false,
|
|
default: false,
|
|
description: 'Whether to load memory files from include directories.',
|
|
showInDialog: true,
|
|
},
|
|
fileFiltering: {
|
|
type: 'object',
|
|
label: 'File Filtering',
|
|
category: 'Context',
|
|
requiresRestart: true,
|
|
default: {},
|
|
description: 'Settings for git-aware file filtering.',
|
|
showInDialog: false,
|
|
properties: {
|
|
respectGitIgnore: {
|
|
type: 'boolean',
|
|
label: 'Respect .gitignore',
|
|
category: 'Context',
|
|
requiresRestart: true,
|
|
default: true,
|
|
description: 'Respect .gitignore files when searching',
|
|
showInDialog: true,
|
|
},
|
|
respectGeminiIgnore: {
|
|
type: 'boolean',
|
|
label: 'Respect .geminiignore',
|
|
category: 'Context',
|
|
requiresRestart: true,
|
|
default: true,
|
|
description: 'Respect .geminiignore files when searching',
|
|
showInDialog: true,
|
|
},
|
|
enableRecursiveFileSearch: {
|
|
type: 'boolean',
|
|
label: 'Enable Recursive File Search',
|
|
category: 'Context',
|
|
requiresRestart: true,
|
|
default: true,
|
|
description: 'Enable recursive file search functionality',
|
|
showInDialog: true,
|
|
},
|
|
disableFuzzySearch: {
|
|
type: 'boolean',
|
|
label: 'Disable Fuzzy Search',
|
|
category: 'Context',
|
|
requiresRestart: true,
|
|
default: false,
|
|
description: 'Disable fuzzy search when searching for files.',
|
|
showInDialog: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
|
|
tools: {
|
|
type: 'object',
|
|
label: 'Tools',
|
|
category: 'Tools',
|
|
requiresRestart: true,
|
|
default: {},
|
|
description: 'Settings for built-in and custom tools.',
|
|
showInDialog: false,
|
|
properties: {
|
|
sandbox: {
|
|
type: 'object',
|
|
label: 'Sandbox',
|
|
category: 'Tools',
|
|
requiresRestart: true,
|
|
default: undefined as boolean | string | undefined,
|
|
description:
|
|
'Sandbox execution environment (can be a boolean or a path string).',
|
|
showInDialog: false,
|
|
},
|
|
usePty: {
|
|
type: 'boolean',
|
|
label: 'Use node-pty for Shell Execution',
|
|
category: 'Tools',
|
|
requiresRestart: true,
|
|
default: false,
|
|
description:
|
|
'Use node-pty for shell command execution. Fallback to child_process still applies.',
|
|
showInDialog: true,
|
|
},
|
|
core: {
|
|
type: 'array',
|
|
label: 'Core Tools',
|
|
category: 'Tools',
|
|
requiresRestart: true,
|
|
default: undefined as string[] | undefined,
|
|
description: 'Paths to core tool definitions.',
|
|
showInDialog: false,
|
|
},
|
|
allowed: {
|
|
type: 'array',
|
|
label: 'Allowed Tools',
|
|
category: 'Advanced',
|
|
requiresRestart: true,
|
|
default: undefined as string[] | undefined,
|
|
description:
|
|
'A list of tool names that will bypass the confirmation dialog.',
|
|
showInDialog: false,
|
|
},
|
|
exclude: {
|
|
type: 'array',
|
|
label: 'Exclude Tools',
|
|
category: 'Tools',
|
|
requiresRestart: true,
|
|
default: undefined as string[] | undefined,
|
|
description: 'Tool names to exclude from discovery.',
|
|
showInDialog: false,
|
|
},
|
|
discoveryCommand: {
|
|
type: 'string',
|
|
label: 'Tool Discovery Command',
|
|
category: 'Tools',
|
|
requiresRestart: true,
|
|
default: undefined as string | undefined,
|
|
description: 'Command to run for tool discovery.',
|
|
showInDialog: false,
|
|
},
|
|
callCommand: {
|
|
type: 'string',
|
|
label: 'Tool Call Command',
|
|
category: 'Tools',
|
|
requiresRestart: true,
|
|
default: undefined as string | undefined,
|
|
description: 'Command to run for tool calls.',
|
|
showInDialog: false,
|
|
},
|
|
useRipgrep: {
|
|
type: 'boolean',
|
|
label: 'Use Ripgrep',
|
|
category: 'Tools',
|
|
requiresRestart: false,
|
|
default: false,
|
|
description:
|
|
'Use ripgrep for file content search instead of the fallback implementation. Provides faster search performance.',
|
|
showInDialog: true,
|
|
},
|
|
},
|
|
},
|
|
|
|
mcp: {
|
|
type: 'object',
|
|
label: 'MCP',
|
|
category: 'MCP',
|
|
requiresRestart: true,
|
|
default: {},
|
|
description: 'Settings for Model Context Protocol (MCP) servers.',
|
|
showInDialog: false,
|
|
properties: {
|
|
serverCommand: {
|
|
type: 'string',
|
|
label: 'MCP Server Command',
|
|
category: 'MCP',
|
|
requiresRestart: true,
|
|
default: undefined as string | undefined,
|
|
description: 'Command to start an MCP server.',
|
|
showInDialog: false,
|
|
},
|
|
allowed: {
|
|
type: 'array',
|
|
label: 'Allow MCP Servers',
|
|
category: 'MCP',
|
|
requiresRestart: true,
|
|
default: undefined as string[] | undefined,
|
|
description: 'A whitelist of MCP servers to allow.',
|
|
showInDialog: false,
|
|
},
|
|
excluded: {
|
|
type: 'array',
|
|
label: 'Exclude MCP Servers',
|
|
category: 'MCP',
|
|
requiresRestart: true,
|
|
default: undefined as string[] | undefined,
|
|
description: 'A blacklist of MCP servers to exclude.',
|
|
showInDialog: false,
|
|
},
|
|
},
|
|
},
|
|
|
|
security: {
|
|
type: 'object',
|
|
label: 'Security',
|
|
category: 'Security',
|
|
requiresRestart: true,
|
|
default: {},
|
|
description: 'Security-related settings.',
|
|
showInDialog: false,
|
|
properties: {
|
|
folderTrust: {
|
|
type: 'object',
|
|
label: 'Folder Trust',
|
|
category: 'Security',
|
|
requiresRestart: false,
|
|
default: {},
|
|
description: 'Settings for folder trust.',
|
|
showInDialog: false,
|
|
properties: {
|
|
featureEnabled: {
|
|
type: 'boolean',
|
|
label: 'Folder Trust Feature',
|
|
category: 'Security',
|
|
requiresRestart: false,
|
|
default: false,
|
|
description: 'Enable folder trust feature for enhanced security.',
|
|
showInDialog: true,
|
|
},
|
|
enabled: {
|
|
type: 'boolean',
|
|
label: 'Folder Trust',
|
|
category: 'Security',
|
|
requiresRestart: false,
|
|
default: false,
|
|
description: 'Setting to track whether Folder trust is enabled.',
|
|
showInDialog: true,
|
|
},
|
|
},
|
|
},
|
|
auth: {
|
|
type: 'object',
|
|
label: 'Authentication',
|
|
category: 'Security',
|
|
requiresRestart: true,
|
|
default: {},
|
|
description: 'Authentication settings.',
|
|
showInDialog: false,
|
|
properties: {
|
|
selectedType: {
|
|
type: 'string',
|
|
label: 'Selected Auth Type',
|
|
category: 'Security',
|
|
requiresRestart: true,
|
|
default: undefined as AuthType | undefined,
|
|
description: 'The currently selected authentication type.',
|
|
showInDialog: false,
|
|
},
|
|
useExternal: {
|
|
type: 'boolean',
|
|
label: 'Use External Auth',
|
|
category: 'Security',
|
|
requiresRestart: true,
|
|
default: undefined as boolean | undefined,
|
|
description: 'Whether to use an external authentication flow.',
|
|
showInDialog: false,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
|
|
advanced: {
|
|
type: 'object',
|
|
label: 'Advanced',
|
|
category: 'Advanced',
|
|
requiresRestart: true,
|
|
default: {},
|
|
description: 'Advanced settings for power users.',
|
|
showInDialog: false,
|
|
properties: {
|
|
autoConfigureMemory: {
|
|
type: 'boolean',
|
|
label: 'Auto Configure Max Old Space Size',
|
|
category: 'Advanced',
|
|
requiresRestart: true,
|
|
default: false,
|
|
description: 'Automatically configure Node.js memory limits',
|
|
showInDialog: false,
|
|
},
|
|
dnsResolutionOrder: {
|
|
type: 'string',
|
|
label: 'DNS Resolution Order',
|
|
category: 'Advanced',
|
|
requiresRestart: true,
|
|
default: undefined as DnsResolutionOrder | undefined,
|
|
description: 'The DNS resolution order.',
|
|
showInDialog: false,
|
|
},
|
|
excludedEnvVars: {
|
|
type: 'array',
|
|
label: 'Excluded Project Environment Variables',
|
|
category: 'Advanced',
|
|
requiresRestart: false,
|
|
default: ['DEBUG', 'DEBUG_MODE'] as string[],
|
|
description: 'Environment variables to exclude from project context.',
|
|
showInDialog: false,
|
|
},
|
|
bugCommand: {
|
|
type: 'object',
|
|
label: 'Bug Command',
|
|
category: 'Advanced',
|
|
requiresRestart: false,
|
|
default: undefined as BugCommandSettings | undefined,
|
|
description: 'Configuration for the bug report command.',
|
|
showInDialog: false,
|
|
},
|
|
},
|
|
},
|
|
|
|
experimental: {
|
|
type: 'object',
|
|
label: 'Experimental',
|
|
category: 'Experimental',
|
|
requiresRestart: true,
|
|
default: {},
|
|
description: 'Setting to enable experimental features',
|
|
showInDialog: false,
|
|
properties: {
|
|
extensionManagement: {
|
|
type: 'boolean',
|
|
label: 'Extension Management',
|
|
category: 'Experimental',
|
|
requiresRestart: true,
|
|
default: false,
|
|
description: 'Enable extension management features.',
|
|
showInDialog: false,
|
|
},
|
|
},
|
|
},
|
|
|
|
extensions: {
|
|
type: 'object',
|
|
label: 'Extensions',
|
|
category: 'Extensions',
|
|
requiresRestart: true,
|
|
default: {},
|
|
description: 'Settings for extensions.',
|
|
showInDialog: false,
|
|
properties: {
|
|
disabled: {
|
|
type: 'array',
|
|
label: 'Disabled Extensions',
|
|
category: 'Extensions',
|
|
requiresRestart: true,
|
|
default: [] as string[],
|
|
description: 'List of disabled extensions.',
|
|
showInDialog: false,
|
|
},
|
|
workspacesWithMigrationNudge: {
|
|
type: 'array',
|
|
label: 'Workspaces with Migration Nudge',
|
|
category: 'Extensions',
|
|
requiresRestart: false,
|
|
default: [] as string[],
|
|
description:
|
|
'List of workspaces for which the migration nudge has been shown.',
|
|
showInDialog: false,
|
|
},
|
|
},
|
|
},
|
|
} as const;
|
|
|
|
type InferSettings<T extends SettingsSchema> = {
|
|
-readonly [K in keyof T]?: T[K] extends { properties: SettingsSchema }
|
|
? InferSettings<T[K]['properties']>
|
|
: T[K]['default'] extends boolean
|
|
? boolean
|
|
: T[K]['default'];
|
|
};
|
|
|
|
export type Settings = InferSettings<typeof SETTINGS_SCHEMA>;
|