snow-ai 0.4.8 → 0.4.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/app.js +5 -2
  2. package/dist/i18n/lang/en.js +21 -0
  3. package/dist/i18n/lang/es.js +21 -0
  4. package/dist/i18n/lang/ja.js +21 -0
  5. package/dist/i18n/lang/ko.js +21 -0
  6. package/dist/i18n/lang/zh-TW.js +21 -0
  7. package/dist/i18n/lang/zh.js +21 -0
  8. package/dist/i18n/types.d.ts +21 -0
  9. package/dist/mcp/todo.js +1 -1
  10. package/dist/ui/components/AgentPickerPanel.js +8 -6
  11. package/dist/ui/components/ChatInput.js +23 -21
  12. package/dist/ui/components/CommandPanel.js +7 -5
  13. package/dist/ui/components/DiffViewer.js +6 -4
  14. package/dist/ui/components/FileList.js +8 -6
  15. package/dist/ui/components/Menu.d.ts +1 -1
  16. package/dist/ui/components/Menu.js +8 -6
  17. package/dist/ui/components/PendingMessages.js +7 -5
  18. package/dist/ui/components/TodoPickerPanel.js +12 -10
  19. package/dist/ui/components/TodoTree.js +7 -5
  20. package/dist/ui/components/ToolConfirmation.js +14 -12
  21. package/dist/ui/components/ToolResultPreview.js +17 -3
  22. package/dist/ui/contexts/ThemeContext.d.ts +13 -0
  23. package/dist/ui/contexts/ThemeContext.js +28 -0
  24. package/dist/ui/pages/ChatScreen.js +21 -19
  25. package/dist/ui/pages/CodeBaseConfigScreen.js +30 -28
  26. package/dist/ui/pages/ConfigScreen.js +76 -74
  27. package/dist/ui/pages/CustomHeadersScreen.js +33 -31
  28. package/dist/ui/pages/LanguageSettingsScreen.js +6 -4
  29. package/dist/ui/pages/ProxyConfigScreen.js +15 -13
  30. package/dist/ui/pages/SensitiveCommandConfigScreen.js +12 -10
  31. package/dist/ui/pages/SubAgentConfigScreen.js +12 -10
  32. package/dist/ui/pages/SubAgentListScreen.js +11 -9
  33. package/dist/ui/pages/SystemPromptConfigScreen.js +21 -19
  34. package/dist/ui/pages/ThemeSettingsScreen.d.ts +7 -0
  35. package/dist/ui/pages/ThemeSettingsScreen.js +106 -0
  36. package/dist/ui/pages/WelcomeScreen.js +11 -1
  37. package/dist/ui/themes/index.d.ts +23 -0
  38. package/dist/ui/themes/index.js +140 -0
  39. package/dist/utils/themeConfig.d.ts +21 -0
  40. package/dist/utils/themeConfig.js +61 -0
  41. package/dist/utils/toolExecutor.js +11 -1
  42. package/package.json +1 -1
@@ -5,6 +5,7 @@ import { Alert } from '@inkjs/ui';
5
5
  import TextInput from 'ink-text-input';
6
6
  import { loadCodebaseConfig, saveCodebaseConfig, } from '../../utils/codebaseConfig.js';
7
7
  import { useI18n } from '../../i18n/index.js';
8
+ import { useTheme } from '../contexts/ThemeContext.js';
8
9
  const focusEventTokenRegex = /(?:\x1b)?\[[0-9;]*[IO]/g;
9
10
  const isFocusEventInput = (value) => {
10
11
  if (!value) {
@@ -39,6 +40,7 @@ const stripFocusArtifacts = (value) => {
39
40
  };
40
41
  export default function CodeBaseConfigScreen({ onBack, onSave, inlineMode = false, }) {
41
42
  const { t } = useI18n();
43
+ const { theme } = useTheme();
42
44
  // Configuration state
43
45
  const [enabled, setEnabled] = useState(false);
44
46
  const [enableAgentReview, setEnableAgentReview] = useState(true);
@@ -146,21 +148,21 @@ export default function CodeBaseConfigScreen({ onBack, onSave, inlineMode = fals
146
148
  switch (field) {
147
149
  case 'enabled':
148
150
  return (React.createElement(Box, { key: field, flexDirection: "column" },
149
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
151
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
150
152
  isActive ? '❯ ' : ' ',
151
153
  t.codebaseConfig.codebaseEnabled),
152
154
  React.createElement(Box, { marginLeft: 3 },
153
- React.createElement(Text, { color: "gray" },
155
+ React.createElement(Text, { color: theme.colors.menuSecondary },
154
156
  enabled ? t.codebaseConfig.enabled : t.codebaseConfig.disabled,
155
157
  ' ',
156
158
  t.codebaseConfig.toggleHint))));
157
159
  case 'enableAgentReview':
158
160
  return (React.createElement(Box, { key: field, flexDirection: "column" },
159
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
161
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
160
162
  isActive ? '❯ ' : ' ',
161
163
  t.codebaseConfig.agentReview),
162
164
  React.createElement(Box, { marginLeft: 3 },
163
- React.createElement(Text, { color: "gray" },
165
+ React.createElement(Text, { color: theme.colors.menuSecondary },
164
166
  enableAgentReview
165
167
  ? t.codebaseConfig.enabled
166
168
  : t.codebaseConfig.disabled,
@@ -168,43 +170,43 @@ export default function CodeBaseConfigScreen({ onBack, onSave, inlineMode = fals
168
170
  t.codebaseConfig.toggleHint))));
169
171
  case 'embeddingModelName':
170
172
  return (React.createElement(Box, { key: field, flexDirection: "column" },
171
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
173
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
172
174
  isActive ? '❯ ' : ' ',
173
175
  t.codebaseConfig.embeddingModelName),
174
176
  isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
175
- React.createElement(Text, { color: "cyan" },
177
+ React.createElement(Text, { color: theme.colors.menuInfo },
176
178
  React.createElement(TextInput, { value: embeddingModelName, onChange: value => setEmbeddingModelName(stripFocusArtifacts(value)), onSubmit: () => setIsEditing(false) })))),
177
179
  !isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
178
- React.createElement(Text, { color: "gray" }, embeddingModelName || t.codebaseConfig.notSet)))));
180
+ React.createElement(Text, { color: theme.colors.menuSecondary }, embeddingModelName || t.codebaseConfig.notSet)))));
179
181
  case 'embeddingBaseUrl':
180
182
  return (React.createElement(Box, { key: field, flexDirection: "column" },
181
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
183
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
182
184
  isActive ? '❯ ' : ' ',
183
185
  t.codebaseConfig.embeddingBaseUrl),
184
186
  isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
185
- React.createElement(Text, { color: "cyan" },
187
+ React.createElement(Text, { color: theme.colors.menuInfo },
186
188
  React.createElement(TextInput, { value: embeddingBaseUrl, onChange: value => setEmbeddingBaseUrl(stripFocusArtifacts(value)), onSubmit: () => setIsEditing(false) })))),
187
189
  !isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
188
- React.createElement(Text, { color: "gray" }, embeddingBaseUrl || t.codebaseConfig.notSet)))));
190
+ React.createElement(Text, { color: theme.colors.menuSecondary }, embeddingBaseUrl || t.codebaseConfig.notSet)))));
189
191
  case 'embeddingApiKey':
190
192
  return (React.createElement(Box, { key: field, flexDirection: "column" },
191
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
193
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
192
194
  isActive ? '❯ ' : ' ',
193
195
  t.codebaseConfig.embeddingApiKeyOptional),
194
196
  isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
195
- React.createElement(Text, { color: "cyan" },
197
+ React.createElement(Text, { color: theme.colors.menuInfo },
196
198
  React.createElement(TextInput, { value: embeddingApiKey, onChange: value => setEmbeddingApiKey(stripFocusArtifacts(value)), onSubmit: () => setIsEditing(false), mask: "*" })))),
197
199
  !isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
198
- React.createElement(Text, { color: "gray" }, embeddingApiKey
200
+ React.createElement(Text, { color: theme.colors.menuSecondary }, embeddingApiKey
199
201
  ? t.codebaseConfig.masked
200
202
  : t.codebaseConfig.notSet)))));
201
203
  case 'embeddingDimensions':
202
204
  return (React.createElement(Box, { key: field, flexDirection: "column" },
203
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
205
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
204
206
  isActive ? '❯ ' : ' ',
205
207
  t.codebaseConfig.embeddingDimensions),
206
208
  isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
207
- React.createElement(Text, { color: "cyan" },
209
+ React.createElement(Text, { color: theme.colors.menuInfo },
208
210
  React.createElement(TextInput, { value: embeddingDimensions.toString(), onChange: value => {
209
211
  const num = parseInt(stripFocusArtifacts(value) || '0');
210
212
  if (!isNaN(num)) {
@@ -212,14 +214,14 @@ export default function CodeBaseConfigScreen({ onBack, onSave, inlineMode = fals
212
214
  }
213
215
  }, onSubmit: () => setIsEditing(false) })))),
214
216
  !isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
215
- React.createElement(Text, { color: "gray" }, embeddingDimensions)))));
217
+ React.createElement(Text, { color: theme.colors.menuSecondary }, embeddingDimensions)))));
216
218
  case 'batchMaxLines':
217
219
  return (React.createElement(Box, { key: field, flexDirection: "column" },
218
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
220
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
219
221
  isActive ? '❯ ' : ' ',
220
222
  t.codebaseConfig.batchMaxLines),
221
223
  isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
222
- React.createElement(Text, { color: "cyan" },
224
+ React.createElement(Text, { color: theme.colors.menuInfo },
223
225
  React.createElement(TextInput, { value: batchMaxLines.toString(), onChange: value => {
224
226
  const num = parseInt(stripFocusArtifacts(value) || '0');
225
227
  if (!isNaN(num)) {
@@ -227,14 +229,14 @@ export default function CodeBaseConfigScreen({ onBack, onSave, inlineMode = fals
227
229
  }
228
230
  }, onSubmit: () => setIsEditing(false) })))),
229
231
  !isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
230
- React.createElement(Text, { color: "gray" }, batchMaxLines)))));
232
+ React.createElement(Text, { color: theme.colors.menuSecondary }, batchMaxLines)))));
231
233
  case 'batchConcurrency':
232
234
  return (React.createElement(Box, { key: field, flexDirection: "column" },
233
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
235
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
234
236
  isActive ? '❯ ' : ' ',
235
237
  t.codebaseConfig.batchConcurrency),
236
238
  isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
237
- React.createElement(Text, { color: "cyan" },
239
+ React.createElement(Text, { color: theme.colors.menuInfo },
238
240
  React.createElement(TextInput, { value: batchConcurrency.toString(), onChange: value => {
239
241
  const num = parseInt(stripFocusArtifacts(value) || '0');
240
242
  if (!isNaN(num)) {
@@ -242,7 +244,7 @@ export default function CodeBaseConfigScreen({ onBack, onSave, inlineMode = fals
242
244
  }
243
245
  }, onSubmit: () => setIsEditing(false) })))),
244
246
  !isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
245
- React.createElement(Text, { color: "gray" }, batchConcurrency)))));
247
+ React.createElement(Text, { color: theme.colors.menuSecondary }, batchConcurrency)))));
246
248
  default:
247
249
  return null;
248
250
  }
@@ -307,19 +309,19 @@ export default function CodeBaseConfigScreen({ onBack, onSave, inlineMode = fals
307
309
  }
308
310
  });
309
311
  return (React.createElement(Box, { flexDirection: "column", padding: 1 },
310
- !inlineMode && (React.createElement(Box, { marginBottom: 1, borderStyle: "double", borderColor: 'cyan', paddingX: 2 },
312
+ !inlineMode && (React.createElement(Box, { marginBottom: 1, borderStyle: "double", borderColor: theme.colors.menuInfo, paddingX: 2 },
311
313
  React.createElement(Box, { flexDirection: "column" },
312
314
  React.createElement(Gradient, { name: "rainbow" }, t.codebaseConfig.title),
313
- React.createElement(Text, { color: "gray", dimColor: true }, t.codebaseConfig.subtitle)))),
315
+ React.createElement(Text, { color: theme.colors.menuSecondary }, t.codebaseConfig.subtitle)))),
314
316
  React.createElement(Box, { marginBottom: 1 },
315
- React.createElement(Text, { color: "yellow", bold: true },
317
+ React.createElement(Text, { color: theme.colors.warning, bold: true },
316
318
  t.codebaseConfig.settingsPosition,
317
319
  " (",
318
320
  currentFieldIndex + 1,
319
321
  "/",
320
322
  totalFields,
321
323
  ")"),
322
- totalFields > MAX_VISIBLE_FIELDS && (React.createElement(Text, { color: "gray", dimColor: true },
324
+ totalFields > MAX_VISIBLE_FIELDS && (React.createElement(Text, { color: theme.colors.menuSecondary },
323
325
  ' ',
324
326
  t.codebaseConfig.scrollHint))),
325
327
  React.createElement(Box, { flexDirection: "column" }, (() => {
@@ -340,8 +342,8 @@ export default function CodeBaseConfigScreen({ onBack, onSave, inlineMode = fals
340
342
  return visibleFields.map(field => renderField(field));
341
343
  })()),
342
344
  errors.length > 0 && (React.createElement(Box, { flexDirection: "column", marginTop: 1 },
343
- React.createElement(Text, { color: "red", bold: true }, t.codebaseConfig.errors),
344
- errors.map((error, index) => (React.createElement(Text, { key: index, color: "red" },
345
+ React.createElement(Text, { color: theme.colors.error, bold: true }, t.codebaseConfig.errors),
346
+ errors.map((error, index) => (React.createElement(Text, { key: index, color: theme.colors.error },
345
347
  "\u2022 ",
346
348
  error))))),
347
349
  React.createElement(Box, { flexDirection: "column", marginTop: 1 }, isEditing ? (React.createElement(Alert, { variant: "info" }, t.codebaseConfig.editingHint)) : (React.createElement(Alert, { variant: "info" }, t.codebaseConfig.navigationHint)))));
@@ -7,6 +7,7 @@ import { getOpenAiConfig, updateOpenAiConfig, validateApiConfig, } from '../../u
7
7
  import { fetchAvailableModels, filterModels, } from '../../api/models.js';
8
8
  import { getActiveProfileName, getAllProfiles, switchProfile, createProfile, deleteProfile, saveProfile, } from '../../utils/configManager.js';
9
9
  import { useI18n } from '../../i18n/index.js';
10
+ import { useTheme } from '../contexts/ThemeContext.js';
10
11
  const focusEventTokenRegex = /(?:\x1b)?\[[0-9;]*[IO]/g;
11
12
  const isFocusEventInput = (value) => {
12
13
  if (!value) {
@@ -41,6 +42,7 @@ const stripFocusArtifacts = (value) => {
41
42
  };
42
43
  export default function ConfigScreen({ onBack, onSave, inlineMode = false, }) {
43
44
  const { t } = useI18n();
45
+ const { theme } = useTheme();
44
46
  // Profile management
45
47
  const [profiles, setProfiles] = useState([]);
46
48
  const [activeProfile, setActiveProfile] = useState('');
@@ -428,129 +430,129 @@ export default function ConfigScreen({ onBack, onSave, inlineMode = false, }) {
428
430
  switch (field) {
429
431
  case 'profile':
430
432
  return (React.createElement(Box, { key: field, flexDirection: "column" },
431
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
433
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
432
434
  isActive ? '❯ ' : ' ',
433
435
  t.configScreen.profile),
434
436
  !isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
435
- React.createElement(Text, { color: "gray" }, profiles.find(p => p.name === activeProfile)?.displayName ||
437
+ React.createElement(Text, { color: theme.colors.menuSecondary }, profiles.find(p => p.name === activeProfile)?.displayName ||
436
438
  activeProfile)))));
437
439
  case 'baseUrl':
438
440
  return (React.createElement(Box, { key: field, flexDirection: "column" },
439
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
441
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
440
442
  isActive ? '❯ ' : ' ',
441
443
  t.configScreen.baseUrl),
442
444
  isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
443
445
  React.createElement(TextInput, { value: baseUrl, onChange: value => setBaseUrl(stripFocusArtifacts(value)), placeholder: "https://api.openai.com/v1" }))),
444
446
  !isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
445
- React.createElement(Text, { color: "gray" }, baseUrl || t.configScreen.notSet)))));
447
+ React.createElement(Text, { color: theme.colors.menuSecondary }, baseUrl || t.configScreen.notSet)))));
446
448
  case 'apiKey':
447
449
  return (React.createElement(Box, { key: field, flexDirection: "column" },
448
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
450
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
449
451
  isActive ? '❯ ' : ' ',
450
452
  t.configScreen.apiKey),
451
453
  isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
452
454
  React.createElement(TextInput, { value: apiKey, onChange: value => setApiKey(stripFocusArtifacts(value)), placeholder: "sk-...", mask: "*" }))),
453
455
  !isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
454
- React.createElement(Text, { color: "gray" }, apiKey ? '*'.repeat(Math.min(apiKey.length, 20)) : t.configScreen.notSet)))));
456
+ React.createElement(Text, { color: theme.colors.menuSecondary }, apiKey ? '*'.repeat(Math.min(apiKey.length, 20)) : t.configScreen.notSet)))));
455
457
  case 'requestMethod':
456
458
  return (React.createElement(Box, { key: field, flexDirection: "column" },
457
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
459
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
458
460
  isActive ? '❯ ' : ' ',
459
461
  t.configScreen.requestMethod),
460
462
  !isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
461
- React.createElement(Text, { color: "gray" }, requestMethodOptions.find(opt => opt.value === requestMethod)
463
+ React.createElement(Text, { color: theme.colors.menuSecondary }, requestMethodOptions.find(opt => opt.value === requestMethod)
462
464
  ?.label || t.configScreen.notSet)))));
463
465
  case 'anthropicBeta':
464
466
  return (React.createElement(Box, { key: field, flexDirection: "column" },
465
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
467
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
466
468
  isActive ? '❯ ' : ' ',
467
469
  t.configScreen.anthropicBeta),
468
470
  React.createElement(Box, { marginLeft: 3 },
469
- React.createElement(Text, { color: "gray" },
471
+ React.createElement(Text, { color: theme.colors.menuSecondary },
470
472
  anthropicBeta ? t.configScreen.enabled : t.configScreen.disabled,
471
473
  " ",
472
474
  t.configScreen.toggleHint))));
473
475
  case 'enablePromptOptimization':
474
476
  return (React.createElement(Box, { key: field, flexDirection: "column" },
475
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
477
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
476
478
  isActive ? '❯ ' : ' ',
477
479
  t.configScreen.enablePromptOptimization),
478
480
  React.createElement(Box, { marginLeft: 3 },
479
- React.createElement(Text, { color: "gray" },
481
+ React.createElement(Text, { color: theme.colors.menuSecondary },
480
482
  enablePromptOptimization ? t.configScreen.enabled : t.configScreen.disabled,
481
483
  " ",
482
484
  t.configScreen.toggleHint))));
483
485
  case 'enableAutoCompress':
484
486
  return (React.createElement(Box, { key: field, flexDirection: "column" },
485
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
487
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
486
488
  isActive ? '❯ ' : ' ',
487
489
  t.configScreen.enableAutoCompress),
488
490
  React.createElement(Box, { marginLeft: 3 },
489
- React.createElement(Text, { color: "gray" },
491
+ React.createElement(Text, { color: theme.colors.menuSecondary },
490
492
  enableAutoCompress ? t.configScreen.enabled : t.configScreen.disabled,
491
493
  " ",
492
494
  t.configScreen.toggleHint))));
493
495
  case 'thinkingEnabled':
494
496
  return (React.createElement(Box, { key: field, flexDirection: "column" },
495
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
497
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
496
498
  isActive ? '❯ ' : ' ',
497
499
  t.configScreen.thinkingEnabled),
498
500
  React.createElement(Box, { marginLeft: 3 },
499
- React.createElement(Text, { color: "gray" },
501
+ React.createElement(Text, { color: theme.colors.menuSecondary },
500
502
  thinkingEnabled ? t.configScreen.enabled : t.configScreen.disabled,
501
503
  " ",
502
504
  t.configScreen.toggleHint))));
503
505
  case 'thinkingBudgetTokens':
504
506
  return (React.createElement(Box, { key: field, flexDirection: "column" },
505
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
507
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
506
508
  isActive ? '❯ ' : ' ',
507
509
  t.configScreen.thinkingBudgetTokens),
508
510
  isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
509
- React.createElement(Text, { color: "cyan" },
511
+ React.createElement(Text, { color: theme.colors.menuInfo },
510
512
  t.configScreen.enterValue,
511
513
  " ",
512
514
  thinkingBudgetTokens))),
513
515
  !isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
514
- React.createElement(Text, { color: "gray" }, thinkingBudgetTokens)))));
516
+ React.createElement(Text, { color: theme.colors.menuSecondary }, thinkingBudgetTokens)))));
515
517
  case 'geminiThinkingEnabled':
516
518
  return (React.createElement(Box, { key: field, flexDirection: "column" },
517
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
519
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
518
520
  isActive ? '❯ ' : ' ',
519
521
  t.configScreen.geminiThinkingEnabled),
520
522
  React.createElement(Box, { marginLeft: 3 },
521
- React.createElement(Text, { color: "gray" },
523
+ React.createElement(Text, { color: theme.colors.menuSecondary },
522
524
  geminiThinkingEnabled ? t.configScreen.enabled : t.configScreen.disabled,
523
525
  " ",
524
526
  t.configScreen.toggleHint))));
525
527
  case 'geminiThinkingBudget':
526
528
  return (React.createElement(Box, { key: field, flexDirection: "column" },
527
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
529
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
528
530
  isActive ? '❯ ' : ' ',
529
531
  t.configScreen.geminiThinkingBudget),
530
532
  isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
531
- React.createElement(Text, { color: "cyan" },
533
+ React.createElement(Text, { color: theme.colors.menuInfo },
532
534
  t.configScreen.enterValue,
533
535
  " ",
534
536
  geminiThinkingBudget))),
535
537
  !isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
536
- React.createElement(Text, { color: "gray" }, geminiThinkingBudget)))));
538
+ React.createElement(Text, { color: theme.colors.menuSecondary }, geminiThinkingBudget)))));
537
539
  case 'responsesReasoningEnabled':
538
540
  return (React.createElement(Box, { key: field, flexDirection: "column" },
539
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
541
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
540
542
  isActive ? '❯ ' : ' ',
541
543
  t.configScreen.responsesReasoningEnabled),
542
544
  React.createElement(Box, { marginLeft: 3 },
543
- React.createElement(Text, { color: "gray" },
545
+ React.createElement(Text, { color: theme.colors.menuSecondary },
544
546
  responsesReasoningEnabled ? t.configScreen.enabled : t.configScreen.disabled,
545
547
  ' ',
546
548
  t.configScreen.toggleHint))));
547
549
  case 'responsesReasoningEffort':
548
550
  return (React.createElement(Box, { key: field, flexDirection: "column" },
549
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
551
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
550
552
  isActive ? '❯ ' : ' ',
551
553
  t.configScreen.responsesReasoningEffort),
552
554
  !isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
553
- React.createElement(Text, { color: "gray" }, responsesReasoningEffort.toUpperCase()))),
555
+ React.createElement(Text, { color: theme.colors.menuSecondary }, responsesReasoningEffort.toUpperCase()))),
554
556
  isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
555
557
  React.createElement(Select, { options: [
556
558
  { label: t.configScreen.low, value: 'low' },
@@ -562,49 +564,49 @@ export default function ConfigScreen({ onBack, onSave, inlineMode = false, }) {
562
564
  } })))));
563
565
  case 'advancedModel':
564
566
  return (React.createElement(Box, { key: field, flexDirection: "column" },
565
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
567
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
566
568
  isActive ? '❯ ' : ' ',
567
569
  t.configScreen.advancedModel),
568
570
  !isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
569
- React.createElement(Text, { color: "gray" }, advancedModel || t.configScreen.notSet)))));
571
+ React.createElement(Text, { color: theme.colors.menuSecondary }, advancedModel || t.configScreen.notSet)))));
570
572
  case 'basicModel':
571
573
  return (React.createElement(Box, { key: field, flexDirection: "column" },
572
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
574
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
573
575
  isActive ? '❯ ' : ' ',
574
576
  t.configScreen.basicModel),
575
577
  !isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
576
- React.createElement(Text, { color: "gray" }, basicModel || t.configScreen.notSet)))));
578
+ React.createElement(Text, { color: theme.colors.menuSecondary }, basicModel || t.configScreen.notSet)))));
577
579
  case 'compactModelName':
578
580
  return (React.createElement(Box, { key: field, flexDirection: "column" },
579
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
581
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
580
582
  isActive ? '❯ ' : ' ',
581
583
  t.configScreen.compactModel),
582
584
  !isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
583
- React.createElement(Text, { color: "gray" }, compactModelName || t.configScreen.notSet)))));
585
+ React.createElement(Text, { color: theme.colors.menuSecondary }, compactModelName || t.configScreen.notSet)))));
584
586
  case 'maxContextTokens':
585
587
  return (React.createElement(Box, { key: field, flexDirection: "column" },
586
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
588
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
587
589
  isActive ? '❯ ' : ' ',
588
590
  t.configScreen.maxContextTokens),
589
591
  isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
590
- React.createElement(Text, { color: "cyan" },
592
+ React.createElement(Text, { color: theme.colors.menuInfo },
591
593
  t.configScreen.enterValue,
592
594
  " ",
593
595
  maxContextTokens))),
594
596
  !isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
595
- React.createElement(Text, { color: "gray" }, maxContextTokens)))));
597
+ React.createElement(Text, { color: theme.colors.menuSecondary }, maxContextTokens)))));
596
598
  case 'maxTokens':
597
599
  return (React.createElement(Box, { key: field, flexDirection: "column" },
598
- React.createElement(Text, { color: isActive ? 'green' : 'white' },
600
+ React.createElement(Text, { color: isActive ? theme.colors.menuSelected : theme.colors.menuNormal },
599
601
  isActive ? '❯ ' : ' ',
600
602
  t.configScreen.maxTokens),
601
603
  isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
602
- React.createElement(Text, { color: "cyan" },
604
+ React.createElement(Text, { color: theme.colors.menuInfo },
603
605
  t.configScreen.enterValue,
604
606
  " ",
605
607
  maxTokens))),
606
608
  !isCurrentlyEditing && (React.createElement(Box, { marginLeft: 3 },
607
- React.createElement(Text, { color: "gray" }, maxTokens)))));
609
+ React.createElement(Text, { color: theme.colors.menuSecondary }, maxTokens)))));
608
610
  default:
609
611
  return null;
610
612
  }
@@ -910,93 +912,93 @@ export default function ConfigScreen({ onBack, onSave, inlineMode = false, }) {
910
912
  // Render profile creation mode
911
913
  if (profileMode === 'creating') {
912
914
  return (React.createElement(Box, { flexDirection: "column", padding: 1 },
913
- !inlineMode && (React.createElement(Box, { marginBottom: 1, borderStyle: "double", borderColor: 'cyan', paddingX: 2 },
915
+ !inlineMode && (React.createElement(Box, { marginBottom: 1, borderStyle: "double", borderColor: theme.colors.menuInfo, paddingX: 2 },
914
916
  React.createElement(Box, { flexDirection: "column" },
915
917
  React.createElement(Gradient, { name: "rainbow" }, t.configScreen.createNewProfile),
916
- React.createElement(Text, { color: "gray", dimColor: true }, t.configScreen.enterProfileName)))),
918
+ React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true }, t.configScreen.enterProfileName)))),
917
919
  React.createElement(Box, { flexDirection: "column" },
918
- React.createElement(Text, { color: "cyan" }, "Profile Name:"),
920
+ React.createElement(Text, { color: theme.colors.menuInfo }, "Profile Name:"),
919
921
  React.createElement(Box, { marginLeft: 2 },
920
922
  React.createElement(TextInput, { value: newProfileName, onChange: value => setNewProfileName(stripFocusArtifacts(value)), placeholder: t.configScreen.profileNamePlaceholder }))),
921
923
  errors.length > 0 && (React.createElement(Box, { marginTop: 1 },
922
- React.createElement(Text, { color: "red" }, errors[0]))),
924
+ React.createElement(Text, { color: theme.colors.error }, errors[0]))),
923
925
  React.createElement(Box, { marginTop: 1 },
924
926
  React.createElement(Alert, { variant: "info" }, t.configScreen.createHint))));
925
927
  }
926
928
  // Render profile deletion confirmation
927
929
  if (profileMode === 'deleting') {
928
930
  return (React.createElement(Box, { flexDirection: "column", padding: 1 },
929
- !inlineMode && (React.createElement(Box, { marginBottom: 1, borderStyle: "double", borderColor: 'cyan', paddingX: 2 },
931
+ !inlineMode && (React.createElement(Box, { marginBottom: 1, borderStyle: "double", borderColor: theme.colors.menuInfo, paddingX: 2 },
930
932
  React.createElement(Box, { flexDirection: "column" },
931
933
  React.createElement(Gradient, { name: "rainbow" }, t.configScreen.deleteProfile),
932
- React.createElement(Text, { color: "gray", dimColor: true }, t.configScreen.confirmDelete)))),
934
+ React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true }, t.configScreen.confirmDelete)))),
933
935
  React.createElement(Box, { flexDirection: "column" },
934
- React.createElement(Text, { color: "yellow" },
936
+ React.createElement(Text, { color: theme.colors.warning },
935
937
  "Are you sure you want to delete the profile \"",
936
938
  activeProfile,
937
939
  "\"?"),
938
- React.createElement(Text, { color: "gray", dimColor: true }, t.configScreen.deleteWarning)),
940
+ React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true }, t.configScreen.deleteWarning)),
939
941
  errors.length > 0 && (React.createElement(Box, { marginTop: 1 },
940
- React.createElement(Text, { color: "red" }, errors[0]))),
942
+ React.createElement(Text, { color: theme.colors.error }, errors[0]))),
941
943
  React.createElement(Box, { marginTop: 1 },
942
944
  React.createElement(Alert, { variant: "warning" }, t.configScreen.confirmHint))));
943
945
  }
944
946
  if (loading) {
945
947
  return (React.createElement(Box, { flexDirection: "column", padding: 1 },
946
- !inlineMode && (React.createElement(Box, { marginBottom: 1, borderStyle: "double", borderColor: 'cyan', paddingX: 2 },
948
+ !inlineMode && (React.createElement(Box, { marginBottom: 1, borderStyle: "double", borderColor: theme.colors.menuInfo, paddingX: 2 },
947
949
  React.createElement(Box, { flexDirection: "column" },
948
950
  React.createElement(Gradient, { name: "rainbow" }, t.configScreen.title),
949
- React.createElement(Text, { color: "gray", dimColor: true }, t.configScreen.loadingMessage)))),
951
+ React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true }, t.configScreen.loadingMessage)))),
950
952
  React.createElement(Box, { flexDirection: "column" },
951
953
  React.createElement(Box, null,
952
954
  React.createElement(Spinner, { type: "dots" }),
953
- React.createElement(Text, { color: "cyan" },
955
+ React.createElement(Text, { color: theme.colors.menuInfo },
954
956
  " ",
955
957
  t.configScreen.fetchingModels)),
956
958
  React.createElement(Box, { marginLeft: 2 },
957
- React.createElement(Text, { color: "gray", dimColor: true }, t.configScreen.fetchingHint))),
959
+ React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true }, t.configScreen.fetchingHint))),
958
960
  React.createElement(Box, { flexDirection: "column", marginTop: 1 },
959
961
  React.createElement(Alert, { variant: "info" }, t.configScreen.loadingCancelHint))));
960
962
  }
961
963
  if (manualInputMode) {
962
964
  return (React.createElement(Box, { flexDirection: "column", padding: 1 },
963
- !inlineMode && (React.createElement(Box, { marginBottom: 1, borderStyle: "double", borderColor: 'cyan', paddingX: 2 },
965
+ !inlineMode && (React.createElement(Box, { marginBottom: 1, borderStyle: "double", borderColor: theme.colors.menuInfo, paddingX: 2 },
964
966
  React.createElement(Box, { flexDirection: "column" },
965
967
  React.createElement(Gradient, { name: "rainbow" }, t.configScreen.manualInputTitle),
966
- React.createElement(Text, { color: "gray", dimColor: true }, t.configScreen.manualInputSubtitle)))),
968
+ React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true }, t.configScreen.manualInputSubtitle)))),
967
969
  loadError && (React.createElement(Box, { flexDirection: "column", marginBottom: 1 },
968
- React.createElement(Text, { color: "yellow" }, t.configScreen.loadingError),
969
- React.createElement(Text, { color: "gray", dimColor: true }, loadError))),
970
+ React.createElement(Text, { color: theme.colors.warning }, t.configScreen.loadingError),
971
+ React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true }, loadError))),
970
972
  React.createElement(Box, { flexDirection: "column" },
971
- React.createElement(Text, { color: "cyan" },
973
+ React.createElement(Text, { color: theme.colors.menuInfo },
972
974
  currentField === 'advancedModel' && t.configScreen.advancedModel,
973
975
  currentField === 'basicModel' && t.configScreen.basicModel,
974
976
  currentField === 'compactModelName' && t.configScreen.compactModel),
975
977
  React.createElement(Box, { marginLeft: 2 },
976
- React.createElement(Text, { color: "green" },
978
+ React.createElement(Text, { color: theme.colors.menuSelected },
977
979
  `> ${manualInputValue}`,
978
- React.createElement(Text, { color: "white" }, "_")))),
980
+ React.createElement(Text, { color: theme.colors.menuNormal }, "_")))),
979
981
  React.createElement(Box, { flexDirection: "column", marginTop: 1 },
980
982
  React.createElement(Alert, { variant: "info" }, t.configScreen.manualInputHint))));
981
983
  }
982
984
  return (React.createElement(Box, { flexDirection: "column", padding: 1 },
983
- !inlineMode && (React.createElement(Box, { marginBottom: 1, borderStyle: "double", borderColor: 'cyan', paddingX: 2 },
985
+ !inlineMode && (React.createElement(Box, { marginBottom: 1, borderStyle: "double", borderColor: theme.colors.menuInfo, paddingX: 2 },
984
986
  React.createElement(Box, { flexDirection: "column" },
985
987
  React.createElement(Gradient, { name: "rainbow" }, t.configScreen.title),
986
- React.createElement(Text, { color: "gray", dimColor: true }, t.configScreen.subtitle),
987
- activeProfile && (React.createElement(Text, { color: "cyan", dimColor: true },
988
+ React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true }, t.configScreen.subtitle),
989
+ activeProfile && (React.createElement(Text, { color: theme.colors.menuInfo, dimColor: true },
988
990
  t.configScreen.activeProfile,
989
991
  " ",
990
992
  activeProfile))))),
991
993
  React.createElement(Box, { marginBottom: 1 },
992
- React.createElement(Text, { color: "yellow", bold: true },
994
+ React.createElement(Text, { color: theme.colors.warning, bold: true },
993
995
  t.configScreen.settingsPosition,
994
996
  " (",
995
997
  currentFieldIndex + 1,
996
998
  "/",
997
999
  totalFields,
998
1000
  ")"),
999
- totalFields > MAX_VISIBLE_FIELDS && (React.createElement(Text, { color: "gray", dimColor: true }, t.configScreen.scrollHint))),
1001
+ totalFields > MAX_VISIBLE_FIELDS && (React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true }, t.configScreen.scrollHint))),
1000
1002
  isEditing &&
1001
1003
  (currentField === 'profile' ||
1002
1004
  currentField === 'requestMethod' ||
@@ -1004,7 +1006,7 @@ export default function ConfigScreen({ onBack, onSave, inlineMode = false, }) {
1004
1006
  currentField === 'basicModel' ||
1005
1007
  currentField === 'compactModelName' ||
1006
1008
  currentField === 'responsesReasoningEffort') ? (React.createElement(Box, { flexDirection: "column" },
1007
- React.createElement(Text, { color: "green" },
1009
+ React.createElement(Text, { color: theme.colors.menuSelected },
1008
1010
  "\u276F ",
1009
1011
  currentField === 'profile' && t.configScreen.profile.replace(':', ''),
1010
1012
  currentField === 'requestMethod' && t.configScreen.requestMethod.replace(':', ''),
@@ -1015,7 +1017,7 @@ export default function ConfigScreen({ onBack, onSave, inlineMode = false, }) {
1015
1017
  t.configScreen.responsesReasoningEffort.replace(':', '')),
1016
1018
  React.createElement(Box, { marginLeft: 3, marginTop: 1 },
1017
1019
  currentField === 'profile' && (React.createElement(Box, { flexDirection: "column" },
1018
- profiles.length > 1 && (React.createElement(Text, { color: "gray", dimColor: true }, "Scroll to see more profiles (\u2191\u2193)")),
1020
+ profiles.length > 1 && (React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true }, "Scroll to see more profiles (\u2191\u2193)")),
1019
1021
  React.createElement(Select, { options: profiles.map(p => ({
1020
1022
  label: `${p.displayName}${p.isActive ? ' (Active)' : ''}`,
1021
1023
  value: p.name,
@@ -1027,11 +1029,11 @@ export default function ConfigScreen({ onBack, onSave, inlineMode = false, }) {
1027
1029
  } }),
1028
1030
  React.createElement(Box, { flexDirection: "row", marginTop: 1 },
1029
1031
  React.createElement(Box, { marginRight: 2 },
1030
- React.createElement(Text, { color: "green" }, t.configScreen.newProfile),
1031
- React.createElement(Text, { color: "gray" }, " (n)")),
1032
+ React.createElement(Text, { color: theme.colors.menuSelected }, t.configScreen.newProfile),
1033
+ React.createElement(Text, { color: theme.colors.menuSecondary }, " (n)")),
1032
1034
  React.createElement(Box, null,
1033
- React.createElement(Text, { color: "red" }, t.configScreen.deleteProfileShort),
1034
- React.createElement(Text, { color: "gray" }, " (d)"))))),
1035
+ React.createElement(Text, { color: theme.colors.error }, t.configScreen.deleteProfileShort),
1036
+ React.createElement(Text, { color: theme.colors.menuSecondary }, " (d)"))))),
1035
1037
  currentField === 'requestMethod' && (React.createElement(Select, { options: requestMethodOptions, defaultValue: requestMethod, onChange: value => {
1036
1038
  setRequestMethod(value);
1037
1039
  setIsEditing(false);
@@ -1039,7 +1041,7 @@ export default function ConfigScreen({ onBack, onSave, inlineMode = false, }) {
1039
1041
  (currentField === 'advancedModel' ||
1040
1042
  currentField === 'basicModel' ||
1041
1043
  currentField === 'compactModelName') && (React.createElement(Box, { flexDirection: "column" },
1042
- searchTerm && React.createElement(Text, { color: "cyan" },
1044
+ searchTerm && React.createElement(Text, { color: theme.colors.menuInfo },
1043
1045
  "Filter: ",
1044
1046
  searchTerm),
1045
1047
  React.createElement(Select, { options: getCurrentOptions(), defaultValue: getCurrentValue(), onChange: handleModelChange }))),
@@ -1080,8 +1082,8 @@ export default function ConfigScreen({ onBack, onSave, inlineMode = false, }) {
1080
1082
  return visibleFields.map(field => renderField(field));
1081
1083
  })())),
1082
1084
  errors.length > 0 && (React.createElement(Box, { flexDirection: "column", marginTop: 1 },
1083
- React.createElement(Text, { color: "red", bold: true }, t.configScreen.errors),
1084
- errors.map((error, index) => (React.createElement(Text, { key: index, color: "red" },
1085
+ React.createElement(Text, { color: theme.colors.error, bold: true }, t.configScreen.errors),
1086
+ errors.map((error, index) => (React.createElement(Text, { key: index, color: theme.colors.error },
1085
1087
  "\u2022 ",
1086
1088
  error))))),
1087
1089
  !(isEditing &&