@loxia-labs/loxia-autopilot-one 1.0.1
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.
- package/LICENSE +267 -0
- package/README.md +509 -0
- package/bin/cli.js +117 -0
- package/package.json +94 -0
- package/scripts/install-scanners.js +236 -0
- package/src/analyzers/CSSAnalyzer.js +297 -0
- package/src/analyzers/ConfigValidator.js +690 -0
- package/src/analyzers/ESLintAnalyzer.js +320 -0
- package/src/analyzers/JavaScriptAnalyzer.js +261 -0
- package/src/analyzers/PrettierFormatter.js +247 -0
- package/src/analyzers/PythonAnalyzer.js +266 -0
- package/src/analyzers/SecurityAnalyzer.js +729 -0
- package/src/analyzers/TypeScriptAnalyzer.js +247 -0
- package/src/analyzers/codeCloneDetector/analyzer.js +344 -0
- package/src/analyzers/codeCloneDetector/detector.js +203 -0
- package/src/analyzers/codeCloneDetector/index.js +160 -0
- package/src/analyzers/codeCloneDetector/parser.js +199 -0
- package/src/analyzers/codeCloneDetector/reporter.js +148 -0
- package/src/analyzers/codeCloneDetector/scanner.js +59 -0
- package/src/core/agentPool.js +1474 -0
- package/src/core/agentScheduler.js +2147 -0
- package/src/core/contextManager.js +709 -0
- package/src/core/messageProcessor.js +732 -0
- package/src/core/orchestrator.js +548 -0
- package/src/core/stateManager.js +877 -0
- package/src/index.js +631 -0
- package/src/interfaces/cli.js +549 -0
- package/src/interfaces/webServer.js +2162 -0
- package/src/modules/fileExplorer/controller.js +280 -0
- package/src/modules/fileExplorer/index.js +37 -0
- package/src/modules/fileExplorer/middleware.js +92 -0
- package/src/modules/fileExplorer/routes.js +125 -0
- package/src/modules/fileExplorer/types.js +44 -0
- package/src/services/aiService.js +1232 -0
- package/src/services/apiKeyManager.js +164 -0
- package/src/services/benchmarkService.js +366 -0
- package/src/services/budgetService.js +539 -0
- package/src/services/contextInjectionService.js +247 -0
- package/src/services/conversationCompactionService.js +637 -0
- package/src/services/errorHandler.js +810 -0
- package/src/services/fileAttachmentService.js +544 -0
- package/src/services/modelRouterService.js +366 -0
- package/src/services/modelsService.js +322 -0
- package/src/services/qualityInspector.js +796 -0
- package/src/services/tokenCountingService.js +536 -0
- package/src/tools/agentCommunicationTool.js +1344 -0
- package/src/tools/agentDelayTool.js +485 -0
- package/src/tools/asyncToolManager.js +604 -0
- package/src/tools/baseTool.js +800 -0
- package/src/tools/browserTool.js +920 -0
- package/src/tools/cloneDetectionTool.js +621 -0
- package/src/tools/dependencyResolverTool.js +1215 -0
- package/src/tools/fileContentReplaceTool.js +875 -0
- package/src/tools/fileSystemTool.js +1107 -0
- package/src/tools/fileTreeTool.js +853 -0
- package/src/tools/imageTool.js +901 -0
- package/src/tools/importAnalyzerTool.js +1060 -0
- package/src/tools/jobDoneTool.js +248 -0
- package/src/tools/seekTool.js +956 -0
- package/src/tools/staticAnalysisTool.js +1778 -0
- package/src/tools/taskManagerTool.js +2873 -0
- package/src/tools/terminalTool.js +2304 -0
- package/src/tools/webTool.js +1430 -0
- package/src/types/agent.js +519 -0
- package/src/types/contextReference.js +972 -0
- package/src/types/conversation.js +730 -0
- package/src/types/toolCommand.js +747 -0
- package/src/utilities/attachmentValidator.js +292 -0
- package/src/utilities/configManager.js +582 -0
- package/src/utilities/constants.js +722 -0
- package/src/utilities/directoryAccessManager.js +535 -0
- package/src/utilities/fileProcessor.js +307 -0
- package/src/utilities/logger.js +436 -0
- package/src/utilities/tagParser.js +1246 -0
- package/src/utilities/toolConstants.js +317 -0
- package/web-ui/build/index.html +15 -0
- package/web-ui/build/logo.png +0 -0
- package/web-ui/build/logo2.png +0 -0
- package/web-ui/build/static/index-CjkkcnFA.js +344 -0
- package/web-ui/build/static/index-Dy2bYbOa.css +1 -0
|
@@ -0,0 +1,549 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Interface - Command Line Interface for Loxia AI Agents System
|
|
3
|
+
*
|
|
4
|
+
* Purpose:
|
|
5
|
+
* - Provide command-line interaction with the orchestrator
|
|
6
|
+
* - Handle user input and display responses
|
|
7
|
+
* - Support basic agent management and messaging
|
|
8
|
+
* - Interactive REPL-style interface
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import readline from 'readline';
|
|
12
|
+
import { INTERFACE_TYPES, ORCHESTRATOR_ACTIONS } from '../utilities/constants.js';
|
|
13
|
+
|
|
14
|
+
class CLIInterface {
|
|
15
|
+
constructor(orchestrator, logger, config = {}) {
|
|
16
|
+
this.orchestrator = orchestrator;
|
|
17
|
+
this.logger = logger;
|
|
18
|
+
this.config = config;
|
|
19
|
+
|
|
20
|
+
this.rl = null;
|
|
21
|
+
this.sessionId = `cli-${Date.now()}`;
|
|
22
|
+
this.currentAgent = null;
|
|
23
|
+
this.isRunning = false;
|
|
24
|
+
this.historySize = config.historySize || 1000;
|
|
25
|
+
this.commandHistory = [];
|
|
26
|
+
|
|
27
|
+
// CLI commands
|
|
28
|
+
this.commands = {
|
|
29
|
+
help: this.showHelp.bind(this),
|
|
30
|
+
exit: this.exit.bind(this),
|
|
31
|
+
quit: this.exit.bind(this),
|
|
32
|
+
status: this.showStatus.bind(this),
|
|
33
|
+
agents: this.listAgents.bind(this),
|
|
34
|
+
create: this.createAgent.bind(this),
|
|
35
|
+
switch: this.switchAgent.bind(this),
|
|
36
|
+
pause: this.pauseAgent.bind(this),
|
|
37
|
+
resume: this.resumeAgent.bind(this),
|
|
38
|
+
clear: this.clearScreen.bind(this),
|
|
39
|
+
history: this.showHistory.bind(this)
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Initialize CLI interface
|
|
45
|
+
* @returns {Promise<void>}
|
|
46
|
+
*/
|
|
47
|
+
async initialize() {
|
|
48
|
+
this.rl = readline.createInterface({
|
|
49
|
+
input: process.stdin,
|
|
50
|
+
output: process.stdout,
|
|
51
|
+
prompt: this.getPrompt(),
|
|
52
|
+
historySize: this.historySize
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Setup input handling
|
|
56
|
+
this.rl.on('line', this.handleInput.bind(this));
|
|
57
|
+
this.rl.on('close', this.exit.bind(this));
|
|
58
|
+
|
|
59
|
+
// Setup tab completion
|
|
60
|
+
this.rl.on('SIGINT', () => {
|
|
61
|
+
console.log('\n(To exit, type "exit" or press Ctrl+C again)');
|
|
62
|
+
this.rl.prompt();
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
this.isRunning = true;
|
|
66
|
+
|
|
67
|
+
// Show welcome message
|
|
68
|
+
this.showWelcome();
|
|
69
|
+
|
|
70
|
+
// Start the prompt
|
|
71
|
+
this.rl.prompt();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Handle user input
|
|
76
|
+
* @private
|
|
77
|
+
*/
|
|
78
|
+
async handleInput(input) {
|
|
79
|
+
const trimmedInput = input.trim();
|
|
80
|
+
|
|
81
|
+
if (trimmedInput.length === 0) {
|
|
82
|
+
this.rl.prompt();
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Add to history
|
|
87
|
+
this.commandHistory.push({
|
|
88
|
+
command: trimmedInput,
|
|
89
|
+
timestamp: new Date().toISOString()
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// Keep history within limits
|
|
93
|
+
if (this.commandHistory.length > this.historySize) {
|
|
94
|
+
this.commandHistory.shift();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
await this.processInput(trimmedInput);
|
|
99
|
+
} catch (error) {
|
|
100
|
+
console.error('❌ Error:', error.message);
|
|
101
|
+
this.logger?.error('CLI command error', {
|
|
102
|
+
command: trimmedInput,
|
|
103
|
+
error: error.message
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (this.isRunning) {
|
|
108
|
+
this.rl.prompt();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Process user input
|
|
114
|
+
* @private
|
|
115
|
+
*/
|
|
116
|
+
async processInput(input) {
|
|
117
|
+
// Check for CLI commands
|
|
118
|
+
if (input.startsWith('/')) {
|
|
119
|
+
const commandParts = input.slice(1).split(' ');
|
|
120
|
+
const command = commandParts[0].toLowerCase();
|
|
121
|
+
const args = commandParts.slice(1);
|
|
122
|
+
|
|
123
|
+
if (this.commands[command]) {
|
|
124
|
+
await this.commands[command](args);
|
|
125
|
+
return;
|
|
126
|
+
} else {
|
|
127
|
+
console.log(`❌ Unknown command: /${command}`);
|
|
128
|
+
console.log('Type /help for available commands');
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// If no current agent, suggest creating one
|
|
134
|
+
if (!this.currentAgent) {
|
|
135
|
+
console.log('💡 No agent selected. Create an agent first with: /create <agent-name>');
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Send message to current agent
|
|
140
|
+
await this.sendMessageToAgent(input);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Send message to current agent
|
|
145
|
+
* @private
|
|
146
|
+
*/
|
|
147
|
+
async sendMessageToAgent(message) {
|
|
148
|
+
console.log('📤 Sending to agent...');
|
|
149
|
+
|
|
150
|
+
try {
|
|
151
|
+
const request = {
|
|
152
|
+
interface: INTERFACE_TYPES.CLI,
|
|
153
|
+
sessionId: this.sessionId,
|
|
154
|
+
action: ORCHESTRATOR_ACTIONS.SEND_MESSAGE,
|
|
155
|
+
payload: {
|
|
156
|
+
agentId: this.currentAgent.id,
|
|
157
|
+
message,
|
|
158
|
+
mode: 'chat'
|
|
159
|
+
},
|
|
160
|
+
projectDir: process.cwd()
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
const response = await this.orchestrator.processRequest(request);
|
|
164
|
+
|
|
165
|
+
if (response.success) {
|
|
166
|
+
console.log('🤖 Agent response:');
|
|
167
|
+
console.log(response.data.message.content);
|
|
168
|
+
|
|
169
|
+
// Show tool results if any
|
|
170
|
+
if (response.data.toolResults && response.data.toolResults.length > 0) {
|
|
171
|
+
console.log('\n🔧 Tool execution results:');
|
|
172
|
+
for (const result of response.data.toolResults) {
|
|
173
|
+
console.log(` ${result.toolId}: ${result.status}`);
|
|
174
|
+
if (result.result) {
|
|
175
|
+
console.log(` Result: ${JSON.stringify(result.result, null, 2)}`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
} else {
|
|
181
|
+
console.error('❌ Agent response failed:', response.error);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
} catch (error) {
|
|
185
|
+
console.error('❌ Failed to send message:', error.message);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Show welcome message
|
|
191
|
+
* @private
|
|
192
|
+
*/
|
|
193
|
+
showWelcome() {
|
|
194
|
+
console.log('');
|
|
195
|
+
console.log('🎯 Welcome to Loxia Autopilot One CLI');
|
|
196
|
+
console.log(' Type /help for available commands');
|
|
197
|
+
console.log(' Type /create <name> to create your first agent');
|
|
198
|
+
console.log('');
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Show help information
|
|
203
|
+
* @private
|
|
204
|
+
*/
|
|
205
|
+
async showHelp() {
|
|
206
|
+
console.log('');
|
|
207
|
+
console.log('📚 Loxia Autopilot One CLI Commands:');
|
|
208
|
+
console.log('');
|
|
209
|
+
console.log(' /help - Show this help message');
|
|
210
|
+
console.log(' /status - Show system status');
|
|
211
|
+
console.log(' /agents - List all agents');
|
|
212
|
+
console.log(' /create <name> - Create a new agent');
|
|
213
|
+
console.log(' /switch <agent-id> - Switch to different agent');
|
|
214
|
+
console.log(' /pause <agent-id> - Pause an agent');
|
|
215
|
+
console.log(' /resume <agent-id> - Resume a paused agent');
|
|
216
|
+
console.log(' /history - Show command history');
|
|
217
|
+
console.log(' /clear - Clear screen');
|
|
218
|
+
console.log(' /exit or /quit - Exit the CLI');
|
|
219
|
+
console.log('');
|
|
220
|
+
console.log('💬 Chat with agents:');
|
|
221
|
+
console.log(' Simply type your message to send it to the current agent');
|
|
222
|
+
console.log(' Agents can use tools and communicate with other agents');
|
|
223
|
+
console.log('');
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Show system status
|
|
228
|
+
* @private
|
|
229
|
+
*/
|
|
230
|
+
async showStatus() {
|
|
231
|
+
try {
|
|
232
|
+
const request = {
|
|
233
|
+
interface: INTERFACE_TYPES.CLI,
|
|
234
|
+
sessionId: this.sessionId,
|
|
235
|
+
action: ORCHESTRATOR_ACTIONS.GET_SESSION_STATE,
|
|
236
|
+
payload: {},
|
|
237
|
+
projectDir: process.cwd()
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
const response = await this.orchestrator.processRequest(request);
|
|
241
|
+
|
|
242
|
+
if (response.success) {
|
|
243
|
+
const state = response.data;
|
|
244
|
+
console.log('');
|
|
245
|
+
console.log('📊 System Status:');
|
|
246
|
+
console.log(` Session ID: ${state.sessionId}`);
|
|
247
|
+
console.log(` Project: ${state.projectDir}`);
|
|
248
|
+
console.log(` Agents: ${state.agents.length}`);
|
|
249
|
+
console.log(` Current Agent: ${this.currentAgent ? this.currentAgent.name : 'None'}`);
|
|
250
|
+
console.log('');
|
|
251
|
+
|
|
252
|
+
if (state.agents.length > 0) {
|
|
253
|
+
console.log('🤖 Active Agents:');
|
|
254
|
+
for (const agent of state.agents) {
|
|
255
|
+
const status = agent.isPaused ? `${agent.status} (until ${agent.pausedUntil})` : agent.status;
|
|
256
|
+
console.log(` ${agent.id}: ${agent.name} (${status})`);
|
|
257
|
+
}
|
|
258
|
+
console.log('');
|
|
259
|
+
}
|
|
260
|
+
} else {
|
|
261
|
+
console.error('❌ Failed to get status:', response.error);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
} catch (error) {
|
|
265
|
+
console.error('❌ Status command failed:', error.message);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* List all agents
|
|
271
|
+
* @private
|
|
272
|
+
*/
|
|
273
|
+
async listAgents() {
|
|
274
|
+
try {
|
|
275
|
+
const request = {
|
|
276
|
+
interface: INTERFACE_TYPES.CLI,
|
|
277
|
+
sessionId: this.sessionId,
|
|
278
|
+
action: ORCHESTRATOR_ACTIONS.LIST_AGENTS,
|
|
279
|
+
payload: {},
|
|
280
|
+
projectDir: process.cwd()
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
const response = await this.orchestrator.processRequest(request);
|
|
284
|
+
|
|
285
|
+
if (response.success) {
|
|
286
|
+
const agents = response.data;
|
|
287
|
+
console.log('');
|
|
288
|
+
|
|
289
|
+
if (agents.length === 0) {
|
|
290
|
+
console.log('📭 No agents created yet');
|
|
291
|
+
console.log(' Use /create <name> to create your first agent');
|
|
292
|
+
} else {
|
|
293
|
+
console.log('🤖 Available Agents:');
|
|
294
|
+
|
|
295
|
+
for (const agent of agents) {
|
|
296
|
+
const current = this.currentAgent && this.currentAgent.id === agent.id ? ' (current)' : '';
|
|
297
|
+
const status = agent.isPaused ? `${agent.status} (until ${agent.pausedUntil})` : agent.status;
|
|
298
|
+
|
|
299
|
+
console.log(` ${agent.id}: ${agent.name}${current}`);
|
|
300
|
+
console.log(` Status: ${status}`);
|
|
301
|
+
console.log(` Model: ${agent.currentModel}`);
|
|
302
|
+
console.log(` Messages: ${agent.messageCount}`);
|
|
303
|
+
console.log('');
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
} else {
|
|
308
|
+
console.error('❌ Failed to list agents:', response.error);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
} catch (error) {
|
|
312
|
+
console.error('❌ List agents command failed:', error.message);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Create a new agent
|
|
318
|
+
* @private
|
|
319
|
+
*/
|
|
320
|
+
async createAgent(args) {
|
|
321
|
+
if (args.length === 0) {
|
|
322
|
+
console.log('❌ Usage: /create <agent-name> [model]');
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
const name = args[0];
|
|
327
|
+
const model = args[1] || 'anthropic-sonnet';
|
|
328
|
+
|
|
329
|
+
console.log(`🔨 Creating agent "${name}" with model ${model}...`);
|
|
330
|
+
|
|
331
|
+
try {
|
|
332
|
+
const request = {
|
|
333
|
+
interface: INTERFACE_TYPES.CLI,
|
|
334
|
+
sessionId: this.sessionId,
|
|
335
|
+
action: ORCHESTRATOR_ACTIONS.CREATE_AGENT,
|
|
336
|
+
payload: {
|
|
337
|
+
name,
|
|
338
|
+
systemPrompt: `You are ${name}, an AI assistant created in the Loxia Autopilot One system. You can help with coding, analysis, and various tasks using the available tools.`,
|
|
339
|
+
model,
|
|
340
|
+
capabilities: ['terminal', 'filesystem', 'agentdelay', 'browser']
|
|
341
|
+
},
|
|
342
|
+
projectDir: process.cwd()
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
const response = await this.orchestrator.processRequest(request);
|
|
346
|
+
|
|
347
|
+
if (response.success) {
|
|
348
|
+
const agent = response.data;
|
|
349
|
+
this.currentAgent = agent;
|
|
350
|
+
|
|
351
|
+
console.log('✅ Agent created successfully!');
|
|
352
|
+
console.log(` ID: ${agent.id}`);
|
|
353
|
+
console.log(` Name: ${agent.name}`);
|
|
354
|
+
console.log(` Model: ${agent.preferredModel}`);
|
|
355
|
+
console.log(' Switched to this agent automatically');
|
|
356
|
+
|
|
357
|
+
// Update prompt
|
|
358
|
+
this.rl.setPrompt(this.getPrompt());
|
|
359
|
+
|
|
360
|
+
} else {
|
|
361
|
+
console.error('❌ Failed to create agent:', response.error);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
} catch (error) {
|
|
365
|
+
console.error('❌ Create agent command failed:', error.message);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Switch to different agent
|
|
371
|
+
* @private
|
|
372
|
+
*/
|
|
373
|
+
async switchAgent(args) {
|
|
374
|
+
if (args.length === 0) {
|
|
375
|
+
console.log('❌ Usage: /switch <agent-id>');
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
const agentId = args[0];
|
|
380
|
+
|
|
381
|
+
try {
|
|
382
|
+
// First, get the agent to verify it exists
|
|
383
|
+
const request = {
|
|
384
|
+
interface: INTERFACE_TYPES.CLI,
|
|
385
|
+
sessionId: this.sessionId,
|
|
386
|
+
action: ORCHESTRATOR_ACTIONS.GET_AGENT_STATUS,
|
|
387
|
+
payload: { agentId },
|
|
388
|
+
projectDir: process.cwd()
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
const response = await this.orchestrator.processRequest(request);
|
|
392
|
+
|
|
393
|
+
if (response.success) {
|
|
394
|
+
this.currentAgent = response.data;
|
|
395
|
+
console.log(`✅ Switched to agent: ${this.currentAgent.name} (${this.currentAgent.id})`);
|
|
396
|
+
|
|
397
|
+
// Update prompt
|
|
398
|
+
this.rl.setPrompt(this.getPrompt());
|
|
399
|
+
|
|
400
|
+
} else {
|
|
401
|
+
console.error('❌ Failed to switch agent:', response.error);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
} catch (error) {
|
|
405
|
+
console.error('❌ Switch agent command failed:', error.message);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Pause an agent
|
|
411
|
+
* @private
|
|
412
|
+
*/
|
|
413
|
+
async pauseAgent(args) {
|
|
414
|
+
if (args.length === 0) {
|
|
415
|
+
console.log('❌ Usage: /pause <agent-id> [duration] [reason]');
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
const agentId = args[0];
|
|
420
|
+
const duration = parseInt(args[1]) || 60;
|
|
421
|
+
const reason = args.slice(2).join(' ') || 'Manual pause from CLI';
|
|
422
|
+
|
|
423
|
+
try {
|
|
424
|
+
const request = {
|
|
425
|
+
interface: INTERFACE_TYPES.CLI,
|
|
426
|
+
sessionId: this.sessionId,
|
|
427
|
+
action: ORCHESTRATOR_ACTIONS.PAUSE_AGENT,
|
|
428
|
+
payload: { agentId, duration, reason },
|
|
429
|
+
projectDir: process.cwd()
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
const response = await this.orchestrator.processRequest(request);
|
|
433
|
+
|
|
434
|
+
if (response.success) {
|
|
435
|
+
console.log(`✅ Agent paused for ${duration} seconds`);
|
|
436
|
+
console.log(` Reason: ${reason}`);
|
|
437
|
+
} else {
|
|
438
|
+
console.error('❌ Failed to pause agent:', response.error);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
} catch (error) {
|
|
442
|
+
console.error('❌ Pause agent command failed:', error.message);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Resume a paused agent
|
|
448
|
+
* @private
|
|
449
|
+
*/
|
|
450
|
+
async resumeAgent(args) {
|
|
451
|
+
if (args.length === 0) {
|
|
452
|
+
console.log('❌ Usage: /resume <agent-id>');
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
const agentId = args[0];
|
|
457
|
+
|
|
458
|
+
try {
|
|
459
|
+
const request = {
|
|
460
|
+
interface: INTERFACE_TYPES.CLI,
|
|
461
|
+
sessionId: this.sessionId,
|
|
462
|
+
action: ORCHESTRATOR_ACTIONS.RESUME_AGENT,
|
|
463
|
+
payload: { agentId },
|
|
464
|
+
projectDir: process.cwd()
|
|
465
|
+
};
|
|
466
|
+
|
|
467
|
+
const response = await this.orchestrator.processRequest(request);
|
|
468
|
+
|
|
469
|
+
if (response.success) {
|
|
470
|
+
console.log('✅ Agent resumed successfully');
|
|
471
|
+
} else {
|
|
472
|
+
console.error('❌ Failed to resume agent:', response.error);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
} catch (error) {
|
|
476
|
+
console.error('❌ Resume agent command failed:', error.message);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Show command history
|
|
482
|
+
* @private
|
|
483
|
+
*/
|
|
484
|
+
async showHistory() {
|
|
485
|
+
console.log('');
|
|
486
|
+
console.log('📜 Command History:');
|
|
487
|
+
|
|
488
|
+
if (this.commandHistory.length === 0) {
|
|
489
|
+
console.log(' No commands executed yet');
|
|
490
|
+
} else {
|
|
491
|
+
const recent = this.commandHistory.slice(-10); // Show last 10 commands
|
|
492
|
+
|
|
493
|
+
for (let i = 0; i < recent.length; i++) {
|
|
494
|
+
const entry = recent[i];
|
|
495
|
+
const time = new Date(entry.timestamp).toLocaleTimeString();
|
|
496
|
+
console.log(` ${i + 1}. [${time}] ${entry.command}`);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
if (this.commandHistory.length > 10) {
|
|
500
|
+
console.log(` ... and ${this.commandHistory.length - 10} more commands`);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
console.log('');
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Clear screen
|
|
509
|
+
* @private
|
|
510
|
+
*/
|
|
511
|
+
async clearScreen() {
|
|
512
|
+
console.clear();
|
|
513
|
+
this.showWelcome();
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* Exit the CLI
|
|
518
|
+
* @private
|
|
519
|
+
*/
|
|
520
|
+
async exit() {
|
|
521
|
+
if (this.isRunning) {
|
|
522
|
+
console.log('\n👋 Goodbye!');
|
|
523
|
+
this.isRunning = false;
|
|
524
|
+
|
|
525
|
+
if (this.rl) {
|
|
526
|
+
this.rl.close();
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* Get command prompt
|
|
533
|
+
* @private
|
|
534
|
+
*/
|
|
535
|
+
getPrompt() {
|
|
536
|
+
const agentName = this.currentAgent ? this.currentAgent.name : 'no-agent';
|
|
537
|
+
return `loxia:${agentName}> `;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
/**
|
|
541
|
+
* Shutdown the CLI interface
|
|
542
|
+
* @returns {Promise<void>}
|
|
543
|
+
*/
|
|
544
|
+
async shutdown() {
|
|
545
|
+
await this.exit();
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
export default CLIInterface;
|