activo 0.4.3 → 0.5.0

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 (166) hide show
  1. package/README.md +203 -1
  2. package/data/2026-03-04_20-54.json +181 -0
  3. package/data/2026-03-04_20-56.json +181 -0
  4. package/data/apex-rulesets/egov.yaml +469 -0
  5. package/data/apex-rulesets/modernize.yaml +687 -0
  6. package/data/apex-rulesets/quality.yaml +1677 -0
  7. package/data/apex-rulesets/rule-schema.yaml +587 -0
  8. package/data/apex-rulesets/secure.yaml +1688 -0
  9. package/data/apex-rulesets/spring.yaml +455 -0
  10. package/data/apex-rulesets/sql-format.yaml +99 -0
  11. package/data/apex-rulesets/sql-oracle.yaml +281 -0
  12. package/data/apex-rulesets/sql.yaml +1660 -0
  13. package/dist/cli/headless.d.ts.map +1 -1
  14. package/dist/cli/headless.js +32 -10
  15. package/dist/cli/headless.js.map +1 -1
  16. package/dist/cli/index.js +31 -3
  17. package/dist/cli/index.js.map +1 -1
  18. package/dist/core/agent.d.ts +3 -3
  19. package/dist/core/agent.d.ts.map +1 -1
  20. package/dist/core/agent.js +255 -17
  21. package/dist/core/agent.js.map +1 -1
  22. package/dist/core/commands.d.ts +2 -1
  23. package/dist/core/commands.d.ts.map +1 -1
  24. package/dist/core/commands.js +61 -9
  25. package/dist/core/commands.js.map +1 -1
  26. package/dist/core/config.d.ts +14 -0
  27. package/dist/core/config.d.ts.map +1 -1
  28. package/dist/core/config.js +41 -4
  29. package/dist/core/config.js.map +1 -1
  30. package/dist/core/conversation.d.ts +2 -2
  31. package/dist/core/conversation.d.ts.map +1 -1
  32. package/dist/core/conversation.js.map +1 -1
  33. package/dist/core/intentRouter.d.ts +43 -0
  34. package/dist/core/intentRouter.d.ts.map +1 -0
  35. package/dist/core/intentRouter.js +804 -0
  36. package/dist/core/intentRouter.js.map +1 -0
  37. package/dist/core/llm/anthropic.d.ts +24 -0
  38. package/dist/core/llm/anthropic.d.ts.map +1 -0
  39. package/dist/core/llm/anthropic.js +226 -0
  40. package/dist/core/llm/anthropic.js.map +1 -0
  41. package/dist/core/llm/ollama.d.ts +5 -14
  42. package/dist/core/llm/ollama.d.ts.map +1 -1
  43. package/dist/core/llm/ollama.js +3 -0
  44. package/dist/core/llm/ollama.js.map +1 -1
  45. package/dist/core/llm/types.d.ts +22 -0
  46. package/dist/core/llm/types.d.ts.map +1 -0
  47. package/dist/core/llm/types.js +2 -0
  48. package/dist/core/llm/types.js.map +1 -0
  49. package/dist/core/mcp/client.d.ts +6 -0
  50. package/dist/core/mcp/client.d.ts.map +1 -1
  51. package/dist/core/mcp/client.js +16 -0
  52. package/dist/core/mcp/client.js.map +1 -1
  53. package/dist/core/mcp/init.d.ts +12 -0
  54. package/dist/core/mcp/init.d.ts.map +1 -0
  55. package/dist/core/mcp/init.js +55 -0
  56. package/dist/core/mcp/init.js.map +1 -0
  57. package/dist/core/mcp/logger.d.ts +14 -0
  58. package/dist/core/mcp/logger.d.ts.map +1 -0
  59. package/dist/core/mcp/logger.js +50 -0
  60. package/dist/core/mcp/logger.js.map +1 -0
  61. package/dist/core/tools/analyzeAll.d.ts.map +1 -1
  62. package/dist/core/tools/analyzeAll.js +16 -28
  63. package/dist/core/tools/analyzeAll.js.map +1 -1
  64. package/dist/core/tools/analyzePatterns.d.ts +3 -0
  65. package/dist/core/tools/analyzePatterns.d.ts.map +1 -0
  66. package/dist/core/tools/analyzePatterns.js +293 -0
  67. package/dist/core/tools/analyzePatterns.js.map +1 -0
  68. package/dist/core/tools/apexPaths.d.ts +14 -0
  69. package/dist/core/tools/apexPaths.d.ts.map +1 -0
  70. package/dist/core/tools/apexPaths.js +54 -0
  71. package/dist/core/tools/apexPaths.js.map +1 -0
  72. package/dist/core/tools/apexUtils.d.ts +36 -0
  73. package/dist/core/tools/apexUtils.d.ts.map +1 -0
  74. package/dist/core/tools/apexUtils.js +83 -0
  75. package/dist/core/tools/apexUtils.js.map +1 -0
  76. package/dist/core/tools/explainIssue.d.ts +3 -0
  77. package/dist/core/tools/explainIssue.d.ts.map +1 -0
  78. package/dist/core/tools/explainIssue.js +181 -0
  79. package/dist/core/tools/explainIssue.js.map +1 -0
  80. package/dist/core/tools/fixGen.d.ts +3 -0
  81. package/dist/core/tools/fixGen.d.ts.map +1 -0
  82. package/dist/core/tools/fixGen.js +338 -0
  83. package/dist/core/tools/fixGen.js.map +1 -0
  84. package/dist/core/tools/generateImprovements.d.ts +21 -0
  85. package/dist/core/tools/generateImprovements.d.ts.map +1 -0
  86. package/dist/core/tools/generateImprovements.js +602 -0
  87. package/dist/core/tools/generateImprovements.js.map +1 -0
  88. package/dist/core/tools/generateReport.d.ts +3 -0
  89. package/dist/core/tools/generateReport.d.ts.map +1 -0
  90. package/dist/core/tools/generateReport.js +315 -0
  91. package/dist/core/tools/generateReport.js.map +1 -0
  92. package/dist/core/tools/index.d.ts +7 -0
  93. package/dist/core/tools/index.d.ts.map +1 -1
  94. package/dist/core/tools/index.js +62 -23
  95. package/dist/core/tools/index.js.map +1 -1
  96. package/dist/core/tools/javaAst.d.ts.map +1 -1
  97. package/dist/core/tools/javaAst.js +191 -0
  98. package/dist/core/tools/javaAst.js.map +1 -1
  99. package/dist/core/tools/recommendProfile.d.ts +3 -0
  100. package/dist/core/tools/recommendProfile.d.ts.map +1 -0
  101. package/dist/core/tools/recommendProfile.js +334 -0
  102. package/dist/core/tools/recommendProfile.js.map +1 -0
  103. package/dist/core/tools/ruleGen.d.ts +3 -0
  104. package/dist/core/tools/ruleGen.d.ts.map +1 -0
  105. package/dist/core/tools/ruleGen.js +1103 -0
  106. package/dist/core/tools/ruleGen.js.map +1 -0
  107. package/dist/core/tools/standards.d.ts.map +1 -1
  108. package/dist/core/tools/standards.js +7 -3
  109. package/dist/core/tools/standards.js.map +1 -1
  110. package/dist/ui/App.d.ts.map +1 -1
  111. package/dist/ui/App.js +86 -35
  112. package/dist/ui/App.js.map +1 -1
  113. package/dist/ui/components/InputBox.d.ts +1 -3
  114. package/dist/ui/components/InputBox.d.ts.map +1 -1
  115. package/dist/ui/components/InputBox.js +146 -5
  116. package/dist/ui/components/InputBox.js.map +1 -1
  117. package/dist/ui/components/MessageList.d.ts +3 -1
  118. package/dist/ui/components/MessageList.d.ts.map +1 -1
  119. package/dist/ui/components/MessageList.js +13 -7
  120. package/dist/ui/components/MessageList.js.map +1 -1
  121. package/dist/ui/components/StatusBar.d.ts +1 -1
  122. package/dist/ui/components/StatusBar.d.ts.map +1 -1
  123. package/dist/ui/components/StatusBar.js +3 -2
  124. package/dist/ui/components/StatusBar.js.map +1 -1
  125. package/dist/ui/components/ToolStatus.d.ts +3 -1
  126. package/dist/ui/components/ToolStatus.d.ts.map +1 -1
  127. package/dist/ui/components/ToolStatus.js +19 -4
  128. package/dist/ui/components/ToolStatus.js.map +1 -1
  129. package/package.json +7 -1
  130. package/demo.gif +0 -0
  131. package/demo.tape +0 -53
  132. package/screenshot.png +0 -0
  133. package/src/cli/banner.ts +0 -38
  134. package/src/cli/headless.ts +0 -63
  135. package/src/cli/index.ts +0 -57
  136. package/src/core/agent.ts +0 -237
  137. package/src/core/commands.ts +0 -118
  138. package/src/core/config.ts +0 -98
  139. package/src/core/conversation.ts +0 -235
  140. package/src/core/llm/ollama.ts +0 -351
  141. package/src/core/mcp/client.ts +0 -143
  142. package/src/core/tools/analyzeAll.ts +0 -494
  143. package/src/core/tools/ast.ts +0 -826
  144. package/src/core/tools/builtIn.ts +0 -221
  145. package/src/core/tools/cache.ts +0 -570
  146. package/src/core/tools/cssAnalysis.ts +0 -324
  147. package/src/core/tools/dependencyAnalysis.ts +0 -363
  148. package/src/core/tools/embeddings.ts +0 -746
  149. package/src/core/tools/frontendAst.ts +0 -802
  150. package/src/core/tools/htmlAnalysis.ts +0 -466
  151. package/src/core/tools/index.ts +0 -160
  152. package/src/core/tools/javaAst.ts +0 -812
  153. package/src/core/tools/memory.ts +0 -655
  154. package/src/core/tools/mybatisAnalysis.ts +0 -322
  155. package/src/core/tools/openapiAnalysis.ts +0 -431
  156. package/src/core/tools/pythonAnalysis.ts +0 -477
  157. package/src/core/tools/sqlAnalysis.ts +0 -298
  158. package/src/core/tools/standards.test.ts +0 -186
  159. package/src/core/tools/standards.ts +0 -889
  160. package/src/core/tools/types.ts +0 -38
  161. package/src/ui/App.tsx +0 -334
  162. package/src/ui/components/InputBox.tsx +0 -37
  163. package/src/ui/components/MessageList.tsx +0 -80
  164. package/src/ui/components/StatusBar.tsx +0 -36
  165. package/src/ui/components/ToolStatus.tsx +0 -38
  166. package/tsconfig.json +0 -21
@@ -1,38 +0,0 @@
1
- export interface Tool {
2
- name: string;
3
- description: string;
4
- parameters: {
5
- type: "object";
6
- required?: string[];
7
- properties: Record<string, ToolParameter>;
8
- };
9
- handler: (args: Record<string, unknown>) => Promise<ToolResult>;
10
- }
11
-
12
- export interface ToolParameter {
13
- type: string;
14
- description: string;
15
- enum?: string[];
16
- default?: unknown;
17
- items?: { type: string };
18
- }
19
-
20
- export interface ToolCall {
21
- id: string;
22
- name: string;
23
- arguments: Record<string, unknown>;
24
- }
25
-
26
- export interface ToolResult {
27
- success: boolean;
28
- content: string;
29
- error?: string;
30
- }
31
-
32
- export interface ToolEvent {
33
- type: "tool_use";
34
- tool: string;
35
- status: "start" | "complete" | "error";
36
- args?: Record<string, unknown>;
37
- result?: ToolResult;
38
- }
package/src/ui/App.tsx DELETED
@@ -1,334 +0,0 @@
1
- import React, { useState, useEffect, useCallback, useRef } from "react";
2
- import { Box, Text, useApp, useInput } from "ink";
3
- import { Config } from "../core/config.js";
4
- import { OllamaClient, ChatMessage } from "../core/llm/ollama.js";
5
- import { streamProcessMessage, AgentEvent } from "../core/agent.js";
6
- import { handleSlashCommand } from "../core/commands.js";
7
- import { InputBox } from "./components/InputBox.js";
8
- import { MessageList } from "./components/MessageList.js";
9
- import { StatusBar } from "./components/StatusBar.js";
10
- import { ToolStatus } from "./components/ToolStatus.js";
11
- import {
12
- createSession,
13
- loadLatestSession,
14
- saveSession,
15
- getSessionContext,
16
- cleanOldSessions,
17
- } from "../core/conversation.js";
18
-
19
- interface AppProps {
20
- initialPrompt?: string;
21
- config: Config;
22
- resume?: boolean;
23
- }
24
-
25
- interface Message {
26
- role: "user" | "assistant";
27
- content: string;
28
- toolCalls?: Array<{
29
- tool: string;
30
- status: "running" | "complete" | "error";
31
- result?: string;
32
- }>;
33
- }
34
-
35
- export function App({ initialPrompt, config, resume }: AppProps): React.ReactElement {
36
- const { exit } = useApp();
37
- const [messages, setMessages] = useState<Message[]>([]);
38
- const [input, setInput] = useState("");
39
- const [isProcessing, setIsProcessing] = useState(false);
40
- const [currentTool, setCurrentTool] = useState<string | null>(null);
41
- const [toolStatus, setToolStatus] = useState<"running" | "complete" | "error" | null>(null);
42
- const [error, setError] = useState<string | null>(null);
43
- const [client] = useState(() => new OllamaClient(config.ollama));
44
- const [currentModel, setCurrentModel] = useState(config.ollama.model);
45
- const [exitPending, setExitPending] = useState(false);
46
- const [cancelled, setCancelled] = useState(false);
47
- const abortControllerRef = useRef<AbortController | null>(null);
48
-
49
- // Session management
50
- const [session, setSession] = useState(() => createSession());
51
- const [contextSummary, setContextSummary] = useState<string>("");
52
-
53
- // Handle Ctrl+C and ESC
54
- useInput((inputChar, key) => {
55
- // ESC key to cancel current operation
56
- if (key.escape && isProcessing) {
57
- if (abortControllerRef.current) {
58
- abortControllerRef.current.abort();
59
- setCancelled(true);
60
- setIsProcessing(false);
61
- setCurrentTool(null);
62
- setToolStatus(null);
63
- setError("Operation cancelled by user (ESC)");
64
- }
65
- return;
66
- }
67
-
68
- // Ctrl+C to exit
69
- if (key.ctrl && inputChar === "c") {
70
- if (isProcessing && abortControllerRef.current) {
71
- abortControllerRef.current.abort();
72
- setCancelled(true);
73
- setIsProcessing(false);
74
- setCurrentTool(null);
75
- setToolStatus(null);
76
- return;
77
- }
78
- if (exitPending) {
79
- exit();
80
- } else {
81
- setExitPending(true);
82
- setTimeout(() => setExitPending(false), 1000);
83
- }
84
- }
85
- });
86
-
87
- // Check Ollama connection on mount
88
- useEffect(() => {
89
- const checkConnection = async () => {
90
- const connected = await client.isConnected();
91
- if (!connected) {
92
- setError(`Cannot connect to Ollama at ${config.ollama.baseUrl}`);
93
- }
94
- };
95
- checkConnection();
96
- }, [client, config.ollama.baseUrl]);
97
-
98
- // Load previous session context on mount (if resume)
99
- useEffect(() => {
100
- const loadContext = async () => {
101
- if (resume) {
102
- try {
103
- const { summary, recentMessages } = await getSessionContext(client, 5);
104
- if (summary) {
105
- setContextSummary(summary);
106
- }
107
- // Optionally load recent messages to display
108
- if (recentMessages.length > 0) {
109
- const displayMessages: Message[] = recentMessages
110
- .filter(m => m.role === "user" || m.role === "assistant")
111
- .map(m => ({
112
- role: m.role as "user" | "assistant",
113
- content: m.content,
114
- }));
115
- setMessages(displayMessages);
116
- }
117
- } catch {
118
- // Ignore context loading errors
119
- }
120
- }
121
- // Clean old sessions
122
- cleanOldSessions(10);
123
- };
124
- loadContext();
125
- }, [resume, client]);
126
-
127
- // Process initial prompt
128
- useEffect(() => {
129
- if (initialPrompt) {
130
- handleSubmit(initialPrompt);
131
- }
132
- }, [initialPrompt]);
133
-
134
- const handleSubmit = useCallback(async (text: string) => {
135
- if (!text.trim() || isProcessing) return;
136
-
137
- setInput("");
138
- setError(null);
139
-
140
- // Handle slash commands first
141
- if (text.startsWith("/")) {
142
- const result = handleSlashCommand(text, config);
143
- if (result) {
144
- // Add command as user message
145
- setMessages((prev) => [...prev, { role: "user", content: text }]);
146
-
147
- if (result.exit) {
148
- const exitMsg: Message = { role: "assistant", content: result.output || "Goodbye!" };
149
- setMessages((prev) => [...prev, exitMsg]);
150
- setTimeout(() => exit(), 500);
151
- return;
152
- }
153
-
154
- if (result.clear) {
155
- setMessages([]);
156
- return;
157
- }
158
-
159
- if (result.changeModel) {
160
- setCurrentModel(result.changeModel);
161
- client.setModel(result.changeModel);
162
- }
163
-
164
- if (result.output) {
165
- const outputMsg: Message = { role: "assistant", content: result.output };
166
- setMessages((prev) => [...prev, outputMsg]);
167
- }
168
-
169
- return;
170
- }
171
- }
172
-
173
- setIsProcessing(true);
174
- setCancelled(false);
175
-
176
- // Create AbortController for this request
177
- const abortController = new AbortController();
178
- abortControllerRef.current = abortController;
179
-
180
- // Add user message
181
- const userMessage: Message = { role: "user", content: text };
182
- setMessages((prev) => [...prev, userMessage]);
183
-
184
- // Convert messages to chat format
185
- const history: ChatMessage[] = messages.map((m) => ({
186
- role: m.role,
187
- content: m.content,
188
- }));
189
-
190
- // Create assistant message placeholder
191
- const assistantMessage: Message = { role: "assistant", content: "", toolCalls: [] };
192
- setMessages((prev) => [...prev, assistantMessage]);
193
-
194
- try {
195
- let fullContent = "";
196
-
197
- for await (const event of streamProcessMessage(text, history, client, config, abortController.signal, contextSummary)) {
198
- // Check if cancelled
199
- if (abortController.signal.aborted) {
200
- break;
201
- }
202
- switch (event.type) {
203
- case "content":
204
- fullContent += event.content || "";
205
- setMessages((prev) => {
206
- const updated = [...prev];
207
- const last = updated[updated.length - 1];
208
- if (last.role === "assistant") {
209
- last.content = fullContent;
210
- }
211
- return updated;
212
- });
213
- break;
214
-
215
- case "tool_use":
216
- setCurrentTool(event.tool || null);
217
- setToolStatus("running");
218
- setMessages((prev) => {
219
- const updated = [...prev];
220
- const last = updated[updated.length - 1];
221
- if (last.role === "assistant") {
222
- last.toolCalls = [
223
- ...(last.toolCalls || []),
224
- { tool: event.tool!, status: "running" },
225
- ];
226
- }
227
- return updated;
228
- });
229
- break;
230
-
231
- case "tool_result":
232
- setToolStatus(event.status as "complete" | "error");
233
- setMessages((prev) => {
234
- const updated = [...prev];
235
- const last = updated[updated.length - 1];
236
- if (last.role === "assistant" && last.toolCalls) {
237
- const toolCall = last.toolCalls.find((tc) => tc.tool === event.tool);
238
- if (toolCall) {
239
- toolCall.status = event.status as "complete" | "error";
240
- toolCall.result = event.result?.content || event.result?.error;
241
- }
242
- }
243
- return updated;
244
- });
245
- setTimeout(() => {
246
- setCurrentTool(null);
247
- setToolStatus(null);
248
- }, 500);
249
- break;
250
-
251
- case "error":
252
- setError(event.error || "Unknown error");
253
- break;
254
-
255
- case "done":
256
- break;
257
- }
258
- }
259
- } catch (err) {
260
- if (!abortController.signal.aborted) {
261
- setError(String(err));
262
- }
263
- } finally {
264
- setIsProcessing(false);
265
- setCurrentTool(null);
266
- setToolStatus(null);
267
- abortControllerRef.current = null;
268
-
269
- // Save conversation to session
270
- setSession((prevSession) => {
271
- const updatedSession = { ...prevSession };
272
- // Add user message
273
- updatedSession.messages.push({ role: "user", content: text });
274
- // Add assistant message (get from current messages state)
275
- setMessages((currentMessages) => {
276
- const lastMessage = currentMessages[currentMessages.length - 1];
277
- if (lastMessage?.role === "assistant") {
278
- updatedSession.messages.push({
279
- role: "assistant",
280
- content: lastMessage.content,
281
- });
282
- }
283
- return currentMessages;
284
- });
285
- saveSession(updatedSession);
286
- return updatedSession;
287
- });
288
- }
289
- }, [messages, client, config, isProcessing, contextSummary]);
290
-
291
- return (
292
- <Box flexDirection="column" height="100%">
293
- {/* Messages */}
294
- <Box flexDirection="column" flexGrow={1}>
295
- <MessageList messages={messages} />
296
- </Box>
297
-
298
- {/* Tool Status */}
299
- {currentTool && (
300
- <ToolStatus tool={currentTool} status={toolStatus || "running"} />
301
- )}
302
-
303
- {/* Error */}
304
- {error && (
305
- <Box marginY={1}>
306
- <Text color="red">⚠ {error}</Text>
307
- </Box>
308
- )}
309
-
310
- {/* Exit Warning */}
311
- {exitPending && (
312
- <Box marginY={1}>
313
- <Text color="yellow">Press Ctrl+C again to exit</Text>
314
- </Box>
315
- )}
316
-
317
- {/* Input */}
318
- <InputBox
319
- value={input}
320
- onChange={setInput}
321
- onSubmit={handleSubmit}
322
- isProcessing={isProcessing}
323
- placeholder="Type your message..."
324
- />
325
-
326
- {/* Status Bar */}
327
- <StatusBar
328
- model={currentModel}
329
- isProcessing={isProcessing}
330
- messageCount={messages.length}
331
- />
332
- </Box>
333
- );
334
- }
@@ -1,37 +0,0 @@
1
- import React from "react";
2
- import { Box, Text } from "ink";
3
- import TextInput from "ink-text-input";
4
-
5
- interface InputBoxProps {
6
- value: string;
7
- onChange: (value: string) => void;
8
- onSubmit: (value: string) => void;
9
- isProcessing: boolean;
10
- placeholder?: string;
11
- }
12
-
13
- export function InputBox({
14
- value,
15
- onChange,
16
- onSubmit,
17
- isProcessing,
18
- placeholder,
19
- }: InputBoxProps): React.ReactElement {
20
- return (
21
- <Box borderStyle="round" borderColor={isProcessing ? "gray" : "cyan"} paddingX={1}>
22
- <Text color="green" bold>
23
- {isProcessing ? "⏳" : "❯"}{" "}
24
- </Text>
25
- {isProcessing ? (
26
- <Text color="gray">Processing...</Text>
27
- ) : (
28
- <TextInput
29
- value={value}
30
- onChange={onChange}
31
- onSubmit={onSubmit}
32
- placeholder={placeholder}
33
- />
34
- )}
35
- </Box>
36
- );
37
- }
@@ -1,80 +0,0 @@
1
- import React from "react";
2
- import { Box, Text } from "ink";
3
-
4
- interface ToolCall {
5
- tool: string;
6
- status: "running" | "complete" | "error";
7
- result?: string;
8
- }
9
-
10
- interface Message {
11
- role: "user" | "assistant";
12
- content: string;
13
- toolCalls?: ToolCall[];
14
- }
15
-
16
- interface MessageListProps {
17
- messages: Message[];
18
- }
19
-
20
- export function MessageList({ messages }: MessageListProps): React.ReactElement {
21
- if (messages.length === 0) {
22
- return (
23
- <Box marginY={1}>
24
- <Text color="gray">Start a conversation by typing below...</Text>
25
- </Box>
26
- );
27
- }
28
-
29
- return (
30
- <Box flexDirection="column">
31
- {messages.map((message, index) => (
32
- <MessageItem key={index} message={message} />
33
- ))}
34
- </Box>
35
- );
36
- }
37
-
38
- function MessageItem({ message }: { message: Message }): React.ReactElement {
39
- const isUser = message.role === "user";
40
-
41
- return (
42
- <Box flexDirection="column" marginY={1}>
43
- {/* Role indicator */}
44
- <Box>
45
- <Text color={isUser ? "green" : "cyan"} bold>
46
- {isUser ? "You" : "ACTIVO"}
47
- </Text>
48
- </Box>
49
-
50
- {/* Tool calls */}
51
- {message.toolCalls && message.toolCalls.length > 0 && (
52
- <Box flexDirection="column" marginLeft={2} marginY={1}>
53
- {message.toolCalls.map((tc, idx) => (
54
- <Box key={idx}>
55
- <Text color="gray">
56
- {tc.status === "running" ? "🔄" : tc.status === "complete" ? "✓" : "✗"}{" "}
57
- </Text>
58
- <Text color={tc.status === "error" ? "red" : "yellow"}>{tc.tool}</Text>
59
- {tc.status === "complete" && tc.result && (
60
- <Text color="gray"> - {truncate(tc.result, 50)}</Text>
61
- )}
62
- </Box>
63
- ))}
64
- </Box>
65
- )}
66
-
67
- {/* Content */}
68
- {message.content && (
69
- <Box marginLeft={2}>
70
- <Text wrap="wrap">{message.content}</Text>
71
- </Box>
72
- )}
73
- </Box>
74
- );
75
- }
76
-
77
- function truncate(text: string, maxLength: number): string {
78
- if (text.length <= maxLength) return text;
79
- return text.slice(0, maxLength) + "...";
80
- }
@@ -1,36 +0,0 @@
1
- import React from "react";
2
- import { Box, Text } from "ink";
3
-
4
- interface StatusBarProps {
5
- model: string;
6
- isProcessing: boolean;
7
- messageCount: number;
8
- }
9
-
10
- export function StatusBar({
11
- model,
12
- isProcessing,
13
- messageCount,
14
- }: StatusBarProps): React.ReactElement {
15
- return (
16
- <Box justifyContent="space-between" paddingX={1} marginTop={1}>
17
- <Box>
18
- <Text color="gray">Model: </Text>
19
- <Text color="cyan">{model}</Text>
20
- </Box>
21
-
22
- <Box>
23
- <Text color="gray">Messages: </Text>
24
- <Text color="white">{messageCount}</Text>
25
- </Box>
26
-
27
- <Box>
28
- {isProcessing ? (
29
- <Text color="yellow">● Processing</Text>
30
- ) : (
31
- <Text color="green">● Ready</Text>
32
- )}
33
- </Box>
34
- </Box>
35
- );
36
- }
@@ -1,38 +0,0 @@
1
- import React from "react";
2
- import { Box, Text } from "ink";
3
- import Spinner from "ink-spinner";
4
-
5
- interface ToolStatusProps {
6
- tool: string;
7
- status: "running" | "complete" | "error";
8
- }
9
-
10
- export function ToolStatus({ tool, status }: ToolStatusProps): React.ReactElement {
11
- return (
12
- <Box marginY={1} paddingX={1}>
13
- {status === "running" ? (
14
- <>
15
- <Text color="cyan">
16
- <Spinner type="dots" />
17
- </Text>
18
- <Text color="cyan"> Using tool: </Text>
19
- <Text color="yellow" bold>
20
- {tool}
21
- </Text>
22
- </>
23
- ) : status === "complete" ? (
24
- <>
25
- <Text color="green">✓ </Text>
26
- <Text color="gray">Tool completed: </Text>
27
- <Text color="white">{tool}</Text>
28
- </>
29
- ) : (
30
- <>
31
- <Text color="red">✗ </Text>
32
- <Text color="gray">Tool failed: </Text>
33
- <Text color="red">{tool}</Text>
34
- </>
35
- )}
36
- </Box>
37
- );
38
- }
package/tsconfig.json DELETED
@@ -1,21 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "lib": ["ES2022"],
7
- "outDir": "./dist",
8
- "rootDir": "./src",
9
- "strict": true,
10
- "esModuleInterop": true,
11
- "skipLibCheck": true,
12
- "forceConsistentCasingInFileNames": true,
13
- "declaration": true,
14
- "declarationMap": true,
15
- "sourceMap": true,
16
- "resolveJsonModule": true,
17
- "jsx": "react-jsx"
18
- },
19
- "include": ["src/**/*"],
20
- "exclude": ["node_modules", "dist", "**/*.test.ts"]
21
- }