@bestdefense/bd-agent 0.1.2 → 0.1.4

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 (69) hide show
  1. package/dist/cli.js +25 -5
  2. package/dist/cli.js.map +1 -1
  3. package/dist/commands/chat.d.ts.map +1 -1
  4. package/dist/commands/chat.js +463 -66
  5. package/dist/commands/chat.js.map +1 -1
  6. package/dist/services/bedrock-client.d.ts +1 -0
  7. package/dist/services/bedrock-client.d.ts.map +1 -1
  8. package/dist/services/bedrock-client.js +82 -12
  9. package/dist/services/bedrock-client.js.map +1 -1
  10. package/dist/services/conversation-manager.d.ts +9 -0
  11. package/dist/services/conversation-manager.d.ts.map +1 -1
  12. package/dist/services/conversation-manager.js +13 -0
  13. package/dist/services/conversation-manager.js.map +1 -1
  14. package/dist/services/history-manager.d.ts +18 -0
  15. package/dist/services/history-manager.d.ts.map +1 -0
  16. package/dist/services/history-manager.js +140 -0
  17. package/dist/services/history-manager.js.map +1 -0
  18. package/dist/services/memory-manager.d.ts +47 -0
  19. package/dist/services/memory-manager.d.ts.map +1 -0
  20. package/dist/services/memory-manager.js +157 -0
  21. package/dist/services/memory-manager.js.map +1 -0
  22. package/dist/services/slash-commands.d.ts +21 -0
  23. package/dist/services/slash-commands.d.ts.map +1 -0
  24. package/dist/services/slash-commands.js +142 -0
  25. package/dist/services/slash-commands.js.map +1 -0
  26. package/dist/services/tool-executor.d.ts.map +1 -1
  27. package/dist/services/tool-executor.js +16 -2
  28. package/dist/services/tool-executor.js.map +1 -1
  29. package/dist/tools/advanced-edit.d.ts +94 -0
  30. package/dist/tools/advanced-edit.d.ts.map +1 -0
  31. package/dist/tools/advanced-edit.js +265 -0
  32. package/dist/tools/advanced-edit.js.map +1 -0
  33. package/dist/tools/file-system.d.ts +5 -0
  34. package/dist/tools/file-system.d.ts.map +1 -1
  35. package/dist/tools/file-system.js +8 -1
  36. package/dist/tools/file-system.js.map +1 -1
  37. package/dist/tools/search-tools.d.ts +110 -0
  38. package/dist/tools/search-tools.d.ts.map +1 -0
  39. package/dist/tools/search-tools.js +321 -0
  40. package/dist/tools/search-tools.js.map +1 -0
  41. package/dist/types/conversation.d.ts +6 -0
  42. package/dist/types/conversation.d.ts.map +1 -0
  43. package/dist/types/conversation.js +3 -0
  44. package/dist/types/conversation.js.map +1 -0
  45. package/dist/utils/claude-md.d.ts +24 -0
  46. package/dist/utils/claude-md.d.ts.map +1 -0
  47. package/dist/utils/claude-md.js +222 -0
  48. package/dist/utils/claude-md.js.map +1 -0
  49. package/dist/utils/error-handler.d.ts +20 -0
  50. package/dist/utils/error-handler.d.ts.map +1 -0
  51. package/dist/utils/error-handler.js +130 -0
  52. package/dist/utils/error-handler.js.map +1 -0
  53. package/dist/utils/markdown-renderer.d.ts +15 -0
  54. package/dist/utils/markdown-renderer.d.ts.map +1 -0
  55. package/dist/utils/markdown-renderer.js +143 -0
  56. package/dist/utils/markdown-renderer.js.map +1 -0
  57. package/dist/utils/multi-line-input.d.ts +3 -0
  58. package/dist/utils/multi-line-input.d.ts.map +1 -0
  59. package/dist/utils/multi-line-input.js +68 -0
  60. package/dist/utils/multi-line-input.js.map +1 -0
  61. package/dist/utils/prompts.d.ts +1 -0
  62. package/dist/utils/prompts.d.ts.map +1 -1
  63. package/dist/utils/prompts.js +17 -1
  64. package/dist/utils/prompts.js.map +1 -1
  65. package/dist/utils/readline-with-history.d.ts +13 -0
  66. package/dist/utils/readline-with-history.d.ts.map +1 -0
  67. package/dist/utils/readline-with-history.js +196 -0
  68. package/dist/utils/readline-with-history.js.map +1 -0
  69. package/package.json +9 -4
package/dist/cli.js CHANGED
@@ -9,6 +9,7 @@ const chalk_1 = __importDefault(require("chalk"));
9
9
  const inquirer_1 = __importDefault(require("inquirer"));
10
10
  const config_1 = require("./utils/config");
11
11
  const chat_1 = require("./commands/chat");
12
+ const claude_md_1 = require("./utils/claude-md");
12
13
  const package_json_1 = require("../package.json");
13
14
  const program = new commander_1.Command();
14
15
  program
@@ -20,16 +21,35 @@ program
20
21
  .description('Start an interactive chat session')
21
22
  .option('-m, --model <model>', 'Bedrock model ID to use')
22
23
  .action(async (options) => {
23
- if (!(0, config_1.validateConfig)()) {
24
- console.log(chalk_1.default.yellow('AWS credentials not configured. Running setup...'));
25
- await runSetup();
24
+ try {
25
+ if (!(0, config_1.validateConfig)()) {
26
+ console.log(chalk_1.default.yellow('AWS credentials not configured. Running setup...'));
27
+ await runSetup();
28
+ }
29
+ await (0, chat_1.startChat)(options);
30
+ }
31
+ catch (error) {
32
+ console.error(chalk_1.default.red(`\nUnexpected error: ${error.message}`));
33
+ console.error(chalk_1.default.gray(error.stack));
34
+ process.exit(1);
26
35
  }
27
- await (0, chat_1.startChat)(options);
28
36
  });
29
37
  program
30
38
  .command('setup')
31
39
  .description('Configure AWS credentials and settings')
32
40
  .action(runSetup);
41
+ program
42
+ .command('init')
43
+ .description('Create a CLAUDE.md template for project-specific instructions')
44
+ .action(() => {
45
+ try {
46
+ claude_md_1.ClaudeMdManager.createTemplate(process.cwd());
47
+ }
48
+ catch (error) {
49
+ console.error(chalk_1.default.red(`Error: ${error.message}`));
50
+ process.exit(1);
51
+ }
52
+ });
33
53
  async function runSetup() {
34
54
  console.log(chalk_1.default.blue('BD Agent Setup'));
35
55
  console.log(chalk_1.default.gray('Configure your AWS credentials for Bedrock access\n'));
@@ -71,7 +91,7 @@ async function runSetup() {
71
91
  { name: 'Claude Opus 4 (requires setup)', value: 'opus-setup' },
72
92
  { name: 'Custom Model/Profile (enter manually)', value: 'custom' }
73
93
  ],
74
- default: 'anthropic.claude-3-5-sonnet-20241022-v2:0'
94
+ default: 'us.anthropic.claude-opus-4-20250514-v1:0'
75
95
  },
76
96
  {
77
97
  type: 'input',
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/commands/chat.ts"],"names":[],"mappings":"AAYA,wBAAsB,SAAS,CAAC,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,iBAyG1D"}
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/commands/chat.ts"],"names":[],"mappings":"AAeA,wBAAsB,SAAS,CAAC,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,iBA2gB1D"}
@@ -5,97 +5,494 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.startChat = startChat;
7
7
  const chalk_1 = __importDefault(require("chalk"));
8
- const inquirer_1 = __importDefault(require("inquirer"));
9
- const ora_1 = __importDefault(require("ora"));
10
- const marked_1 = require("marked");
11
8
  const bedrock_client_1 = require("../services/bedrock-client");
12
9
  const conversation_manager_1 = require("../services/conversation-manager");
13
10
  const tool_executor_1 = require("../services/tool-executor");
11
+ const memory_manager_1 = require("../services/memory-manager");
12
+ const slash_commands_1 = require("../services/slash-commands");
13
+ const history_manager_1 = require("../services/history-manager");
14
+ const readline_with_history_1 = require("../utils/readline-with-history");
14
15
  const prompts_1 = require("../utils/prompts");
15
- const markedTerminal = require('marked-terminal');
16
- marked_1.marked.use(markedTerminal);
16
+ const markdown_renderer_1 = require("../utils/markdown-renderer");
17
+ const error_handler_1 = require("../utils/error-handler");
17
18
  async function startChat(options) {
19
+ // Initialize CLAUDE.md support
20
+ (0, prompts_1.initializeClaudeMd)(process.cwd());
18
21
  const client = new bedrock_client_1.BedrockClient();
19
22
  const conversation = new conversation_manager_1.ConversationManager();
20
23
  const toolExecutor = new tool_executor_1.ToolExecutor();
24
+ const memoryManager = new memory_manager_1.MemoryManager(client);
25
+ const slashCommands = new slash_commands_1.SlashCommandManager();
26
+ const historyManager = new history_manager_1.HistoryManager();
27
+ // Connect memory manager to conversation
28
+ conversation.setMemoryManager(memoryManager);
21
29
  console.log(chalk_1.default.blue('BD Agent - AI Coding Assistant'));
22
- console.log(chalk_1.default.gray('Type "exit" or "quit" to end the session\n'));
30
+ console.log(chalk_1.default.gray('Type "exit" or "quit" to end the session'));
31
+ console.log(chalk_1.default.gray('Type "/help" for available commands'));
32
+ console.log(chalk_1.default.gray('Use ↑/↓ arrow keys to navigate command history\n'));
33
+ // Create readline interface with history support
34
+ const readlineWithHistory = new readline_with_history_1.ReadlineWithHistory(historyManager);
35
+ // Handle stdin close event (happens when piping input)
36
+ process.stdin.on('end', () => {
37
+ console.log(chalk_1.default.gray('\nInput stream ended.'));
38
+ readlineWithHistory.close();
39
+ });
40
+ // Keep the process alive
41
+ process.stdin.resume();
23
42
  while (true) {
24
- const { message } = await inquirer_1.default.prompt([
25
- {
26
- type: 'input',
27
- name: 'message',
28
- message: chalk_1.default.green('You:'),
29
- validate: (input) => input.trim().length > 0 || 'Please enter a message'
30
- }
31
- ]);
32
- if (['exit', 'quit'].includes(message.toLowerCase())) {
33
- console.log(chalk_1.default.yellow('\nGoodbye!'));
34
- break;
35
- }
36
- conversation.addMessage('user', message);
37
- const spinner = (0, ora_1.default)('Thinking...').start();
38
43
  try {
39
- const messages = conversation.getMessages();
40
- const tools = toolExecutor.getAvailableTools();
41
- const systemPrompt = (0, prompts_1.getSystemPrompt)();
42
- let assistantMessage = '';
43
- let pendingToolCalls = [];
44
- const stream = client.streamMessage(messages, tools, systemPrompt);
45
- for await (const chunk of stream) {
46
- if (typeof chunk === 'string') {
47
- assistantMessage += chunk;
44
+ // Get input with history support
45
+ let message;
46
+ if (process.stdin.isTTY) {
47
+ // Use custom readline with history for TTY
48
+ message = await readlineWithHistory.question(chalk_1.default.green('You: '));
49
+ }
50
+ else {
51
+ // Fallback for non-TTY environments
52
+ message = await readlineWithHistory.questionSimple(chalk_1.default.green('You: '));
53
+ }
54
+ if (['exit', 'quit'].includes(message.toLowerCase().trim())) {
55
+ console.log(chalk_1.default.yellow('\nGoodbye!'));
56
+ readlineWithHistory.close();
57
+ break;
58
+ }
59
+ // Memory management commands
60
+ if (message.trim() === '/memory') {
61
+ const stats = conversation.getMemoryStats();
62
+ if (stats) {
63
+ console.log(chalk_1.default.cyan('\nMemory Statistics:'));
64
+ console.log(chalk_1.default.gray(`Total messages: ${stats.totalMessages}`));
65
+ console.log(chalk_1.default.gray(`Summaries created: ${stats.summaryCount}`));
66
+ console.log(chalk_1.default.gray(`Max messages: ${stats.config.maxMessages}`));
67
+ console.log(chalk_1.default.gray(`Summary threshold: ${stats.config.summaryThreshold}`));
48
68
  }
49
- else if (chunk && 'toolUseId' in chunk) {
50
- pendingToolCalls.push(chunk);
69
+ else {
70
+ console.log(chalk_1.default.yellow('Memory management not available'));
51
71
  }
72
+ console.log('');
73
+ continue;
52
74
  }
53
- spinner.stop();
54
- if (assistantMessage) {
55
- console.log(chalk_1.default.blue('\nAssistant:'));
56
- console.log((0, marked_1.marked)(assistantMessage));
57
- conversation.addMessage('assistant', assistantMessage);
75
+ if (message.trim() === '/clear') {
76
+ conversation.clear();
77
+ memoryManager.clear();
78
+ console.log(chalk_1.default.green('Conversation cleared!\n'));
79
+ continue;
58
80
  }
59
- if (pendingToolCalls.length > 0) {
60
- for (const toolCall of pendingToolCalls) {
61
- const toolSpinner = (0, ora_1.default)(`Executing ${toolCall.name}...`).start();
62
- try {
63
- const result = await toolExecutor.executeTool(toolCall.name, toolCall.input);
64
- toolSpinner.succeed(`${toolCall.name} completed`);
65
- conversation.addToolResult(toolCall.toolUseId, result);
66
- if (result) {
67
- console.log(chalk_1.default.gray(`\nTool Result (${toolCall.name}):`));
68
- console.log((0, marked_1.marked)(typeof result === 'string' ? result : JSON.stringify(result, null, 2)));
81
+ if (message.trim() === '/help') {
82
+ console.log(chalk_1.default.cyan('\nAvailable commands:'));
83
+ console.log(chalk_1.default.gray(' /memory - Show memory statistics'));
84
+ console.log(chalk_1.default.gray(' /history - Show command history'));
85
+ console.log(chalk_1.default.gray(' /clear - Clear conversation history'));
86
+ console.log(chalk_1.default.gray(' /commands - List available slash commands'));
87
+ console.log(chalk_1.default.gray(' /help - Show this help message'));
88
+ console.log(chalk_1.default.gray(' exit - Exit the chat session'));
89
+ console.log(chalk_1.default.gray('\nNavigation:'));
90
+ console.log(chalk_1.default.gray(' ↑/↓ - Navigate through command history'));
91
+ console.log(chalk_1.default.gray(' Ctrl+A - Move to beginning of line'));
92
+ console.log(chalk_1.default.gray(' Ctrl+E - Move to end of line'));
93
+ console.log(chalk_1.default.gray('\nSlash commands:'));
94
+ const commands = slashCommands.getAllCommands();
95
+ for (const cmd of commands.slice(0, 5)) {
96
+ console.log(chalk_1.default.gray(` /${cmd.name} - ${cmd.description}`));
97
+ }
98
+ if (commands.length > 5) {
99
+ console.log(chalk_1.default.gray(` ... and ${commands.length - 5} more (use /commands to see all)`));
100
+ }
101
+ console.log('');
102
+ continue;
103
+ }
104
+ if (message.trim() === '/history') {
105
+ const history = historyManager.getHistory(20); // Show last 20 commands
106
+ if (history.length === 0) {
107
+ console.log(chalk_1.default.yellow('No command history available yet.'));
108
+ }
109
+ else {
110
+ console.log(chalk_1.default.cyan('\nCommand History (most recent first):'));
111
+ history.reverse().forEach((cmd, index) => {
112
+ console.log(chalk_1.default.gray(` ${index + 1}. ${cmd}`));
113
+ });
114
+ }
115
+ console.log('');
116
+ continue;
117
+ }
118
+ if (message.trim() === '/commands') {
119
+ console.log(chalk_1.default.cyan('\nAvailable slash commands:'));
120
+ const commands = slashCommands.getAllCommands();
121
+ for (const cmd of commands) {
122
+ console.log(chalk_1.default.yellow(` /${cmd.name}`) + chalk_1.default.gray(` - ${cmd.description}`));
123
+ if (cmd.arguments && cmd.arguments.length > 0) {
124
+ console.log(chalk_1.default.gray(` Arguments: ${cmd.arguments.join(', ')}`));
125
+ }
126
+ }
127
+ console.log(chalk_1.default.gray(`\nCustom commands directory: ${slashCommands.getCommandsDirectory()}`));
128
+ console.log('');
129
+ continue;
130
+ }
131
+ if (!message.trim()) {
132
+ continue;
133
+ }
134
+ // Check if it's a slash command
135
+ let processedMessage = message;
136
+ if (message.trim().startsWith('/')) {
137
+ const parts = message.trim().split(' ');
138
+ const commandName = parts[0].substring(1); // Remove the '/'
139
+ const args = parts.slice(1);
140
+ const expandedPrompt = slashCommands.executeCommand(commandName, args);
141
+ if (expandedPrompt) {
142
+ processedMessage = expandedPrompt;
143
+ console.log(chalk_1.default.gray(`Executing /${commandName}...\n`));
144
+ }
145
+ else {
146
+ console.log(chalk_1.default.red(`Unknown command: /${commandName}`));
147
+ console.log(chalk_1.default.gray('Use /help to see available commands\n'));
148
+ continue;
149
+ }
150
+ }
151
+ conversation.addMessage('user', processedMessage);
152
+ console.log(chalk_1.default.gray('Analyzing your request...'));
153
+ let timeoutCleared = false;
154
+ let isResponseReceived = false;
155
+ // Add timeout for initial response
156
+ const initialTimeout = setTimeout(() => {
157
+ if (!timeoutCleared && !isResponseReceived) {
158
+ console.log(chalk_1.default.red('\n✗ Response timeout - the AI is taking longer than expected'));
159
+ console.log(chalk_1.default.yellow('Please try again or check your AWS Bedrock connection.'));
160
+ }
161
+ }, 30000); // 30 second timeout for initial response
162
+ try {
163
+ const messages = await conversation.getOptimizedMessages();
164
+ const tools = toolExecutor.getAvailableTools();
165
+ const systemPrompt = (0, prompts_1.getSystemPrompt)();
166
+ let assistantMessage = '';
167
+ let pendingToolCalls = [];
168
+ let isFirstChunk = true;
169
+ const markdownRenderer = new markdown_renderer_1.StreamingMarkdownRenderer();
170
+ const stream = client.streamMessage(messages, tools, systemPrompt);
171
+ for await (const chunk of stream) {
172
+ if (typeof chunk === 'string') {
173
+ if (isFirstChunk) {
174
+ timeoutCleared = true;
175
+ isResponseReceived = true;
176
+ clearTimeout(initialTimeout); // Clear the timeout when we get first response
177
+ console.log(chalk_1.default.blue('\nAssistant:'));
178
+ isFirstChunk = false;
69
179
  }
180
+ // Process chunk through streaming markdown renderer
181
+ const formatted = markdownRenderer.addChunk(chunk);
182
+ process.stdout.write(formatted);
183
+ assistantMessage += chunk;
70
184
  }
71
- catch (error) {
72
- toolSpinner.fail(`${toolCall.name} failed`);
73
- console.error(chalk_1.default.red(`Error: ${error}`));
74
- conversation.addToolResult(toolCall.toolUseId, `Error: ${error}`);
185
+ else if (chunk && 'toolUseId' in chunk) {
186
+ if (!isFirstChunk) {
187
+ // Flush any remaining markdown content
188
+ const remaining = markdownRenderer.flush();
189
+ if (remaining)
190
+ process.stdout.write(remaining);
191
+ console.log(); // New line after text output
192
+ }
193
+ else {
194
+ timeoutCleared = true;
195
+ isResponseReceived = true;
196
+ clearTimeout(initialTimeout); // Clear the timeout when we get first response
197
+ }
198
+ pendingToolCalls.push(chunk);
75
199
  }
76
200
  }
77
- const followUpSpinner = (0, ora_1.default)('Processing tool results...').start();
78
- const followUpMessages = conversation.getMessages();
79
- const followUpStream = client.streamMessage(followUpMessages, tools, systemPrompt);
80
- let followUpMessage = '';
81
- for await (const chunk of followUpStream) {
82
- if (typeof chunk === 'string') {
83
- followUpMessage += chunk;
201
+ if (assistantMessage || pendingToolCalls.length > 0) {
202
+ // Flush any remaining content
203
+ const remaining = markdownRenderer.flush();
204
+ if (remaining)
205
+ process.stdout.write(remaining);
206
+ if (assistantMessage)
207
+ console.log(); // Ensure we end with a newline
208
+ // Add assistant message with both text and tool use blocks
209
+ const contentBlocks = [];
210
+ if (assistantMessage) {
211
+ contentBlocks.push({ text: assistantMessage });
212
+ }
213
+ for (const toolCall of pendingToolCalls) {
214
+ contentBlocks.push({ toolUse: toolCall });
215
+ }
216
+ if (contentBlocks.length > 0) {
217
+ conversation.addMessage('assistant', contentBlocks);
84
218
  }
85
219
  }
86
- followUpSpinner.stop();
87
- if (followUpMessage) {
88
- console.log(chalk_1.default.blue('\nAssistant:'));
89
- console.log((0, marked_1.marked)(followUpMessage));
90
- conversation.addMessage('assistant', followUpMessage);
220
+ // Tool execution loop - keep executing tools until no more are requested
221
+ let toolRounds = 0;
222
+ const MAX_TOOL_ROUNDS = 100; // Allow extended tool usage for mission completion
223
+ let consecutiveToolOnlyRounds = 0;
224
+ while (pendingToolCalls.length > 0 && toolRounds < MAX_TOOL_ROUNDS) {
225
+ toolRounds++;
226
+ const currentToolCalls = [...pendingToolCalls];
227
+ pendingToolCalls = []; // Clear for next round
228
+ for (const toolCall of currentToolCalls) {
229
+ // Create more descriptive spinner text based on tool
230
+ let spinnerText = `Executing ${toolCall.name}...`;
231
+ switch (toolCall.name) {
232
+ case 'read_file':
233
+ spinnerText = `Reading file: ${toolCall.input?.path || toolCall.input?.file_path || 'unknown'}`;
234
+ break;
235
+ case 'read':
236
+ spinnerText = `Reading file: ${toolCall.input?.file_path || toolCall.input?.path || 'unknown'}`;
237
+ break;
238
+ case 'write_file':
239
+ case 'write':
240
+ spinnerText = `Writing to file: ${toolCall.input.file_path || 'unknown'}`;
241
+ break;
242
+ case 'edit_file':
243
+ case 'edit':
244
+ case 'multi_edit':
245
+ spinnerText = `Editing file: ${toolCall.input.file_path || 'unknown'}`;
246
+ break;
247
+ case 'list_directory':
248
+ spinnerText = `Listing directory: ${toolCall.input.path || '.'}`;
249
+ break;
250
+ case 'run_command':
251
+ case 'bash':
252
+ spinnerText = `Running command: ${toolCall.input.command?.substring(0, 50) || 'unknown'}${toolCall.input.command?.length > 50 ? '...' : ''}`;
253
+ break;
254
+ case 'grep':
255
+ spinnerText = `Searching for pattern: "${toolCall.input.pattern?.substring(0, 30) || 'unknown'}"${toolCall.input.pattern?.length > 30 ? '...' : ''}`;
256
+ break;
257
+ case 'glob':
258
+ spinnerText = `Finding files matching: ${toolCall.input.pattern || 'unknown'}`;
259
+ break;
260
+ case 'git_status':
261
+ spinnerText = 'Checking git status...';
262
+ break;
263
+ case 'git_diff':
264
+ spinnerText = 'Getting git diff...';
265
+ break;
266
+ case 'git_add':
267
+ spinnerText = `Staging files: ${toolCall.input.files?.join(', ') || 'unknown'}`;
268
+ break;
269
+ case 'git_commit':
270
+ spinnerText = 'Creating git commit...';
271
+ break;
272
+ }
273
+ console.log(chalk_1.default.yellow(`⚡ ${spinnerText}`));
274
+ try {
275
+ // Check if tool exists
276
+ if (!toolExecutor.hasTool(toolCall.name)) {
277
+ throw new Error(`Unknown tool: ${toolCall.name}. Did you mean 'read_file'?`);
278
+ }
279
+ const result = await toolExecutor.executeTool(toolCall.name, toolCall.input);
280
+ // Create success message based on tool and result
281
+ let successMessage = `${toolCall.name} completed`;
282
+ switch (toolCall.name) {
283
+ case 'read_file':
284
+ if (result.success && result.content) {
285
+ const lines = result.content.split('\n').length;
286
+ successMessage = `Read ${lines} lines from ${toolCall.input?.path || 'file'}`;
287
+ }
288
+ break;
289
+ case 'read':
290
+ if (result.success && result.content) {
291
+ const lines = result.content.split('\n').length;
292
+ successMessage = `Read ${lines} lines from ${toolCall.input?.file_path || 'file'}`;
293
+ }
294
+ break;
295
+ case 'write_file':
296
+ case 'write':
297
+ if (result.success) {
298
+ successMessage = `Successfully wrote to ${toolCall.input.file_path}`;
299
+ }
300
+ break;
301
+ case 'edit_file':
302
+ case 'edit':
303
+ if (result.success) {
304
+ successMessage = `Successfully edited ${toolCall.input.file_path}`;
305
+ }
306
+ break;
307
+ case 'multi_edit':
308
+ if (result.success && toolCall.input.edits) {
309
+ successMessage = `Applied ${toolCall.input.edits.length} edits to ${toolCall.input.file_path}`;
310
+ }
311
+ break;
312
+ case 'grep':
313
+ if (result.success && result.matches) {
314
+ successMessage = `Found ${result.matches.length} matches`;
315
+ }
316
+ else if (result.success && result.count !== undefined) {
317
+ successMessage = `Found ${result.count} total matches`;
318
+ }
319
+ break;
320
+ case 'glob':
321
+ if (result.success && result.files) {
322
+ successMessage = `Found ${result.files.length} files matching pattern`;
323
+ }
324
+ break;
325
+ case 'run_command':
326
+ case 'bash':
327
+ if (result.success) {
328
+ successMessage = `Command executed successfully`;
329
+ }
330
+ break;
331
+ }
332
+ console.log(chalk_1.default.green(`✓ ${successMessage}`));
333
+ conversation.addToolResult(toolCall.toolUseId, result);
334
+ if (result) {
335
+ console.log(chalk_1.default.gray(`\nTool Result (${toolCall.name}):`));
336
+ // Special handling for edit tools to show diffs
337
+ if ((toolCall.name === 'edit_file' || toolCall.name === 'edit' || toolCall.name === 'multi_edit')
338
+ && result.success && result.diff) {
339
+ console.log((0, markdown_renderer_1.renderDiff)(result.diff.old, result.diff.new));
340
+ if (result.preview) {
341
+ console.log(chalk_1.default.gray('\nPreview:'));
342
+ console.log(result.preview);
343
+ }
344
+ }
345
+ else if (result.error) {
346
+ // Show errors in a more readable format
347
+ console.log(chalk_1.default.red(result.error));
348
+ }
349
+ else if ((toolCall.name === 'grep' || toolCall.name === 'glob') && result.success) {
350
+ // Special formatting for search results
351
+ if (result.matches) {
352
+ console.log(chalk_1.default.cyan(`Found ${result.matches.length} matches:`));
353
+ result.matches.forEach((match) => {
354
+ console.log(` ${chalk_1.default.yellow(match.file)}:${chalk_1.default.green(match.line)} ${match.match}`);
355
+ });
356
+ }
357
+ else if (result.files) {
358
+ console.log(chalk_1.default.cyan(`Found ${result.files.length} files:`));
359
+ result.files.forEach((file) => {
360
+ console.log(` ${chalk_1.default.yellow(file)}`);
361
+ });
362
+ }
363
+ else if (result.count !== undefined) {
364
+ console.log(chalk_1.default.cyan(`Total matches: ${result.count}`));
365
+ }
366
+ }
367
+ else {
368
+ // Regular JSON output for other tools
369
+ console.log(chalk_1.default.gray(JSON.stringify(result, null, 2)));
370
+ }
371
+ }
372
+ }
373
+ catch (error) {
374
+ console.log(chalk_1.default.red(`✗ ${toolCall.name} failed`));
375
+ const toolError = new error_handler_1.ToolExecutionError(error.message || String(error), toolCall.name, error);
376
+ console.error((0, error_handler_1.formatError)(toolError));
377
+ conversation.addToolResult(toolCall.toolUseId, `Error: ${error.message || error}`);
378
+ }
379
+ }
380
+ // Only show spinner if we're expecting a follow-up
381
+ console.log(''); // Add spacing
382
+ console.log(chalk_1.default.cyan('⏳ Waiting for AI response...'));
383
+ let streamTimeout;
384
+ try {
385
+ const followUpMessages = await conversation.getOptimizedMessages();
386
+ // Add timeout for streaming - give more time for follow-up responses
387
+ streamTimeout = setTimeout(() => {
388
+ if (!followUpMessage && pendingToolCalls.length === 0) {
389
+ console.log(chalk_1.default.gray('(AI completed tool execution without additional commentary)'));
390
+ }
391
+ }, 10000); // 10 second timeout for follow-up
392
+ const followUpStream = client.streamMessage(followUpMessages, tools, systemPrompt);
393
+ let followUpMessage = '';
394
+ let isFirstFollowUpChunk = true;
395
+ const followUpRenderer = new markdown_renderer_1.StreamingMarkdownRenderer();
396
+ for await (const chunk of followUpStream) {
397
+ if (typeof chunk === 'string') {
398
+ if (isFirstFollowUpChunk) {
399
+ console.log(chalk_1.default.blue('\nAssistant:'));
400
+ isFirstFollowUpChunk = false;
401
+ }
402
+ const formatted = followUpRenderer.addChunk(chunk);
403
+ process.stdout.write(formatted);
404
+ followUpMessage += chunk;
405
+ }
406
+ else if (chunk && 'toolUseId' in chunk) {
407
+ // Handle additional tool calls in follow-up
408
+ if (isFirstFollowUpChunk) {
409
+ isFirstFollowUpChunk = false;
410
+ }
411
+ // Collect the new tool call for the next iteration
412
+ console.log(chalk_1.default.yellow(`\n[AI requests tool: ${chunk.name}]`));
413
+ pendingToolCalls.push(chunk);
414
+ }
415
+ }
416
+ // Clear timeout since we completed successfully
417
+ clearTimeout(streamTimeout);
418
+ // Ensure spinner is stopped even if no chunks received
419
+ if (isFirstFollowUpChunk) {
420
+ }
421
+ if (followUpMessage || pendingToolCalls.length > 0) {
422
+ const remaining = followUpRenderer.flush();
423
+ if (remaining)
424
+ process.stdout.write(remaining);
425
+ if (followUpMessage)
426
+ console.log(); // Ensure we end with a newline
427
+ // Track if this was a tool-only response
428
+ if (!followUpMessage && pendingToolCalls.length > 0) {
429
+ consecutiveToolOnlyRounds++;
430
+ }
431
+ else {
432
+ consecutiveToolOnlyRounds = 0;
433
+ }
434
+ // Add assistant message with both text and any new tool calls
435
+ const followUpContentBlocks = [];
436
+ if (followUpMessage) {
437
+ followUpContentBlocks.push({ text: followUpMessage });
438
+ }
439
+ for (const toolCall of pendingToolCalls) {
440
+ followUpContentBlocks.push({ toolUse: toolCall });
441
+ }
442
+ if (followUpContentBlocks.length > 0) {
443
+ conversation.addMessage('assistant', followUpContentBlocks);
444
+ }
445
+ }
446
+ }
447
+ catch (followUpError) {
448
+ clearTimeout(streamTimeout);
449
+ console.log(chalk_1.default.red('✗ Failed to process tool results'));
450
+ console.error(chalk_1.default.red(`Error: ${followUpError.message}`));
451
+ // If it's a specific error about the model not responding, handle gracefully
452
+ if (followUpError.message?.includes('timeout') || followUpError.message?.includes('stream')) {
453
+ console.log(chalk_1.default.yellow('\nThe AI completed the tool execution but didn\'t provide additional commentary.'));
454
+ }
455
+ }
456
+ // Check if we should continue the loop
457
+ if (pendingToolCalls.length === 0) {
458
+ // No more tools to execute, we're done
459
+ break;
460
+ }
461
+ // Stop if too many consecutive tool-only responses
462
+ if (consecutiveToolOnlyRounds >= 100) {
463
+ console.log(chalk_1.default.yellow('\nThe AI is requesting many tools without providing explanations. Stopping here.'));
464
+ console.log(chalk_1.default.gray('You can ask a follow-up question to get more details.'));
465
+ break;
466
+ }
467
+ if (toolRounds >= MAX_TOOL_ROUNDS) {
468
+ console.log(chalk_1.default.yellow('\nReached maximum tool execution rounds.'));
469
+ break;
470
+ }
471
+ // Otherwise, continue with the next round of tool execution
472
+ } // End of while loop for tool execution
473
+ }
474
+ catch (error) {
475
+ timeoutCleared = true;
476
+ clearTimeout(initialTimeout); // Clear timeout on error
477
+ console.error((0, error_handler_1.formatError)(error));
478
+ // If it's a retryable error, suggest retrying
479
+ if (error.retryable) {
480
+ console.log(chalk_1.default.yellow('\nWould you like to try again? The error might be temporary.'));
91
481
  }
482
+ // Don't break the main loop - continue to accept new prompts
483
+ // This matches Claude's behavior of continuing after errors
92
484
  }
485
+ console.log('');
93
486
  }
94
- catch (error) {
95
- spinner.stop();
96
- console.error(chalk_1.default.red(`\nError: ${error}`));
487
+ catch (outerError) {
488
+ console.error(chalk_1.default.red(`\nFatal error in chat loop: ${outerError.message}`));
489
+ console.error(chalk_1.default.gray(outerError.stack));
490
+ readlineWithHistory.close();
491
+ break;
97
492
  }
98
- console.log('');
99
493
  }
494
+ // This should never be reached unless exit/quit is typed
495
+ console.log(chalk_1.default.gray('Chat session ended.'));
496
+ process.stdin.pause();
100
497
  }
101
498
  //# sourceMappingURL=chat.js.map