galaxy-code 0.1.2 → 0.1.5

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 (74) hide show
  1. package/dist/app.d.ts +1 -1
  2. package/dist/app.js +5 -5
  3. package/dist/cli.js +4 -4
  4. package/dist/connections/claude.d.ts +71 -0
  5. package/dist/connections/claude.js +303 -0
  6. package/dist/connections/gemini.d.ts +40 -0
  7. package/dist/connections/gemini.js +232 -0
  8. package/dist/connections/index.d.ts +11 -0
  9. package/dist/connections/index.js +11 -0
  10. package/dist/connections/ollama.d.ts +37 -0
  11. package/dist/connections/ollama.js +73 -0
  12. package/dist/connections/types.d.ts +22 -0
  13. package/dist/connections/types.js +7 -0
  14. package/dist/node_modules/@workspace/agent-core/providers/agent-selector.d.ts.map +1 -1
  15. package/dist/node_modules/@workspace/agent-core/providers/agent-selector.js +18 -18
  16. package/dist/node_modules/@workspace/agent-core/providers/agent-selector.js.map +1 -1
  17. package/dist/prompts/ba-it-analyzer.d.ts +1 -0
  18. package/dist/prompts/ba-it-analyzer.js +143 -0
  19. package/dist/prompts/index.d.ts +11 -0
  20. package/dist/prompts/index.js +11 -0
  21. package/dist/prompts/orchestrator.d.ts +8 -0
  22. package/dist/prompts/orchestrator.js +88 -0
  23. package/dist/prompts/planning-agent.d.ts +8 -0
  24. package/dist/prompts/planning-agent.js +195 -0
  25. package/dist/prompts/universal-agent.d.ts +7 -0
  26. package/dist/prompts/universal-agent.js +111 -0
  27. package/dist/providers/agent-selector.d.ts +29 -0
  28. package/dist/providers/agent-selector.js +84 -0
  29. package/dist/providers/claude-agent.d.ts +29 -0
  30. package/dist/providers/claude-agent.js +121 -0
  31. package/dist/providers/gemini-agent.d.ts +36 -0
  32. package/dist/providers/gemini-agent.js +168 -0
  33. package/dist/providers/index.d.ts +12 -0
  34. package/dist/providers/index.js +12 -0
  35. package/dist/providers/ollama-agent.d.ts +53 -0
  36. package/dist/providers/ollama-agent.js +276 -0
  37. package/dist/providers/orchestrator.d.ts +16 -0
  38. package/dist/providers/orchestrator.js +76 -0
  39. package/dist/tools/ba-it-analyzer.d.ts +66 -0
  40. package/dist/tools/ba-it-analyzer.js +90 -0
  41. package/dist/tools/code-generate-agent.d.ts +51 -0
  42. package/dist/tools/code-generate-agent.js +159 -0
  43. package/dist/tools/command-runner.d.ts +14 -0
  44. package/dist/tools/command-runner.js +120 -0
  45. package/dist/tools/document-parser.d.ts +11 -0
  46. package/dist/tools/document-parser.js +83 -0
  47. package/dist/tools/file-operations.d.ts +17 -0
  48. package/dist/tools/file-operations.js +127 -0
  49. package/dist/tools/galaxy-ui-integration.d.ts +94 -0
  50. package/dist/tools/galaxy-ui-integration.js +244 -0
  51. package/dist/tools/git-operations.d.ts +11 -0
  52. package/dist/tools/git-operations.js +114 -0
  53. package/dist/tools/index.d.ts +10 -0
  54. package/dist/tools/index.js +10 -0
  55. package/dist/tools/planning-agent.d.ts +29 -0
  56. package/dist/tools/planning-agent.js +134 -0
  57. package/dist/tools/progress-reporter.d.ts +19 -0
  58. package/dist/tools/progress-reporter.js +52 -0
  59. package/dist/tools/registry.d.ts +21 -0
  60. package/dist/tools/registry.js +695 -0
  61. package/dist/tools/tool-event-emitter.d.ts +24 -0
  62. package/dist/tools/tool-event-emitter.js +25 -0
  63. package/dist/tools/types.d.ts +31 -0
  64. package/dist/tools/types.js +1 -0
  65. package/dist/types.d.ts +1 -1
  66. package/dist/utils/config-manager.d.ts +102 -0
  67. package/dist/utils/config-manager.js +326 -0
  68. package/dist/utils/devtools.d.ts +21 -0
  69. package/dist/utils/devtools.js +61 -0
  70. package/dist/utils/message-formatters.d.ts +32 -0
  71. package/dist/utils/message-formatters.js +590 -0
  72. package/dist/utils/progress-tracker.d.ts +59 -0
  73. package/dist/utils/progress-tracker.js +213 -0
  74. package/package.json +3 -2
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Tool Event Emitter
3
+ * Central event system for tool execution tracking
4
+ */
5
+ import { EventEmitter } from 'events';
6
+ export interface ToolExecutionEvent {
7
+ toolName: string;
8
+ content: string;
9
+ timestamp?: number;
10
+ status?: 'start' | 'success' | 'error';
11
+ error?: string;
12
+ toolInfo?: {
13
+ toolName: string;
14
+ args?: any;
15
+ result?: any;
16
+ };
17
+ }
18
+ declare class ToolEventEmitter extends EventEmitter {
19
+ constructor();
20
+ emitToolExecution(event: ToolExecutionEvent): void;
21
+ onToolExecution(callback: (event: ToolExecutionEvent) => void): () => void;
22
+ }
23
+ export declare const toolEventEmitter: ToolEventEmitter;
24
+ export {};
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Tool Event Emitter
3
+ * Central event system for tool execution tracking
4
+ */
5
+ import { EventEmitter } from 'events';
6
+ class ToolEventEmitter extends EventEmitter {
7
+ constructor() {
8
+ super();
9
+ this.setMaxListeners(100); // Increase for multiple listeners
10
+ }
11
+ emitToolExecution(event) {
12
+ const enrichedEvent = {
13
+ ...event,
14
+ timestamp: Date.now(),
15
+ };
16
+ this.emit('tool-execution', enrichedEvent);
17
+ }
18
+ onToolExecution(callback) {
19
+ this.on('tool-execution', callback);
20
+ // Return unsubscribe function
21
+ return () => this.off('tool-execution', callback);
22
+ }
23
+ }
24
+ // Singleton instance
25
+ export const toolEventEmitter = new ToolEventEmitter();
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @author Bùi Trọng Hiếu
3
+ * @email kevinbui210191@gmail.com
4
+ * @create 2024-10-08
5
+ * @modify 2024-10-08
6
+ * @desc Shared typing for MCP-style tools.
7
+ */
8
+ export type ToolInputSchema = {
9
+ readonly type: 'object';
10
+ readonly properties: Record<string, {
11
+ readonly type: 'string' | 'number' | 'boolean' | 'array' | 'object';
12
+ readonly description?: string;
13
+ readonly default?: string | boolean | number | Array<any> | object;
14
+ readonly items?: {
15
+ readonly type?: 'string' | 'number' | 'boolean' | 'object';
16
+ readonly properties?: Record<string, any>;
17
+ };
18
+ }>;
19
+ readonly required?: readonly string[];
20
+ };
21
+ export type ToolExecutionContext = {
22
+ readonly abortSignal?: AbortSignal;
23
+ };
24
+ export type Tool<Input, Output> = {
25
+ readonly name: string;
26
+ readonly description: string;
27
+ readonly inputSchema: ToolInputSchema;
28
+ readonly execute: (input: Input, context: ToolExecutionContext) => Promise<Output>;
29
+ };
30
+ export type InferToolInput<T extends Tool<unknown, unknown>> = T extends Tool<infer Input, unknown> ? Input : never;
31
+ export type InferToolOutput<T extends Tool<unknown, unknown>> = T extends Tool<unknown, infer Output> ? Output : never;
@@ -0,0 +1 @@
1
+ export {};
package/dist/types.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  * @modify 2025-10-21
6
6
  * @desc Type definitions for Galaxy Code
7
7
  */
8
- import type { ToolExecutionInfo } from '@workspace/agent-core';
8
+ import { ToolExecutionInfo } from './connections/types.js';
9
9
  export type MessageAuthor = 'user' | 'assistant' | 'system' | 'tool' | 'plan';
10
10
  export interface ConversationMessage {
11
11
  id: string;
@@ -0,0 +1,102 @@
1
+ export type AgentType = 'claude' | 'gemini' | 'ollama' | 'manual';
2
+ export interface AgentConfig {
3
+ model?: string;
4
+ type: AgentType;
5
+ apiKey?: string;
6
+ host?: string;
7
+ }
8
+ export interface AutoUpdateConfig {
9
+ enabled: boolean;
10
+ checkOnStartup: boolean;
11
+ silent: boolean;
12
+ maxAttempts: number;
13
+ timeout: number;
14
+ skipVersions: string[];
15
+ lastChecked: number | null;
16
+ lastAttemptedVersion: string | null;
17
+ }
18
+ export interface GalaxyConfig {
19
+ agent: AgentConfig[];
20
+ git: boolean;
21
+ test: boolean;
22
+ autoUpdate: AutoUpdateConfig;
23
+ }
24
+ export interface CLIFlags {
25
+ git?: boolean;
26
+ test?: boolean;
27
+ }
28
+ export interface MergedConfig {
29
+ model: AgentType;
30
+ git: boolean;
31
+ test: boolean;
32
+ agent: AgentConfig[];
33
+ error?: string;
34
+ }
35
+ export declare class ConfigManager {
36
+ private configPath;
37
+ private config;
38
+ constructor();
39
+ /**
40
+ * Get config directory path based on OS
41
+ */
42
+ private getConfigDir;
43
+ /**
44
+ * Get full config file path
45
+ */
46
+ private getConfigPath;
47
+ /**
48
+ * Get default configuration
49
+ */
50
+ private getDefaultConfig;
51
+ /**
52
+ * Load configuration from file or create default
53
+ */
54
+ private loadConfig;
55
+ /**
56
+ * Validate and merge config with defaults
57
+ */
58
+ private validateConfig;
59
+ /**
60
+ * Create default config file
61
+ */
62
+ private createDefaultConfig;
63
+ /**
64
+ * Save current config to file
65
+ */
66
+ saveConfig(): void;
67
+ /**
68
+ * Get merged config with CLI flags priority
69
+ * Priority: CLI flags > config.json > defaults
70
+ * Returns: { model: AgentType, git: boolean, test: boolean }
71
+ */
72
+ getMergedConfig(cliFlags?: CLIFlags): MergedConfig;
73
+ /**
74
+ * Validate agent configuration
75
+ */
76
+ private validateAgent;
77
+ /**
78
+ * Update config values
79
+ */
80
+ updateConfig(updates: Partial<GalaxyConfig>): void;
81
+ /**
82
+ * Get current config
83
+ */
84
+ getConfig(): GalaxyConfig;
85
+ /**
86
+ * Get config file path
87
+ */
88
+ getConfigFilePath(): string;
89
+ /**
90
+ * Reset config to defaults
91
+ */
92
+ resetConfig(): void;
93
+ /**
94
+ * Open config folder in file explorer
95
+ */
96
+ openConfigFolder(): void;
97
+ /**
98
+ * Display current config and open config folder
99
+ */
100
+ displayConfig(): void;
101
+ }
102
+ export declare const configManager: ConfigManager;
@@ -0,0 +1,326 @@
1
+ /**
2
+ * @author Bùi Trọng Hiếu
3
+ * @email kevinbui210191@gmail.com
4
+ * @create 2024-10-13
5
+ * @desc Configuration manager for Galaxy CLI
6
+ */
7
+ import fs from 'node:fs';
8
+ import path from 'node:path';
9
+ import os from 'node:os';
10
+ import { execSync } from 'node:child_process';
11
+ export class ConfigManager {
12
+ constructor() {
13
+ Object.defineProperty(this, "configPath", {
14
+ enumerable: true,
15
+ configurable: true,
16
+ writable: true,
17
+ value: void 0
18
+ });
19
+ Object.defineProperty(this, "config", {
20
+ enumerable: true,
21
+ configurable: true,
22
+ writable: true,
23
+ value: void 0
24
+ });
25
+ this.configPath = this.getConfigPath();
26
+ this.config = this.loadConfig();
27
+ }
28
+ /**
29
+ * Get config directory path based on OS
30
+ */
31
+ getConfigDir() {
32
+ const homeDir = os.homedir();
33
+ const platform = os.platform();
34
+ switch (platform) {
35
+ case 'darwin': // macOS
36
+ case 'linux':
37
+ return path.join(homeDir, '.galaxy');
38
+ case 'win32': // Windows
39
+ return path.join(homeDir, 'AppData', 'Local', 'Galaxy');
40
+ default:
41
+ return path.join(homeDir, '.galaxy');
42
+ }
43
+ }
44
+ /**
45
+ * Get full config file path
46
+ */
47
+ getConfigPath() {
48
+ return path.join(this.getConfigDir(), 'config.json');
49
+ }
50
+ /**
51
+ * Get default configuration
52
+ */
53
+ getDefaultConfig() {
54
+ return {
55
+ agent: [
56
+ {
57
+ type: 'manual',
58
+ },
59
+ ],
60
+ git: true,
61
+ test: true,
62
+ autoUpdate: {
63
+ enabled: true,
64
+ checkOnStartup: true,
65
+ silent: false,
66
+ maxAttempts: 3,
67
+ timeout: 3000,
68
+ skipVersions: [],
69
+ lastChecked: null,
70
+ lastAttemptedVersion: null,
71
+ },
72
+ };
73
+ }
74
+ /**
75
+ * Load configuration from file or create default
76
+ */
77
+ loadConfig() {
78
+ try {
79
+ // Check if config file exists
80
+ if (!fs.existsSync(this.configPath)) {
81
+ console.log('📝 Creating default config at:', this.configPath);
82
+ return this.createDefaultConfig();
83
+ }
84
+ // Read and parse config file
85
+ const configData = fs.readFileSync(this.configPath, 'utf-8');
86
+ const config = JSON.parse(configData);
87
+ // Validate config structure
88
+ return this.validateConfig(config);
89
+ }
90
+ catch (error) {
91
+ console.warn('⚠️ Failed to load config, using defaults:', error instanceof Error ? error.message : String(error));
92
+ return this.getDefaultConfig();
93
+ }
94
+ }
95
+ /**
96
+ * Validate and merge config with defaults
97
+ */
98
+ validateConfig(config) {
99
+ const defaults = this.getDefaultConfig();
100
+ // Ensure agent is always an array
101
+ let agent = defaults.agent;
102
+ if (config.agent && Array.isArray(config.agent)) {
103
+ agent = config.agent;
104
+ }
105
+ // Merge autoUpdate config with defaults
106
+ const autoUpdate = {
107
+ ...defaults.autoUpdate,
108
+ ...(config.autoUpdate || {}),
109
+ };
110
+ return {
111
+ agent: agent,
112
+ git: config.git ?? defaults.git,
113
+ test: config.test ?? defaults.test,
114
+ autoUpdate,
115
+ };
116
+ }
117
+ /**
118
+ * Create default config file
119
+ */
120
+ createDefaultConfig() {
121
+ const config = this.getDefaultConfig();
122
+ try {
123
+ // Ensure config directory exists
124
+ const configDir = this.getConfigDir();
125
+ if (!fs.existsSync(configDir)) {
126
+ fs.mkdirSync(configDir, { recursive: true });
127
+ }
128
+ // Write default config
129
+ fs.writeFileSync(this.configPath, JSON.stringify(config, null, 2), 'utf-8');
130
+ console.log('✅ Created default config file');
131
+ console.log('📁 Location:', this.configPath);
132
+ console.log('');
133
+ console.log('You can customize settings by editing this file.');
134
+ console.log('');
135
+ }
136
+ catch (error) {
137
+ console.error('❌ Failed to create config file:', error instanceof Error ? error.message : String(error));
138
+ }
139
+ return config;
140
+ }
141
+ /**
142
+ * Save current config to file
143
+ */
144
+ saveConfig() {
145
+ try {
146
+ const configDir = this.getConfigDir();
147
+ if (!fs.existsSync(configDir)) {
148
+ fs.mkdirSync(configDir, { recursive: true });
149
+ }
150
+ fs.writeFileSync(this.configPath, JSON.stringify(this.config, null, 2), 'utf-8');
151
+ }
152
+ catch (error) {
153
+ console.error('❌ Failed to save config:', error instanceof Error ? error.message : String(error));
154
+ }
155
+ }
156
+ /**
157
+ * Get merged config with CLI flags priority
158
+ * Priority: CLI flags > config.json > defaults
159
+ * Returns: { model: AgentType, git: boolean, test: boolean }
160
+ */
161
+ getMergedConfig(cliFlags = {}) {
162
+ // Check if agent is array and not empty
163
+ if (!this.config.agent || !Array.isArray(this.config.agent) || this.config.agent.length === 0) {
164
+ return {
165
+ model: 'manual',
166
+ git: cliFlags.git ?? this.config.git,
167
+ test: cliFlags.test ?? this.config.test,
168
+ agent: [],
169
+ error: 'Hiện tại chưa có agent nào được cấu hình. Vui lòng gõ "galaxy --config" để xem file config và thêm agent.',
170
+ };
171
+ }
172
+ // Find manual agent first, otherwise get first agent
173
+ let primaryAgent = this.config.agent.find(a => a.type === 'manual') ?? this.config.agent[0];
174
+ // Check if primaryAgent is defined
175
+ if (!primaryAgent) {
176
+ return {
177
+ model: 'manual',
178
+ git: cliFlags.git ?? this.config.git,
179
+ test: cliFlags.test ?? this.config.test,
180
+ agent: this.config.agent,
181
+ error: 'Không tìm thấy agent hợp lệ. Vui lòng kiểm tra lại file cấu hình.',
182
+ };
183
+ }
184
+ // Validate agent configuration
185
+ const validation = this.validateAgent(primaryAgent);
186
+ if (validation.error) {
187
+ return {
188
+ model: primaryAgent.type,
189
+ git: cliFlags.git ?? this.config.git,
190
+ test: cliFlags.test ?? this.config.test,
191
+ agent: this.config.agent,
192
+ error: validation.error,
193
+ };
194
+ }
195
+ return {
196
+ model: primaryAgent.type,
197
+ git: cliFlags.git ?? this.config.git,
198
+ test: cliFlags.test ?? this.config.test,
199
+ agent: this.config.agent,
200
+ };
201
+ }
202
+ /**
203
+ * Validate agent configuration
204
+ */
205
+ validateAgent(agent) {
206
+ // Manual mode uses Ollama cloud, needs apiKey
207
+ if (agent.type === 'manual') {
208
+ if (!agent.apiKey) {
209
+ return {
210
+ valid: false,
211
+ error: `Mode Manual cần API Key. Vui lòng:\n1. Gõ /config để mở folder cấu hình\n2. Thêm "apiKey": "your-api-key" vào agent type "manual"\n3. Thoát CLI và vào lại để nhận API Key.`,
212
+ };
213
+ }
214
+ return { valid: true };
215
+ }
216
+ // Claude needs apiKey
217
+ if (agent.type === 'claude') {
218
+ if (!agent.apiKey) {
219
+ return {
220
+ valid: false,
221
+ error: `Hiện tại bạn chưa thêm apikey cho model ${agent.type}. Vui lòng:\n1. Gõ /config để mở folder cấu hình\n2. Thêm "apiKey": "your-api-key" vào agent type "claude"\n3. Thoát CLI và vào lại để nhận API Key.`,
222
+ };
223
+ }
224
+ }
225
+ // Gemini needs apiKey
226
+ if (agent.type === 'gemini') {
227
+ if (!agent.apiKey) {
228
+ return {
229
+ valid: false,
230
+ error: `Hiện tại bạn chưa thêm apikey cho model ${agent.type}. Vui lòng:\n1. Gõ /config để mở folder cấu hình\n2. Thêm "apiKey": "your-api-key" vào agent type "gemini"\n3. Thoát CLI và vào lại để nhận API Key.`,
231
+ };
232
+ }
233
+ }
234
+ // Ollama needs host and apiKey
235
+ if (agent.type === 'ollama') {
236
+ if (!agent.host) {
237
+ return {
238
+ valid: false,
239
+ error: `Hiện tại bạn chưa cài đặt host cho Ollama. Vui lòng gõ "galaxy --config" để xem file config và thêm host (ví dụ: "http://localhost:11434").`,
240
+ };
241
+ }
242
+ // Check if using cloud host
243
+ if ((agent.host === 'https://ollama.com' || agent.host.includes('ollama.com')) &&
244
+ !agent.apiKey) {
245
+ return {
246
+ valid: false,
247
+ error: `Hiện tại bạn chưa thêm apikey cho model ollama. Vui lòng:\n1. Gõ /config để mở folder cấu hình\n2. Thêm "apiKey": "your-api-key" vào agent type "ollama"\n3. Thoát CLI và vào lại để nhận API Key.`,
248
+ };
249
+ }
250
+ }
251
+ return { valid: true };
252
+ }
253
+ /**
254
+ * Update config values
255
+ */
256
+ updateConfig(updates) {
257
+ this.config = { ...this.config, ...updates };
258
+ this.saveConfig();
259
+ }
260
+ /**
261
+ * Get current config
262
+ */
263
+ getConfig() {
264
+ return { ...this.config };
265
+ }
266
+ /**
267
+ * Get config file path
268
+ */
269
+ getConfigFilePath() {
270
+ return this.configPath;
271
+ }
272
+ /**
273
+ * Reset config to defaults
274
+ */
275
+ resetConfig() {
276
+ this.config = this.getDefaultConfig();
277
+ this.saveConfig();
278
+ console.log('✅ Config reset to defaults');
279
+ }
280
+ /**
281
+ * Open config folder in file explorer
282
+ */
283
+ openConfigFolder() {
284
+ const configDir = path.dirname(this.configPath);
285
+ try {
286
+ const platform = os.platform();
287
+ if (platform === 'darwin') {
288
+ execSync(`open "${configDir}"`);
289
+ }
290
+ else if (platform === 'win32') {
291
+ execSync(`start "" "${configDir}"`);
292
+ }
293
+ else {
294
+ // Linux
295
+ execSync(`xdg-open "${configDir}"`);
296
+ }
297
+ console.log('✅ Opened config folder');
298
+ }
299
+ catch (error) {
300
+ console.log('❌ Could not open folder automatically. Please open it manually.');
301
+ }
302
+ }
303
+ /**
304
+ * Display current config and open config folder
305
+ */
306
+ displayConfig() {
307
+ console.log('');
308
+ console.log('📊 Current Galaxy Configuration:');
309
+ console.log('━'.repeat(50));
310
+ console.log('📁 Config file:', this.configPath);
311
+ console.log('');
312
+ console.log('Settings:');
313
+ console.log(' Agents:');
314
+ this.config.agent.forEach((agent, index) => {
315
+ console.log(` ${index + 1}. Type: ${agent.type}${agent.model ? ` | Model: ${agent.model}` : ''}`);
316
+ });
317
+ console.log(' Git:', this.config.git ? 'ON' : 'OFF');
318
+ console.log(' Test:', this.config.test ? 'ON' : 'OFF');
319
+ console.log('━'.repeat(50));
320
+ console.log('');
321
+ // Open config folder
322
+ this.openConfigFolder();
323
+ }
324
+ }
325
+ // Singleton instance
326
+ export const configManager = new ConfigManager();
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @author Bùi Trọng Hiếu
3
+ * @email kevinbui210191@gmail.com
4
+ * @create 2024-10-13
5
+ * @modify 2024-10-13
6
+ * @desc React DevTools integration for development
7
+ */
8
+ /**
9
+ * Initialize React DevTools connection for debugging
10
+ * Only runs in development mode
11
+ *
12
+ * Note: react-devtools-core requires browser globals that don't exist in Node.js
13
+ * This may not work reliably in terminal environments
14
+ */
15
+ export declare function initDevTools(): Promise<void>;
16
+ /**
17
+ * Display component for DevTools status
18
+ */
19
+ export declare function DevToolsStatus({ connected }: {
20
+ connected: boolean;
21
+ }): "🔧 DevTools Đã Kết Nối" | "⚠️ DevTools Chưa Kết Nối" | null;
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @author Bùi Trọng Hiếu
3
+ * @email kevinbui210191@gmail.com
4
+ * @create 2024-10-13
5
+ * @modify 2024-10-13
6
+ * @desc React DevTools integration for development
7
+ */
8
+ /**
9
+ * Initialize React DevTools connection for debugging
10
+ * Only runs in development mode
11
+ *
12
+ * Note: react-devtools-core requires browser globals that don't exist in Node.js
13
+ * This may not work reliably in terminal environments
14
+ */
15
+ export async function initDevTools() {
16
+ if (process.env['NODE_ENV'] !== 'development') {
17
+ return;
18
+ }
19
+ try {
20
+ // Polyfill browser globals for react-devtools-core
21
+ if (typeof globalThis.self === 'undefined') {
22
+ // @ts-ignore - Adding browser global to Node.js
23
+ globalThis.self = globalThis;
24
+ }
25
+ if (typeof globalThis.window === 'undefined') {
26
+ // @ts-ignore - Adding browser global to Node.js
27
+ globalThis.window = globalThis;
28
+ }
29
+ // Dynamic import to avoid bundling in production
30
+ // @ts-expect-error - react-devtools-core doesn't have type definitions
31
+ const devTools = await import('react-devtools-core');
32
+ const { connectToDevTools } = devTools;
33
+ connectToDevTools({
34
+ host: 'localhost',
35
+ port: 8097,
36
+ useHttps: false,
37
+ retryDelay: 1000,
38
+ });
39
+ console.log('✅ React DevTools: Đã kết nối tới localhost:8097');
40
+ }
41
+ catch (error) {
42
+ // Silently ignore DevTools errors - it's optional
43
+ // Users can still use the app without DevTools
44
+ const message = error instanceof Error ? error.message : String(error);
45
+ if (message.includes('Cannot find module')) {
46
+ console.log('💡 DevTools không khả dụng (chưa cài đặt react-devtools-core)');
47
+ }
48
+ else {
49
+ console.log('💡 DevTools không khả dụng (không hỗ trợ trong môi trường này)');
50
+ }
51
+ }
52
+ }
53
+ /**
54
+ * Display component for DevTools status
55
+ */
56
+ export function DevToolsStatus({ connected }) {
57
+ if (process.env['NODE_ENV'] !== 'development') {
58
+ return null;
59
+ }
60
+ return connected ? '🔧 DevTools Đã Kết Nối' : '⚠️ DevTools Chưa Kết Nối';
61
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @author Bùi Trọng Hiếu
3
+ * @email kevinbui210191@gmail.com
4
+ * @create 2025-01-10
5
+ * @desc Message formatters for rich tool output display
6
+ */
7
+ import React from 'react';
8
+ import type { ToolExecutionInfo } from '../connections/types.js';
9
+ export interface FormattedMessage {
10
+ type: 'plain' | 'todos' | 'diff' | 'code';
11
+ content: React.ReactNode;
12
+ }
13
+ /**
14
+ * Parse tool result to detect format type
15
+ */
16
+ export declare function detectMessageType(content: string, toolName?: string): FormattedMessage['type'];
17
+ /**
18
+ * Format todo list output from plan_task
19
+ */
20
+ export declare function formatTodos(content: string): React.ReactNode;
21
+ /**
22
+ * Format git-style diff output for file operations
23
+ */
24
+ export declare function formatDiff(content: string, filePath?: string): React.ReactNode;
25
+ /**
26
+ * Format code blocks
27
+ */
28
+ export declare function formatCode(content: string): React.ReactNode;
29
+ /**
30
+ * Main formatter dispatcher
31
+ */
32
+ export declare function formatMessage(content: string | object | any[], toolName?: string, toolInfo?: ToolExecutionInfo): React.ReactNode;