aegiscode 3.1.10 → 3.4.2

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 (209) hide show
  1. package/bin/aegis.js +165 -0
  2. package/package.json +18 -86
  3. package/LICENSE +0 -21
  4. package/README.md +0 -394
  5. package/dist/main.js +0 -2171
  6. package/gui/run-gui.cjs +0 -13
  7. package/src/agent/Agent.ts +0 -903
  8. package/src/agent/SimpleAgent.ts +0 -48
  9. package/src/agent/index.ts +0 -54
  10. package/src/agent/orchestrator/AppBuilder.ts +0 -443
  11. package/src/agent/orchestrator/CouncilAgent.ts +0 -310
  12. package/src/agent/orchestrator/DiscussionRoom.ts +0 -462
  13. package/src/agent/orchestrator/OrchestratorAgent.ts +0 -637
  14. package/src/agent/orchestrator/index.ts +0 -38
  15. package/src/agent/orchestrator/utils.ts +0 -397
  16. package/src/agent/pricing.ts +0 -115
  17. package/src/agent/router.ts +0 -74
  18. package/src/agent/routerStats.ts +0 -121
  19. package/src/agent/types.ts +0 -318
  20. package/src/auth/login.ts +0 -383
  21. package/src/cli/config.ts +0 -189
  22. package/src/cli/index.ts +0 -17
  23. package/src/cli/middleware.ts +0 -119
  24. package/src/cli/types.ts +0 -75
  25. package/src/config/ConfigManager.ts +0 -587
  26. package/src/config/index.ts +0 -7
  27. package/src/config/types.ts +0 -584
  28. package/src/context/CompactionService.ts +0 -300
  29. package/src/context/ContextManager.ts +0 -450
  30. package/src/context/FileAnalyzer.ts +0 -267
  31. package/src/context/TokenCounter.ts +0 -265
  32. package/src/context/index.ts +0 -27
  33. package/src/context/storage/CacheStore.ts +0 -176
  34. package/src/context/storage/JSONLStore.ts +0 -201
  35. package/src/context/storage/MemoryStore.ts +0 -205
  36. package/src/context/storage/PersistentStore.ts +0 -327
  37. package/src/context/storage/index.ts +0 -9
  38. package/src/context/storage/pathUtils.ts +0 -114
  39. package/src/context/test.ts +0 -309
  40. package/src/context/types.ts +0 -268
  41. package/src/hooks/HookExecutor.ts +0 -434
  42. package/src/hooks/HookManager.ts +0 -596
  43. package/src/hooks/HookService.ts +0 -269
  44. package/src/hooks/Matcher.ts +0 -157
  45. package/src/hooks/index.ts +0 -63
  46. package/src/hooks/types.ts +0 -424
  47. package/src/main.tsx +0 -596
  48. package/src/mcp/HealthMonitor.ts +0 -150
  49. package/src/mcp/McpClient.ts +0 -491
  50. package/src/mcp/McpRegistry.ts +0 -321
  51. package/src/mcp/createMcpTool.ts +0 -251
  52. package/src/mcp/index.ts +0 -15
  53. package/src/mcp/server.ts +0 -334
  54. package/src/mcp/test-server.ts +0 -88
  55. package/src/mcp/test.ts +0 -372
  56. package/src/mcp/types.ts +0 -247
  57. package/src/memory/AgentMemoryBus.ts +0 -432
  58. package/src/memory/CloudSync.ts +0 -99
  59. package/src/memory/DriveSync.ts +0 -106
  60. package/src/memory/SharedMemory.ts +0 -951
  61. package/src/memory/index.ts +0 -14
  62. package/src/memory/machineFingerprint.ts +0 -40
  63. package/src/orchestrator/SubAgentMetadata.ts +0 -136
  64. package/src/prompts/builder.ts +0 -213
  65. package/src/prompts/default.ts +0 -144
  66. package/src/prompts/index.ts +0 -16
  67. package/src/prompts/plan.ts +0 -64
  68. package/src/prompts/test.ts +0 -78
  69. package/src/services/AnthropicChatService.ts +0 -341
  70. package/src/services/ChatService.ts +0 -347
  71. package/src/services/ClaudeCliChatService.ts +0 -256
  72. package/src/services/CloudSync.ts +0 -168
  73. package/src/services/CostLedger.ts +0 -211
  74. package/src/services/Heartbeat.ts +0 -135
  75. package/src/services/LearningCollector.ts +0 -291
  76. package/src/services/OllamaInstaller.ts +0 -342
  77. package/src/services/VersionChecker.ts +0 -445
  78. package/src/services/index.ts +0 -57
  79. package/src/services/streaming/OpenAIEventAdapter.ts +0 -126
  80. package/src/services/streaming/RenderingProfile.ts +0 -90
  81. package/src/services/streaming/StreamEventParser.ts +0 -181
  82. package/src/services/streaming/ThrottledRenderer.ts +0 -139
  83. package/src/services/streaming/TranscriptBuffer.ts +0 -574
  84. package/src/services/streaming/eventStatusMap.ts +0 -52
  85. package/src/services/streaming/index.ts +0 -46
  86. package/src/services/streaming/renderFormatting.ts +0 -79
  87. package/src/services/streaming/types.ts +0 -234
  88. package/src/skills/SkillLoader.ts +0 -126
  89. package/src/skills/SkillRegistry.ts +0 -366
  90. package/src/skills/index.ts +0 -48
  91. package/src/skills/types.ts +0 -146
  92. package/src/slash-commands/billing.ts +0 -70
  93. package/src/slash-commands/build.ts +0 -413
  94. package/src/slash-commands/builtinCommands.ts +0 -2733
  95. package/src/slash-commands/clone.ts +0 -242
  96. package/src/slash-commands/council.ts +0 -125
  97. package/src/slash-commands/custom/CustomCommandExecutor.ts +0 -143
  98. package/src/slash-commands/custom/CustomCommandLoader.ts +0 -251
  99. package/src/slash-commands/custom/CustomCommandRegistry.ts +0 -144
  100. package/src/slash-commands/custom/index.ts +0 -7
  101. package/src/slash-commands/debate.ts +0 -254
  102. package/src/slash-commands/gmail.ts +0 -105
  103. package/src/slash-commands/index.ts +0 -388
  104. package/src/slash-commands/mcpCommand.ts +0 -205
  105. package/src/slash-commands/types.ts +0 -201
  106. package/src/store/index.ts +0 -76
  107. package/src/store/selectors.ts +0 -246
  108. package/src/store/slices/appSlice.ts +0 -205
  109. package/src/store/slices/commandSlice.ts +0 -115
  110. package/src/store/slices/configSlice.ts +0 -46
  111. package/src/store/slices/focusSlice.ts +0 -64
  112. package/src/store/slices/index.ts +0 -9
  113. package/src/store/slices/sessionSlice.ts +0 -424
  114. package/src/store/streaming-buffer.ts +0 -425
  115. package/src/store/test.ts +0 -296
  116. package/src/store/types.ts +0 -274
  117. package/src/store/vanilla.ts +0 -186
  118. package/src/tools/builtin/bash.ts +0 -236
  119. package/src/tools/builtin/council.ts +0 -105
  120. package/src/tools/builtin/edit.ts +0 -213
  121. package/src/tools/builtin/glob.ts +0 -136
  122. package/src/tools/builtin/grep.ts +0 -263
  123. package/src/tools/builtin/index.ts +0 -61
  124. package/src/tools/builtin/memory.ts +0 -66
  125. package/src/tools/builtin/read.ts +0 -168
  126. package/src/tools/builtin/skill.ts +0 -97
  127. package/src/tools/builtin/snapshot.ts +0 -40
  128. package/src/tools/builtin/task.ts +0 -106
  129. package/src/tools/builtin/write.ts +0 -134
  130. package/src/tools/createTool.ts +0 -221
  131. package/src/tools/execution/ExecutionPipeline.ts +0 -263
  132. package/src/tools/execution/index.ts +0 -40
  133. package/src/tools/execution/stages/CacheStage.ts +0 -131
  134. package/src/tools/execution/stages/ConfirmationStage.ts +0 -203
  135. package/src/tools/execution/stages/DiscoveryStage.ts +0 -46
  136. package/src/tools/execution/stages/ExecutionStage.ts +0 -48
  137. package/src/tools/execution/stages/FormattingStage.ts +0 -44
  138. package/src/tools/execution/stages/HookStage.ts +0 -72
  139. package/src/tools/execution/stages/PermissionStage.ts +0 -287
  140. package/src/tools/execution/stages/PostHookStage.ts +0 -71
  141. package/src/tools/execution/stages/index.ts +0 -12
  142. package/src/tools/execution/test.ts +0 -266
  143. package/src/tools/execution/types.ts +0 -273
  144. package/src/tools/index.ts +0 -81
  145. package/src/tools/registry.ts +0 -304
  146. package/src/tools/schemas.ts +0 -109
  147. package/src/tools/test.ts +0 -220
  148. package/src/tools/types.ts +0 -175
  149. package/src/tools/validation/PermissionChecker.ts +0 -242
  150. package/src/tools/validation/SensitiveFileDetector.ts +0 -210
  151. package/src/tools/validation/index.ts +0 -11
  152. package/src/ui/App.tsx +0 -166
  153. package/src/ui/components/AegisInterface.tsx +0 -484
  154. package/src/ui/components/common/ChatSearch.tsx +0 -150
  155. package/src/ui/components/common/ErrorBoundary.tsx +0 -82
  156. package/src/ui/components/common/ExitMessage.tsx +0 -120
  157. package/src/ui/components/common/LoadingIndicator.tsx +0 -49
  158. package/src/ui/components/common/index.ts +0 -6
  159. package/src/ui/components/dialog/ConfirmationPrompt.tsx +0 -208
  160. package/src/ui/components/dialog/InteractiveSelector.tsx +0 -149
  161. package/src/ui/components/dialog/SetupWizard.tsx +0 -297
  162. package/src/ui/components/dialog/UpdatePrompt.tsx +0 -155
  163. package/src/ui/components/dialog/index.ts +0 -8
  164. package/src/ui/components/index.ts +0 -28
  165. package/src/ui/components/input/CommandSuggestions.tsx +0 -139
  166. package/src/ui/components/input/CustomTextInput.tsx +0 -220
  167. package/src/ui/components/input/InputArea.tsx +0 -361
  168. package/src/ui/components/input/PromptSuggestions.tsx +0 -66
  169. package/src/ui/components/input/index.ts +0 -6
  170. package/src/ui/components/layout/ChatStatusBar.tsx +0 -90
  171. package/src/ui/components/layout/ContextBar.tsx +0 -79
  172. package/src/ui/components/layout/MessageArea.tsx +0 -96
  173. package/src/ui/components/layout/MessageList.tsx +0 -647
  174. package/src/ui/components/layout/MessageSeparator.tsx +0 -26
  175. package/src/ui/components/layout/WelcomeMessage.tsx +0 -93
  176. package/src/ui/components/layout/index.ts +0 -7
  177. package/src/ui/components/markdown/CodeHighlighter.tsx +0 -292
  178. package/src/ui/components/markdown/MessageRenderer.tsx +0 -1211
  179. package/src/ui/components/markdown/index.ts +0 -8
  180. package/src/ui/components/markdown/parser.ts +0 -336
  181. package/src/ui/components/markdown/types.ts +0 -66
  182. package/src/ui/focus/FocusManager.ts +0 -137
  183. package/src/ui/focus/index.ts +0 -13
  184. package/src/ui/focus/types.ts +0 -54
  185. package/src/ui/focus/useFocus.ts +0 -75
  186. package/src/ui/hooks/index.ts +0 -11
  187. package/src/ui/hooks/useAgent.ts +0 -284
  188. package/src/ui/hooks/useCommandHistory.ts +0 -87
  189. package/src/ui/hooks/useCommandProcessor.ts +0 -443
  190. package/src/ui/hooks/useConfirmation.ts +0 -99
  191. package/src/ui/hooks/useCtrlCHandler.ts +0 -100
  192. package/src/ui/hooks/useInputBuffer.ts +0 -122
  193. package/src/ui/hooks/useTerminalSize.ts +0 -68
  194. package/src/ui/hooks/useTerminalWidth.ts +0 -5
  195. package/src/ui/hooks/useWindowedList.ts +0 -118
  196. package/src/ui/render-debugger.ts +0 -621
  197. package/src/ui/test.ts +0 -189
  198. package/src/ui/themes/ThemeManager.ts +0 -332
  199. package/src/ui/themes/aegisTheme.ts +0 -87
  200. package/src/ui/themes/darkTheme.ts +0 -87
  201. package/src/ui/themes/defaultTheme.ts +0 -85
  202. package/src/ui/themes/index.ts +0 -10
  203. package/src/ui/themes/lightTheme.ts +0 -89
  204. package/src/ui/themes/popularThemes.ts +0 -187
  205. package/src/ui/themes/types.ts +0 -130
  206. package/src/utils/clipboard.ts +0 -48
  207. package/src/utils/debug.ts +0 -43
  208. package/src/utils/environment.ts +0 -68
  209. package/src/utils/index.ts +0 -10
package/src/ui/test.ts DELETED
@@ -1,189 +0,0 @@
1
- /**
2
- * UI Component Tests (D)
3
- *
4
- * Tests for MessageList, MessageRenderer, ErrorBoundary, ChatSearch,
5
- * and other UI components.
6
- *
7
- * Run with: tsx src/ui/test.ts
8
- *
9
- * Rendering debugger:
10
- * tsx src/ui/test.ts --debug-rendering Enable render debugger during tests
11
- * tsx src/ui/test.ts --render-report Run tests then print render report
12
- */
13
-
14
- import React from 'react';
15
- import { render } from 'ink';
16
- import { ErrorBoundary } from './components/common/ErrorBoundary.js';
17
- import { MessageList } from './components/layout/MessageList.js';
18
- import { WelcomeMessage } from './components/layout/WelcomeMessage.js';
19
- import { MessageSeparator } from './components/layout/MessageSeparator.js';
20
- import { ChatStatusBar } from './components/layout/ChatStatusBar.js';
21
- import { vanillaStore, getState } from '../store/index.js';
22
- import { startRenderDebugger, stopRenderDebugger, getRenderReport } from './render-debugger.js';
23
-
24
- let testsPassed = 0;
25
- let testsFailed = 0;
26
-
27
- function pass(msg: string) {
28
- testsPassed++;
29
- console.log(` ✓ ${msg}`);
30
- }
31
-
32
- function fail(msg: string, error?: any) {
33
- testsFailed++;
34
- console.log(` ✗ ${msg}${error ? `: ${error}` : ''}`);
35
- }
36
-
37
- async function runTests() {
38
- console.log('\nUI Component Tests\n');
39
-
40
- // Auto-start render debugger if --debug-rendering flag is set
41
- const enableDebug = process.argv.includes('--debug-rendering');
42
- if (enableDebug) {
43
- startRenderDebugger({ reportInterval: 5000, verbose: false });
44
- }
45
-
46
- // ===== ErrorBoundary =====
47
- console.log('ErrorBoundary:');
48
-
49
- // 1. ErrorBoundary renders children normally
50
- const GoodComponent = () => React.createElement('test-good', null, 'hello');
51
- try {
52
- const { unmount } = render(
53
- React.createElement(ErrorBoundary, null,
54
- React.createElement(GoodComponent),
55
- ),
56
- );
57
- pass('renders children without error');
58
- unmount();
59
- } catch (e) {
60
- fail('renders children without error', e);
61
- }
62
-
63
- // 2. ErrorBoundary catches errors
64
- const BadComponent = () => { throw new Error('test error'); };
65
- try {
66
- const { unmount } = render(
67
- React.createElement(ErrorBoundary,
68
- { fallback: React.createElement('div', null, 'fallback'), children: React.createElement(BadComponent) },
69
- ),
70
- );
71
- pass('catches rendering errors');
72
- unmount();
73
- } catch (e) {
74
- // If we get here, ErrorBoundary caught it - that's fine for ink
75
- pass('catches rendering errors (error propagated)');
76
- }
77
-
78
- // ===== MessageList =====
79
- console.log('\nMessageList:');
80
-
81
- // 3. MessageList renders welcome when empty
82
- try {
83
- const { unmount } = render(
84
- React.createElement(MessageList, { terminalWidth: 80, terminalHeight: 24 }),
85
- );
86
- pass('renders without messages');
87
- unmount();
88
- } catch (e) {
89
- fail('renders without messages', e);
90
- }
91
-
92
- // 4. MessageList renders messages
93
- try {
94
- // Add a test message directly to store
95
- getState().session.messages.push({
96
- id: 'test-1',
97
- role: 'user',
98
- content: 'Hello world',
99
- timestamp: Date.now(),
100
- });
101
-
102
- const { unmount, rerender } = render(
103
- React.createElement(MessageList, { terminalWidth: 80, terminalHeight: 24 }),
104
- );
105
-
106
- pass('renders with messages');
107
- unmount();
108
-
109
- // Clean up
110
- getState().session.messages = [];
111
- } catch (e) {
112
- fail('renders with messages', e);
113
- }
114
-
115
- // ===== ChatStatusBar =====
116
- console.log('\nChatStatusBar:');
117
-
118
- // 5. ChatStatusBar renders
119
- try {
120
- const { unmount } = render(
121
- React.createElement(ChatStatusBar, null),
122
- );
123
- pass('renders ChatStatusBar');
124
- unmount();
125
- } catch (e) {
126
- fail('renders ChatStatusBar', e);
127
- }
128
-
129
- // ===== Store Integration =====
130
- console.log('\nStore Integration:');
131
-
132
- // 6. Messages have expected shape
133
- const msg = { id: 'test-2', role: 'assistant' as const, content: 'test', timestamp: Date.now() };
134
- getState().session.messages.push(msg);
135
- const messages = getState().session.messages;
136
- if (messages.length > 0 && messages[0].id && messages[0].role && messages[0].content) {
137
- pass('messages have correct shape');
138
- } else {
139
- fail('messages missing required fields');
140
- }
141
-
142
- // 7. Message streaming state transitions
143
- const streamId = 'test-stream-1';
144
- getState().session.messages.push({
145
- id: streamId,
146
- role: 'assistant',
147
- content: '',
148
- timestamp: Date.now(),
149
- isStreaming: true,
150
- });
151
-
152
- // Simulate streaming
153
- const msgIndex = getState().session.messages.findIndex(m => m.id === streamId);
154
- if (msgIndex >= 0) {
155
- getState().session.messages[msgIndex].content = 'partial';
156
- pass('streaming content update works');
157
- } else {
158
- fail('streaming message not found');
159
- }
160
-
161
- // Finish streaming
162
- getState().session.messages[msgIndex].isStreaming = false;
163
- pass('streaming completion works');
164
-
165
- // Clean up
166
- getState().session.messages = [];
167
-
168
- // ===== Summary =====
169
- console.log(`\n${'='.repeat(40)}`);
170
- console.log(`Tests: ${testsPassed} passed, ${testsFailed} failed`);
171
-
172
- // Print render report if debug was enabled or --render-report flag set
173
- if (enableDebug || process.argv.includes('--render-report')) {
174
- console.log(getRenderReport());
175
- }
176
-
177
- if (enableDebug) {
178
- stopRenderDebugger();
179
- }
180
-
181
- if (testsFailed > 0) {
182
- process.exit(1);
183
- }
184
- }
185
-
186
- runTests().catch((error) => {
187
- console.error('Test suite error:', error);
188
- process.exit(1);
189
- });
@@ -1,332 +0,0 @@
1
- /**
2
- *
3
- *
4
- *
5
- *
6
- */
7
-
8
- import { execSync } from 'node:child_process';
9
- import type { Theme, ThemePreset, RoleStyle, ColorMode } from './types.js';
10
- import { defaultTheme } from './defaultTheme.js';
11
- import { darkTheme } from './darkTheme.js';
12
- import { lightTheme } from './lightTheme.js';
13
- import { aegisTheme } from './aegisTheme.js';
14
- import { configManager } from '../../config/ConfigManager.js';
15
-
16
- /**
17
- *
18
- *
19
- *
20
- * 1. macOS 系统级暗色模式
21
- * 2. COLORFGBG 环境变量(一些终端会设置)
22
- * 3. 默认返回 unknown
23
- */
24
- function detectColorMode(): ColorMode {
25
- // 1. macOS 系统级检
26
- if (process.platform === 'darwin') {
27
- try {
28
- const result = execSync('defaults read -g AppleInterfaceStyle 2>/dev/null', {
29
- encoding: 'utf-8',
30
- timeout: 1000,
31
- }).trim();
32
- if (result === 'Dark') {
33
- return 'dark';
34
- }
35
- } catch {
36
- // 如果命令失败或返回空,说明是亮色模
37
- return 'light';
38
- }
39
- }
40
-
41
- // 2. 检查 COLORFGBG 环境变
42
- // 格式: "foreground;background" 如 "15;0" (白字黑底) 或 "0;15" (黑字白
43
- const colorFgBg = process.env.COLORFGBG;
44
- if (colorFgBg) {
45
- const parts = colorFgBg.split(';');
46
- if (parts.length >= 2) {
47
- const bg = parseInt(parts[parts.length - 1], 10);
48
- // 背景色 0-7 通常是暗色,8-15 通常是亮
49
- // 0=黑, 7=白(暗), 8=亮黑(灰), 15=亮
50
- if (!isNaN(bg)) {
51
- if (bg === 0 || bg <= 6) {
52
- return 'dark';
53
- } else if (bg === 7 || bg >= 8) {
54
- return 'light';
55
- }
56
- }
57
- }
58
- }
59
-
60
- // 3. 检查常见终端的默认模
61
- const termProgram = process.env.TERM_PROGRAM?.toLowerCase();
62
- if (termProgram) {
63
- // VS Code 集成终端通常跟随编辑器主
64
- if (termProgram === 'vscode') {
65
- // VS Code 的 VSCODE_THEME_KIND 变
66
- const themeKind = process.env.VSCODE_THEME_KIND;
67
- if (themeKind === 'vscode-dark' || themeKind === 'vscode-high-contrast') {
68
- return 'dark';
69
- } else if (themeKind === 'vscode-light' || themeKind === 'vscode-high-contrast-light') {
70
- return 'light';
71
- }
72
- }
73
- }
74
-
75
- return 'unknown';
76
- }
77
-
78
- /**
79
- *
80
- */
81
- const presetThemes: ThemePreset[] = [
82
- {
83
- id: 'default',
84
- name: 'Default',
85
- description: 'Balanced theme (works on most terminals)',
86
- theme: defaultTheme,
87
- },
88
- {
89
- id: 'aegis',
90
- name: 'ÆGIS',
91
- description: 'ÆGIS teal — the signature brand theme',
92
- theme: aegisTheme,
93
- },
94
- {
95
- id: 'light',
96
- name: 'Light',
97
- description: 'Optimized for light/white terminal backgrounds',
98
- theme: lightTheme,
99
- },
100
- {
101
- id: 'dark',
102
- name: 'Dark',
103
- description: 'Dark theme for dark terminal backgrounds',
104
- theme: darkTheme,
105
- },
106
- {
107
- id: 'ocean',
108
- name: 'Ocean',
109
- description: 'Deep blue ocean theme',
110
- theme: {
111
- ...darkTheme,
112
- name: 'ocean',
113
- colors: {
114
- ...darkTheme.colors,
115
- primary: '#0ea5e9', // sky-500
116
- secondary: '#06b6d4', // cyan-500
117
- accent: '#14b8a6', // teal-500
118
- background: {
119
- primary: '#0c4a6e', // sky-900
120
- secondary: '#075985', // sky-800
121
- dark: '#082f49', // sky-950
122
- },
123
- },
124
- },
125
- },
126
- {
127
- id: 'forest',
128
- name: 'Forest',
129
- description: 'Natural green forest theme',
130
- theme: {
131
- ...darkTheme,
132
- name: 'forest',
133
- colors: {
134
- ...darkTheme.colors,
135
- primary: '#22c55e', // green-500
136
- secondary: '#16a34a', // green-600
137
- accent: '#84cc16', // lime-500
138
- background: {
139
- primary: '#14532d', // green-900
140
- secondary: '#166534', // green-800
141
- dark: '#052e16', // green-950
142
- },
143
- },
144
- },
145
- },
146
- {
147
- id: 'sunset',
148
- name: 'Sunset',
149
- description: 'Warm sunset colors',
150
- theme: {
151
- ...darkTheme,
152
- name: 'sunset',
153
- colors: {
154
- ...darkTheme.colors,
155
- primary: '#f97316', // orange-500
156
- secondary: '#ea580c', // orange-600
157
- accent: '#eab308', // yellow-500
158
- background: {
159
- primary: '#7c2d12', // orange-900
160
- secondary: '#9a3412', // orange-800
161
- dark: '#431407', // orange-950
162
- },
163
- },
164
- },
165
- },
166
- ];
167
-
168
- /**
169
- *
170
- */
171
- export class ThemeManager {
172
- private currentTheme: Theme = defaultTheme;
173
- private themes: Map<string, Theme> = new Map();
174
- private initialized: boolean = false;
175
-
176
- constructor() {
177
- // 注册预设主
178
- for (const preset of presetThemes) {
179
- this.themes.set(preset.id, preset.theme);
180
- }
181
- }
182
-
183
- /**
184
- *
185
- *
186
- *
187
- * 1. 用户保存的主题(用户配置文件中)
188
- * 2. 自动检测终端颜色模式,选择合适的主题
189
- * 3. 使用默认主题
190
- */
191
- initializeFromConfig(): void {
192
- if (this.initialized) return;
193
-
194
- try {
195
- const savedTheme = configManager.getTheme();
196
-
197
- // 如果用户之前保存过主题,使用保存的主
198
- if (savedTheme && this.themes.has(savedTheme)) {
199
- this.currentTheme = this.themes.get(savedTheme)!;
200
- this.initialized = true;
201
- return;
202
- }
203
-
204
- // 没有用户保存的主题,自动检测终端颜色模
205
- const colorMode = detectColorMode();
206
-
207
- if (colorMode === 'dark') {
208
- this.currentTheme = this.themes.get('dark')!;
209
- } else if (colorMode === 'light') {
210
- this.currentTheme = this.themes.get('light')!;
211
- }
212
- // colorMode === 'unknown' 时保持默认主
213
-
214
- this.initialized = true;
215
- } catch {
216
- // 配置读取失败时使用默认主
217
- this.initialized = true;
218
- }
219
- }
220
-
221
- /**
222
- *
223
- */
224
- getDetectedColorMode(): ColorMode {
225
- return detectColorMode();
226
- }
227
-
228
- /**
229
- *
230
- */
231
- setTheme(themeName: string, persist: boolean = true): void {
232
- const theme = this.themes.get(themeName);
233
- if (theme) {
234
- this.currentTheme = theme;
235
-
236
- // 同步保存到配置文件,确保立即生
237
- if (persist) {
238
- try {
239
- configManager.saveTheme(themeName);
240
- } catch {
241
- // 保存失败时静默忽
242
- }
243
- }
244
- } else {
245
- throw new Error(`Theme '${themeName}' not found`);
246
- }
247
- }
248
-
249
- /**
250
- *
251
- */
252
- getTheme(): Theme {
253
- return this.currentTheme;
254
- }
255
-
256
- /**
257
- *
258
- */
259
- getCurrentThemeName(): string {
260
- return this.currentTheme.name;
261
- }
262
-
263
- /**
264
- *
265
- */
266
- hasTheme(themeName: string): boolean {
267
- return this.themes.has(themeName);
268
- }
269
-
270
- /**
271
- *
272
- */
273
- getAvailableThemes(): string[] {
274
- return Array.from(this.themes.keys());
275
- }
276
-
277
- /**
278
- *
279
- */
280
- getThemePresets(): ThemePreset[] {
281
- return presetThemes;
282
- }
283
-
284
- /**
285
- *
286
- */
287
- registerTheme(id: string, theme: Theme): void {
288
- this.themes.set(id, theme);
289
- }
290
-
291
- /**
292
- *
293
- */
294
- getRoleStyle(role: 'user' | 'assistant' | 'system' | 'tool'): RoleStyle {
295
- const colors = this.currentTheme.colors;
296
-
297
- switch (role) {
298
- case 'user':
299
- return {
300
- color: colors.text.muted,
301
- prefix: '',
302
- bold: false,
303
- };
304
- case 'assistant':
305
- return {
306
- color: colors.primary,
307
- prefix: '',
308
- bold: false,
309
- };
310
- case 'system':
311
- return {
312
- color: colors.warning,
313
- prefix: '!',
314
- bold: true,
315
- };
316
- case 'tool':
317
- return {
318
- color: colors.info,
319
- prefix: '',
320
- bold: false,
321
- };
322
- default:
323
- return {
324
- color: colors.text.primary,
325
- prefix: '',
326
- };
327
- }
328
- }
329
- }
330
-
331
- // 导出单
332
- export const themeManager = new ThemeManager();
@@ -1,87 +0,0 @@
1
- import type { Theme, BaseColors, Spacing } from './types.js';
2
-
3
- const aegisColors: BaseColors = {
4
- primary: '#00e5c0', // teal
5
- secondary: '#7c6fd4', // purple
6
- accent: '#00e5c0', // teal
7
- success: '#22c55e',
8
- warning: '#f59e0b',
9
- error: '#ef4444',
10
- info: '#00e5c0',
11
- text: {
12
- primary: '#e8e6f4',
13
- secondary: '#8882a4',
14
- muted: '#44405a',
15
- light: '#e8e6f4',
16
- },
17
- background: {
18
- primary: '#04040c',
19
- secondary: '#181828',
20
- dark: '#0c0c16',
21
- },
22
- border: {
23
- light: 'rgba(255,255,255,0.06)',
24
- dark: '#1a1a2a',
25
- },
26
- syntax: {
27
- keyword: '#00e5c0',
28
- string: '#7c6fd4',
29
- number: '#f59e0b',
30
- comment: '#44405a',
31
- function: '#f472b6',
32
- variable: '#e8e6f4',
33
- operator: '#89DDFF',
34
- type: '#FFCB6B',
35
- tag: '#F07178',
36
- attr: '#C3E88D',
37
- default: '#A6ACCD',
38
- },
39
- };
40
-
41
- const spacing: Spacing = {
42
- xs: 0, sm: 1, md: 2, lg: 3, xl: 4
43
- };
44
-
45
- const tokens = {
46
- elevation: {
47
- flat: 'rgba(0,0,0,0)',
48
- raised: 'rgba(0, 229, 192, 0.08)',
49
- overlay: 'rgba(0, 0, 0, 0.5)',
50
- sticky: 'rgba(0, 229, 192, 0.15)',
51
- },
52
- radius: {
53
- sm: 0,
54
- md: 1,
55
- lg: 2,
56
- full: 0,
57
- },
58
- animation: {
59
- fast: 80,
60
- normal: 150,
61
- slow: 300,
62
- easing: 'ease-out',
63
- },
64
- semantic: {
65
- interactive: {
66
- idle: aegisColors.primary,
67
- hover: '#33ffd9',
68
- active: '#00bfa0',
69
- disabled: '#44405a',
70
- },
71
- focus: {
72
- ring: '#00e5c0',
73
- glow: 'rgba(0, 229, 192, 0.3)',
74
- },
75
- code: {
76
- background: '#08080f',
77
- border: '#1a1a2a',
78
- },
79
- },
80
- };
81
-
82
- export const aegisTheme: Theme = {
83
- name: 'aegis',
84
- colors: aegisColors,
85
- spacing,
86
- tokens,
87
- };
@@ -1,87 +0,0 @@
1
- /**
2
- *
3
- */
4
-
5
- import type { Theme } from './types.js';
6
- import { defaultTheme } from './defaultTheme.js';
7
-
8
- const darkTokens = {
9
- elevation: {
10
- flat: 'rgba(0,0,0,0)',
11
- raised: 'rgba(96, 165, 250, 0.08)',
12
- overlay: 'rgba(0, 0, 0, 0.4)',
13
- sticky: 'rgba(96, 165, 250, 0.12)',
14
- },
15
- radius: {
16
- sm: 0,
17
- md: 1,
18
- lg: 2,
19
- full: 0,
20
- },
21
- animation: {
22
- fast: 80,
23
- normal: 150,
24
- slow: 300,
25
- easing: 'ease-out',
26
- },
27
- semantic: {
28
- interactive: {
29
- idle: '#60a5fa',
30
- hover: '#93c5fd',
31
- active: '#3b82f6',
32
- disabled: '#9ca3af',
33
- },
34
- focus: {
35
- ring: '#60a5fa',
36
- glow: 'rgba(96, 165, 250, 0.3)',
37
- },
38
- code: {
39
- background: '#1f2937',
40
- border: '#374151',
41
- },
42
- },
43
- };
44
-
45
- export const darkTheme: Theme = {
46
- ...defaultTheme,
47
- name: 'dark',
48
- tokens: darkTokens,
49
- colors: {
50
- ...defaultTheme.colors,
51
- primary: '#60a5fa', // blue-400
52
- secondary: '#818cf8', // indigo-400
53
- accent: '#a78bfa', // violet-400
54
- success: '#34d399', // emerald-400
55
- warning: '#fbbf24', // amber-400
56
- error: '#f87171', // red-400
57
- info: '#22d3ee', // cyan-400
58
- text: {
59
- primary: '#f9fafb', // gray-50
60
- secondary: '#e5e7eb', // gray-200
61
- muted: '#9ca3af', // gray-400
62
- light: '#111827', // gray-900
63
- },
64
- background: {
65
- primary: '#111827', // gray-900
66
- secondary: '#374151', // gray-700
67
- dark: '#030712', // gray-950
68
- },
69
- border: {
70
- light: '#374151', // gray-700
71
- dark: '#1f2937', // gray-800
72
- },
73
- syntax: {
74
- comment: '#9ca3af', // gray-400
75
- string: '#34d399', // emerald-400
76
- number: '#f472b6', // pink-400
77
- keyword: '#a78bfa', // violet-400
78
- function: '#60a5fa', // blue-400
79
- variable: '#e5e7eb', // gray-200
80
- operator: '#fbbf24', // amber-400
81
- type: '#22d3ee', // cyan-400
82
- tag: '#fb7185', // rose-400
83
- attr: '#facc15', // yellow-400
84
- default: '#f9fafb', // gray-50
85
- },
86
- },
87
- };