source dump of claude code
at main 211 lines 6.4 kB view raw
1import { feature } from 'bun:bundle' 2import { getRemoteControlAtStartup } from '../../utils/config.js' 3import { 4 EDITOR_MODES, 5 NOTIFICATION_CHANNELS, 6 TEAMMATE_MODES, 7} from '../../utils/configConstants.js' 8import { getModelOptions } from '../../utils/model/modelOptions.js' 9import { validateModel } from '../../utils/model/validateModel.js' 10import { THEME_NAMES, THEME_SETTINGS } from '../../utils/theme.js' 11 12/** AppState keys that can be synced for immediate UI effect */ 13type SyncableAppStateKey = 'verbose' | 'mainLoopModel' | 'thinkingEnabled' 14 15type SettingConfig = { 16 source: 'global' | 'settings' 17 type: 'boolean' | 'string' 18 description: string 19 path?: string[] 20 options?: readonly string[] 21 getOptions?: () => string[] 22 appStateKey?: SyncableAppStateKey 23 /** Async validation called when writing/setting a value */ 24 validateOnWrite?: (v: unknown) => Promise<{ valid: boolean; error?: string }> 25 /** Format value when reading/getting for display */ 26 formatOnRead?: (v: unknown) => unknown 27} 28 29export const SUPPORTED_SETTINGS: Record<string, SettingConfig> = { 30 theme: { 31 source: 'global', 32 type: 'string', 33 description: 'Color theme for the UI', 34 options: feature('AUTO_THEME') ? THEME_SETTINGS : THEME_NAMES, 35 }, 36 editorMode: { 37 source: 'global', 38 type: 'string', 39 description: 'Key binding mode', 40 options: EDITOR_MODES, 41 }, 42 verbose: { 43 source: 'global', 44 type: 'boolean', 45 description: 'Show detailed debug output', 46 appStateKey: 'verbose', 47 }, 48 preferredNotifChannel: { 49 source: 'global', 50 type: 'string', 51 description: 'Preferred notification channel', 52 options: NOTIFICATION_CHANNELS, 53 }, 54 autoCompactEnabled: { 55 source: 'global', 56 type: 'boolean', 57 description: 'Auto-compact when context is full', 58 }, 59 autoMemoryEnabled: { 60 source: 'settings', 61 type: 'boolean', 62 description: 'Enable auto-memory', 63 }, 64 autoDreamEnabled: { 65 source: 'settings', 66 type: 'boolean', 67 description: 'Enable background memory consolidation', 68 }, 69 fileCheckpointingEnabled: { 70 source: 'global', 71 type: 'boolean', 72 description: 'Enable file checkpointing for code rewind', 73 }, 74 showTurnDuration: { 75 source: 'global', 76 type: 'boolean', 77 description: 78 'Show turn duration message after responses (e.g., "Cooked for 1m 6s")', 79 }, 80 terminalProgressBarEnabled: { 81 source: 'global', 82 type: 'boolean', 83 description: 'Show OSC 9;4 progress indicator in supported terminals', 84 }, 85 todoFeatureEnabled: { 86 source: 'global', 87 type: 'boolean', 88 description: 'Enable todo/task tracking', 89 }, 90 model: { 91 source: 'settings', 92 type: 'string', 93 description: 'Override the default model', 94 appStateKey: 'mainLoopModel', 95 getOptions: () => { 96 try { 97 return getModelOptions() 98 .filter(o => o.value !== null) 99 .map(o => o.value as string) 100 } catch { 101 return ['sonnet', 'opus', 'haiku'] 102 } 103 }, 104 validateOnWrite: v => validateModel(String(v)), 105 formatOnRead: v => (v === null ? 'default' : v), 106 }, 107 alwaysThinkingEnabled: { 108 source: 'settings', 109 type: 'boolean', 110 description: 'Enable extended thinking (false to disable)', 111 appStateKey: 'thinkingEnabled', 112 }, 113 'permissions.defaultMode': { 114 source: 'settings', 115 type: 'string', 116 description: 'Default permission mode for tool usage', 117 options: feature('TRANSCRIPT_CLASSIFIER') 118 ? ['default', 'plan', 'acceptEdits', 'dontAsk', 'auto'] 119 : ['default', 'plan', 'acceptEdits', 'dontAsk'], 120 }, 121 language: { 122 source: 'settings', 123 type: 'string', 124 description: 125 'Preferred language for Claude responses and voice dictation (e.g., "japanese", "spanish")', 126 }, 127 teammateMode: { 128 source: 'global', 129 type: 'string', 130 description: 131 'How to spawn teammates: "tmux" for traditional tmux, "in-process" for same process, "auto" to choose automatically', 132 options: TEAMMATE_MODES, 133 }, 134 ...(process.env.USER_TYPE === 'ant' 135 ? { 136 classifierPermissionsEnabled: { 137 source: 'settings' as const, 138 type: 'boolean' as const, 139 description: 140 'Enable AI-based classification for Bash(prompt:...) permission rules', 141 }, 142 } 143 : {}), 144 ...(feature('VOICE_MODE') 145 ? { 146 voiceEnabled: { 147 source: 'settings' as const, 148 type: 'boolean' as const, 149 description: 'Enable voice dictation (hold-to-talk)', 150 }, 151 } 152 : {}), 153 ...(feature('BRIDGE_MODE') 154 ? { 155 remoteControlAtStartup: { 156 source: 'global' as const, 157 type: 'boolean' as const, 158 description: 159 'Enable Remote Control for all sessions (true | false | default)', 160 formatOnRead: () => getRemoteControlAtStartup(), 161 }, 162 } 163 : {}), 164 ...(feature('KAIROS') || feature('KAIROS_PUSH_NOTIFICATION') 165 ? { 166 taskCompleteNotifEnabled: { 167 source: 'global' as const, 168 type: 'boolean' as const, 169 description: 170 'Push to your mobile device when idle after Claude finishes (requires Remote Control)', 171 }, 172 inputNeededNotifEnabled: { 173 source: 'global' as const, 174 type: 'boolean' as const, 175 description: 176 'Push to your mobile device when a permission prompt or question is waiting (requires Remote Control)', 177 }, 178 agentPushNotifEnabled: { 179 source: 'global' as const, 180 type: 'boolean' as const, 181 description: 182 'Allow Claude to push to your mobile device when it deems it appropriate (requires Remote Control)', 183 }, 184 } 185 : {}), 186} 187 188export function isSupported(key: string): boolean { 189 return key in SUPPORTED_SETTINGS 190} 191 192export function getConfig(key: string): SettingConfig | undefined { 193 return SUPPORTED_SETTINGS[key] 194} 195 196export function getAllKeys(): string[] { 197 return Object.keys(SUPPORTED_SETTINGS) 198} 199 200export function getOptionsForSetting(key: string): string[] | undefined { 201 const config = SUPPORTED_SETTINGS[key] 202 if (!config) return undefined 203 if (config.options) return [...config.options] 204 if (config.getOptions) return config.getOptions() 205 return undefined 206} 207 208export function getPath(key: string): string[] { 209 const config = SUPPORTED_SETTINGS[key] 210 return config?.path ?? key.split('.') 211}