galaxy-code 0.1.5 → 0.1.7

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 (222) hide show
  1. package/README.md +149 -600
  2. package/dist/cli.bundle.js +588 -0
  3. package/package.json +14 -12
  4. package/dist/app.d.ts +0 -7
  5. package/dist/app.js +0 -597
  6. package/dist/auto-updater.d.ts +0 -21
  7. package/dist/auto-updater.js +0 -144
  8. package/dist/cli.d.ts +0 -2
  9. package/dist/cli.js +0 -159
  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/node_modules/@workspace/agent-core/connections/claude.d.ts +0 -72
  23. package/dist/node_modules/@workspace/agent-core/connections/claude.d.ts.map +0 -1
  24. package/dist/node_modules/@workspace/agent-core/connections/claude.js +0 -270
  25. package/dist/node_modules/@workspace/agent-core/connections/claude.js.map +0 -1
  26. package/dist/node_modules/@workspace/agent-core/connections/gemini.d.ts +0 -41
  27. package/dist/node_modules/@workspace/agent-core/connections/gemini.d.ts.map +0 -1
  28. package/dist/node_modules/@workspace/agent-core/connections/gemini.js +0 -203
  29. package/dist/node_modules/@workspace/agent-core/connections/gemini.js.map +0 -1
  30. package/dist/node_modules/@workspace/agent-core/connections/index.d.ts +0 -12
  31. package/dist/node_modules/@workspace/agent-core/connections/index.d.ts.map +0 -1
  32. package/dist/node_modules/@workspace/agent-core/connections/index.js +0 -12
  33. package/dist/node_modules/@workspace/agent-core/connections/index.js.map +0 -1
  34. package/dist/node_modules/@workspace/agent-core/connections/ollama.d.ts +0 -38
  35. package/dist/node_modules/@workspace/agent-core/connections/ollama.d.ts.map +0 -1
  36. package/dist/node_modules/@workspace/agent-core/connections/ollama.js +0 -64
  37. package/dist/node_modules/@workspace/agent-core/connections/ollama.js.map +0 -1
  38. package/dist/node_modules/@workspace/agent-core/connections/types.d.ts +0 -23
  39. package/dist/node_modules/@workspace/agent-core/connections/types.d.ts.map +0 -1
  40. package/dist/node_modules/@workspace/agent-core/connections/types.js +0 -8
  41. package/dist/node_modules/@workspace/agent-core/connections/types.js.map +0 -1
  42. package/dist/node_modules/@workspace/agent-core/index.d.ts +0 -13
  43. package/dist/node_modules/@workspace/agent-core/index.d.ts.map +0 -1
  44. package/dist/node_modules/@workspace/agent-core/index.js +0 -22
  45. package/dist/node_modules/@workspace/agent-core/index.js.map +0 -1
  46. package/dist/node_modules/@workspace/agent-core/package.json +0 -53
  47. package/dist/node_modules/@workspace/agent-core/prompts/ba-it-analyzer.d.ts +0 -2
  48. package/dist/node_modules/@workspace/agent-core/prompts/ba-it-analyzer.d.ts.map +0 -1
  49. package/dist/node_modules/@workspace/agent-core/prompts/ba-it-analyzer.js +0 -144
  50. package/dist/node_modules/@workspace/agent-core/prompts/ba-it-analyzer.js.map +0 -1
  51. package/dist/node_modules/@workspace/agent-core/prompts/index.d.ts +0 -12
  52. package/dist/node_modules/@workspace/agent-core/prompts/index.d.ts.map +0 -1
  53. package/dist/node_modules/@workspace/agent-core/prompts/index.js +0 -12
  54. package/dist/node_modules/@workspace/agent-core/prompts/index.js.map +0 -1
  55. package/dist/node_modules/@workspace/agent-core/prompts/orchestrator.d.ts +0 -9
  56. package/dist/node_modules/@workspace/agent-core/prompts/orchestrator.d.ts.map +0 -1
  57. package/dist/node_modules/@workspace/agent-core/prompts/orchestrator.js +0 -89
  58. package/dist/node_modules/@workspace/agent-core/prompts/orchestrator.js.map +0 -1
  59. package/dist/node_modules/@workspace/agent-core/prompts/planning-agent.d.ts +0 -9
  60. package/dist/node_modules/@workspace/agent-core/prompts/planning-agent.d.ts.map +0 -1
  61. package/dist/node_modules/@workspace/agent-core/prompts/planning-agent.js +0 -196
  62. package/dist/node_modules/@workspace/agent-core/prompts/planning-agent.js.map +0 -1
  63. package/dist/node_modules/@workspace/agent-core/prompts/universal-agent.d.ts +0 -8
  64. package/dist/node_modules/@workspace/agent-core/prompts/universal-agent.d.ts.map +0 -1
  65. package/dist/node_modules/@workspace/agent-core/prompts/universal-agent.js +0 -112
  66. package/dist/node_modules/@workspace/agent-core/prompts/universal-agent.js.map +0 -1
  67. package/dist/node_modules/@workspace/agent-core/providers/agent-selector.d.ts +0 -30
  68. package/dist/node_modules/@workspace/agent-core/providers/agent-selector.d.ts.map +0 -1
  69. package/dist/node_modules/@workspace/agent-core/providers/agent-selector.js +0 -76
  70. package/dist/node_modules/@workspace/agent-core/providers/agent-selector.js.map +0 -1
  71. package/dist/node_modules/@workspace/agent-core/providers/claude-agent.d.ts +0 -30
  72. package/dist/node_modules/@workspace/agent-core/providers/claude-agent.d.ts.map +0 -1
  73. package/dist/node_modules/@workspace/agent-core/providers/claude-agent.js +0 -107
  74. package/dist/node_modules/@workspace/agent-core/providers/claude-agent.js.map +0 -1
  75. package/dist/node_modules/@workspace/agent-core/providers/gemini-agent.d.ts +0 -37
  76. package/dist/node_modules/@workspace/agent-core/providers/gemini-agent.d.ts.map +0 -1
  77. package/dist/node_modules/@workspace/agent-core/providers/gemini-agent.js +0 -144
  78. package/dist/node_modules/@workspace/agent-core/providers/gemini-agent.js.map +0 -1
  79. package/dist/node_modules/@workspace/agent-core/providers/index.d.ts +0 -13
  80. package/dist/node_modules/@workspace/agent-core/providers/index.d.ts.map +0 -1
  81. package/dist/node_modules/@workspace/agent-core/providers/index.js +0 -13
  82. package/dist/node_modules/@workspace/agent-core/providers/index.js.map +0 -1
  83. package/dist/node_modules/@workspace/agent-core/providers/ollama-agent.d.ts +0 -54
  84. package/dist/node_modules/@workspace/agent-core/providers/ollama-agent.d.ts.map +0 -1
  85. package/dist/node_modules/@workspace/agent-core/providers/ollama-agent.js +0 -247
  86. package/dist/node_modules/@workspace/agent-core/providers/ollama-agent.js.map +0 -1
  87. package/dist/node_modules/@workspace/agent-core/providers/orchestrator.d.ts +0 -17
  88. package/dist/node_modules/@workspace/agent-core/providers/orchestrator.d.ts.map +0 -1
  89. package/dist/node_modules/@workspace/agent-core/providers/orchestrator.js +0 -62
  90. package/dist/node_modules/@workspace/agent-core/providers/orchestrator.js.map +0 -1
  91. package/dist/node_modules/@workspace/agent-core/tools/ba-it-analyzer.d.ts +0 -67
  92. package/dist/node_modules/@workspace/agent-core/tools/ba-it-analyzer.d.ts.map +0 -1
  93. package/dist/node_modules/@workspace/agent-core/tools/ba-it-analyzer.js +0 -81
  94. package/dist/node_modules/@workspace/agent-core/tools/ba-it-analyzer.js.map +0 -1
  95. package/dist/node_modules/@workspace/agent-core/tools/code-generate-agent.d.ts +0 -52
  96. package/dist/node_modules/@workspace/agent-core/tools/code-generate-agent.d.ts.map +0 -1
  97. package/dist/node_modules/@workspace/agent-core/tools/code-generate-agent.js +0 -150
  98. package/dist/node_modules/@workspace/agent-core/tools/code-generate-agent.js.map +0 -1
  99. package/dist/node_modules/@workspace/agent-core/tools/command-runner.d.ts +0 -15
  100. package/dist/node_modules/@workspace/agent-core/tools/command-runner.d.ts.map +0 -1
  101. package/dist/node_modules/@workspace/agent-core/tools/command-runner.js +0 -121
  102. package/dist/node_modules/@workspace/agent-core/tools/command-runner.js.map +0 -1
  103. package/dist/node_modules/@workspace/agent-core/tools/document-parser.d.ts +0 -12
  104. package/dist/node_modules/@workspace/agent-core/tools/document-parser.d.ts.map +0 -1
  105. package/dist/node_modules/@workspace/agent-core/tools/document-parser.js +0 -84
  106. package/dist/node_modules/@workspace/agent-core/tools/document-parser.js.map +0 -1
  107. package/dist/node_modules/@workspace/agent-core/tools/file-operations.d.ts +0 -18
  108. package/dist/node_modules/@workspace/agent-core/tools/file-operations.d.ts.map +0 -1
  109. package/dist/node_modules/@workspace/agent-core/tools/file-operations.js +0 -126
  110. package/dist/node_modules/@workspace/agent-core/tools/file-operations.js.map +0 -1
  111. package/dist/node_modules/@workspace/agent-core/tools/galaxy-ui-integration.d.ts +0 -95
  112. package/dist/node_modules/@workspace/agent-core/tools/galaxy-ui-integration.d.ts.map +0 -1
  113. package/dist/node_modules/@workspace/agent-core/tools/galaxy-ui-integration.js +0 -245
  114. package/dist/node_modules/@workspace/agent-core/tools/galaxy-ui-integration.js.map +0 -1
  115. package/dist/node_modules/@workspace/agent-core/tools/git-operations.d.ts +0 -12
  116. package/dist/node_modules/@workspace/agent-core/tools/git-operations.d.ts.map +0 -1
  117. package/dist/node_modules/@workspace/agent-core/tools/git-operations.js +0 -115
  118. package/dist/node_modules/@workspace/agent-core/tools/git-operations.js.map +0 -1
  119. package/dist/node_modules/@workspace/agent-core/tools/index.d.ts +0 -11
  120. package/dist/node_modules/@workspace/agent-core/tools/index.d.ts.map +0 -1
  121. package/dist/node_modules/@workspace/agent-core/tools/index.js +0 -11
  122. package/dist/node_modules/@workspace/agent-core/tools/index.js.map +0 -1
  123. package/dist/node_modules/@workspace/agent-core/tools/planning-agent.d.ts +0 -30
  124. package/dist/node_modules/@workspace/agent-core/tools/planning-agent.d.ts.map +0 -1
  125. package/dist/node_modules/@workspace/agent-core/tools/planning-agent.js +0 -125
  126. package/dist/node_modules/@workspace/agent-core/tools/planning-agent.js.map +0 -1
  127. package/dist/node_modules/@workspace/agent-core/tools/progress-reporter.d.ts +0 -20
  128. package/dist/node_modules/@workspace/agent-core/tools/progress-reporter.d.ts.map +0 -1
  129. package/dist/node_modules/@workspace/agent-core/tools/progress-reporter.js +0 -46
  130. package/dist/node_modules/@workspace/agent-core/tools/progress-reporter.js.map +0 -1
  131. package/dist/node_modules/@workspace/agent-core/tools/registry.d.ts +0 -22
  132. package/dist/node_modules/@workspace/agent-core/tools/registry.d.ts.map +0 -1
  133. package/dist/node_modules/@workspace/agent-core/tools/registry.js +0 -651
  134. package/dist/node_modules/@workspace/agent-core/tools/registry.js.map +0 -1
  135. package/dist/node_modules/@workspace/agent-core/tools/tool-event-emitter.d.ts +0 -25
  136. package/dist/node_modules/@workspace/agent-core/tools/tool-event-emitter.d.ts.map +0 -1
  137. package/dist/node_modules/@workspace/agent-core/tools/tool-event-emitter.js +0 -26
  138. package/dist/node_modules/@workspace/agent-core/tools/tool-event-emitter.js.map +0 -1
  139. package/dist/node_modules/@workspace/agent-core/tools/types.d.ts +0 -32
  140. package/dist/node_modules/@workspace/agent-core/tools/types.d.ts.map +0 -1
  141. package/dist/node_modules/@workspace/agent-core/tools/types.js +0 -2
  142. package/dist/node_modules/@workspace/agent-core/tools/types.js.map +0 -1
  143. package/dist/node_modules/@workspace/agent-core/types.d.ts +0 -40
  144. package/dist/node_modules/@workspace/agent-core/types.d.ts.map +0 -1
  145. package/dist/node_modules/@workspace/agent-core/types.js +0 -9
  146. package/dist/node_modules/@workspace/agent-core/types.js.map +0 -1
  147. package/dist/node_modules/@workspace/agent-core/utils/config-manager.d.ts +0 -103
  148. package/dist/node_modules/@workspace/agent-core/utils/config-manager.d.ts.map +0 -1
  149. package/dist/node_modules/@workspace/agent-core/utils/config-manager.js +0 -307
  150. package/dist/node_modules/@workspace/agent-core/utils/config-manager.js.map +0 -1
  151. package/dist/node_modules/@workspace/agent-core/utils/devtools.d.ts +0 -22
  152. package/dist/node_modules/@workspace/agent-core/utils/devtools.d.ts.map +0 -1
  153. package/dist/node_modules/@workspace/agent-core/utils/devtools.js +0 -62
  154. package/dist/node_modules/@workspace/agent-core/utils/devtools.js.map +0 -1
  155. package/dist/node_modules/@workspace/agent-core/utils/message-formatters.d.ts +0 -33
  156. package/dist/node_modules/@workspace/agent-core/utils/message-formatters.d.ts.map +0 -1
  157. package/dist/node_modules/@workspace/agent-core/utils/message-formatters.js +0 -591
  158. package/dist/node_modules/@workspace/agent-core/utils/message-formatters.js.map +0 -1
  159. package/dist/node_modules/@workspace/agent-core/utils/progress-tracker.d.ts +0 -60
  160. package/dist/node_modules/@workspace/agent-core/utils/progress-tracker.d.ts.map +0 -1
  161. package/dist/node_modules/@workspace/agent-core/utils/progress-tracker.js +0 -204
  162. package/dist/node_modules/@workspace/agent-core/utils/progress-tracker.js.map +0 -1
  163. package/dist/prompts/ba-it-analyzer.d.ts +0 -1
  164. package/dist/prompts/ba-it-analyzer.js +0 -143
  165. package/dist/prompts/index.d.ts +0 -11
  166. package/dist/prompts/index.js +0 -11
  167. package/dist/prompts/orchestrator.d.ts +0 -8
  168. package/dist/prompts/orchestrator.js +0 -88
  169. package/dist/prompts/planning-agent.d.ts +0 -8
  170. package/dist/prompts/planning-agent.js +0 -195
  171. package/dist/prompts/universal-agent.d.ts +0 -7
  172. package/dist/prompts/universal-agent.js +0 -111
  173. package/dist/providers/agent-selector.d.ts +0 -29
  174. package/dist/providers/agent-selector.js +0 -84
  175. package/dist/providers/claude-agent.d.ts +0 -29
  176. package/dist/providers/claude-agent.js +0 -121
  177. package/dist/providers/gemini-agent.d.ts +0 -36
  178. package/dist/providers/gemini-agent.js +0 -168
  179. package/dist/providers/index.d.ts +0 -12
  180. package/dist/providers/index.js +0 -12
  181. package/dist/providers/ollama-agent.d.ts +0 -53
  182. package/dist/providers/ollama-agent.js +0 -276
  183. package/dist/providers/orchestrator.d.ts +0 -16
  184. package/dist/providers/orchestrator.js +0 -76
  185. package/dist/tools/ba-it-analyzer.d.ts +0 -66
  186. package/dist/tools/ba-it-analyzer.js +0 -90
  187. package/dist/tools/code-generate-agent.d.ts +0 -51
  188. package/dist/tools/code-generate-agent.js +0 -159
  189. package/dist/tools/command-runner.d.ts +0 -14
  190. package/dist/tools/command-runner.js +0 -120
  191. package/dist/tools/document-parser.d.ts +0 -11
  192. package/dist/tools/document-parser.js +0 -83
  193. package/dist/tools/file-operations.d.ts +0 -17
  194. package/dist/tools/file-operations.js +0 -127
  195. package/dist/tools/galaxy-ui-integration.d.ts +0 -94
  196. package/dist/tools/galaxy-ui-integration.js +0 -244
  197. package/dist/tools/git-operations.d.ts +0 -11
  198. package/dist/tools/git-operations.js +0 -114
  199. package/dist/tools/index.d.ts +0 -10
  200. package/dist/tools/index.js +0 -10
  201. package/dist/tools/planning-agent.d.ts +0 -29
  202. package/dist/tools/planning-agent.js +0 -134
  203. package/dist/tools/progress-reporter.d.ts +0 -19
  204. package/dist/tools/progress-reporter.js +0 -52
  205. package/dist/tools/registry.d.ts +0 -21
  206. package/dist/tools/registry.js +0 -695
  207. package/dist/tools/tool-event-emitter.d.ts +0 -24
  208. package/dist/tools/tool-event-emitter.js +0 -25
  209. package/dist/tools/types.d.ts +0 -31
  210. package/dist/tools/types.js +0 -1
  211. package/dist/types.d.ts +0 -39
  212. package/dist/types.js +0 -8
  213. package/dist/update-checker.d.ts +0 -22
  214. package/dist/update-checker.js +0 -85
  215. package/dist/utils/config-manager.d.ts +0 -102
  216. package/dist/utils/config-manager.js +0 -326
  217. package/dist/utils/devtools.d.ts +0 -21
  218. package/dist/utils/devtools.js +0 -61
  219. package/dist/utils/message-formatters.d.ts +0 -32
  220. package/dist/utils/message-formatters.js +0 -590
  221. package/dist/utils/progress-tracker.d.ts +0 -59
  222. package/dist/utils/progress-tracker.js +0 -213
@@ -1,61 +0,0 @@
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
- }
@@ -1,32 +0,0 @@
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;
@@ -1,590 +0,0 @@
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 { Box, Text } from 'ink';
9
- /**
10
- * Get terminal width with fallback
11
- */
12
- const getTerminalWidth = () => {
13
- const width = process.stdout?.columns;
14
- return typeof width === 'number' && Number.isFinite(width) ? width : 80;
15
- };
16
- /**
17
- * Truncate long lines to fit terminal width
18
- */
19
- const truncateLine = (line, maxWidth) => {
20
- if (line.length <= maxWidth)
21
- return line;
22
- return line.slice(0, maxWidth - 3) + '...';
23
- };
24
- /**
25
- * Parse tool result to detect format type
26
- */
27
- export function detectMessageType(content, toolName) {
28
- // Plan task outputs todos
29
- if (toolName === 'plan_task') {
30
- return 'todos';
31
- }
32
- // File operations show diffs
33
- if (toolName === 'file_write' || toolName === 'code_generate') {
34
- // Check if content has diff markers
35
- if (content.includes('---') ||
36
- content.includes('+++') ||
37
- content.includes('@@')) {
38
- return 'diff';
39
- }
40
- }
41
- // Code blocks
42
- if (content.includes('```')) {
43
- return 'code';
44
- }
45
- return 'plain';
46
- }
47
- /**
48
- * Generate simple diff between two texts
49
- */
50
- function generateDiff(oldText, newText) {
51
- const oldLines = oldText.split('\n');
52
- const newLines = newText.split('\n');
53
- const diffLines = [];
54
- let oldIdx = 0;
55
- let newIdx = 0;
56
- // Simple line-by-line comparison
57
- while (oldIdx < oldLines.length || newIdx < newLines.length) {
58
- const oldLine = oldLines[oldIdx];
59
- const newLine = newLines[newIdx];
60
- if (oldLine === newLine) {
61
- // Context line
62
- diffLines.push({
63
- type: 'context',
64
- oldLineNum: oldIdx + 1,
65
- newLineNum: newIdx + 1,
66
- content: oldLine || '',
67
- });
68
- oldIdx++;
69
- newIdx++;
70
- }
71
- else if (oldIdx < oldLines.length && oldLine !== undefined && !newLines.includes(oldLine)) {
72
- // Line removed
73
- diffLines.push({
74
- type: 'remove',
75
- oldLineNum: oldIdx + 1,
76
- content: oldLine || '',
77
- });
78
- oldIdx++;
79
- }
80
- else if (newIdx < newLines.length && newLine !== undefined && !oldLines.includes(newLine)) {
81
- // Line added
82
- diffLines.push({
83
- type: 'add',
84
- newLineNum: newIdx + 1,
85
- content: newLine || '',
86
- });
87
- newIdx++;
88
- }
89
- else {
90
- // Lines differ but exist in both - treat as remove + add
91
- if (oldIdx < oldLines.length) {
92
- diffLines.push({
93
- type: 'remove',
94
- oldLineNum: oldIdx + 1,
95
- content: oldLine || '',
96
- });
97
- oldIdx++;
98
- }
99
- if (newIdx < newLines.length) {
100
- diffLines.push({
101
- type: 'add',
102
- newLineNum: newIdx + 1,
103
- content: newLine || '',
104
- });
105
- newIdx++;
106
- }
107
- }
108
- }
109
- return diffLines;
110
- }
111
- /**
112
- * Compress diff by grouping context lines
113
- */
114
- function compressDiff(diffLines, contextLines = 2) {
115
- const compressed = [];
116
- let i = 0;
117
- while (i < diffLines.length) {
118
- const line = diffLines[i];
119
- if (line && line.type !== 'context') {
120
- // Add changed line
121
- compressed.push(line);
122
- i++;
123
- }
124
- else {
125
- // Look for runs of context lines
126
- const contextStart = i;
127
- let contextEnd = i;
128
- while (contextEnd < diffLines.length &&
129
- diffLines[contextEnd]?.type === 'context') {
130
- contextEnd++;
131
- }
132
- const contextLength = contextEnd - contextStart;
133
- if (contextLength <= contextLines * 2) {
134
- // Keep all context if small
135
- for (let j = contextStart; j < contextEnd; j++) {
136
- if (diffLines[j])
137
- compressed.push(diffLines[j]);
138
- }
139
- }
140
- else {
141
- // Keep only beginning and end context
142
- for (let j = contextStart; j < contextStart + contextLines; j++) {
143
- if (diffLines[j])
144
- compressed.push(diffLines[j]);
145
- }
146
- // Add placeholder for skipped lines
147
- const skipped = contextLength - contextLines * 2;
148
- compressed.push({
149
- type: 'context',
150
- content: `... ${skipped} unchanged lines ...`,
151
- });
152
- for (let j = contextEnd - contextLines; j < contextEnd; j++) {
153
- if (diffLines[j])
154
- compressed.push(diffLines[j]);
155
- }
156
- }
157
- i = contextEnd;
158
- }
159
- }
160
- return compressed;
161
- }
162
- /**
163
- * Format todo list output from plan_task
164
- */
165
- export function formatTodos(content) {
166
- try {
167
- // Try to parse as JSON first (if plan_task returns structured data)
168
- const data = JSON.parse(content);
169
- if (data.tasks && Array.isArray(data.tasks)) {
170
- return (React.createElement(Box, { flexDirection: "column" },
171
- React.createElement(Text, { bold: true, color: "cyan" }, "\uD83D\uDCCB Todos"),
172
- data.tasks.map((task, idx) => (React.createElement(Box, { key: idx, marginLeft: 2 },
173
- React.createElement(Text, { color: task.completed ? 'green' : 'gray' },
174
- task.completed ? '☒' : '☐',
175
- ' ',
176
- task.content || task.title || task.description))))));
177
- }
178
- }
179
- catch {
180
- // Not JSON, parse as plain text todo list
181
- const lines = content.split('\n');
182
- const todoLines = [];
183
- for (const line of lines) {
184
- const trimmed = line.trim();
185
- // Match patterns like: "☒ Task name" or "- [x] Task name" or "✓ Task name"
186
- if (trimmed.match(/^[☒✓✅-]\s*\[x\]\s*/i)) {
187
- todoLines.push({
188
- completed: true,
189
- text: trimmed.replace(/^[☒✓✅-]\s*\[x\]\s*/i, ''),
190
- });
191
- }
192
- else if (trimmed.match(/^[☐-]\s*\[\s*\]\s*/)) {
193
- todoLines.push({
194
- completed: false,
195
- text: trimmed.replace(/^[☐-]\s*\[\s*\]\s*/, ''),
196
- });
197
- }
198
- else if (trimmed.match(/^[-*•]\s+/)) {
199
- todoLines.push({
200
- completed: false,
201
- text: trimmed.replace(/^[-*•]\s+/, ''),
202
- });
203
- }
204
- }
205
- if (todoLines.length > 0) {
206
- return (React.createElement(Box, { flexDirection: "column" },
207
- React.createElement(Text, { bold: true, color: "cyan" }, "\uD83D\uDCCB Todos"),
208
- todoLines.map((todo, idx) => (React.createElement(Box, { key: idx, marginLeft: 2 },
209
- React.createElement(Text, { color: todo.completed ? 'green' : 'gray' },
210
- todo.completed ? '☒' : '☐',
211
- " ",
212
- todo.text))))));
213
- }
214
- }
215
- // Fallback to plain text
216
- return React.createElement(Text, null, content);
217
- }
218
- /**
219
- * Format git-style diff output for file operations
220
- */
221
- export function formatDiff(content, filePath) {
222
- const lines = content.split('\n');
223
- const diffLines = [];
224
- let lineNumber = 1;
225
- for (let i = 0; i < lines.length; i++) {
226
- const line = lines[i] || '';
227
- // File header
228
- if (line.startsWith('---') || line.startsWith('+++')) {
229
- diffLines.push(React.createElement(Box, { key: i },
230
- React.createElement(Text, { bold: true, color: "cyan" }, line)));
231
- continue;
232
- }
233
- // Hunk header (e.g., @@ -1,4 +1,6 @@)
234
- if (line.startsWith('@@')) {
235
- diffLines.push(React.createElement(Box, { key: i },
236
- React.createElement(Text, { bold: true, color: "magenta" }, line)));
237
- continue;
238
- }
239
- // Deleted line
240
- if (line.startsWith('-')) {
241
- diffLines.push(React.createElement(Box, { key: i },
242
- React.createElement(Text, { dimColor: true }, String(lineNumber).padStart(4, ' ')),
243
- React.createElement(Text, { color: "red" }, ` ${line}`)));
244
- lineNumber++;
245
- continue;
246
- }
247
- // Added line
248
- if (line.startsWith('+')) {
249
- diffLines.push(React.createElement(Box, { key: i },
250
- React.createElement(Text, { dimColor: true }, String(lineNumber).padStart(4, ' ')),
251
- React.createElement(Text, { color: "green" }, ` ${line}`)));
252
- lineNumber++;
253
- continue;
254
- }
255
- // Context line (unchanged)
256
- diffLines.push(React.createElement(Box, { key: i },
257
- React.createElement(Text, { dimColor: true }, String(lineNumber).padStart(4, ' ')),
258
- React.createElement(Text, null, ` ${line}`)));
259
- lineNumber++;
260
- }
261
- return (React.createElement(Box, { flexDirection: "column" },
262
- filePath && React.createElement(Text, { bold: true, color: "yellow" }, `📝 ${filePath}`),
263
- diffLines));
264
- }
265
- /**
266
- * Format code blocks
267
- */
268
- export function formatCode(content) {
269
- const codeBlockRegex = /```(\w+)?\n([\s\S]*?)```/g;
270
- const parts = [];
271
- let lastIndex = 0;
272
- let match;
273
- let idx = 0;
274
- while ((match = codeBlockRegex.exec(content)) !== null) {
275
- // Text before code block
276
- if (match.index > lastIndex) {
277
- parts.push(React.createElement(Text, { key: `text-${idx}` }, content.slice(lastIndex, match.index)));
278
- }
279
- // Code block
280
- const language = match[1] || 'text';
281
- const code = match[2];
282
- parts.push(React.createElement(Box, { key: `code-${idx}`, flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 1 },
283
- React.createElement(Text, { dimColor: true }, language),
284
- React.createElement(Text, { color: "cyan" }, code)));
285
- lastIndex = match.index + match[0].length;
286
- idx++;
287
- }
288
- // Remaining text
289
- if (lastIndex < content.length) {
290
- parts.push(React.createElement(Text, { key: `text-${idx}` }, content.slice(lastIndex)));
291
- }
292
- return React.createElement(Box, { flexDirection: "column" }, parts);
293
- }
294
- /**
295
- * Format file tree output
296
- * Pattern: 📁 LIST DIRECTORY (path)
297
- * ↳ Listed X items.
298
- */
299
- const formatFileTree = (content, toolInfo) => {
300
- let itemCount = 0;
301
- let directory = 'current directory';
302
- // Get directory from toolInfo args
303
- if (toolInfo?.args?.path) {
304
- directory = toolInfo?.args.path;
305
- }
306
- // Count items from tree output
307
- if (content) {
308
- const lines = content.split('\n').filter(line => {
309
- const trimmed = line.trim();
310
- return trimmed && !trimmed.startsWith('Failed');
311
- });
312
- itemCount = lines.length;
313
- }
314
- return (React.createElement(Box, { flexDirection: "column" },
315
- React.createElement(Text, { bold: true, color: "cyan" },
316
- "\uD83D\uDCC1 LIST DIRECTORY ",
317
- React.createElement(Text, { color: "gray" },
318
- "(",
319
- directory,
320
- ")")),
321
- React.createElement(Box, { marginLeft: 1 },
322
- React.createElement(Text, { color: "green" },
323
- "\u21B3 Listed ",
324
- itemCount,
325
- " items."))));
326
- };
327
- /**
328
- * Format file read output
329
- * Pattern: 📄 READ (filename)
330
- * ↳ Read X lines.
331
- */
332
- const formatFileRead = (content, toolInfo) => {
333
- let lineCount = 0;
334
- let fileName = 'file';
335
- // Get file name from toolInfo args
336
- if (toolInfo?.args?.path) {
337
- const parts = toolInfo.args.path.split('/');
338
- fileName = parts[parts.length - 1] || toolInfo.args.path;
339
- }
340
- // Count lines from content
341
- if (content) {
342
- lineCount = content.split('\n').length;
343
- }
344
- return (React.createElement(Box, { flexDirection: "column" },
345
- React.createElement(Text, { bold: true, color: "cyan" },
346
- "\uD83D\uDCC4 READ ",
347
- React.createElement(Text, { color: "gray" },
348
- "(",
349
- fileName,
350
- ")")),
351
- React.createElement(Box, { marginLeft: 1 },
352
- React.createElement(Text, { color: "green" },
353
- "\u21B3 Read ",
354
- lineCount,
355
- " lines."))));
356
- };
357
- /**
358
- * Format file write output with diff view
359
- * Handles both new file creation and file updates
360
- */
361
- const formatFileWrite = (content, toolInfo) => {
362
- let fileName = 'file';
363
- let writeResult = null;
364
- // Try to parse FileWriteResult from content
365
- try {
366
- writeResult = JSON.parse(content);
367
- }
368
- catch {
369
- // Fallback: treat as new file with content from args
370
- if (toolInfo?.args?.content) {
371
- writeResult = {
372
- isNewFile: true,
373
- newContent: toolInfo.args.content,
374
- linesAdded: toolInfo.args.content.split('\n').length,
375
- linesRemoved: 0,
376
- path: toolInfo.args.path,
377
- };
378
- }
379
- }
380
- if (!writeResult) {
381
- return React.createElement(Text, { wrap: "wrap" }, content);
382
- }
383
- // Get file name
384
- if (writeResult.path) {
385
- const parts = writeResult.path.split('/');
386
- fileName = parts[parts.length - 1] || writeResult.path;
387
- }
388
- const { isNewFile, oldContent, newContent, linesAdded, linesRemoved } = writeResult;
389
- // Header and status
390
- const statusText = isNewFile
391
- ? `Succeeded. File created. (+${linesAdded} added)`
392
- : `Succeeded. File edited. (+${linesAdded} added, -${linesRemoved} removed)`;
393
- // Calculate max content width (terminal width - border - padding - line numbers)
394
- const terminalWidth = getTerminalWidth();
395
- const maxContentWidth = terminalWidth - 15; // Reserve space for borders, padding, line numbers
396
- if (isNewFile) {
397
- // New file: show only first 10 lines
398
- const diffLines = [];
399
- const contentLines = newContent.split('\n');
400
- const MAX_DISPLAY_LINES = 10;
401
- // Chỉ hiển thị 10 dòng đầu nếu file có nhiều hơn 10 dòng
402
- const linesToShow = contentLines.length > MAX_DISPLAY_LINES
403
- ? contentLines.slice(0, MAX_DISPLAY_LINES)
404
- : contentLines;
405
- linesToShow.forEach((line, idx) => {
406
- const truncated = truncateLine(line, maxContentWidth);
407
- diffLines.push(React.createElement(Box, { key: idx },
408
- React.createElement(Text, { dimColor: true }, String(idx + 1).padStart(4, ' ')),
409
- React.createElement(Text, { color: "green" }, ` + ${truncated}`)));
410
- });
411
- // Thêm dòng "..." nếu có nhiều hơn 10 dòng
412
- if (contentLines.length > MAX_DISPLAY_LINES) {
413
- diffLines.push(React.createElement(Box, { key: "truncated" },
414
- React.createElement(Text, { dimColor: true },
415
- "... (",
416
- contentLines.length - MAX_DISPLAY_LINES,
417
- " more lines)")));
418
- }
419
- return (React.createElement(Box, { flexDirection: "column", width: terminalWidth - 2 },
420
- React.createElement(Text, { bold: true, color: "cyan" },
421
- "\uD83D\uDCDD APPLY PATCH ",
422
- React.createElement(Text, { color: "gray" },
423
- "(",
424
- fileName,
425
- ")")),
426
- React.createElement(Box, { marginLeft: 1, marginBottom: 1 },
427
- React.createElement(Text, { color: "green" },
428
- "\u21B3 ",
429
- statusText)),
430
- React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 1, paddingY: 0, width: terminalWidth - 4 }, diffLines)));
431
- }
432
- else {
433
- // File edited: show full diff
434
- const diffLines = generateDiff(oldContent || '', newContent);
435
- const compressedDiff = compressDiff(diffLines, 2);
436
- const diffElements = [];
437
- compressedDiff.forEach((line, idx) => {
438
- if (line.content.startsWith('...') &&
439
- line.content.includes('unchanged')) {
440
- // Placeholder for skipped lines
441
- diffElements.push(React.createElement(Box, { key: idx },
442
- React.createElement(Text, { dimColor: true }, line.content)));
443
- }
444
- else if (line.type === 'add') {
445
- const truncated = truncateLine(line.content, maxContentWidth);
446
- diffElements.push(React.createElement(Box, { key: idx },
447
- React.createElement(Text, { dimColor: true }, ' '.padStart(4, ' ')),
448
- React.createElement(Text, { dimColor: true }, "|"),
449
- React.createElement(Text, { dimColor: true }, String(line.newLineNum).padStart(4, ' ')),
450
- React.createElement(Text, { color: "green" }, ` + ${truncated}`)));
451
- }
452
- else if (line.type === 'remove') {
453
- const truncated = truncateLine(line.content, maxContentWidth);
454
- diffElements.push(React.createElement(Box, { key: idx },
455
- React.createElement(Text, { dimColor: true }, String(line.oldLineNum).padStart(4, ' ')),
456
- React.createElement(Text, { dimColor: true }, "|"),
457
- React.createElement(Text, { dimColor: true }, ' '.padStart(4, ' ')),
458
- React.createElement(Text, { color: "red" }, ` - ${truncated}`)));
459
- }
460
- else {
461
- // Context line
462
- const truncated = truncateLine(line.content, maxContentWidth);
463
- diffElements.push(React.createElement(Box, { key: idx },
464
- React.createElement(Text, { dimColor: true }, String(line.oldLineNum).padStart(4, ' ')),
465
- React.createElement(Text, { dimColor: true }, "|"),
466
- React.createElement(Text, { dimColor: true }, String(line.newLineNum).padStart(4, ' ')),
467
- React.createElement(Text, null, ` ${truncated}`)));
468
- }
469
- });
470
- // Add truncation notice if diff is too long
471
- if (diffElements.length > 30) {
472
- diffElements.splice(30);
473
- diffElements.push(React.createElement(Box, { key: "truncated" },
474
- React.createElement(Text, { dimColor: true }, "... (diff truncated for display)")));
475
- }
476
- return (React.createElement(Box, { flexDirection: "column", width: terminalWidth - 2 },
477
- React.createElement(Text, { bold: true, color: "cyan" },
478
- "\uD83D\uDCDD APPLY PATCH ",
479
- React.createElement(Text, { color: "gray" },
480
- "(",
481
- fileName,
482
- ")")),
483
- React.createElement(Box, { marginLeft: 1, marginBottom: 1 },
484
- React.createElement(Text, { color: "green" },
485
- "\u21B3 ",
486
- statusText)),
487
- React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 1, paddingY: 0, width: terminalWidth - 4 }, diffElements)));
488
- }
489
- };
490
- /**
491
- * Format command execution output
492
- * Pattern: ⚡ EXECUTE (command)
493
- * ↳ ✓ Success. Output: X lines. (hoặc ✗ Failed)
494
- */
495
- const formatCommandRun = (content, toolInfo) => {
496
- let isSuccess = true;
497
- let outputLines = 0;
498
- let command = 'command';
499
- // Get command from toolInfo args
500
- if (toolInfo?.args?.command) {
501
- command = toolInfo.args.command;
502
- }
503
- // Parse content to determine success/failure
504
- if (content) {
505
- // Format: stdout:\n...\n\nstderr:\n...
506
- const stdoutMatch = content.match(/stdout:\n([\s\S]*?)\n\nstderr:/);
507
- const stderrMatch = content.match(/stderr:\n([\s\S]*)/);
508
- if (stdoutMatch && stdoutMatch[1]) {
509
- const lines = stdoutMatch[1].split('\n').filter(line => line.trim());
510
- outputLines = lines.length;
511
- }
512
- // Check if there's meaningful error content in stderr
513
- if (stderrMatch && stderrMatch[1]) {
514
- const stderrContent = stderrMatch[1].trim();
515
- // Some commands output warnings to stderr but still succeed
516
- // Only mark as failed if there's actual error content
517
- if (stderrContent && stderrContent.toLowerCase().includes('error')) {
518
- isSuccess = false;
519
- }
520
- }
521
- // Check for common error indicators
522
- if (content.toLowerCase().includes('command not found') ||
523
- content.toLowerCase().includes('no such file') ||
524
- content.toLowerCase().includes('permission denied')) {
525
- isSuccess = false;
526
- }
527
- }
528
- const statusIcon = isSuccess ? '✓' : '✗';
529
- const statusText = isSuccess ? 'Success' : 'Failed';
530
- const statusColor = isSuccess ? 'green' : 'red';
531
- return (React.createElement(Box, { flexDirection: "column" },
532
- React.createElement(Text, { bold: true, color: "cyan" },
533
- "\u26A1 EXECUTE ",
534
- React.createElement(Text, { color: "gray" },
535
- "(",
536
- command,
537
- ")")),
538
- React.createElement(Box, { marginLeft: 1 },
539
- React.createElement(Text, { color: statusColor },
540
- "\u21B3 ",
541
- statusIcon,
542
- " ",
543
- statusText,
544
- ". Output: ",
545
- outputLines,
546
- " lines."))));
547
- };
548
- /**
549
- * Normalize tool name by removing "galaxy:" prefix if present
550
- */
551
- const normalizeToolName = (toolName) => {
552
- if (!toolName)
553
- return '';
554
- return toolName.replace(/^galaxy:/, '');
555
- };
556
- /**
557
- * Main formatter dispatcher
558
- */
559
- export function formatMessage(content, toolName, toolInfo) {
560
- // Normalize tool name
561
- const normalizedToolName = normalizeToolName(toolName);
562
- // Convert to string if needed
563
- const contentStr = typeof content === 'string' ? content : JSON.stringify(content, null, 2);
564
- // Match tool-specific formatters
565
- switch (normalizedToolName) {
566
- case 'file_tree':
567
- return formatFileTree(contentStr, toolInfo);
568
- case 'file_read':
569
- return formatFileRead(contentStr, toolInfo);
570
- case 'file_write':
571
- return formatFileWrite(contentStr, toolInfo);
572
- case 'command_run':
573
- return formatCommandRun(contentStr, toolInfo);
574
- case 'plan_task':
575
- // Plan is already displayed in planning list, don't show tool result
576
- return null;
577
- case 'progress_reporter':
578
- // Progress updates are shown in planning list status, don't show tool result
579
- return null;
580
- case 'todos':
581
- return formatTodos(contentStr);
582
- case 'diff':
583
- return formatDiff(contentStr, toolName);
584
- case 'code':
585
- return formatCode(contentStr);
586
- default:
587
- // Full content display with word wrap
588
- return React.createElement(Text, { wrap: "wrap" }, contentStr);
589
- }
590
- }