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.
- package/dist/app.js +5 -2
- package/dist/i18n/lang/en.js +21 -0
- package/dist/i18n/lang/es.js +21 -0
- package/dist/i18n/lang/ja.js +21 -0
- package/dist/i18n/lang/ko.js +21 -0
- package/dist/i18n/lang/zh-TW.js +21 -0
- package/dist/i18n/lang/zh.js +21 -0
- package/dist/i18n/types.d.ts +21 -0
- package/dist/mcp/todo.js +1 -1
- package/dist/ui/components/AgentPickerPanel.js +8 -6
- package/dist/ui/components/ChatInput.js +23 -21
- package/dist/ui/components/CommandPanel.js +7 -5
- package/dist/ui/components/DiffViewer.js +6 -4
- package/dist/ui/components/FileList.js +8 -6
- package/dist/ui/components/Menu.d.ts +1 -1
- package/dist/ui/components/Menu.js +8 -6
- package/dist/ui/components/PendingMessages.js +7 -5
- package/dist/ui/components/TodoPickerPanel.js +12 -10
- package/dist/ui/components/TodoTree.js +7 -5
- package/dist/ui/components/ToolConfirmation.js +14 -12
- package/dist/ui/components/ToolResultPreview.js +17 -3
- package/dist/ui/contexts/ThemeContext.d.ts +13 -0
- package/dist/ui/contexts/ThemeContext.js +28 -0
- package/dist/ui/pages/ChatScreen.js +21 -19
- package/dist/ui/pages/CodeBaseConfigScreen.js +30 -28
- package/dist/ui/pages/ConfigScreen.js +76 -74
- package/dist/ui/pages/CustomHeadersScreen.js +33 -31
- package/dist/ui/pages/LanguageSettingsScreen.js +6 -4
- package/dist/ui/pages/ProxyConfigScreen.js +15 -13
- package/dist/ui/pages/SensitiveCommandConfigScreen.js +12 -10
- package/dist/ui/pages/SubAgentConfigScreen.js +12 -10
- package/dist/ui/pages/SubAgentListScreen.js +11 -9
- package/dist/ui/pages/SystemPromptConfigScreen.js +21 -19
- package/dist/ui/pages/ThemeSettingsScreen.d.ts +7 -0
- package/dist/ui/pages/ThemeSettingsScreen.js +106 -0
- package/dist/ui/pages/WelcomeScreen.js +11 -1
- package/dist/ui/themes/index.d.ts +23 -0
- package/dist/ui/themes/index.js +140 -0
- package/dist/utils/themeConfig.d.ts +21 -0
- package/dist/utils/themeConfig.js +61 -0
- package/dist/utils/toolExecutor.js +11 -1
- 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:
|
|
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:
|
|
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:
|
|
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:
|
|
357
|
-
React.createElement(Text, { bold: true, color:
|
|
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
|
-
?
|
|
370
|
+
? theme.colors.menuSelected
|
|
369
371
|
: scheme.id === config.active
|
|
370
|
-
?
|
|
371
|
-
:
|
|
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:
|
|
383
|
-
React.createElement(Box, { flexDirection: "column", marginBottom: 1, marginLeft: 2 }, actions.map(action => (React.createElement(Text, { key: action, color: 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:
|
|
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:
|
|
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' ?
|
|
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:
|
|
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' ?
|
|
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:
|
|
431
|
-
React.createElement(Text, { color:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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 ?
|
|
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 ?
|
|
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:
|
|
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' ?
|
|
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:
|
|
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' ?
|
|
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:
|
|
483
|
+
React.createElement(Text, { color: theme.colors.menuSecondary }, headerEditValue || t.customHeaders.notSet))))),
|
|
482
484
|
React.createElement(Box, { marginTop: 1 },
|
|
483
|
-
React.createElement(Text, { color:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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' ?
|
|
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:
|
|
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' ?
|
|
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:
|
|
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' ?
|
|
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:
|
|
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:
|
|
126
|
-
errors.map((error, index) => (React.createElement(Text, { key: index, color:
|
|
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:
|
|
139
|
+
React.createElement(Text, { color: theme.colors.menuInfo }, t.proxyConfig.windowsExample),
|
|
138
140
|
" ",
|
|
139
141
|
React.createElement(Newline, null),
|
|
140
|
-
React.createElement(Text, { color:
|
|
142
|
+
React.createElement(Text, { color: theme.colors.success }, t.proxyConfig.macosExample),
|
|
141
143
|
" ",
|
|
142
144
|
React.createElement(Newline, null),
|
|
143
|
-
React.createElement(Text, { color:
|
|
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:
|
|
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' ?
|
|
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' ?
|
|
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:
|
|
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
|
-
?
|
|
240
|
+
? theme.colors.menuInfo
|
|
239
241
|
: cmd.enabled
|
|
240
|
-
?
|
|
241
|
-
:
|
|
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:
|
|
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:
|
|
264
|
-
confirmReset && (React.createElement(Text, { bold: true, color:
|
|
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:
|
|
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:
|
|
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' ?
|
|
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 ?
|
|
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:
|
|
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:
|
|
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' ?
|
|
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' ?
|
|
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' ?
|
|
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:
|
|
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:
|
|
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:
|
|
102
|
-
React.createElement(Text, { color:
|
|
103
|
-
React.createElement(Text, { bold: true, color:
|
|
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 ?
|
|
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:
|
|
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:
|
|
121
|
+
React.createElement(Text, { color: theme.colors.menuSecondary },
|
|
120
122
|
"Tools: ",
|
|
121
123
|
agent.tools.length,
|
|
122
124
|
" selected"),
|
|
123
|
-
React.createElement(Text, { color:
|
|
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:
|
|
130
|
+
React.createElement(Text, { color: theme.colors.menuSecondary, dimColor: true }, "\u2191\u2193: Navigate | Enter: Edit | A: Add New | D: Delete | Esc: Back")))));
|
|
129
131
|
}
|