snow-ai 0.4.7 → 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 +5 -1
@@ -5,8 +5,10 @@ import { Alert } from '@inkjs/ui';
5
5
  import TextInput from 'ink-text-input';
6
6
  import { getCustomHeadersConfig, saveCustomHeadersConfig, } from '../../utils/apiConfig.js';
7
7
  import { useI18n } from '../../i18n/index.js';
8
+ import { useTheme } from '../contexts/ThemeContext.js';
8
9
  export default function CustomHeadersScreen({ onBack }) {
9
10
  const { t } = useI18n();
11
+ const { theme } = useTheme();
10
12
  const [config, setConfig] = useState(() => {
11
13
  return (getCustomHeadersConfig() || {
12
14
  active: '',
@@ -341,20 +343,20 @@ export default function CustomHeadersScreen({ onBack }) {
341
343
  if (view === 'list') {
342
344
  const activeScheme = config.schemes.find(s => s.id === config.active);
343
345
  return (React.createElement(Box, { flexDirection: "column", padding: 1 },
344
- React.createElement(Box, { marginBottom: 1, borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1 },
346
+ React.createElement(Box, { marginBottom: 1, borderStyle: "round", borderColor: theme.colors.menuInfo, paddingX: 2, paddingY: 1 },
345
347
  React.createElement(Box, { flexDirection: "column" },
346
348
  React.createElement(Gradient, { name: "rainbow" }, t.customHeaders.title),
347
- React.createElement(Text, { color: "gray", dimColor: true }, t.customHeaders.subtitle))),
349
+ React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true }, t.customHeaders.subtitle))),
348
350
  error && (React.createElement(Box, { marginBottom: 1 },
349
351
  React.createElement(Alert, { variant: "error" }, error))),
350
352
  React.createElement(Box, { marginBottom: 1 },
351
353
  React.createElement(Text, { bold: true },
352
354
  t.customHeaders.activeScheme,
353
355
  ' ',
354
- React.createElement(Text, { color: "green" }, activeScheme?.name || t.customHeaders.none))),
356
+ React.createElement(Text, { color: theme.colors.success }, activeScheme?.name || t.customHeaders.none))),
355
357
  config.schemes.length === 0 ? (React.createElement(Box, { marginBottom: 1 },
356
- React.createElement(Text, { color: "yellow" }, t.customHeaders.noSchemesConfigured))) : (React.createElement(Box, { flexDirection: "column", marginBottom: 1 },
357
- React.createElement(Text, { bold: true, color: "cyan" }, t.customHeaders.availableSchemes),
358
+ React.createElement(Text, { color: theme.colors.warning }, t.customHeaders.noSchemesConfigured))) : (React.createElement(Box, { flexDirection: "column", marginBottom: 1 },
359
+ React.createElement(Text, { bold: true, color: theme.colors.menuInfo }, t.customHeaders.availableSchemes),
358
360
  config.schemes.map((scheme, index) => {
359
361
  const headerCount = Object.keys(scheme.headers).length;
360
362
  const headerPreview = headerCount > 0
@@ -365,10 +367,10 @@ export default function CustomHeadersScreen({ onBack }) {
365
367
  : '';
366
368
  return (React.createElement(Box, { key: scheme.id, marginLeft: 2 },
367
369
  React.createElement(Text, { color: index === selectedIndex
368
- ? 'green'
370
+ ? theme.colors.menuSelected
369
371
  : scheme.id === config.active
370
- ? 'cyan'
371
- : 'white' },
372
+ ? theme.colors.menuInfo
373
+ : theme.colors.menuNormal },
372
374
  index === selectedIndex ? '❯ ' : ' ',
373
375
  scheme.id === config.active ? '✓ ' : ' ',
374
376
  scheme.name,
@@ -379,8 +381,8 @@ export default function CustomHeadersScreen({ onBack }) {
379
381
  headerPreview.length > 50 ? '...' : '')))));
380
382
  }))),
381
383
  React.createElement(Box, { marginBottom: 1 },
382
- React.createElement(Text, { bold: true, color: "cyan" }, t.customHeaders.actions)),
383
- React.createElement(Box, { flexDirection: "column", marginBottom: 1, marginLeft: 2 }, actions.map(action => (React.createElement(Text, { key: action, color: currentAction === action ? 'green' : 'gray', bold: currentAction === action },
384
+ React.createElement(Text, { bold: true, color: theme.colors.menuInfo }, t.customHeaders.actions)),
385
+ React.createElement(Box, { flexDirection: "column", marginBottom: 1, marginLeft: 2 }, actions.map(action => (React.createElement(Text, { key: action, color: currentAction === action ? theme.colors.menuSelected : theme.colors.menuSecondary, bold: currentAction === action },
384
386
  currentAction === action ? '❯ ' : ' ',
385
387
  action === 'activate' && t.customHeaders.activate,
386
388
  action === 'deactivate' && t.customHeaders.deactivate,
@@ -389,7 +391,7 @@ export default function CustomHeadersScreen({ onBack }) {
389
391
  action === 'add' && t.customHeaders.addNew,
390
392
  action === 'back' && t.customHeaders.escBack)))),
391
393
  React.createElement(Box, { marginTop: 1 },
392
- React.createElement(Text, { color: "gray", dimColor: true }, t.customHeaders.navigationHint))));
394
+ React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true }, t.customHeaders.navigationHint))));
393
395
  }
394
396
  // Render add/edit view
395
397
  if (view === 'add' || view === 'edit') {
@@ -401,7 +403,7 @@ export default function CustomHeadersScreen({ onBack }) {
401
403
  .join(', ')
402
404
  : t.customHeaders.notSet;
403
405
  return (React.createElement(Box, { flexDirection: "column", padding: 1 },
404
- React.createElement(Box, { marginBottom: 1, borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1 },
406
+ React.createElement(Box, { marginBottom: 1, borderStyle: "round", borderColor: theme.colors.menuInfo, paddingX: 2, paddingY: 1 },
405
407
  React.createElement(Gradient, { name: "rainbow" }, view === 'add'
406
408
  ? t.customHeaders.addNewTitle
407
409
  : t.customHeaders.editTitle)),
@@ -409,16 +411,16 @@ export default function CustomHeadersScreen({ onBack }) {
409
411
  React.createElement(Alert, { variant: "error" }, error))),
410
412
  React.createElement(Box, { marginBottom: 1 },
411
413
  React.createElement(Box, { flexDirection: "column" },
412
- React.createElement(Text, { color: editingField === 'name' ? 'green' : 'white' },
414
+ React.createElement(Text, { color: editingField === 'name' ? theme.colors.menuSelected : theme.colors.menuNormal },
413
415
  editingField === 'name' ? '❯ ' : ' ',
414
416
  t.customHeaders.nameLabel),
415
417
  editingField === 'name' && isEditing && (React.createElement(Box, { marginLeft: 3 },
416
418
  React.createElement(TextInput, { value: editName, onChange: setEditName, placeholder: t.customHeaders.enterSchemeName }))),
417
419
  (!isEditing || editingField !== 'name') && (React.createElement(Box, { marginLeft: 3 },
418
- React.createElement(Text, { color: "gray" }, editName || t.customHeaders.notSet))))),
420
+ React.createElement(Text, { color: theme.colors.menuSecondary }, editName || t.customHeaders.notSet))))),
419
421
  React.createElement(Box, { marginBottom: 1 },
420
422
  React.createElement(Box, { flexDirection: "column" },
421
- React.createElement(Text, { color: editingField === 'headers' ? 'green' : 'white' },
423
+ React.createElement(Text, { color: editingField === 'headers' ? theme.colors.menuSelected : theme.colors.menuNormal },
422
424
  editingField === 'headers' ? '❯ ' : ' ',
423
425
  t.customHeaders.headersLabel,
424
426
  " (",
@@ -427,60 +429,60 @@ export default function CustomHeadersScreen({ onBack }) {
427
429
  t.customHeaders.headersConfigured,
428
430
  "):"),
429
431
  editingField === 'headers' && !isEditing ? (React.createElement(Box, { marginLeft: 3 },
430
- React.createElement(Text, { color: "cyan", dimColor: true }, t.customHeaders.pressEnterToEdit))) : (React.createElement(Box, { marginLeft: 3 },
431
- React.createElement(Text, { color: "gray" },
432
+ React.createElement(Text, { color: theme.colors.menuInfo, dimColor: true }, t.customHeaders.pressEnterToEdit))) : (React.createElement(Box, { marginLeft: 3 },
433
+ React.createElement(Text, { color: theme.colors.menuSecondary },
432
434
  headerPreview.substring(0, 100),
433
435
  headerPreview.length > 100 ? '...' : ''))))),
434
436
  React.createElement(Box, { marginTop: 1 },
435
- React.createElement(Text, { color: "gray", dimColor: true }, t.customHeaders.editingHint))));
437
+ React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true }, t.customHeaders.editingHint))));
436
438
  }
437
439
  // Render headers edit view
438
440
  if (view === 'editHeaders') {
439
441
  return (React.createElement(Box, { flexDirection: "column", padding: 1 },
440
- React.createElement(Box, { marginBottom: 1, borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1 },
442
+ React.createElement(Box, { marginBottom: 1, borderStyle: "round", borderColor: theme.colors.menuInfo, paddingX: 2, paddingY: 1 },
441
443
  React.createElement(Gradient, { name: "rainbow" },
442
444
  t.customHeaders.editHeadersTitle,
443
445
  " - ",
444
446
  editName)),
445
447
  headerEditingIndex === -1 ? (React.createElement(React.Fragment, null,
446
448
  React.createElement(Box, { marginBottom: 1 },
447
- React.createElement(Text, { bold: true, color: "cyan" }, t.customHeaders.headerList)),
449
+ React.createElement(Text, { bold: true, color: theme.colors.menuInfo }, t.customHeaders.headerList)),
448
450
  headerKeys.length === 0 ? (React.createElement(Box, { marginBottom: 1 },
449
- React.createElement(Text, { color: "yellow" }, t.customHeaders.noHeadersConfigured))) : (React.createElement(Box, { flexDirection: "column", marginBottom: 1 }, headerKeys.map((key, index) => {
451
+ React.createElement(Text, { color: theme.colors.warning }, t.customHeaders.noHeadersConfigured))) : (React.createElement(Box, { flexDirection: "column", marginBottom: 1 }, headerKeys.map((key, index) => {
450
452
  const isSelected = index === headerSelectedIndex;
451
453
  return (React.createElement(Box, { key: index, marginLeft: 2 },
452
- React.createElement(Text, { color: isSelected ? 'green' : 'white', bold: isSelected },
454
+ React.createElement(Text, { color: isSelected ? theme.colors.menuSelected : theme.colors.menuNormal, bold: isSelected },
453
455
  isSelected ? '❯ ' : ' ',
454
456
  key,
455
457
  ": ",
456
458
  editHeaders[key])));
457
459
  }))),
458
460
  React.createElement(Box, { marginLeft: 2, marginBottom: 1 },
459
- React.createElement(Text, { color: headerSelectedIndex === headerKeys.length ? 'green' : 'gray', bold: headerSelectedIndex === headerKeys.length },
461
+ React.createElement(Text, { color: headerSelectedIndex === headerKeys.length ? theme.colors.menuSelected : theme.colors.menuSecondary, bold: headerSelectedIndex === headerKeys.length },
460
462
  headerSelectedIndex === headerKeys.length ? '❯ ' : ' ',
461
463
  t.customHeaders.addNewHeader)),
462
464
  React.createElement(Box, { marginTop: 1 },
463
- React.createElement(Text, { color: "gray", dimColor: true }, t.customHeaders.headerNavigationHint)))) : (React.createElement(React.Fragment, null,
465
+ React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true }, t.customHeaders.headerNavigationHint)))) : (React.createElement(React.Fragment, null,
464
466
  React.createElement(Box, { marginBottom: 1 },
465
467
  React.createElement(Box, { flexDirection: "column" },
466
- React.createElement(Text, { color: headerEditingField === 'key' ? 'green' : 'white' },
468
+ React.createElement(Text, { color: headerEditingField === 'key' ? theme.colors.menuSelected : theme.colors.menuNormal },
467
469
  headerEditingField === 'key' ? '❯ ' : ' ',
468
470
  t.customHeaders.keyLabel),
469
471
  headerEditingField === 'key' && isEditing && (React.createElement(Box, { marginLeft: 3 },
470
472
  React.createElement(TextInput, { value: headerEditKey, onChange: setHeaderEditKey, placeholder: t.customHeaders.headerKeyPlaceholder }))),
471
473
  (!isEditing || headerEditingField !== 'key') && (React.createElement(Box, { marginLeft: 3 },
472
- React.createElement(Text, { color: "gray" }, headerEditKey || t.customHeaders.notSet))))),
474
+ React.createElement(Text, { color: theme.colors.menuSecondary }, headerEditKey || t.customHeaders.notSet))))),
473
475
  React.createElement(Box, { marginBottom: 1 },
474
476
  React.createElement(Box, { flexDirection: "column" },
475
- React.createElement(Text, { color: headerEditingField === 'value' ? 'green' : 'white' },
477
+ React.createElement(Text, { color: headerEditingField === 'value' ? theme.colors.menuSelected : theme.colors.menuNormal },
476
478
  headerEditingField === 'value' ? '❯ ' : ' ',
477
479
  t.customHeaders.valueLabel),
478
480
  headerEditingField === 'value' && isEditing && (React.createElement(Box, { marginLeft: 3 },
479
481
  React.createElement(TextInput, { value: headerEditValue, onChange: setHeaderEditValue, placeholder: t.customHeaders.headerValuePlaceholder }))),
480
482
  (!isEditing || headerEditingField !== 'value') && (React.createElement(Box, { marginLeft: 3 },
481
- React.createElement(Text, { color: "gray" }, headerEditValue || t.customHeaders.notSet))))),
483
+ React.createElement(Text, { color: theme.colors.menuSecondary }, headerEditValue || t.customHeaders.notSet))))),
482
484
  React.createElement(Box, { marginTop: 1 },
483
- React.createElement(Text, { color: "gray", dimColor: true }, t.customHeaders.headerEditingHint))))));
485
+ React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true }, t.customHeaders.headerEditingHint))))));
484
486
  }
485
487
  // Render delete confirmation
486
488
  if (view === 'confirmDelete') {
@@ -491,10 +493,10 @@ export default function CustomHeadersScreen({ onBack }) {
491
493
  React.createElement(Text, null,
492
494
  t.customHeaders.deleteConfirmMessage,
493
495
  " \"",
494
- React.createElement(Text, { bold: true, color: "yellow" }, schemeToDelete?.name),
496
+ React.createElement(Text, { bold: true, color: theme.colors.warning }, schemeToDelete?.name),
495
497
  "\"?")),
496
498
  React.createElement(Box, { marginTop: 1 },
497
- React.createElement(Text, { color: "gray", dimColor: true }, t.customHeaders.confirmHint))));
499
+ React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true }, t.customHeaders.confirmHint))));
498
500
  }
499
501
  return null;
500
502
  }
@@ -2,8 +2,10 @@ import React, { useState, useCallback } from 'react';
2
2
  import { Box, Text, useInput } from 'ink';
3
3
  import Menu from '../components/Menu.js';
4
4
  import { useI18n } from '../../i18n/index.js';
5
+ import { useTheme } from '../contexts/ThemeContext.js';
5
6
  export default function LanguageSettingsScreen({ onBack, inlineMode = false, }) {
6
7
  const { language, setLanguage } = useI18n();
8
+ const { theme } = useTheme();
7
9
  const [selectedLanguage, setSelectedLanguage] = useState(language);
8
10
  const languageOptions = [
9
11
  {
@@ -39,7 +41,7 @@ export default function LanguageSettingsScreen({ onBack, inlineMode = false, })
39
41
  {
40
42
  label: '← Back',
41
43
  value: 'back',
42
- color: 'gray',
44
+ color: theme.colors.menuSecondary,
43
45
  infoText: 'Return to main menu',
44
46
  },
45
47
  ];
@@ -66,12 +68,12 @@ export default function LanguageSettingsScreen({ onBack, inlineMode = false, })
66
68
  }
67
69
  });
68
70
  return (React.createElement(Box, { flexDirection: "column", paddingX: 1 },
69
- !inlineMode && (React.createElement(Box, { borderStyle: "round", borderColor: "cyan", paddingX: 1, marginBottom: 1 },
71
+ !inlineMode && (React.createElement(Box, { borderStyle: "round", borderColor: theme.colors.menuInfo, paddingX: 1, marginBottom: 1 },
70
72
  React.createElement(Box, { flexDirection: "column" },
71
- React.createElement(Text, { bold: true, color: "cyan" }, "Language Settings / \u8BED\u8A00\u8BBE\u7F6E")))),
73
+ React.createElement(Text, { bold: true, color: theme.colors.menuInfo }, "Language Settings / \u8BED\u8A00\u8BBE\u7F6E")))),
72
74
  React.createElement(Box, { flexDirection: "column" },
73
75
  React.createElement(Box, { paddingX: 1 },
74
- React.createElement(Text, { color: "gray", dimColor: true },
76
+ React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true },
75
77
  "Current:",
76
78
  ' ',
77
79
  selectedLanguage === 'en'
@@ -5,8 +5,10 @@ import { Alert } from '@inkjs/ui';
5
5
  import TextInput from 'ink-text-input';
6
6
  import { getProxyConfig, updateProxyConfig, } from '../../utils/apiConfig.js';
7
7
  import { useI18n } from '../../i18n/index.js';
8
+ import { useTheme } from '../contexts/ThemeContext.js';
8
9
  export default function ProxyConfigScreen({ onBack, onSave, inlineMode = false, }) {
9
10
  const { t } = useI18n();
11
+ const { theme } = useTheme();
10
12
  const [enabled, setEnabled] = useState(false);
11
13
  const [port, setPort] = useState('7890');
12
14
  const [browserPath, setBrowserPath] = useState('');
@@ -88,42 +90,42 @@ export default function ProxyConfigScreen({ onBack, onSave, inlineMode = false,
88
90
  }
89
91
  });
90
92
  return (React.createElement(Box, { flexDirection: "column", padding: 1 },
91
- !inlineMode && (React.createElement(Box, { marginBottom: 1, borderStyle: "double", borderColor: 'cyan', paddingX: 2, paddingY: 1 },
93
+ !inlineMode && (React.createElement(Box, { marginBottom: 1, borderStyle: "double", borderColor: theme.colors.menuInfo, paddingX: 2, paddingY: 1 },
92
94
  React.createElement(Box, { flexDirection: "column" },
93
95
  React.createElement(Gradient, { name: "rainbow" }, t.proxyConfig.title),
94
- React.createElement(Text, { color: "gray", dimColor: true }, t.proxyConfig.subtitle)))),
96
+ React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true }, t.proxyConfig.subtitle)))),
95
97
  React.createElement(Box, { flexDirection: "column", marginBottom: 1 },
96
98
  React.createElement(Box, { marginBottom: 1 },
97
99
  React.createElement(Box, { flexDirection: "column" },
98
- React.createElement(Text, { color: currentField === 'enabled' ? 'green' : 'white' },
100
+ React.createElement(Text, { color: currentField === 'enabled' ? theme.colors.menuSelected : theme.colors.menuNormal },
99
101
  currentField === 'enabled' ? '❯ ' : ' ',
100
102
  t.proxyConfig.enableProxy),
101
103
  React.createElement(Box, { marginLeft: 3 },
102
- React.createElement(Text, { color: "gray" },
104
+ React.createElement(Text, { color: theme.colors.menuSecondary },
103
105
  enabled ? t.proxyConfig.enabled : t.proxyConfig.disabled,
104
106
  ' ',
105
107
  t.proxyConfig.toggleHint)))),
106
108
  React.createElement(Box, { marginBottom: 1 },
107
109
  React.createElement(Box, { flexDirection: "column" },
108
- React.createElement(Text, { color: currentField === 'port' ? 'green' : 'white' },
110
+ React.createElement(Text, { color: currentField === 'port' ? theme.colors.menuSelected : theme.colors.menuNormal },
109
111
  currentField === 'port' ? '❯ ' : ' ',
110
112
  t.proxyConfig.proxyPort),
111
113
  currentField === 'port' && isEditing && (React.createElement(Box, { marginLeft: 3 },
112
114
  React.createElement(TextInput, { value: port, onChange: setPort, placeholder: t.proxyConfig.portPlaceholder }))),
113
115
  (!isEditing || currentField !== 'port') && (React.createElement(Box, { marginLeft: 3 },
114
- React.createElement(Text, { color: "gray" }, port || t.proxyConfig.notSet))))),
116
+ React.createElement(Text, { color: theme.colors.menuSecondary }, port || t.proxyConfig.notSet))))),
115
117
  React.createElement(Box, { marginBottom: 1 },
116
118
  React.createElement(Box, { flexDirection: "column" },
117
- React.createElement(Text, { color: currentField === 'browserPath' ? 'green' : 'white' },
119
+ React.createElement(Text, { color: currentField === 'browserPath' ? theme.colors.menuSelected : theme.colors.menuNormal },
118
120
  currentField === 'browserPath' ? '❯ ' : ' ',
119
121
  t.proxyConfig.browserPath),
120
122
  currentField === 'browserPath' && isEditing && (React.createElement(Box, { marginLeft: 3 },
121
123
  React.createElement(TextInput, { value: browserPath, onChange: setBrowserPath, placeholder: t.proxyConfig.browserPathPlaceholder }))),
122
124
  (!isEditing || currentField !== 'browserPath') && (React.createElement(Box, { marginLeft: 3 },
123
- React.createElement(Text, { color: "gray" }, browserPath || t.proxyConfig.autoDetect)))))),
125
+ React.createElement(Text, { color: theme.colors.menuSecondary }, browserPath || t.proxyConfig.autoDetect)))))),
124
126
  errors.length > 0 && (React.createElement(Box, { flexDirection: "column", marginBottom: 2 },
125
- React.createElement(Text, { color: "red", bold: true }, t.proxyConfig.errors),
126
- errors.map((error, index) => (React.createElement(Text, { key: index, color: "red" },
127
+ React.createElement(Text, { color: theme.colors.error, bold: true }, t.proxyConfig.errors),
128
+ errors.map((error, index) => (React.createElement(Text, { key: index, color: theme.colors.error },
127
129
  "\u2022 ",
128
130
  error))))),
129
131
  React.createElement(Box, { flexDirection: "column" }, isEditing ? (React.createElement(React.Fragment, null,
@@ -134,13 +136,13 @@ export default function ProxyConfigScreen({ onBack, onSave, inlineMode = false,
134
136
  t.proxyConfig.browserExamplesTitle,
135
137
  " ",
136
138
  React.createElement(Newline, null),
137
- React.createElement(Text, { color: 'blue' }, t.proxyConfig.windowsExample),
139
+ React.createElement(Text, { color: theme.colors.menuInfo }, t.proxyConfig.windowsExample),
138
140
  " ",
139
141
  React.createElement(Newline, null),
140
- React.createElement(Text, { color: 'green' }, t.proxyConfig.macosExample),
142
+ React.createElement(Text, { color: theme.colors.success }, t.proxyConfig.macosExample),
141
143
  " ",
142
144
  React.createElement(Newline, null),
143
- React.createElement(Text, { color: 'yellow' }, t.proxyConfig.linuxExample),
145
+ React.createElement(Text, { color: theme.colors.warning }, t.proxyConfig.linuxExample),
144
146
  " ",
145
147
  React.createElement(Newline, null),
146
148
  t.proxyConfig.browserExamplesFooter))));
@@ -4,6 +4,7 @@ import TextInput from 'ink-text-input';
4
4
  import { Alert } from '@inkjs/ui';
5
5
  import { getAllSensitiveCommands, toggleSensitiveCommand, addSensitiveCommand, removeSensitiveCommand, resetToDefaults, } from '../../utils/sensitiveCommandManager.js';
6
6
  import { useI18n } from '../../i18n/index.js';
7
+ import { useTheme } from '../contexts/ThemeContext.js';
7
8
  // Focus event handling
8
9
  const focusEventTokenRegex = /(?:\x1b)?\[[0-9;]*[IO]/g;
9
10
  const isFocusEventInput = (value) => {
@@ -35,6 +36,7 @@ const stripFocusArtifacts = (value) => {
35
36
  };
36
37
  export default function SensitiveCommandConfigScreen({ onBack, inlineMode = false, }) {
37
38
  const { t } = useI18n();
39
+ const { theme } = useTheme();
38
40
  const [commands, setCommands] = useState([]);
39
41
  const [selectedIndex, setSelectedIndex] = useState(0);
40
42
  const [viewMode, setViewMode] = useState('list');
@@ -203,16 +205,16 @@ export default function SensitiveCommandConfigScreen({ onBack, inlineMode = fals
203
205
  }, [addField, customPattern, customDescription, loadCommands, t]);
204
206
  if (viewMode === 'add') {
205
207
  return (React.createElement(Box, { flexDirection: "column", paddingX: inlineMode ? 0 : 2, paddingY: 1 },
206
- React.createElement(Text, { bold: true, color: "cyan" }, t.sensitiveCommandConfig.addTitle),
208
+ React.createElement(Text, { bold: true, color: theme.colors.menuInfo }, t.sensitiveCommandConfig.addTitle),
207
209
  React.createElement(Box, { marginTop: 1 }),
208
210
  React.createElement(Text, { dimColor: true }, t.sensitiveCommandConfig.patternLabel),
209
211
  React.createElement(Box, null,
210
- React.createElement(Text, { color: addField === 'pattern' ? 'cyan' : 'gray' }, "\u276F "),
212
+ React.createElement(Text, { color: addField === 'pattern' ? theme.colors.menuInfo : theme.colors.menuSecondary }, "\u276F "),
211
213
  React.createElement(TextInput, { value: customPattern, onChange: handlePatternChange, onSubmit: handleAddSubmit, focus: addField === 'pattern', placeholder: t.sensitiveCommandConfig.patternPlaceholder })),
212
214
  React.createElement(Box, { marginTop: 1 }),
213
215
  React.createElement(Text, { dimColor: true }, t.sensitiveCommandConfig.descriptionLabel),
214
216
  React.createElement(Box, null,
215
- React.createElement(Text, { color: addField === 'description' ? 'cyan' : 'gray' }, "\u276F "),
217
+ React.createElement(Text, { color: addField === 'description' ? theme.colors.menuInfo : theme.colors.menuSecondary }, "\u276F "),
216
218
  React.createElement(TextInput, { value: customDescription, onChange: handleDescriptionChange, onSubmit: handleAddSubmit, focus: addField === 'description' })),
217
219
  React.createElement(Box, { marginTop: 1 }),
218
220
  React.createElement(Text, { dimColor: true }, t.sensitiveCommandConfig.addEditingHint)));
@@ -224,7 +226,7 @@ export default function SensitiveCommandConfigScreen({ onBack, inlineMode = fals
224
226
  const adjustedStart = Math.max(0, endIndex - viewportHeight);
225
227
  const selectedCmd = commands[selectedIndex];
226
228
  return (React.createElement(Box, { flexDirection: "column", paddingX: inlineMode ? 0 : 2, paddingY: 1 },
227
- React.createElement(Text, { bold: true, color: "cyan" }, t.sensitiveCommandConfig.title),
229
+ React.createElement(Text, { bold: true, color: theme.colors.menuInfo }, t.sensitiveCommandConfig.title),
228
230
  React.createElement(Text, { dimColor: true }, t.sensitiveCommandConfig.subtitle),
229
231
  showSuccess && (React.createElement(Box, { marginTop: 1 },
230
232
  React.createElement(Alert, { variant: "success" }, successMessage))),
@@ -235,17 +237,17 @@ export default function SensitiveCommandConfigScreen({ onBack, inlineMode = fals
235
237
  return null;
236
238
  }
237
239
  return (React.createElement(Text, { key: cmd.id, color: selectedIndex === index
238
- ? 'cyan'
240
+ ? theme.colors.menuInfo
239
241
  : cmd.enabled
240
- ? 'white'
241
- : 'gray', bold: selectedIndex === index, dimColor: !cmd.enabled },
242
+ ? theme.colors.menuNormal
243
+ : theme.colors.menuSecondary, bold: selectedIndex === index, dimColor: !cmd.enabled },
242
244
  selectedIndex === index ? '❯ ' : ' ',
243
245
  "[",
244
246
  cmd.enabled ? '✓' : ' ',
245
247
  "]",
246
248
  ' ',
247
249
  cmd.pattern,
248
- !cmd.isPreset && (React.createElement(Text, { color: "yellow" },
250
+ !cmd.isPreset && (React.createElement(Text, { color: theme.colors.warning },
249
251
  " (",
250
252
  t.sensitiveCommandConfig.custom,
251
253
  ")"))));
@@ -260,8 +262,8 @@ export default function SensitiveCommandConfigScreen({ onBack, inlineMode = fals
260
262
  ")",
261
263
  !selectedCmd.isPreset &&
262
264
  ` [${t.sensitiveCommandConfig.customLabel}]`)),
263
- confirmDelete && selectedCmd && (React.createElement(Text, { bold: true, color: "yellow" }, t.sensitiveCommandConfig.confirmDeleteMessage.replace('{pattern}', selectedCmd.pattern))),
264
- confirmReset && (React.createElement(Text, { bold: true, color: "yellow" }, t.sensitiveCommandConfig.confirmResetMessage)),
265
+ confirmDelete && selectedCmd && (React.createElement(Text, { bold: true, color: theme.colors.warning }, t.sensitiveCommandConfig.confirmDeleteMessage.replace('{pattern}', selectedCmd.pattern))),
266
+ confirmReset && (React.createElement(Text, { bold: true, color: theme.colors.warning }, t.sensitiveCommandConfig.confirmResetMessage)),
265
267
  React.createElement(Box, { marginTop: 1 }),
266
268
  React.createElement(Text, { dimColor: true }, confirmDelete || confirmReset
267
269
  ? t.sensitiveCommandConfig.confirmHint
@@ -5,6 +5,7 @@ import { Alert, Spinner } from '@inkjs/ui';
5
5
  import { getMCPServicesInfo } from '../../utils/mcpToolsManager.js';
6
6
  import { createSubAgent, updateSubAgent, getSubAgent, validateSubAgent, } from '../../utils/subAgentConfig.js';
7
7
  import { useI18n } from '../../i18n/index.js';
8
+ import { useTheme } from '../contexts/ThemeContext.js';
8
9
  // Focus event handling - prevent terminal focus events from appearing as input
9
10
  const focusEventTokenRegex = /(?:\x1b)?\[[0-9;]*[IO]/g;
10
11
  const isFocusEventInput = (value) => {
@@ -39,6 +40,7 @@ const stripFocusArtifacts = (value) => {
39
40
  .replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '');
40
41
  };
41
42
  export default function SubAgentConfigScreen({ onBack, onSave, inlineMode = false, agentId, }) {
43
+ const { theme } = useTheme();
42
44
  const { t } = useI18n();
43
45
  const [agentName, setAgentName] = useState('');
44
46
  const [description, setDescription] = useState('');
@@ -352,11 +354,11 @@ export default function SubAgentConfigScreen({ onBack, onSave, inlineMode = fals
352
354
  });
353
355
  const renderToolSelection = () => {
354
356
  return (React.createElement(Box, { flexDirection: "column" },
355
- React.createElement(Text, { bold: true, color: "cyan" }, t.subAgentConfig.toolSelection),
357
+ React.createElement(Text, { bold: true, color: theme.colors.menuInfo }, t.subAgentConfig.toolSelection),
356
358
  isLoadingMCP && (React.createElement(Box, null,
357
359
  React.createElement(Spinner, { label: t.subAgentConfig.loadingMCP }))),
358
360
  loadError && (React.createElement(Box, null,
359
- React.createElement(Text, { color: "yellow" },
361
+ React.createElement(Text, { color: theme.colors.warning },
360
362
  t.subAgentConfig.mcpLoadError,
361
363
  " ",
362
364
  loadError))),
@@ -365,7 +367,7 @@ export default function SubAgentConfigScreen({ onBack, onSave, inlineMode = fals
365
367
  const selectedInCategory = category.tools.filter(tool => selectedTools.has(tool)).length;
366
368
  return (React.createElement(Box, { key: category.name, flexDirection: "column" },
367
369
  React.createElement(Box, null,
368
- React.createElement(Text, { color: isCurrent && currentField === 'tools' ? 'green' : 'white', bold: isCurrent && currentField === 'tools' },
370
+ React.createElement(Text, { color: isCurrent && currentField === 'tools' ? theme.colors.menuSelected : theme.colors.menuNormal, bold: isCurrent && currentField === 'tools' },
369
371
  isCurrent && currentField === 'tools' ? '▶ ' : ' ',
370
372
  category.name,
371
373
  " (",
@@ -376,14 +378,14 @@ export default function SubAgentConfigScreen({ onBack, onSave, inlineMode = fals
376
378
  isCurrent && currentField === 'tools' && (React.createElement(Box, { flexDirection: "column", marginLeft: 2 }, category.tools.map((tool, toolIndex) => {
377
379
  const isCurrentTool = toolIndex === selectedToolIndex;
378
380
  return (React.createElement(Box, { key: tool },
379
- React.createElement(Text, { color: isCurrentTool ? 'cyan' : 'white', bold: isCurrentTool },
381
+ React.createElement(Text, { color: isCurrentTool ? theme.colors.menuInfo : theme.colors.menuNormal, bold: isCurrentTool },
380
382
  isCurrentTool ? '❯ ' : ' ',
381
383
  selectedTools.has(tool) ? '[✓]' : '[ ]',
382
384
  " ",
383
385
  tool)));
384
386
  })))));
385
387
  }),
386
- React.createElement(Text, { color: "gray", dimColor: true },
388
+ React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true },
387
389
  t.subAgentConfig.selectedTools,
388
390
  " ",
389
391
  selectedTools.size,
@@ -395,7 +397,7 @@ export default function SubAgentConfigScreen({ onBack, onSave, inlineMode = fals
395
397
  };
396
398
  return (React.createElement(Box, { flexDirection: "column", padding: 1 },
397
399
  !inlineMode && (React.createElement(Box, { marginBottom: 1 },
398
- React.createElement(Text, { bold: true, color: "cyan" },
400
+ React.createElement(Text, { bold: true, color: theme.colors.menuInfo },
399
401
  "\u2746",
400
402
  ' ',
401
403
  isEditMode
@@ -416,18 +418,18 @@ export default function SubAgentConfigScreen({ onBack, onSave, inlineMode = fals
416
418
  React.createElement(Alert, { variant: "error" }, saveError))),
417
419
  React.createElement(Box, { flexDirection: "column" },
418
420
  React.createElement(Box, { flexDirection: "column" },
419
- React.createElement(Text, { bold: true, color: currentField === 'name' ? 'green' : 'white' }, t.subAgentConfig.agentName),
421
+ React.createElement(Text, { bold: true, color: currentField === 'name' ? theme.colors.menuSelected : theme.colors.menuNormal }, t.subAgentConfig.agentName),
420
422
  React.createElement(Box, { marginLeft: 2 },
421
423
  React.createElement(TextInput, { value: agentName, onChange: value => setAgentName(stripFocusArtifacts(value)), placeholder: t.subAgentConfig.agentNamePlaceholder, focus: currentField === 'name' }))),
422
424
  React.createElement(Box, { flexDirection: "column" },
423
- React.createElement(Text, { bold: true, color: currentField === 'description' ? 'green' : 'white' }, t.subAgentConfig.description),
425
+ React.createElement(Text, { bold: true, color: currentField === 'description' ? theme.colors.menuSelected : theme.colors.menuNormal }, t.subAgentConfig.description),
424
426
  React.createElement(Box, { marginLeft: 2 },
425
427
  React.createElement(TextInput, { value: description, onChange: value => setDescription(stripFocusArtifacts(value)), placeholder: t.subAgentConfig.descriptionPlaceholder, focus: currentField === 'description' }))),
426
428
  React.createElement(Box, { flexDirection: "column" },
427
- React.createElement(Text, { bold: true, color: currentField === 'role' ? 'green' : 'white' }, t.subAgentConfig.roleOptional),
429
+ React.createElement(Text, { bold: true, color: currentField === 'role' ? theme.colors.menuSelected : theme.colors.menuNormal }, t.subAgentConfig.roleOptional),
428
430
  React.createElement(Box, { marginLeft: 2 },
429
431
  React.createElement(TextInput, { value: role, onChange: value => setRole(stripFocusArtifacts(value)), placeholder: t.subAgentConfig.rolePlaceholder, focus: currentField === 'role' }))),
430
432
  renderToolSelection(),
431
433
  React.createElement(Box, { marginTop: 1 },
432
- React.createElement(Text, { color: "gray", dimColor: true }, t.subAgentConfig.navigationHint)))));
434
+ React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true }, t.subAgentConfig.navigationHint)))));
433
435
  }
@@ -3,7 +3,9 @@ import { Box, Text, useInput } from 'ink';
3
3
  import { Alert } from '@inkjs/ui';
4
4
  import { getSubAgents, deleteSubAgent, } from '../../utils/subAgentConfig.js';
5
5
  import { useTerminalSize } from '../../hooks/useTerminalSize.js';
6
+ import { useTheme } from '../contexts/ThemeContext.js';
6
7
  export default function SubAgentListScreen({ onBack, onAdd, onEdit, inlineMode = false, }) {
8
+ const { theme } = useTheme();
7
9
  const { columns } = useTerminalSize();
8
10
  const [agents, setAgents] = useState([]);
9
11
  const [selectedIndex, setSelectedIndex] = useState(0);
@@ -88,7 +90,7 @@ export default function SubAgentListScreen({ onBack, onAdd, onEdit, inlineMode =
88
90
  });
89
91
  return (React.createElement(Box, { flexDirection: "column", padding: 1 },
90
92
  !inlineMode && (React.createElement(Box, { marginBottom: 1 },
91
- React.createElement(Text, { bold: true, color: "cyan" }, "\u2746 Sub-Agent Management"))),
93
+ React.createElement(Text, { bold: true, color: theme.colors.menuInfo }, "\u2746 Sub-Agent Management"))),
92
94
  deleteSuccess && (React.createElement(Box, { marginBottom: 1 },
93
95
  React.createElement(Alert, { variant: "success" }, "Sub-agent deleted successfully!"))),
94
96
  showDeleteConfirm && agents[selectedIndex] && (React.createElement(Box, { marginBottom: 1 },
@@ -98,9 +100,9 @@ export default function SubAgentListScreen({ onBack, onAdd, onEdit, inlineMode =
98
100
  "\"? (Y/N)"))),
99
101
  React.createElement(Box, { flexDirection: "column" },
100
102
  agents.length === 0 ? (React.createElement(Box, { flexDirection: "column" },
101
- React.createElement(Text, { color: "gray" }, "No sub-agents configured yet."),
102
- React.createElement(Text, { color: "gray" }, "Press 'A' to add a new sub-agent."))) : (React.createElement(Box, { flexDirection: "column" },
103
- React.createElement(Text, { bold: true, color: "cyan" },
103
+ React.createElement(Text, { color: theme.colors.menuSecondary }, "No sub-agents configured yet."),
104
+ React.createElement(Text, { color: theme.colors.menuSecondary }, "Press 'A' to add a new sub-agent."))) : (React.createElement(Box, { flexDirection: "column" },
105
+ React.createElement(Text, { bold: true, color: theme.colors.menuInfo },
104
106
  "Sub-Agents (",
105
107
  agents.length,
106
108
  "):"),
@@ -108,22 +110,22 @@ export default function SubAgentListScreen({ onBack, onAdd, onEdit, inlineMode =
108
110
  const isSelected = index === selectedIndex;
109
111
  return (React.createElement(Box, { key: agent.id, flexDirection: "column" },
110
112
  React.createElement(Box, null,
111
- React.createElement(Text, { color: isSelected ? 'green' : 'white', bold: isSelected },
113
+ React.createElement(Text, { color: isSelected ? theme.colors.menuSelected : theme.colors.menuNormal, bold: isSelected },
112
114
  isSelected ? '❯ ' : ' ',
113
115
  agent.name)),
114
116
  isSelected && (React.createElement(Box, { flexDirection: "column", marginLeft: 3 },
115
- React.createElement(Text, { color: "gray" },
117
+ React.createElement(Text, { color: theme.colors.menuSecondary },
116
118
  "Description:",
117
119
  ' ',
118
120
  truncateText(agent.description || 'No description', 'Description: '.length)),
119
- React.createElement(Text, { color: "gray" },
121
+ React.createElement(Text, { color: theme.colors.menuSecondary },
120
122
  "Tools: ",
121
123
  agent.tools.length,
122
124
  " selected"),
123
- React.createElement(Text, { color: "gray", dimColor: true },
125
+ React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true },
124
126
  "Updated: ",
125
127
  new Date(agent.updatedAt).toLocaleString())))));
126
128
  }))),
127
129
  React.createElement(Box, { marginTop: 1 },
128
- React.createElement(Text, { color: "gray", dimColor: true }, "\u2191\u2193: Navigate | Enter: Edit | A: Add New | D: Delete | Esc: Back")))));
130
+ React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true }, "\u2191\u2193: Navigate | Enter: Edit | A: Add New | D: Delete | Esc: Back")))));
129
131
  }