galaxy-code 0.1.6 → 0.1.8

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 (81) hide show
  1. package/dist/cli.bundle.js +317 -0
  2. package/package.json +6 -6
  3. package/dist/app.d.ts +0 -7
  4. package/dist/app.js +0 -597
  5. package/dist/auto-updater.d.ts +0 -21
  6. package/dist/auto-updater.js +0 -144
  7. package/dist/cli.d.ts +0 -2
  8. package/dist/cli.js +0 -159
  9. package/dist/cli.min.js +0 -589
  10. package/dist/connections/claude.d.ts +0 -71
  11. package/dist/connections/claude.js +0 -303
  12. package/dist/connections/gemini.d.ts +0 -40
  13. package/dist/connections/gemini.js +0 -232
  14. package/dist/connections/index.d.ts +0 -11
  15. package/dist/connections/index.js +0 -11
  16. package/dist/connections/ollama.d.ts +0 -37
  17. package/dist/connections/ollama.js +0 -73
  18. package/dist/connections/types.d.ts +0 -22
  19. package/dist/connections/types.js +0 -7
  20. package/dist/env.d.ts +0 -1
  21. package/dist/env.js +0 -29
  22. package/dist/prompts/ba-it-analyzer.d.ts +0 -1
  23. package/dist/prompts/ba-it-analyzer.js +0 -143
  24. package/dist/prompts/index.d.ts +0 -11
  25. package/dist/prompts/index.js +0 -11
  26. package/dist/prompts/orchestrator.d.ts +0 -8
  27. package/dist/prompts/orchestrator.js +0 -88
  28. package/dist/prompts/planning-agent.d.ts +0 -8
  29. package/dist/prompts/planning-agent.js +0 -195
  30. package/dist/prompts/universal-agent.d.ts +0 -7
  31. package/dist/prompts/universal-agent.js +0 -111
  32. package/dist/providers/agent-selector.d.ts +0 -29
  33. package/dist/providers/agent-selector.js +0 -84
  34. package/dist/providers/claude-agent.d.ts +0 -29
  35. package/dist/providers/claude-agent.js +0 -121
  36. package/dist/providers/gemini-agent.d.ts +0 -36
  37. package/dist/providers/gemini-agent.js +0 -168
  38. package/dist/providers/index.d.ts +0 -12
  39. package/dist/providers/index.js +0 -12
  40. package/dist/providers/ollama-agent.d.ts +0 -53
  41. package/dist/providers/ollama-agent.js +0 -276
  42. package/dist/providers/orchestrator.d.ts +0 -16
  43. package/dist/providers/orchestrator.js +0 -76
  44. package/dist/tools/ba-it-analyzer.d.ts +0 -66
  45. package/dist/tools/ba-it-analyzer.js +0 -90
  46. package/dist/tools/code-generate-agent.d.ts +0 -51
  47. package/dist/tools/code-generate-agent.js +0 -159
  48. package/dist/tools/command-runner.d.ts +0 -14
  49. package/dist/tools/command-runner.js +0 -120
  50. package/dist/tools/document-parser.d.ts +0 -11
  51. package/dist/tools/document-parser.js +0 -83
  52. package/dist/tools/file-operations.d.ts +0 -17
  53. package/dist/tools/file-operations.js +0 -127
  54. package/dist/tools/galaxy-ui-integration.d.ts +0 -94
  55. package/dist/tools/galaxy-ui-integration.js +0 -244
  56. package/dist/tools/git-operations.d.ts +0 -11
  57. package/dist/tools/git-operations.js +0 -114
  58. package/dist/tools/index.d.ts +0 -10
  59. package/dist/tools/index.js +0 -10
  60. package/dist/tools/planning-agent.d.ts +0 -29
  61. package/dist/tools/planning-agent.js +0 -134
  62. package/dist/tools/progress-reporter.d.ts +0 -19
  63. package/dist/tools/progress-reporter.js +0 -52
  64. package/dist/tools/registry.d.ts +0 -21
  65. package/dist/tools/registry.js +0 -695
  66. package/dist/tools/tool-event-emitter.d.ts +0 -24
  67. package/dist/tools/tool-event-emitter.js +0 -25
  68. package/dist/tools/types.d.ts +0 -31
  69. package/dist/tools/types.js +0 -1
  70. package/dist/types.d.ts +0 -39
  71. package/dist/types.js +0 -8
  72. package/dist/update-checker.d.ts +0 -22
  73. package/dist/update-checker.js +0 -85
  74. package/dist/utils/config-manager.d.ts +0 -102
  75. package/dist/utils/config-manager.js +0 -326
  76. package/dist/utils/devtools.d.ts +0 -21
  77. package/dist/utils/devtools.js +0 -61
  78. package/dist/utils/message-formatters.d.ts +0 -32
  79. package/dist/utils/message-formatters.js +0 -590
  80. package/dist/utils/progress-tracker.d.ts +0 -59
  81. package/dist/utils/progress-tracker.js +0 -213
package/dist/app.js DELETED
@@ -1,597 +0,0 @@
1
- /**
2
- * @author Bùi Trọng Hiếu
3
- * @email kevinbui210191@gmail.com
4
- * @create 2024-10-08
5
- * @modify 2024-10-13
6
- * @desc Main Ink interface with config-based agent routing.
7
- */
8
- import process from 'node:process';
9
- import React, { useMemo, useState, useEffect } from 'react';
10
- import { Box, Static, Text, useApp, useInput } from 'ink';
11
- import TextInput from 'ink-text-input';
12
- import Spinner from 'ink-spinner';
13
- import figlet from 'figlet';
14
- import { ClaudeAgent, GeminiAgent, OllamaAgent } from './providers/index.js';
15
- import { configManager } from './utils/config-manager.js';
16
- import { formatMessage } from './utils/message-formatters.js';
17
- import { toolEventEmitter } from './tools/index.js';
18
- const cliVersion = '0.1.6';
19
- const getTerminalWidth = () => {
20
- const width = process.stdout?.columns;
21
- return typeof width === 'number' && Number.isFinite(width) ? width : 80;
22
- };
23
- const centerLine = (text, width) => {
24
- const trimmed = text.replace(/\s+$/u, '');
25
- if (!trimmed)
26
- return '';
27
- const padding = Math.max(0, Math.floor((width - trimmed.length) / 2));
28
- return `${' '.repeat(padding)}${trimmed}`;
29
- };
30
- const getInforLines = (config) => {
31
- const width = getTerminalWidth();
32
- const agentStr = config.model;
33
- const lines = [
34
- { id: 'version', text: cliVersion },
35
- {
36
- id: 'hints',
37
- text: 'ENTER to send • \\ + ENTER for a new line ',
38
- },
39
- { id: 'cwd', text: `Current folder: ${process.cwd()}` },
40
- {
41
- id: 'config',
42
- text: `Agent=${agentStr} Git=${config.git ? 'ON' : 'OFF'} Test=${config.test ? 'ON' : 'OFF'}`,
43
- },
44
- ];
45
- return lines.map(line => ({
46
- id: line.id,
47
- text: centerLine(line.text, width - 50),
48
- }));
49
- };
50
- // Generate ASCII art banner once
51
- const bannerText = figlet.textSync('GALAXY', {
52
- font: 'Standard',
53
- horizontalLayout: 'default',
54
- verticalLayout: 'default',
55
- });
56
- export default function App({ config }) {
57
- const { exit } = useApp();
58
- const [input, setInput] = useState('');
59
- const [messages, setMessages] = useState([
60
- { id: 'banner' },
61
- // Show config error as system message if exists
62
- ...(config.error
63
- ? [
64
- {
65
- id: 'config-error',
66
- author: 'system',
67
- content: `⚠️ ${config.error}`,
68
- timestamp: Date.now(),
69
- },
70
- ]
71
- : []),
72
- ]);
73
- const [isProcessing, setIsProcessing] = useState(false);
74
- const [commandSuggestions, setCommandSuggestions] = useState([]);
75
- const [planning, setPlanning] = useState([]);
76
- const [inputHistory, setInputHistory] = useState([]);
77
- const [historyIndex, setHistoryIndex] = useState(-1);
78
- const [suggestionIndex, setSuggestionIndex] = useState(0);
79
- const [currentConfig, setCurrentConfig] = useState(config);
80
- const infoLines = getInforLines(currentConfig);
81
- // Initialize agent connection based on config
82
- const agentConnection = useMemo(() => {
83
- // Manual mode = Use Ollama with specific config
84
- if (currentConfig.model === 'manual') {
85
- // Find manual agent config to get apiKey
86
- const manualAgentConfig = currentConfig.agent.find(value => value.type === 'manual');
87
- return new OllamaAgent({
88
- type: 'ollama',
89
- model: 'qwen3-coder:480b-cloud',
90
- host: 'https://ollama.com',
91
- apiKey: manualAgentConfig?.apiKey,
92
- });
93
- }
94
- // Find agent config by model type
95
- const agentConfig = currentConfig.agent.find(value => value.type === currentConfig.model);
96
- if (!agentConfig) {
97
- return null;
98
- }
99
- // Direct agent mode (claude, gemini, ollama)
100
- switch (currentConfig.model) {
101
- case 'claude':
102
- return new ClaudeAgent(agentConfig);
103
- case 'ollama':
104
- return new OllamaAgent(agentConfig);
105
- case 'gemini':
106
- return new GeminiAgent(agentConfig);
107
- default:
108
- return null;
109
- }
110
- }, [currentConfig.model, currentConfig.agent]);
111
- const commandCatalog = useMemo(() => [
112
- { command: '/help', description: 'Hiển thị danh sách lệnh' },
113
- { command: '/exit', description: 'Thoát khỏi Galaxy CLI' },
114
- { command: '/clear', description: 'Xóa lịch sử hội thoại hiện tại' },
115
- { command: '/history', description: 'Xem danh sách 10 input gần nhất' },
116
- { command: '/pwd', description: 'Hiển thị thư mục làm việc hiện tại' },
117
- { command: '/information', description: 'Hiển thị thông tin hệ thống' },
118
- {
119
- command: '/git',
120
- description: 'Bật/tắt git operations (/git true|false)',
121
- },
122
- {
123
- command: '/test',
124
- description: 'Bật/tắt test planning (/test true|false)',
125
- },
126
- {
127
- command: '/mode',
128
- description: 'Chọn agent mode (/mode claude|gemini|ollama|manual)',
129
- },
130
- { command: '/config', description: 'Mở thư mục chứa file cấu hình' },
131
- ], []);
132
- // Subscribe to tool execution events
133
- useEffect(() => {
134
- const unsubscribe = toolEventEmitter.onToolExecution((event) => {
135
- // Handle plan_task - Create planning list
136
- if (event.toolName === 'plan_task' &&
137
- event.status === 'success' &&
138
- event.toolInfo?.result) {
139
- try {
140
- const plan = event.toolInfo.result;
141
- if (plan.steps && Array.isArray(plan.steps)) {
142
- const planningItems = plan.steps.map((step, index) => ({
143
- step: step.step,
144
- action: step.action,
145
- featureName: step.featureName || '',
146
- featureDescription: step.featureDescription || '',
147
- priority: step.priority || '',
148
- reasoning: step.reasoning || '',
149
- status: index === 0 ? 'in-progress' : 'pending',
150
- }));
151
- setPlanning(planningItems);
152
- }
153
- }
154
- catch (error) { }
155
- }
156
- // Handle progress_reporter - Update planning status
157
- if (event.toolName === 'progress_reporter') {
158
- try {
159
- const progressData = JSON.parse(event.content);
160
- const stepNumber = progressData.step;
161
- const status = progressData.status; // 'success' | 'error' | 'in_progress'
162
- // Map progress_reporter status to PlanningItem status
163
- const mappedStatus = status === 'success'
164
- ? 'completed'
165
- : status === 'error'
166
- ? 'failed'
167
- : 'in-progress';
168
- // Update planning state
169
- setPlanning(prev => {
170
- return prev.map(item => {
171
- // Update current step status
172
- if (item.step === stepNumber) {
173
- return {
174
- ...item,
175
- status: mappedStatus,
176
- };
177
- }
178
- // If current step succeeded, mark next step as in-progress
179
- if (status === 'success' &&
180
- item.step === stepNumber + 1 &&
181
- item.status === 'pending') {
182
- return {
183
- ...item,
184
- status: 'in-progress',
185
- };
186
- }
187
- return item;
188
- });
189
- });
190
- }
191
- catch (error) { }
192
- }
193
- // Add tool execution message to conversation
194
- const message = {
195
- id: `tool-${Date.now()}-${Math.random()}`,
196
- author: 'tool',
197
- toolName: event.toolName,
198
- content: event.content,
199
- toolInfo: event.toolInfo,
200
- timestamp: event.timestamp,
201
- };
202
- setMessages(prev => [...prev, message]);
203
- });
204
- // Cleanup subscription on unmount
205
- return () => {
206
- unsubscribe();
207
- };
208
- }, []);
209
- const handleCommand = (raw) => {
210
- const [cmd, ...args] = raw.slice(1).split(/\s+/);
211
- switch (cmd) {
212
- case 'exit':
213
- appendMessage('system', 'Goodbye!');
214
- exit();
215
- return;
216
- case 'help':
217
- appendMessage('system', [
218
- 'Danh sách lệnh:',
219
- ...commandCatalog.map(cmd => `${cmd.command.padEnd(15, ' ')} ${cmd.description}`),
220
- ].join('\n'));
221
- return;
222
- case 'clear':
223
- setMessages([{ id: 'banner' }]);
224
- setPlanning([]);
225
- // Clear agent conversation history
226
- if (agentConnection) {
227
- if ('clearHistory' in agentConnection) {
228
- agentConnection.clearHistory();
229
- }
230
- }
231
- appendMessage('system', '✅ Cleared conversation and progress');
232
- return;
233
- case 'history':
234
- if (inputHistory.length === 0) {
235
- appendMessage('system', 'No history yet.');
236
- return;
237
- }
238
- {
239
- const recent = [...inputHistory].slice(-10).reverse();
240
- const lines = recent.map((item, idx) => `${idx + 1}. ${item.replace(/\n/g, ' ')}`);
241
- appendMessage('system', ['Recent inputs:', ...lines].join('\n'));
242
- }
243
- return;
244
- case 'pwd':
245
- appendMessage('system', `Working directory: ${process.cwd()}`);
246
- return;
247
- case 'information':
248
- {
249
- const agentStr = currentConfig.model;
250
- appendMessage('system', [
251
- '📊 System Information:',
252
- `Name: Galaxy CLI`,
253
- `Version: ${cliVersion}`,
254
- `Current Project: ${process.cwd()}`,
255
- `Agent Mode: ${agentStr}`,
256
- `Git Operations: ${currentConfig.git ? 'ON' : 'OFF'}`,
257
- `Testing: ${currentConfig.test ? 'ON' : 'OFF'}`,
258
- ].join('\n'));
259
- }
260
- return;
261
- case 'mode':
262
- {
263
- // No arguments - show current mode
264
- if (args.length === 0) {
265
- const agentStr = currentConfig.model;
266
- if (currentConfig.model === 'manual') {
267
- appendMessage('system', `🤖 Agent Mode: ${agentStr}\n\nUsing Orchestrator Agent with full tool access.`);
268
- }
269
- else {
270
- appendMessage('system', `🤖 Agent Mode: ${agentStr}\n\nDirect chat mode - no tools available.`);
271
- }
272
- return;
273
- }
274
- // Has arguments - switch agent mode
275
- const newMode = args[0]?.toLowerCase() ?? '';
276
- const validModes = ['claude', 'gemini', 'ollama', 'manual'];
277
- // Type guard function
278
- const isValidMode = (mode) => {
279
- return validModes.includes(mode);
280
- };
281
- if (!isValidMode(newMode)) {
282
- appendMessage('system', `❌ Invalid mode: ${newMode}\nValid modes: ${validModes.join(', ')}`);
283
- return;
284
- }
285
- // Check if agent config exists (newMode is now ValidMode type)
286
- const agentConfig = currentConfig.agent.find(value => value.type === newMode);
287
- if (!agentConfig) {
288
- appendMessage('system', `❌ Agent config for "${newMode}" not found in config file.\nPlease add it using /config command.`);
289
- return;
290
- }
291
- // Switch to new mode
292
- setCurrentConfig(prev => ({ ...prev, model: newMode }));
293
- // Clear conversation when switching agents
294
- setMessages([{ id: 'banner' }]);
295
- setPlanning([]);
296
- appendMessage('system', `✅ Switched to ${newMode} mode\n🔄 Conversation cleared`);
297
- }
298
- return;
299
- case 'git':
300
- if (args.length === 0) {
301
- appendMessage('system', `Git operations are currently ${currentConfig.git ? 'ON' : 'OFF'}`);
302
- return;
303
- }
304
- {
305
- const value = args[0]?.toLowerCase() ?? '';
306
- if (value === 'true' || value === 'on') {
307
- setCurrentConfig(prev => ({ ...prev, git: true }));
308
- appendMessage('system', '✅ Git operations enabled');
309
- }
310
- else if (value === 'false' || value === 'off') {
311
- setCurrentConfig(prev => ({ ...prev, git: false }));
312
- appendMessage('system', '❌ Git operations disabled');
313
- }
314
- else {
315
- appendMessage('system', 'Usage: /git true|false');
316
- }
317
- }
318
- return;
319
- case 'test':
320
- if (args.length === 0) {
321
- appendMessage('system', `Testing is currently ${currentConfig.test ? 'ON' : 'OFF'}`);
322
- return;
323
- }
324
- {
325
- const value = args[0]?.toLowerCase() ?? '';
326
- if (value === 'true' || value === 'on') {
327
- setCurrentConfig(prev => ({ ...prev, test: true }));
328
- appendMessage('system', '✅ Test planning enabled');
329
- }
330
- else if (value === 'false' || value === 'off') {
331
- setCurrentConfig(prev => ({ ...prev, test: false }));
332
- appendMessage('system', '❌ Test planning disabled');
333
- }
334
- else {
335
- appendMessage('system', 'Usage: /test true|false');
336
- }
337
- }
338
- return;
339
- case 'config':
340
- {
341
- const configPath = configManager.getConfigFilePath();
342
- configManager.openConfigFolder();
343
- appendMessage('system', `📂 Config directory opened\n📄 Config file: ${configPath}`);
344
- }
345
- return;
346
- default:
347
- appendMessage('system', `Unknown command: /${cmd}${args.length ? ' ' + args.join(' ') : ''}`);
348
- }
349
- };
350
- const handleSubmit = async (value) => {
351
- if (isProcessing)
352
- return;
353
- const trimmed = value.trim();
354
- if (!trimmed)
355
- return;
356
- if (trimmed.startsWith('/')) {
357
- setInput('');
358
- handleCommand(trimmed);
359
- return;
360
- }
361
- appendMessage('user', trimmed);
362
- setIsProcessing(true);
363
- setInput('');
364
- setInputHistory(prev => [...prev, trimmed]);
365
- setHistoryIndex(-1);
366
- try {
367
- let responseContent = '';
368
- // Route based on agent type
369
- // if (currentConfig.model === 'manual') {
370
- // // Use orchestrator with tools
371
- // const response = await orchestratorAgent.handleUserInput(
372
- // trimmed,
373
- // {
374
- // gitEnabled: currentConfig.git,
375
- // testEnabled: currentConfig.test,
376
- // },
377
- // appendMessage,
378
- // );
379
- // responseContent = response.content;
380
- // } else {
381
- // Direct chat with specific agent (no tools)
382
- if (!agentConnection) {
383
- throw new Error('Agent connection not initialized');
384
- }
385
- const response = await agentConnection.handleUserInput(trimmed, {
386
- gitEnabled: currentConfig.git,
387
- testEnabled: currentConfig.test,
388
- }, appendMessage);
389
- responseContent = response.content;
390
- // }
391
- if (responseContent) {
392
- // Only parse step completion in manual mode
393
- // if (currentConfig.model === 'manual') {
394
- // parseStepCompletion(responseContent);
395
- // }
396
- appendMessage('assistant', responseContent);
397
- }
398
- }
399
- catch (error) {
400
- appendMessage('system', `❌ Error: ${error instanceof Error ? error.message : String(error)}`);
401
- }
402
- finally {
403
- setIsProcessing(false);
404
- }
405
- };
406
- // const parseStepCompletion = (content: string) => {
407
- // const jsonMatch = content.match(
408
- // /\{step:\s*(\d+),\s*status:\s*['"]completed['"]\}/,
409
- // );
410
- // if (jsonMatch) {
411
- // const stepNum = parseInt(jsonMatch[1] || '0', 10);
412
- // updateStepStatus(stepNum, 'completed');
413
- // return;
414
- // }
415
- // const checkboxMatch = content.match(/☒\s*Step\s+(\d+):/);
416
- // if (checkboxMatch) {
417
- // const stepNum = parseInt(checkboxMatch[1] || '0', 10);
418
- // updateStepStatus(stepNum, 'completed');
419
- // return;
420
- // }
421
- // const completedMatch = content.match(/Step\s+(\d+):.*?[✅✓]\s*Completed/i);
422
- // if (completedMatch) {
423
- // const stepNum = parseInt(completedMatch[1] || '0', 10);
424
- // updateStepStatus(stepNum, 'completed');
425
- // }
426
- // };
427
- // const updateStepStatus = (stepNum: number, status: 'completed') => {
428
- // setPlanning(prev => {
429
- // const updated: PlanningItem[] = prev.map(item => {
430
- // if (item.step === stepNum) {
431
- // return {...item, status: 'completed' as const};
432
- // }
433
- // if (item.step === stepNum + 1 && item.status === 'pending') {
434
- // return {...item, status: 'in-progress' as const};
435
- // }
436
- // return item;
437
- // });
438
- // // Update progress tracker
439
- // return updated;
440
- // });
441
- // };
442
- useInput((inputKey, key) => {
443
- if (key.ctrl && inputKey === 'c') {
444
- exit();
445
- }
446
- if (commandSuggestions.length > 0 && input.startsWith('/')) {
447
- if (key.upArrow || (key.shift && key.tab)) {
448
- setSuggestionIndex(prev => (prev - 1 + commandSuggestions.length) % commandSuggestions.length);
449
- }
450
- else if (key.downArrow || key.tab) {
451
- setSuggestionIndex(prev => (prev + 1) % commandSuggestions.length);
452
- }
453
- else if (key.escape || key.return) {
454
- setCommandSuggestions([]);
455
- setSuggestionIndex(0);
456
- }
457
- return;
458
- }
459
- if (inputHistory.length > 0 && !input.startsWith('/')) {
460
- if (key.upArrow) {
461
- const newIndex = historyIndex === -1
462
- ? inputHistory.length - 1
463
- : Math.max(0, historyIndex - 1);
464
- setHistoryIndex(newIndex);
465
- setInput(inputHistory[newIndex] || '');
466
- }
467
- else if (key.downArrow) {
468
- if (historyIndex === -1)
469
- return;
470
- const newIndex = historyIndex + 1;
471
- if (newIndex >= inputHistory.length) {
472
- setHistoryIndex(-1);
473
- setInput('');
474
- }
475
- else {
476
- setHistoryIndex(newIndex);
477
- setInput(inputHistory[newIndex] || '');
478
- }
479
- }
480
- }
481
- });
482
- const appendMessage = (author, text, toolName, toolInfo) => {
483
- const message = {
484
- id: `${Date.now()}-${author}-${Math.random().toString(16).slice(2)}`,
485
- author,
486
- content: text,
487
- toolName,
488
- toolInfo,
489
- timestamp: Date.now(),
490
- };
491
- if (author === 'tool' && toolName === 'plan_task') {
492
- const planningItems = text.map((item, index) => ({
493
- ...item,
494
- status: (index === 0
495
- ? 'in-progress'
496
- : 'pending'),
497
- }));
498
- setPlanning(planningItems);
499
- // Initialize progress tracker (only in manual mode)
500
- if (currentConfig.model === 'manual') {
501
- }
502
- }
503
- else {
504
- setMessages(prev => [...prev, message]);
505
- }
506
- };
507
- const currentStep = planning.find(p => p.status === 'in-progress');
508
- return (React.createElement(React.Fragment, null,
509
- React.createElement(Static, { items: messages }, msg => {
510
- if (msg.author === 'user') {
511
- return (React.createElement(Box, { key: msg.id, flexDirection: "row", marginTop: 1 },
512
- React.createElement(Text, { color: "red" }, `> ${msg.content}`)));
513
- }
514
- if (msg.author === 'assistant') {
515
- return (React.createElement(Box, { key: msg.id, flexDirection: "column", marginTop: 1, borderStyle: "round", borderColor: "blue", paddingX: 1, paddingY: 0 },
516
- React.createElement(Text, null, msg.content)));
517
- }
518
- if (msg.author === 'tool') {
519
- return (React.createElement(Box, { key: msg.id, flexDirection: "row", marginTop: 1 }, formatMessage(msg.content || '', msg.toolName, msg.toolInfo)));
520
- }
521
- if (msg.author === 'system') {
522
- return (React.createElement(Box, { key: msg.id, flexDirection: "row", marginTop: 1 },
523
- React.createElement(Text, { color: "gray" }, `⚙ ${msg.content}`)));
524
- }
525
- return (React.createElement(Box, { borderColor: "cyan", borderStyle: "round", flexDirection: "row", key: 'banner-box', width: process.stdout.columns },
526
- React.createElement(Box, { flexDirection: "column" },
527
- React.createElement(Text, { color: "cyan" }, bannerText)),
528
- React.createElement(Box, { borderLeft: true, borderLeftColor: "cyan", flexDirection: "column", marginLeft: 2, marginTop: 1 }, infoLines.map(line => (React.createElement(Text, { key: line.id, dimColor: true }, line.text))))));
529
- }),
530
- currentConfig.model === 'manual' && planning.length > 0 && (React.createElement(Box, { flexDirection: "column", paddingTop: 1, paddingBottom: 1 },
531
- currentStep && (React.createElement(Box, { marginBottom: 1 },
532
- React.createElement(Text, { bold: true, color: "cyan" },
533
- "\u26A1 ",
534
- currentStep.action))),
535
- planning.map(item => {
536
- const checkbox = item.status === 'completed'
537
- ? '☑'
538
- : item.status === 'in-progress'
539
- ? '⚙'
540
- : item.status === 'failed'
541
- ? '❌'
542
- : '☐';
543
- const color = item.status === 'completed'
544
- ? 'green'
545
- : item.status === 'in-progress'
546
- ? 'cyan'
547
- : item.status === 'failed'
548
- ? 'red'
549
- : 'gray';
550
- return (React.createElement(Box, { key: item.step },
551
- React.createElement(Text, { color: color },
552
- checkbox,
553
- " Step ",
554
- item.step,
555
- ": ",
556
- item.action)));
557
- }))),
558
- React.createElement(Box, { flexDirection: "row", paddingTop: 1, width: process.stdout.columns }, isProcessing ? (React.createElement(Text, null,
559
- React.createElement(Text, { color: "cyan" },
560
- React.createElement(Spinner, { type: "dots" })),
561
- ' Thinking...')) : null),
562
- React.createElement(Box, { borderColor: "green", borderStyle: "round", flexDirection: "column", marginTop: 1 },
563
- React.createElement(Box, { alignItems: "center", flexDirection: "row" },
564
- React.createElement(Text, { color: "green" }, "> "),
565
- React.createElement(TextInput, { value: input, showCursor: !isProcessing, onChange: isProcessing
566
- ? () => { }
567
- : value => {
568
- setInput(value);
569
- if (value.startsWith('/')) {
570
- const partial = value.toLowerCase();
571
- const matches = commandCatalog.filter(cmd => cmd.command.toLowerCase().startsWith(partial));
572
- setCommandSuggestions(matches);
573
- setSuggestionIndex(0);
574
- }
575
- else {
576
- setCommandSuggestions([]);
577
- setSuggestionIndex(0);
578
- }
579
- }, onSubmit: isProcessing
580
- ? () => { }
581
- : rawValue => {
582
- const trimmed = rawValue.trim();
583
- if (trimmed.startsWith('/') &&
584
- commandSuggestions.length > 0) {
585
- const selected = commandSuggestions[suggestionIndex] ??
586
- commandSuggestions[0];
587
- handleSubmit(selected?.command || '');
588
- return;
589
- }
590
- handleSubmit(rawValue);
591
- }, placeholder: isProcessing
592
- ? 'Processing... (input disabled)'
593
- : 'Type and press Enter to send' }))),
594
- commandSuggestions.length > 0 && (React.createElement(Box, { flexDirection: "column", marginTop: 1, borderStyle: "round", borderColor: "gray" }, commandSuggestions.map((cmd, idx) => (React.createElement(Box, { key: cmd.command, paddingX: 1, paddingY: 0, flexDirection: "row" },
595
- React.createElement(Text, { color: idx === suggestionIndex ? 'cyan' : undefined }, cmd.command.padEnd(15, ' ')),
596
- React.createElement(Text, { dimColor: true }, cmd.description))))))));
597
- }
@@ -1,21 +0,0 @@
1
- export interface UpdateResult {
2
- success: boolean;
3
- error?: string;
4
- needsRestart?: boolean;
5
- }
6
- /**
7
- * Thực hiện update bằng npm install
8
- */
9
- export declare function performUpdate(version: string): Promise<UpdateResult>;
10
- /**
11
- * Restart CLI với arguments hiện tại
12
- */
13
- export declare function restartCLI(): void;
14
- /**
15
- * Hiển thị thông báo update thành công
16
- */
17
- export declare function showUpdateSuccess(version: string): void;
18
- /**
19
- * Hiển thị thông báo update failed
20
- */
21
- export declare function showUpdateError(error: string): void;