helix-assistant-cli 0.0.0-stage → 0.2.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/bin/helix.js +3 -0
- package/dist/client/agent-client.d.ts +60 -0
- package/dist/client/agent-client.js +322 -0
- package/dist/client/agent-launcher.d.ts +30 -0
- package/dist/client/agent-launcher.js +339 -0
- package/dist/client/types.d.ts +88 -0
- package/dist/client/types.js +2 -0
- package/dist/commands/apikey.d.ts +3 -0
- package/dist/commands/apikey.js +123 -0
- package/dist/commands/browser.d.ts +2 -0
- package/dist/commands/browser.js +35 -0
- package/dist/commands/mcp.d.ts +3 -0
- package/dist/commands/mcp.js +102 -0
- package/dist/commands/mic.d.ts +2 -0
- package/dist/commands/mic.js +57 -0
- package/dist/commands/skills.d.ts +3 -0
- package/dist/commands/skills.js +105 -0
- package/dist/config/env.d.ts +6 -0
- package/dist/config/env.js +71 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +126 -0
- package/dist/ui/autocomplete.d.ts +25 -0
- package/dist/ui/autocomplete.js +142 -0
- package/dist/ui/banner.d.ts +24 -0
- package/dist/ui/banner.js +207 -0
- package/dist/ui/chat.d.ts +1 -0
- package/dist/ui/chat.js +5 -0
- package/dist/ui/colors.d.ts +34 -0
- package/dist/ui/colors.js +69 -0
- package/dist/ui/repl.d.ts +31 -0
- package/dist/ui/repl.js +402 -0
- package/package.json +31 -4
- package/src/client/agent-client.ts +387 -0
- package/src/client/agent-launcher.ts +374 -0
- package/src/client/types.ts +95 -0
- package/src/commands/apikey.ts +129 -0
- package/src/commands/browser.ts +39 -0
- package/src/commands/mcp.ts +105 -0
- package/src/commands/mic.ts +57 -0
- package/src/commands/skills.ts +109 -0
- package/src/config/env.ts +63 -0
- package/src/index.ts +139 -0
- package/src/ui/autocomplete.ts +153 -0
- package/src/ui/banner.ts +240 -0
- package/src/ui/chat.ts +1 -0
- package/src/ui/colors.ts +70 -0
- package/src/ui/repl.ts +473 -0
- package/tests/cli.test.ts +141 -0
- package/tsconfig.json +18 -0
- package/tsconfig.test.json +7 -0
- package/README.md +0 -3
package/dist/ui/repl.js
ADDED
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.HelixRepl = void 0;
|
|
7
|
+
const readline_1 = __importDefault(require("readline"));
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const prompts_1 = __importDefault(require("prompts"));
|
|
10
|
+
const agent_client_1 = require("../client/agent-client");
|
|
11
|
+
const autocomplete_1 = require("./autocomplete");
|
|
12
|
+
const banner_1 = require("./banner");
|
|
13
|
+
const colors_1 = require("./colors");
|
|
14
|
+
const apikey_1 = require("../commands/apikey");
|
|
15
|
+
const skills_1 = require("../commands/skills");
|
|
16
|
+
const mcp_1 = require("../commands/mcp");
|
|
17
|
+
const mic_1 = require("../commands/mic");
|
|
18
|
+
const browser_1 = require("../commands/browser");
|
|
19
|
+
class HelixRepl {
|
|
20
|
+
options;
|
|
21
|
+
rl = null;
|
|
22
|
+
client;
|
|
23
|
+
autocompleter;
|
|
24
|
+
conversationId;
|
|
25
|
+
conversationHistory = [];
|
|
26
|
+
voiceEnabled = true;
|
|
27
|
+
isCapturingVoice = false;
|
|
28
|
+
currentModel = null;
|
|
29
|
+
activeTaskId = null;
|
|
30
|
+
activeTasksCount = 0;
|
|
31
|
+
isProcessingPrompt = false;
|
|
32
|
+
constructor(options) {
|
|
33
|
+
this.options = options;
|
|
34
|
+
this.conversationId = `cli_conv_${Date.now()}_${Math.random().toString(36).substring(2, 7)}`;
|
|
35
|
+
this.client = new agent_client_1.AgentClient({
|
|
36
|
+
wsUrl: options.wsUrl,
|
|
37
|
+
wsToken: options.wsToken,
|
|
38
|
+
});
|
|
39
|
+
this.autocompleter = new autocomplete_1.Autocompleter(this.client);
|
|
40
|
+
}
|
|
41
|
+
async start() {
|
|
42
|
+
this._setupClientEvents();
|
|
43
|
+
try {
|
|
44
|
+
await this.client.connect();
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// Connect in background if agent is still starting
|
|
48
|
+
}
|
|
49
|
+
await this._syncSettings();
|
|
50
|
+
await this.autocompleter.refreshSuggestions();
|
|
51
|
+
// Render persistent initial banner
|
|
52
|
+
this.refreshBanner(true);
|
|
53
|
+
this._startReadline();
|
|
54
|
+
}
|
|
55
|
+
async _syncSettings() {
|
|
56
|
+
if (!this.client.connected)
|
|
57
|
+
return;
|
|
58
|
+
try {
|
|
59
|
+
// CLI mode: disable camera/gesture engine and skip per-tool verification
|
|
60
|
+
// (verification adds 2 extra LLM round-trips per tool call, not needed in CLI context)
|
|
61
|
+
await this.client.saveSettings({
|
|
62
|
+
camera_enabled: false,
|
|
63
|
+
tool_verification_enabled: false,
|
|
64
|
+
}).catch(() => { });
|
|
65
|
+
const settings = await this.client.getSettings();
|
|
66
|
+
if (typeof settings.voice_enabled === 'boolean') {
|
|
67
|
+
this.voiceEnabled = settings.voice_enabled;
|
|
68
|
+
}
|
|
69
|
+
if (typeof settings.default_model === 'string') {
|
|
70
|
+
this.currentModel = settings.default_model;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// Fallback defaults
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
refreshBanner(clearScreen = false) {
|
|
78
|
+
const status = {
|
|
79
|
+
connected: this.client.connected,
|
|
80
|
+
wsUrl: this.client.url,
|
|
81
|
+
voiceEnabled: this.voiceEnabled,
|
|
82
|
+
isCapturingVoice: this.isCapturingVoice,
|
|
83
|
+
currentModel: this.currentModel,
|
|
84
|
+
activeTasksCount: this.activeTasksCount,
|
|
85
|
+
};
|
|
86
|
+
(0, banner_1.renderHeader)(status, clearScreen);
|
|
87
|
+
}
|
|
88
|
+
waitingLogged = false;
|
|
89
|
+
_setupClientEvents() {
|
|
90
|
+
this.client.on('connected', async () => {
|
|
91
|
+
this.waitingLogged = false;
|
|
92
|
+
await this._syncSettings();
|
|
93
|
+
await this.autocompleter.refreshSuggestions();
|
|
94
|
+
process.stdout.write(`\r\x1b[K${chalk_1.default.green('●')} ${chalk_1.default.greenBright.bold('Conectado al agente HELIX')} \n`);
|
|
95
|
+
this._promptUser();
|
|
96
|
+
});
|
|
97
|
+
this.client.on('disconnected', () => {
|
|
98
|
+
if (this.client.isStarting) {
|
|
99
|
+
return; // Do not interrupt or print disconnect loops while agent is booting
|
|
100
|
+
}
|
|
101
|
+
if (!this.waitingLogged) {
|
|
102
|
+
this.waitingLogged = true;
|
|
103
|
+
console.log(`\n${(0, colors_1.RED)('●')} ${chalk_1.default.yellowBright('Esperando al servicio del agente HELIX en ws://127.0.0.1:8765...')}`);
|
|
104
|
+
console.log(`${(0, colors_1.GRAY)(' (Si no responde tras 3 reintentos, el CLI lo iniciará automáticamente en segundo plano)')}\n`);
|
|
105
|
+
}
|
|
106
|
+
this._promptUser();
|
|
107
|
+
});
|
|
108
|
+
this.client.on('auto_spawning_agent', () => {
|
|
109
|
+
process.stdout.write(`\n${(0, colors_1.CYAN_BOLD)('⚙️')} ${chalk_1.default.hex('#FF9F1C').bold('[AUTO-START]:')} Iniciando el servicio del agente HELIX en segundo plano...\n`);
|
|
110
|
+
process.stdout.write(`${(0, colors_1.GRAY)(' Por favor espere mientras termina de inicializarse (no se realizarán reintentos hasta que esté listo).')}\n`);
|
|
111
|
+
});
|
|
112
|
+
this.client.on('agent_starting_progress', (data) => {
|
|
113
|
+
process.stdout.write(`\r ${chalk_1.default.hex('#FF9F1C')('⏳')} ${chalk_1.default.gray(`Inicializando subsistemas de HELIX en segundo plano... (${data.elapsedSec}s)`)}`);
|
|
114
|
+
});
|
|
115
|
+
this.client.on('agent_ready', () => {
|
|
116
|
+
process.stdout.write(`\r\x1b[K ${chalk_1.default.green('✔')} ${chalk_1.default.greenBright('Servicio de HELIX listo. Conectando...')}\n\n`);
|
|
117
|
+
});
|
|
118
|
+
this.client.on('agent_start_failed', (data) => {
|
|
119
|
+
process.stdout.write(`\r\x1b[K\n ${chalk_1.default.red('✖')} ${chalk_1.default.redBright('No se pudo iniciar el servicio automáticamente:')} ${chalk_1.default.gray(data?.error || 'Tiempo agotado')}\n`);
|
|
120
|
+
this._promptUser();
|
|
121
|
+
});
|
|
122
|
+
// Voice Capture indicator
|
|
123
|
+
this.client.on('voice_capture_started', () => {
|
|
124
|
+
this.isCapturingVoice = true;
|
|
125
|
+
process.stdout.write(`\n${chalk_1.default.bgRed.white.bold(' 🎙️ [VOZ DETECTADA - HEY HELIX]: Capturando audio... ')}\n`);
|
|
126
|
+
});
|
|
127
|
+
this.client.on('voice_capture_stopped', () => {
|
|
128
|
+
this.isCapturingVoice = false;
|
|
129
|
+
process.stdout.write(`\n${chalk_1.default.bgCyan.black.bold(' 🔊 [AUDIO RECIBIDO]: Procesando voz... ')}\n`);
|
|
130
|
+
this._promptUser();
|
|
131
|
+
});
|
|
132
|
+
// ReAct Step Progress
|
|
133
|
+
this.client.on('react_step', (step) => {
|
|
134
|
+
const iter = step?.iteration ?? 1;
|
|
135
|
+
const role = step?.role ? chalk_1.default.gray(` (${step.role})`) : '';
|
|
136
|
+
process.stdout.write(`\r ${chalk_1.default.hex('#FF9F1C')('◆')} ${chalk_1.default.gray(`Paso ${iter}${role} — Razonando...`)}`);
|
|
137
|
+
});
|
|
138
|
+
// Agent assistant message
|
|
139
|
+
this.client.on('agent_message', (payload) => {
|
|
140
|
+
this.isProcessingPrompt = false;
|
|
141
|
+
this.activeTaskId = null;
|
|
142
|
+
if (this.activeTasksCount > 0)
|
|
143
|
+
this.activeTasksCount--;
|
|
144
|
+
const content = payload?.content ?? '';
|
|
145
|
+
const modelBadge = payload?.model
|
|
146
|
+
? chalk_1.default.gray(` [${payload.model}]`)
|
|
147
|
+
: '';
|
|
148
|
+
// Clear any in-progress step line
|
|
149
|
+
process.stdout.write('\r\x1b[K');
|
|
150
|
+
// Branded header
|
|
151
|
+
console.log('');
|
|
152
|
+
console.log(` ${chalk_1.default.hex('#FF8C00').bold('⬡ HELIX')}${modelBadge}`);
|
|
153
|
+
// Content with subtle left border
|
|
154
|
+
const contentLines = content.trim().split('\n');
|
|
155
|
+
for (const line of contentLines) {
|
|
156
|
+
console.log(` ${chalk_1.default.gray('│')} ${line}`);
|
|
157
|
+
}
|
|
158
|
+
console.log('');
|
|
159
|
+
this.conversationHistory.push({ role: 'assistant', content });
|
|
160
|
+
this._promptUser();
|
|
161
|
+
});
|
|
162
|
+
// Confirmation request from agent
|
|
163
|
+
this.client.on('confirmation_request', async (req) => {
|
|
164
|
+
await this._handleConfirmationDialog(req);
|
|
165
|
+
});
|
|
166
|
+
// Task updates
|
|
167
|
+
this.client.on('task_update', (task) => {
|
|
168
|
+
if (task.status === 'RUNNING') {
|
|
169
|
+
this.activeTaskId = task.task_id || null;
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
async _handleConfirmationDialog(req) {
|
|
174
|
+
console.log(`\n${(0, colors_1.YELLOW_BOLD)('⚠️ CONFIRMACIÓN DE ACCIÓN REQUERIDA')}`);
|
|
175
|
+
console.log(` Acción: ${chalk_1.default.white.bold(req.action || req.tool || 'Acción del sistema')}`);
|
|
176
|
+
if (req.description) {
|
|
177
|
+
console.log(` Descripción: ${(0, colors_1.DIM)(req.description)}`);
|
|
178
|
+
}
|
|
179
|
+
if (req.arguments && Object.keys(req.arguments).length > 0) {
|
|
180
|
+
console.log(` Parámetros: ${(0, colors_1.GRAY)(JSON.stringify(req.arguments))}`);
|
|
181
|
+
}
|
|
182
|
+
const answer = await (0, prompts_1.default)({
|
|
183
|
+
type: 'confirm',
|
|
184
|
+
name: 'confirmed',
|
|
185
|
+
message: '¿Permitir al agente ejecutar esta acción?',
|
|
186
|
+
initial: true,
|
|
187
|
+
});
|
|
188
|
+
const reqId = req.request_id || req.id || '';
|
|
189
|
+
if (answer.confirmed) {
|
|
190
|
+
this.client.confirmAction(reqId);
|
|
191
|
+
console.log((0, colors_1.GREEN)(' ✔ Acción confirmada.\n'));
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
this.client.rejectAction(reqId);
|
|
195
|
+
console.log((0, colors_1.RED)(' ✖ Acción rechazada.\n'));
|
|
196
|
+
}
|
|
197
|
+
this._promptUser();
|
|
198
|
+
}
|
|
199
|
+
_startReadline() {
|
|
200
|
+
const rl = readline_1.default.createInterface({
|
|
201
|
+
input: process.stdin,
|
|
202
|
+
output: process.stdout,
|
|
203
|
+
completer: (line) => this.autocompleter.completer(line),
|
|
204
|
+
terminal: true,
|
|
205
|
+
});
|
|
206
|
+
this.rl = rl;
|
|
207
|
+
rl.on('line', async (line) => {
|
|
208
|
+
await this._handleInputLine(line.trim());
|
|
209
|
+
});
|
|
210
|
+
rl.on('close', () => {
|
|
211
|
+
console.log((0, colors_1.DIM)('\nCerrando sesión de HELIX CLI...'));
|
|
212
|
+
this.client.close();
|
|
213
|
+
process.exit(0);
|
|
214
|
+
});
|
|
215
|
+
// Ctrl+C handling: Cancel active task if running, or exit
|
|
216
|
+
rl.on('SIGINT', () => {
|
|
217
|
+
if (this.isProcessingPrompt && this.activeTaskId) {
|
|
218
|
+
console.log((0, colors_1.YELLOW)('\n[!] Cancelando tarea activa...'));
|
|
219
|
+
this.client.cancelTask(this.activeTaskId);
|
|
220
|
+
this.isProcessingPrompt = false;
|
|
221
|
+
this.activeTaskId = null;
|
|
222
|
+
this._promptUser();
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
console.log((0, colors_1.DIM)('\n¡Hasta pronto!'));
|
|
226
|
+
this.client.close();
|
|
227
|
+
process.exit(0);
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
this._promptUser();
|
|
231
|
+
}
|
|
232
|
+
_promptUser() {
|
|
233
|
+
if (!this.rl)
|
|
234
|
+
return;
|
|
235
|
+
const promptPrefix = ` ${chalk_1.default.hex('#FF8C00').bold('helix')} ${chalk_1.default.gray('❯')} `;
|
|
236
|
+
this.rl.setPrompt(promptPrefix);
|
|
237
|
+
this.rl.prompt();
|
|
238
|
+
}
|
|
239
|
+
async _handleInputLine(line) {
|
|
240
|
+
if (!line) {
|
|
241
|
+
this._promptUser();
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (this.client.isStarting) {
|
|
245
|
+
console.log(`\n ${chalk_1.default.yellow('⚠️')} ${chalk_1.default.yellowBright('El servicio de HELIX se está iniciando en segundo plano. Espera a que termine antes de enviar comandos o reintentar.')}\n`);
|
|
246
|
+
this._promptUser();
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
// --- Slash commands handling ---
|
|
250
|
+
if (line.startsWith('/')) {
|
|
251
|
+
const parts = line.split(/\s+/);
|
|
252
|
+
const cmd = parts[0].toLowerCase();
|
|
253
|
+
const args = line.slice(cmd.length).trim();
|
|
254
|
+
switch (cmd) {
|
|
255
|
+
case '/help':
|
|
256
|
+
this.autocompleter.renderHelp();
|
|
257
|
+
break;
|
|
258
|
+
case '/clear':
|
|
259
|
+
this.refreshBanner(true);
|
|
260
|
+
break;
|
|
261
|
+
case '/config-apikey':
|
|
262
|
+
this.rl?.pause();
|
|
263
|
+
await (0, apikey_1.handleConfigApiKey)(this.client);
|
|
264
|
+
this.rl?.resume();
|
|
265
|
+
break;
|
|
266
|
+
case '/show-apikey':
|
|
267
|
+
await (0, apikey_1.handleShowApiKey)(this.client);
|
|
268
|
+
break;
|
|
269
|
+
case '/skill':
|
|
270
|
+
await (0, skills_1.handleListSkills)(this.client, args || undefined);
|
|
271
|
+
break;
|
|
272
|
+
case '/create-skill':
|
|
273
|
+
this.rl?.pause();
|
|
274
|
+
await (0, skills_1.handleCreateSkill)(this.client);
|
|
275
|
+
await this.autocompleter.refreshSuggestions();
|
|
276
|
+
this.rl?.resume();
|
|
277
|
+
break;
|
|
278
|
+
case '/mcp':
|
|
279
|
+
await (0, mcp_1.handleListMcp)(this.client);
|
|
280
|
+
break;
|
|
281
|
+
case '/create-mcp':
|
|
282
|
+
this.rl?.pause();
|
|
283
|
+
await (0, mcp_1.handleCreateMcp)(this.client);
|
|
284
|
+
await this.autocompleter.refreshSuggestions();
|
|
285
|
+
this.rl?.resume();
|
|
286
|
+
break;
|
|
287
|
+
case '/microphone': {
|
|
288
|
+
const newState = await (0, mic_1.handleMicrophoneCommand)(this.client, args, this.voiceEnabled);
|
|
289
|
+
this.voiceEnabled = newState;
|
|
290
|
+
break;
|
|
291
|
+
}
|
|
292
|
+
case '/browser':
|
|
293
|
+
await (0, browser_1.handleBrowserCommand)(this.client, args);
|
|
294
|
+
break;
|
|
295
|
+
case '/tasks':
|
|
296
|
+
await this._handleListTasks();
|
|
297
|
+
break;
|
|
298
|
+
case '/models':
|
|
299
|
+
await this._handleListModels();
|
|
300
|
+
break;
|
|
301
|
+
case '/status':
|
|
302
|
+
await this._handleStatus();
|
|
303
|
+
break;
|
|
304
|
+
case '/stop':
|
|
305
|
+
console.log((0, colors_1.RED_BOLD)('\n[PARADA DE EMERGENCIA]: Cancelando todas las tareas activas...'));
|
|
306
|
+
this.client.emergencyStop();
|
|
307
|
+
this.isProcessingPrompt = false;
|
|
308
|
+
this.activeTaskId = null;
|
|
309
|
+
console.log((0, colors_1.GREEN)('✔ Todas las tareas han sido detenidas.\n'));
|
|
310
|
+
break;
|
|
311
|
+
case '/exit':
|
|
312
|
+
case '/quit':
|
|
313
|
+
this.client.close();
|
|
314
|
+
process.exit(0);
|
|
315
|
+
break;
|
|
316
|
+
default:
|
|
317
|
+
console.log((0, colors_1.YELLOW)(`Comando desconocido: "${cmd}". Escribe /help para ver la lista de comandos.`));
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
320
|
+
this._promptUser();
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
// --- Direct chat message / @skill / #mcp ---
|
|
324
|
+
if (!this.client.connected) {
|
|
325
|
+
console.log((0, colors_1.YELLOW)('⚠ El agente no está conectado actualmente. Intentando enviar de todos modos...'));
|
|
326
|
+
}
|
|
327
|
+
// Highlight skills in strong orange (#FF8C00) and mcps in cyan
|
|
328
|
+
const knownSkills = this.autocompleter.getSkills();
|
|
329
|
+
const formattedEcho = (0, colors_1.highlightMentions)(line, knownSkills);
|
|
330
|
+
// Record user message in history
|
|
331
|
+
this.conversationHistory.push({ role: 'user', content: line });
|
|
332
|
+
this.isProcessingPrompt = true;
|
|
333
|
+
this.activeTasksCount++;
|
|
334
|
+
process.stdout.write(` ${chalk_1.default.gray('→')} ${formattedEcho}\n`);
|
|
335
|
+
process.stdout.write(` ${chalk_1.default.hex('#FF9F1C')('◆')} ${chalk_1.default.gray('Procesando...')}`);
|
|
336
|
+
const sent = this.client.sendUserText(line, this.conversationId, this.conversationHistory.slice(-10));
|
|
337
|
+
if (!sent) {
|
|
338
|
+
process.stdout.write('\r\x1b[K');
|
|
339
|
+
console.log((0, colors_1.RED)('✖ Error: No se pudo enviar el mensaje (WebSocket desconectado).'));
|
|
340
|
+
this.isProcessingPrompt = false;
|
|
341
|
+
this.activeTasksCount = Math.max(0, this.activeTasksCount - 1);
|
|
342
|
+
this._promptUser();
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
async _handleListTasks() {
|
|
346
|
+
try {
|
|
347
|
+
const tasks = await this.client.getTasks();
|
|
348
|
+
console.log(`\n${(0, colors_1.BOLD)('📋 Tareas Registradas en HELIX:')}\n`);
|
|
349
|
+
if (!tasks || tasks.length === 0) {
|
|
350
|
+
console.log((0, colors_1.GRAY)(' No hay tareas recientes registradas.\n'));
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
for (const t of tasks.slice(-10)) {
|
|
354
|
+
let statusBadge = chalk_1.default.gray(t.status);
|
|
355
|
+
if (t.status === 'COMPLETED')
|
|
356
|
+
statusBadge = chalk_1.default.green('✔ Completada');
|
|
357
|
+
if (t.status === 'RUNNING')
|
|
358
|
+
statusBadge = chalk_1.default.yellow('⏳ En ejecución');
|
|
359
|
+
if (t.status === 'FAILED')
|
|
360
|
+
statusBadge = chalk_1.default.red('✖ Fallida');
|
|
361
|
+
if (t.status === 'CANCELLED')
|
|
362
|
+
statusBadge = chalk_1.default.gray('○ Cancelada');
|
|
363
|
+
console.log(` ${statusBadge} ${(0, colors_1.DIM)(t.task_id)}`);
|
|
364
|
+
if (t.prompt)
|
|
365
|
+
console.log(` ${chalk_1.default.white(t.prompt)}`);
|
|
366
|
+
console.log('');
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
catch (err) {
|
|
370
|
+
console.log((0, colors_1.RED)(` Error al obtener tareas: ${err.message}\n`));
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
async _handleListModels() {
|
|
374
|
+
try {
|
|
375
|
+
const models = await this.client.getModels();
|
|
376
|
+
console.log(`\n${(0, colors_1.BOLD)('🧠 Modelos Disponibles en Proveedores Configurados:')}\n`);
|
|
377
|
+
if (!models || models.length === 0) {
|
|
378
|
+
console.log((0, colors_1.GRAY)(' No hay modelos disponibles. Configura tus API Keys con /config-apikey.\n'));
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
for (const m of models) {
|
|
382
|
+
console.log(` ${(0, colors_1.CYAN)('•')} ${chalk_1.default.bold(m.id)} ${(0, colors_1.DIM)(`[${m.provider}]`)}`);
|
|
383
|
+
}
|
|
384
|
+
console.log('');
|
|
385
|
+
}
|
|
386
|
+
catch (err) {
|
|
387
|
+
console.log((0, colors_1.RED)(` Error al obtener modelos: ${err.message}\n`));
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
async _handleStatus() {
|
|
391
|
+
console.log('');
|
|
392
|
+
console.log(` ${chalk_1.default.hex('#FF8C00').bold('⬡ Estado del Sistema')}`);
|
|
393
|
+
console.log(` ${chalk_1.default.gray('─'.repeat(40))}`);
|
|
394
|
+
console.log(` ${chalk_1.default.gray('Agente WS')} ${this.client.connected ? chalk_1.default.green('● Conectado') : chalk_1.default.red('● Desconectado')} ${chalk_1.default.gray(this.client.url)}`);
|
|
395
|
+
console.log(` ${chalk_1.default.gray('Micrófono')} ${this.voiceEnabled ? chalk_1.default.green('● Activo') + chalk_1.default.gray(' (hey helix)') : chalk_1.default.red('● Inactivo')}`);
|
|
396
|
+
console.log(` ${chalk_1.default.gray('Conversación')} ${chalk_1.default.gray(this.conversationId)} ${chalk_1.default.gray(`(${this.conversationHistory.length} msgs)`)}`);
|
|
397
|
+
console.log(` ${chalk_1.default.gray('Skills')} ${chalk_1.default.hex('#FF8C00').bold(this.autocompleter.getSkills().length.toString())} registradas`);
|
|
398
|
+
console.log(` ${chalk_1.default.gray('MCP Tools')} ${chalk_1.default.cyan.bold(this.autocompleter.getMcpTools().length.toString())} disponibles`);
|
|
399
|
+
console.log('');
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
exports.HelixRepl = HelixRepl;
|
package/package.json
CHANGED
|
@@ -1,6 +1,33 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "helix-assistant-cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "HELIX - Interactive Terminal CLI for Windows AI Desktop Agent",
|
|
5
|
+
"private": false,
|
|
6
|
+
"publishConfig": {
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"bin": {
|
|
10
|
+
"helix": "bin/helix.js"
|
|
11
|
+
},
|
|
12
|
+
"main": "dist/index.js",
|
|
13
|
+
"types": "dist/index.d.ts",
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc -p tsconfig.json",
|
|
16
|
+
"dev": "tsc -w -p tsconfig.json",
|
|
17
|
+
"start": "node dist/index.js",
|
|
18
|
+
"test": "node --test --require ts-node/register/transpile-only tests/cli.test.ts"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"chalk": "^4.1.2",
|
|
22
|
+
"commander": "^12.0.0",
|
|
23
|
+
"dotenv": "^16.4.5",
|
|
24
|
+
"prompts": "^2.4.2",
|
|
25
|
+
"ws": "^8.16.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/node": "^20.11.0",
|
|
29
|
+
"@types/prompts": "^2.4.9",
|
|
30
|
+
"@types/ws": "^8.5.10",
|
|
31
|
+
"typescript": "^5.3.0"
|
|
32
|
+
}
|
|
33
|
+
}
|