helix-assistant-cli 0.6.0 → 0.6.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.
@@ -16,7 +16,7 @@ exports.SLASH_COMMANDS = [
16
16
  { command: '/subagents', description: 'Ver el panel ASCII o chatear con un subagente', usage: '/subagents [list|chat <id> <mensaje>]' },
17
17
  { command: '/config-apikey', description: 'Configurador interactivo de API Keys (OpenAI, Anthropic, Gemini, etc.)' },
18
18
  { command: '/show-apikey', description: 'Ver estado y validez de las API Keys configuradas' },
19
- { command: '/microphone', description: 'Ver o alternar estado del micrófono', usage: '/microphone [enable|disable]' },
19
+ { command: '/microphone', description: 'Ver o alternar estado del micrófono', usage: '/microphone [enable|disable]' },
20
20
  { command: '/tasks', description: 'Ver tareas activas y recientes del agente' },
21
21
  { command: '/model', description: 'Ver o cambiar el modelo activo (free/local/cloud)', usage: '/model [list|set <id>|effort <low|medium|high>]' },
22
22
  { command: '/models', description: 'Listar modelos disponibles de proveedores configurados' },
@@ -24,7 +24,7 @@ exports.SLASH_COMMANDS = [
24
24
  { command: '/status', description: 'Mostrar resumen del estado del sistema' },
25
25
  { command: '/providers', description: 'Ver proveedores configurados y salud de sus claves' },
26
26
  { command: '/capabilities', description: 'Ver capacidades activas: sandbox, subagentes, voz y browser' },
27
- { command: '/settings', description: 'Ver configuración efectiva sin exponer secretos' },
27
+ { command: '/settings', description: 'Ver configuración efectiva sin exponer secretos' },
28
28
  { command: '/clear', description: 'Limpiar pantalla y restaurar el banner de HELIX' },
29
29
  { command: '/stop', description: 'Parada de emergencia de todas las tareas activas' },
30
30
  { command: '/help', description: 'Mostrar ayuda de comandos y atajos' },
@@ -159,15 +159,15 @@ class Autocompleter {
159
159
  */
160
160
  renderHelp() {
161
161
  console.log('');
162
- console.log(` ${chalk_1.default.hex('#FF8C00').bold('⬡ Comandos Disponibles')} ${chalk_1.default.gray('(/ + [Tab] para autocompletar)')}`);
163
- console.log(` ${chalk_1.default.gray('─'.repeat(50))}`);
162
+ console.log(` ${chalk_1.default.hex('#FF8C00').bold('⬡ Comandos Disponibles')} ${chalk_1.default.gray('(/ + [Tab] para autocompletar)')}`);
163
+ console.log(` ${chalk_1.default.gray('─'.repeat(50))}`);
164
164
  for (const cmd of exports.SLASH_COMMANDS) {
165
165
  const usage = cmd.usage ? ` ${chalk_1.default.gray(cmd.usage)}` : '';
166
166
  console.log(` ${chalk_1.default.magenta(cmd.command.padEnd(16))} ${chalk_1.default.gray(cmd.description)}${usage}`);
167
167
  }
168
168
  console.log('');
169
- console.log(` ${chalk_1.default.hex('#FF8C00').bold('⬡ Prefijos Especiales')}`);
170
- console.log(` ${chalk_1.default.gray('─'.repeat(50))}`);
169
+ console.log(` ${chalk_1.default.hex('#FF8C00').bold('⬡ Prefijos Especiales')}`);
170
+ console.log(` ${chalk_1.default.gray('─'.repeat(50))}`);
171
171
  console.log(` ${(0, colors_1.formatSkill)('nombre')} ${chalk_1.default.gray('Invoca una skill registrada')}`);
172
172
  console.log(` ${(0, colors_1.formatMcp)('herramienta')} ${chalk_1.default.gray('Invoca herramientas MCP')}`);
173
173
  console.log('');
package/dist/ui/repl.js CHANGED
@@ -100,7 +100,7 @@ class HelixRepl {
100
100
  this.waitingLogged = false;
101
101
  await this._syncSettings();
102
102
  await this.autocompleter.refreshSuggestions();
103
- process.stdout.write(`\r\x1b[K${chalk_1.default.green('●')} ${chalk_1.default.greenBright.bold('Conectado al agente HELIX')} \n`);
103
+ process.stdout.write(`\r\x1b[K${chalk_1.default.green('●')} ${chalk_1.default.greenBright.bold('Conectado al agente HELIX')} \n`);
104
104
  this._promptUser();
105
105
  });
106
106
  this.client.on('disconnected', () => {
@@ -109,40 +109,40 @@ class HelixRepl {
109
109
  }
110
110
  if (!this.waitingLogged) {
111
111
  this.waitingLogged = true;
112
- console.log(`\n${(0, colors_1.RED)('●')} ${chalk_1.default.yellowBright('Esperando al servicio del agente HELIX en ws://127.0.0.1:8765...')}`);
113
- console.log(`${(0, colors_1.GRAY)(' (Si no responde tras 3 reintentos, el CLI lo iniciará automáticamente en segundo plano)')}\n`);
112
+ console.log(`\n${(0, colors_1.RED)('●')} ${chalk_1.default.yellowBright('Esperando al servicio del agente HELIX en ws://127.0.0.1:8765...')}`);
113
+ console.log(`${(0, colors_1.GRAY)(' (Si no responde tras 3 reintentos, el CLI lo iniciará automáticamente en segundo plano)')}\n`);
114
114
  }
115
115
  this._promptUser();
116
116
  });
117
117
  this.client.on('auto_spawning_agent', () => {
118
- 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`);
119
- process.stdout.write(`${(0, colors_1.GRAY)(' Por favor espere mientras termina de inicializarse (no se realizarán reintentos hasta que esté listo).')}\n`);
118
+ 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`);
119
+ process.stdout.write(`${(0, colors_1.GRAY)(' Por favor espere mientras termina de inicializarse (no se realizarán reintentos hasta que esté listo).')}\n`);
120
120
  });
121
121
  this.client.on('agent_starting_progress', (data) => {
122
- process.stdout.write(`\r ${chalk_1.default.hex('#FF9F1C')('⏳')} ${chalk_1.default.gray(`Inicializando subsistemas de HELIX en segundo plano... (${data.elapsedSec}s)`)}`);
122
+ process.stdout.write(`\r ${chalk_1.default.hex('#FF9F1C')('⏳')} ${chalk_1.default.gray(`Inicializando subsistemas de HELIX en segundo plano... (${data.elapsedSec}s)`)}`);
123
123
  });
124
124
  this.client.on('agent_ready', () => {
125
- process.stdout.write(`\r\x1b[K ${chalk_1.default.green('✔')} ${chalk_1.default.greenBright('Servicio de HELIX listo. Conectando...')}\n\n`);
125
+ process.stdout.write(`\r\x1b[K ${chalk_1.default.green('✔')} ${chalk_1.default.greenBright('Servicio de HELIX listo. Conectando...')}\n\n`);
126
126
  });
127
127
  this.client.on('agent_start_failed', (data) => {
128
- 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`);
128
+ 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`);
129
129
  this._promptUser();
130
130
  });
131
131
  // Voice Capture indicator
132
132
  this.client.on('voice_capture_started', () => {
133
133
  this.isCapturingVoice = true;
134
- process.stdout.write(`\n${chalk_1.default.bgRed.white.bold(' 🎙️ [VOZ DETECTADA - HEY HELIX]: Capturando audio... ')}\n`);
134
+ process.stdout.write(`\n${chalk_1.default.bgRed.white.bold(' 🎙️ [VOZ DETECTADA - HEY HELIX]: Capturando audio... ')}\n`);
135
135
  });
136
136
  this.client.on('voice_capture_stopped', () => {
137
137
  this.isCapturingVoice = false;
138
- process.stdout.write(`\n${chalk_1.default.bgCyan.black.bold(' 🔊 [AUDIO RECIBIDO]: Procesando voz... ')}\n`);
138
+ process.stdout.write(`\n${chalk_1.default.bgCyan.black.bold(' 🔊 [AUDIO RECIBIDO]: Procesando voz... ')}\n`);
139
139
  this._promptUser();
140
140
  });
141
141
  // ReAct Step Progress
142
142
  this.client.on('react_step', (step) => {
143
143
  const iter = step?.iteration ?? 1;
144
144
  const role = step?.role ? chalk_1.default.gray(` (${step.role})`) : '';
145
- process.stdout.write(`\r ${chalk_1.default.hex('#FF9F1C')('◆')} ${chalk_1.default.gray(`Paso ${iter}${role} — Razonando...`)}`);
145
+ process.stdout.write(`\r ${chalk_1.default.hex('#FF9F1C')('◆')} ${chalk_1.default.gray(`Paso ${iter}${role} — Razonando...`)}`);
146
146
  });
147
147
  // Agent assistant message
148
148
  this.client.on('agent_message', (payload) => {
@@ -158,12 +158,12 @@ class HelixRepl {
158
158
  process.stdout.write('\r\x1b[K');
159
159
  // Branded header
160
160
  console.log('');
161
- console.log(` ${chalk_1.default.hex('#FF8C00').bold('⬡ HELIX')}${modelBadge}`);
161
+ console.log(` ${chalk_1.default.hex('#FF8C00').bold('⬡ HELIX')}${modelBadge}`);
162
162
  // Content with subtle left border and clean Markdown formatting
163
163
  const formatted = (0, markdown_1.formatTerminalMarkdown)(content, this.plain);
164
164
  const contentLines = formatted.trim().split('\n');
165
165
  for (const line of contentLines) {
166
- console.log(` ${chalk_1.default.gray('│')} ${line}`);
166
+ console.log(` ${chalk_1.default.gray('│')} ${line}`);
167
167
  }
168
168
  console.log('');
169
169
  this.conversationHistory.push({ role: 'assistant', content });
@@ -198,30 +198,30 @@ class HelixRepl {
198
198
  });
199
199
  }
200
200
  async _handleConfirmationDialog(req) {
201
- console.log(`\n${(0, colors_1.YELLOW_BOLD)('⚠️ CONFIRMACIÓN DE ACCIÓN REQUERIDA')}`);
202
- console.log(` Acción: ${chalk_1.default.white.bold(req.action || req.tool || 'Acción del sistema')}`);
201
+ console.log(`\n${(0, colors_1.YELLOW_BOLD)('⚠️ CONFIRMACIÓN DE ACCIÓN REQUERIDA')}`);
202
+ console.log(` Acción: ${chalk_1.default.white.bold(req.action || req.tool || 'Acción del sistema')}`);
203
203
  if (req.description) {
204
- console.log(` Descripción: ${(0, colors_1.DIM)(req.description)}`);
204
+ console.log(` Descripción: ${(0, colors_1.DIM)(req.description)}`);
205
205
  }
206
206
  if (req.arguments && Object.keys(req.arguments).length > 0) {
207
- console.log(` Parámetros: ${(0, colors_1.GRAY)(JSON.stringify(req.arguments))}`);
207
+ console.log(` Parámetros: ${(0, colors_1.GRAY)(JSON.stringify(req.arguments))}`);
208
208
  }
209
209
  this.rl?.pause();
210
210
  try {
211
211
  const answer = await (0, prompts_1.default)({
212
212
  type: 'confirm',
213
213
  name: 'confirmed',
214
- message: '¿Permitir al agente ejecutar esta acción?',
214
+ message: '¿Permitir al agente ejecutar esta acción?',
215
215
  initial: true,
216
216
  });
217
217
  const reqId = req.request_id || req.id || '';
218
218
  if (answer && answer.confirmed) {
219
219
  this.client.confirmAction(reqId);
220
- console.log((0, colors_1.GREEN)(' ✔ Acción confirmada.\n'));
220
+ console.log((0, colors_1.GREEN)(' ✔ Acción confirmada.\n'));
221
221
  }
222
222
  else {
223
223
  this.client.rejectAction(reqId);
224
- console.log((0, colors_1.RED)(' ✖ Acción rechazada.\n'));
224
+ console.log((0, colors_1.RED)(' ✖ Acción rechazada.\n'));
225
225
  }
226
226
  }
227
227
  finally {
@@ -251,7 +251,7 @@ class HelixRepl {
251
251
  await this._handleInputLine(line.trim());
252
252
  });
253
253
  rl.on('close', () => {
254
- console.log((0, colors_1.DIM)('\nCerrando sesión de HELIX CLI...'));
254
+ console.log((0, colors_1.DIM)('\nCerrando sesión de HELIX CLI...'));
255
255
  this.client.close();
256
256
  process.exit(0);
257
257
  });
@@ -265,7 +265,7 @@ class HelixRepl {
265
265
  this._promptUser();
266
266
  }
267
267
  else {
268
- console.log((0, colors_1.DIM)('\n¡Hasta pronto!'));
268
+ console.log((0, colors_1.DIM)('\n¡Hasta pronto!'));
269
269
  this.client.close();
270
270
  process.exit(0);
271
271
  }
@@ -275,7 +275,7 @@ class HelixRepl {
275
275
  _promptUser() {
276
276
  if (!this.rl)
277
277
  return;
278
- const promptPrefix = ` ${chalk_1.default.hex('#FF8C00').bold('helix')} ${chalk_1.default.gray('❯')} `;
278
+ const promptPrefix = ` ${chalk_1.default.hex('#FF8C00').bold('helix')} ${chalk_1.default.gray('❯')} `;
279
279
  this.rl.setPrompt(promptPrefix);
280
280
  this.rl.prompt();
281
281
  }
@@ -285,7 +285,7 @@ class HelixRepl {
285
285
  return;
286
286
  }
287
287
  if (this.client.isStarting) {
288
- 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`);
288
+ 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`);
289
289
  this._promptUser();
290
290
  return;
291
291
  }
@@ -416,7 +416,7 @@ class HelixRepl {
416
416
  this.client.emergencyStop();
417
417
  this.isProcessingPrompt = false;
418
418
  this.activeTaskId = null;
419
- console.log((0, colors_1.GREEN)('✔ Todas las tareas han sido detenidas.\n'));
419
+ console.log((0, colors_1.GREEN)('✔ Todas las tareas han sido detenidas.\n'));
420
420
  break;
421
421
  case '/exit':
422
422
  case '/quit':
@@ -432,7 +432,7 @@ class HelixRepl {
432
432
  }
433
433
  // --- Direct chat message / @skill / #mcp ---
434
434
  if (!this.client.connected) {
435
- console.log((0, colors_1.YELLOW)('⚠ El agente no está conectado actualmente. Intentando enviar de todos modos...'));
435
+ console.log((0, colors_1.YELLOW)('⚠ El agente no está conectado actualmente. Intentando enviar de todos modos...'));
436
436
  }
437
437
  // Highlight skills in strong orange (#FF8C00) and mcps in cyan
438
438
  const knownSkills = this.autocompleter.getSkills();
@@ -441,12 +441,12 @@ class HelixRepl {
441
441
  this.conversationHistory.push({ role: 'user', content: line });
442
442
  this.isProcessingPrompt = true;
443
443
  this.activeTasksCount++;
444
- process.stdout.write(` ${chalk_1.default.gray('→')} ${formattedEcho}\n`);
445
- process.stdout.write(` ${chalk_1.default.hex('#FF9F1C')('â—†')} ${chalk_1.default.gray('Procesando...')}`);
444
+ process.stdout.write(` ${chalk_1.default.gray('→')} ${formattedEcho}\n`);
445
+ process.stdout.write(` ${chalk_1.default.hex('#FF9F1C')('◆')} ${chalk_1.default.gray('Procesando...')}`);
446
446
  const sent = this.client.sendUserText(line, this.conversationId, this.conversationHistory.slice(-10));
447
447
  if (!sent) {
448
448
  process.stdout.write('\r\x1b[K');
449
- console.log((0, colors_1.RED)('✖ Error: No se pudo enviar el mensaje (WebSocket desconectado).'));
449
+ console.log((0, colors_1.RED)('✖ Error: No se pudo enviar el mensaje (WebSocket desconectado).'));
450
450
  this.isProcessingPrompt = false;
451
451
  this.activeTasksCount = Math.max(0, this.activeTasksCount - 1);
452
452
  this._promptUser();
@@ -455,7 +455,7 @@ class HelixRepl {
455
455
  async _handleListTasks() {
456
456
  try {
457
457
  const tasks = await this.client.getTasks();
458
- console.log(`\n${(0, colors_1.BOLD)('📋 Tareas Registradas en HELIX:')}\n`);
458
+ console.log(`\n${(0, colors_1.BOLD)('📋 Tareas Registradas en HELIX:')}\n`);
459
459
  if (!tasks || tasks.length === 0) {
460
460
  console.log((0, colors_1.GRAY)(' No hay tareas recientes registradas.\n'));
461
461
  return;
@@ -463,13 +463,13 @@ class HelixRepl {
463
463
  for (const t of tasks.slice(-10)) {
464
464
  let statusBadge = chalk_1.default.gray(t.status);
465
465
  if (t.status === 'COMPLETED')
466
- statusBadge = chalk_1.default.green('✔ Completada');
466
+ statusBadge = chalk_1.default.green('✔ Completada');
467
467
  if (t.status === 'RUNNING')
468
- statusBadge = chalk_1.default.yellow('⏳ En ejecución');
468
+ statusBadge = chalk_1.default.yellow('⏳ En ejecución');
469
469
  if (t.status === 'FAILED')
470
- statusBadge = chalk_1.default.red('✖ Fallida');
470
+ statusBadge = chalk_1.default.red('✖ Fallida');
471
471
  if (t.status === 'CANCELLED')
472
- statusBadge = chalk_1.default.gray('â—‹ Cancelada');
472
+ statusBadge = chalk_1.default.gray('○ Cancelada');
473
473
  console.log(` ${statusBadge} ${(0, colors_1.DIM)(t.task_id)}`);
474
474
  if (t.prompt)
475
475
  console.log(` ${chalk_1.default.white(t.prompt)}`);
@@ -483,13 +483,13 @@ class HelixRepl {
483
483
  async _handleListModels() {
484
484
  try {
485
485
  const models = await this.client.getModels();
486
- console.log(`\n${(0, colors_1.BOLD)('🧠 Modelos Disponibles en Proveedores Configurados:')}\n`);
486
+ console.log(`\n${(0, colors_1.BOLD)('🧠 Modelos Disponibles en Proveedores Configurados:')}\n`);
487
487
  if (!models || models.length === 0) {
488
488
  console.log((0, colors_1.GRAY)(' No hay modelos disponibles. Configura tus API Keys con /config-apikey.\n'));
489
489
  return;
490
490
  }
491
491
  for (const m of models) {
492
- console.log(` ${(0, colors_1.CYAN)('•')} ${chalk_1.default.bold(m.id)} ${(0, colors_1.DIM)(`[${m.provider}]`)}`);
492
+ console.log(` ${(0, colors_1.CYAN)('•')} ${chalk_1.default.bold(m.id)} ${(0, colors_1.DIM)(`[${m.provider}]`)}`);
493
493
  }
494
494
  console.log('');
495
495
  }
@@ -499,11 +499,11 @@ class HelixRepl {
499
499
  }
500
500
  async _handleStatus() {
501
501
  console.log('');
502
- console.log(` ${chalk_1.default.hex('#FF8C00').bold('⬡ Estado del Sistema')}`);
503
- console.log(` ${chalk_1.default.gray('─'.repeat(40))}`);
504
- 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)}`);
505
- 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')}`);
506
- console.log(` ${chalk_1.default.gray('Conversación')} ${chalk_1.default.gray(this.conversationId)} ${chalk_1.default.gray(`(${this.conversationHistory.length} msgs)`)}`);
502
+ console.log(` ${chalk_1.default.hex('#FF8C00').bold('⬡ Estado del Sistema')}`);
503
+ console.log(` ${chalk_1.default.gray('─'.repeat(40))}`);
504
+ 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)}`);
505
+ 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')}`);
506
+ console.log(` ${chalk_1.default.gray('Conversación')} ${chalk_1.default.gray(this.conversationId)} ${chalk_1.default.gray(`(${this.conversationHistory.length} msgs)`)}`);
507
507
  console.log(` ${chalk_1.default.gray('Skills')} ${chalk_1.default.hex('#FF8C00').bold(this.autocompleter.getSkills().length.toString())} registradas`);
508
508
  console.log(` ${chalk_1.default.gray('MCP Tools')} ${chalk_1.default.cyan.bold(this.autocompleter.getMcpTools().length.toString())} disponibles`);
509
509
  console.log('');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
- {
1
+ {
2
2
  "name": "helix-assistant-cli",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "HELIX - Interactive Terminal CLI for Windows AI Desktop Agent",
5
5
  "private": false,
6
6
  "publishConfig": {
@@ -1,4 +1,4 @@
1
- import chalk from 'chalk';
1
+ import chalk from 'chalk';
2
2
  import type { AgentClient } from '../client/agent-client';
3
3
  import { formatSkill, formatMcp, ORANGE, CYAN, MAGENTA, DIM } from './colors';
4
4
  import { discoverUserSkillNames, getUserSkillsDirectory } from '../skills/user-skill-discovery';
@@ -18,7 +18,7 @@ export const SLASH_COMMANDS: CommandDefinition[] = [
18
18
  { command: '/subagents', description: 'Ver el panel ASCII o chatear con un subagente', usage: '/subagents [list|chat <id> <mensaje>]' },
19
19
  { command: '/config-apikey', description: 'Configurador interactivo de API Keys (OpenAI, Anthropic, Gemini, etc.)' },
20
20
  { command: '/show-apikey', description: 'Ver estado y validez de las API Keys configuradas' },
21
- { command: '/microphone', description: 'Ver o alternar estado del micrófono', usage: '/microphone [enable|disable]' },
21
+ { command: '/microphone', description: 'Ver o alternar estado del micrófono', usage: '/microphone [enable|disable]' },
22
22
  { command: '/tasks', description: 'Ver tareas activas y recientes del agente' },
23
23
  { command: '/model', description: 'Ver o cambiar el modelo activo (free/local/cloud)', usage: '/model [list|set <id>|effort <low|medium|high>]' },
24
24
  { command: '/models', description: 'Listar modelos disponibles de proveedores configurados' },
@@ -26,7 +26,7 @@ export const SLASH_COMMANDS: CommandDefinition[] = [
26
26
  { command: '/status', description: 'Mostrar resumen del estado del sistema' },
27
27
  { command: '/providers', description: 'Ver proveedores configurados y salud de sus claves' },
28
28
  { command: '/capabilities', description: 'Ver capacidades activas: sandbox, subagentes, voz y browser' },
29
- { command: '/settings', description: 'Ver configuración efectiva sin exponer secretos' },
29
+ { command: '/settings', description: 'Ver configuración efectiva sin exponer secretos' },
30
30
  { command: '/clear', description: 'Limpiar pantalla y restaurar el banner de HELIX' },
31
31
  { command: '/stop', description: 'Parada de emergencia de todas las tareas activas' },
32
32
  { command: '/help', description: 'Mostrar ayuda de comandos y atajos' },
@@ -175,16 +175,16 @@ export class Autocompleter {
175
175
  */
176
176
  public renderHelp(): void {
177
177
  console.log('');
178
- console.log(` ${chalk.hex('#FF8C00').bold('⬡ Comandos Disponibles')} ${chalk.gray('(/ + [Tab] para autocompletar)')}`);
179
- console.log(` ${chalk.gray('─'.repeat(50))}`);
178
+ console.log(` ${chalk.hex('#FF8C00').bold('⬡ Comandos Disponibles')} ${chalk.gray('(/ + [Tab] para autocompletar)')}`);
179
+ console.log(` ${chalk.gray('─'.repeat(50))}`);
180
180
  for (const cmd of SLASH_COMMANDS) {
181
181
  const usage = cmd.usage ? ` ${chalk.gray(cmd.usage)}` : '';
182
182
  console.log(` ${chalk.magenta(cmd.command.padEnd(16))} ${chalk.gray(cmd.description)}${usage}`);
183
183
  }
184
184
 
185
185
  console.log('');
186
- console.log(` ${chalk.hex('#FF8C00').bold('⬡ Prefijos Especiales')}`);
187
- console.log(` ${chalk.gray('─'.repeat(50))}`);
186
+ console.log(` ${chalk.hex('#FF8C00').bold('⬡ Prefijos Especiales')}`);
187
+ console.log(` ${chalk.gray('─'.repeat(50))}`);
188
188
  console.log(` ${formatSkill('nombre')} ${chalk.gray('Invoca una skill registrada')}`);
189
189
  console.log(` ${formatMcp('herramienta')} ${chalk.gray('Invoca herramientas MCP')}`);
190
190
  console.log('');
package/src/ui/repl.ts CHANGED
@@ -1,4 +1,4 @@
1
- import readline from 'readline';
1
+ import readline from 'readline';
2
2
  import chalk from 'chalk';
3
3
  import prompts from 'prompts';
4
4
  import { AgentClient } from '../client/agent-client';
@@ -121,7 +121,7 @@ export class HelixRepl {
121
121
  this.waitingLogged = false;
122
122
  await this._syncSettings();
123
123
  await this.autocompleter.refreshSuggestions();
124
- process.stdout.write(`\r\x1b[K${chalk.green('●')} ${chalk.greenBright.bold('Conectado al agente HELIX')} \n`);
124
+ process.stdout.write(`\r\x1b[K${chalk.green('●')} ${chalk.greenBright.bold('Conectado al agente HELIX')} \n`);
125
125
  this._promptUser();
126
126
  });
127
127
 
@@ -131,39 +131,39 @@ export class HelixRepl {
131
131
  }
132
132
  if (!this.waitingLogged) {
133
133
  this.waitingLogged = true;
134
- console.log(`\n${RED('●')} ${chalk.yellowBright('Esperando al servicio del agente HELIX en ws://127.0.0.1:8765...')}`);
135
- console.log(`${GRAY(' (Si no responde tras 3 reintentos, el CLI lo iniciará automáticamente en segundo plano)')}\n`);
134
+ console.log(`\n${RED('●')} ${chalk.yellowBright('Esperando al servicio del agente HELIX en ws://127.0.0.1:8765...')}`);
135
+ console.log(`${GRAY(' (Si no responde tras 3 reintentos, el CLI lo iniciará automáticamente en segundo plano)')}\n`);
136
136
  }
137
137
  this._promptUser();
138
138
  });
139
139
 
140
140
  this.client.on('auto_spawning_agent', () => {
141
- process.stdout.write(`\n${CYAN_BOLD('⚙️')} ${chalk.hex('#FF9F1C').bold('[AUTO-START]:')} Iniciando el servicio del agente HELIX en segundo plano...\n`);
142
- process.stdout.write(`${GRAY(' Por favor espere mientras termina de inicializarse (no se realizarán reintentos hasta que esté listo).')}\n`);
141
+ process.stdout.write(`\n${CYAN_BOLD('⚙️')} ${chalk.hex('#FF9F1C').bold('[AUTO-START]:')} Iniciando el servicio del agente HELIX en segundo plano...\n`);
142
+ process.stdout.write(`${GRAY(' Por favor espere mientras termina de inicializarse (no se realizarán reintentos hasta que esté listo).')}\n`);
143
143
  });
144
144
 
145
145
  this.client.on('agent_starting_progress', (data: { elapsedSec: number }) => {
146
- process.stdout.write(`\r ${chalk.hex('#FF9F1C')('⏳')} ${chalk.gray(`Inicializando subsistemas de HELIX en segundo plano... (${data.elapsedSec}s)`)}`);
146
+ process.stdout.write(`\r ${chalk.hex('#FF9F1C')('⏳')} ${chalk.gray(`Inicializando subsistemas de HELIX en segundo plano... (${data.elapsedSec}s)`)}`);
147
147
  });
148
148
 
149
149
  this.client.on('agent_ready', () => {
150
- process.stdout.write(`\r\x1b[K ${chalk.green('✔')} ${chalk.greenBright('Servicio de HELIX listo. Conectando...')}\n\n`);
150
+ process.stdout.write(`\r\x1b[K ${chalk.green('✔')} ${chalk.greenBright('Servicio de HELIX listo. Conectando...')}\n\n`);
151
151
  });
152
152
 
153
153
  this.client.on('agent_start_failed', (data: { error?: string }) => {
154
- process.stdout.write(`\r\x1b[K\n ${chalk.red('✖')} ${chalk.redBright('No se pudo iniciar el servicio automáticamente:')} ${chalk.gray(data?.error || 'Tiempo agotado')}\n`);
154
+ process.stdout.write(`\r\x1b[K\n ${chalk.red('✖')} ${chalk.redBright('No se pudo iniciar el servicio automáticamente:')} ${chalk.gray(data?.error || 'Tiempo agotado')}\n`);
155
155
  this._promptUser();
156
156
  });
157
157
 
158
158
  // Voice Capture indicator
159
159
  this.client.on('voice_capture_started', () => {
160
160
  this.isCapturingVoice = true;
161
- process.stdout.write(`\n${chalk.bgRed.white.bold(' 🎙️ [VOZ DETECTADA - HEY HELIX]: Capturando audio... ')}\n`);
161
+ process.stdout.write(`\n${chalk.bgRed.white.bold(' 🎙️ [VOZ DETECTADA - HEY HELIX]: Capturando audio... ')}\n`);
162
162
  });
163
163
 
164
164
  this.client.on('voice_capture_stopped', () => {
165
165
  this.isCapturingVoice = false;
166
- process.stdout.write(`\n${chalk.bgCyan.black.bold(' 🔊 [AUDIO RECIBIDO]: Procesando voz... ')}\n`);
166
+ process.stdout.write(`\n${chalk.bgCyan.black.bold(' 🔊 [AUDIO RECIBIDO]: Procesando voz... ')}\n`);
167
167
  this._promptUser();
168
168
  });
169
169
 
@@ -171,7 +171,7 @@ export class HelixRepl {
171
171
  this.client.on('react_step', (step: { iteration?: number; role?: string }) => {
172
172
  const iter = step?.iteration ?? 1;
173
173
  const role = step?.role ? chalk.gray(` (${step.role})`) : '';
174
- process.stdout.write(`\r ${chalk.hex('#FF9F1C')('◆')} ${chalk.gray(`Paso ${iter}${role} — Razonando...`)}`);
174
+ process.stdout.write(`\r ${chalk.hex('#FF9F1C')('◆')} ${chalk.gray(`Paso ${iter}${role} — Razonando...`)}`);
175
175
  });
176
176
 
177
177
  // Agent assistant message
@@ -190,13 +190,13 @@ export class HelixRepl {
190
190
 
191
191
  // Branded header
192
192
  console.log('');
193
- console.log(` ${chalk.hex('#FF8C00').bold('⬡ HELIX')}${modelBadge}`);
193
+ console.log(` ${chalk.hex('#FF8C00').bold('⬡ HELIX')}${modelBadge}`);
194
194
 
195
195
  // Content with subtle left border and clean Markdown formatting
196
196
  const formatted = formatTerminalMarkdown(content, this.plain);
197
197
  const contentLines = formatted.trim().split('\n');
198
198
  for (const line of contentLines) {
199
- console.log(` ${chalk.gray('│')} ${line}`);
199
+ console.log(` ${chalk.gray('│')} ${line}`);
200
200
  }
201
201
  console.log('');
202
202
 
@@ -241,13 +241,13 @@ export class HelixRepl {
241
241
  }
242
242
 
243
243
  private async _handleConfirmationDialog(req: ConfirmationRequest): Promise<void> {
244
- console.log(`\n${YELLOW_BOLD('⚠️ CONFIRMACIÓN DE ACCIÓN REQUERIDA')}`);
245
- console.log(` Acción: ${chalk.white.bold(req.action || req.tool || 'Acción del sistema')}`);
244
+ console.log(`\n${YELLOW_BOLD('⚠️ CONFIRMACIÓN DE ACCIÓN REQUERIDA')}`);
245
+ console.log(` Acción: ${chalk.white.bold(req.action || req.tool || 'Acción del sistema')}`);
246
246
  if (req.description) {
247
- console.log(` Descripción: ${DIM(req.description)}`);
247
+ console.log(` Descripción: ${DIM(req.description)}`);
248
248
  }
249
249
  if (req.arguments && Object.keys(req.arguments).length > 0) {
250
- console.log(` Parámetros: ${GRAY(JSON.stringify(req.arguments))}`);
250
+ console.log(` Parámetros: ${GRAY(JSON.stringify(req.arguments))}`);
251
251
  }
252
252
 
253
253
  this.rl?.pause();
@@ -255,17 +255,17 @@ export class HelixRepl {
255
255
  const answer = await prompts({
256
256
  type: 'confirm',
257
257
  name: 'confirmed',
258
- message: '¿Permitir al agente ejecutar esta acción?',
258
+ message: '¿Permitir al agente ejecutar esta acción?',
259
259
  initial: true,
260
260
  });
261
261
 
262
262
  const reqId = req.request_id || req.id || '';
263
263
  if (answer && answer.confirmed) {
264
264
  this.client.confirmAction(reqId);
265
- console.log(GREEN(' ✔ Acción confirmada.\n'));
265
+ console.log(GREEN(' ✔ Acción confirmada.\n'));
266
266
  } else {
267
267
  this.client.rejectAction(reqId);
268
- console.log(RED(' ✖ Acción rechazada.\n'));
268
+ console.log(RED(' ✖ Acción rechazada.\n'));
269
269
  }
270
270
  } finally {
271
271
  if (process.stdin.isTTY && typeof process.stdin.setRawMode === 'function') {
@@ -297,7 +297,7 @@ export class HelixRepl {
297
297
  });
298
298
 
299
299
  rl.on('close', () => {
300
- console.log(DIM('\nCerrando sesión de HELIX CLI...'));
300
+ console.log(DIM('\nCerrando sesión de HELIX CLI...'));
301
301
  this.client.close();
302
302
  process.exit(0);
303
303
  });
@@ -311,7 +311,7 @@ export class HelixRepl {
311
311
  this.activeTaskId = null;
312
312
  this._promptUser();
313
313
  } else {
314
- console.log(DIM('\n¡Hasta pronto!'));
314
+ console.log(DIM('\n¡Hasta pronto!'));
315
315
  this.client.close();
316
316
  process.exit(0);
317
317
  }
@@ -322,7 +322,7 @@ export class HelixRepl {
322
322
 
323
323
  private _promptUser(): void {
324
324
  if (!this.rl) return;
325
- const promptPrefix = ` ${chalk.hex('#FF8C00').bold('helix')} ${chalk.gray('❯')} `;
325
+ const promptPrefix = ` ${chalk.hex('#FF8C00').bold('helix')} ${chalk.gray('❯')} `;
326
326
  this.rl.setPrompt(promptPrefix);
327
327
  this.rl.prompt();
328
328
  }
@@ -334,7 +334,7 @@ export class HelixRepl {
334
334
  }
335
335
 
336
336
  if (this.client.isStarting) {
337
- console.log(`\n ${chalk.yellow('⚠️')} ${chalk.yellowBright('El servicio de HELIX se está iniciando en segundo plano. Espera a que termine antes de enviar comandos o reintentar.')}\n`);
337
+ console.log(`\n ${chalk.yellow('⚠️')} ${chalk.yellowBright('El servicio de HELIX se está iniciando en segundo plano. Espera a que termine antes de enviar comandos o reintentar.')}\n`);
338
338
  this._promptUser();
339
339
  return;
340
340
  }
@@ -474,7 +474,7 @@ export class HelixRepl {
474
474
  this.client.emergencyStop();
475
475
  this.isProcessingPrompt = false;
476
476
  this.activeTaskId = null;
477
- console.log(GREEN('✔ Todas las tareas han sido detenidas.\n'));
477
+ console.log(GREEN('✔ Todas las tareas han sido detenidas.\n'));
478
478
  break;
479
479
 
480
480
  case '/exit':
@@ -494,7 +494,7 @@ export class HelixRepl {
494
494
 
495
495
  // --- Direct chat message / @skill / #mcp ---
496
496
  if (!this.client.connected) {
497
- console.log(YELLOW('⚠ El agente no está conectado actualmente. Intentando enviar de todos modos...'));
497
+ console.log(YELLOW('⚠ El agente no está conectado actualmente. Intentando enviar de todos modos...'));
498
498
  }
499
499
 
500
500
  // Highlight skills in strong orange (#FF8C00) and mcps in cyan
@@ -506,8 +506,8 @@ export class HelixRepl {
506
506
  this.isProcessingPrompt = true;
507
507
  this.activeTasksCount++;
508
508
 
509
- process.stdout.write(` ${chalk.gray('→')} ${formattedEcho}\n`);
510
- process.stdout.write(` ${chalk.hex('#FF9F1C')('â—†')} ${chalk.gray('Procesando...')}`);
509
+ process.stdout.write(` ${chalk.gray('→')} ${formattedEcho}\n`);
510
+ process.stdout.write(` ${chalk.hex('#FF9F1C')('◆')} ${chalk.gray('Procesando...')}`);
511
511
 
512
512
  const sent = this.client.sendUserText(
513
513
  line,
@@ -517,7 +517,7 @@ export class HelixRepl {
517
517
 
518
518
  if (!sent) {
519
519
  process.stdout.write('\r\x1b[K');
520
- console.log(RED('✖ Error: No se pudo enviar el mensaje (WebSocket desconectado).'));
520
+ console.log(RED('✖ Error: No se pudo enviar el mensaje (WebSocket desconectado).'));
521
521
  this.isProcessingPrompt = false;
522
522
  this.activeTasksCount = Math.max(0, this.activeTasksCount - 1);
523
523
  this._promptUser();
@@ -527,7 +527,7 @@ export class HelixRepl {
527
527
  private async _handleListTasks(): Promise<void> {
528
528
  try {
529
529
  const tasks = await this.client.getTasks();
530
- console.log(`\n${BOLD('📋 Tareas Registradas en HELIX:')}\n`);
530
+ console.log(`\n${BOLD('📋 Tareas Registradas en HELIX:')}\n`);
531
531
  if (!tasks || tasks.length === 0) {
532
532
  console.log(GRAY(' No hay tareas recientes registradas.\n'));
533
533
  return;
@@ -535,10 +535,10 @@ export class HelixRepl {
535
535
 
536
536
  for (const t of tasks.slice(-10)) {
537
537
  let statusBadge = chalk.gray(t.status);
538
- if (t.status === 'COMPLETED') statusBadge = chalk.green('✔ Completada');
539
- if (t.status === 'RUNNING') statusBadge = chalk.yellow('⏳ En ejecución');
540
- if (t.status === 'FAILED') statusBadge = chalk.red('✖ Fallida');
541
- if (t.status === 'CANCELLED') statusBadge = chalk.gray('â—‹ Cancelada');
538
+ if (t.status === 'COMPLETED') statusBadge = chalk.green('✔ Completada');
539
+ if (t.status === 'RUNNING') statusBadge = chalk.yellow('⏳ En ejecución');
540
+ if (t.status === 'FAILED') statusBadge = chalk.red('✖ Fallida');
541
+ if (t.status === 'CANCELLED') statusBadge = chalk.gray('○ Cancelada');
542
542
 
543
543
  console.log(` ${statusBadge} ${DIM(t.task_id)}`);
544
544
  if (t.prompt) console.log(` ${chalk.white(t.prompt)}`);
@@ -552,14 +552,14 @@ export class HelixRepl {
552
552
  private async _handleListModels(): Promise<void> {
553
553
  try {
554
554
  const models = await this.client.getModels();
555
- console.log(`\n${BOLD('🧠 Modelos Disponibles en Proveedores Configurados:')}\n`);
555
+ console.log(`\n${BOLD('🧠 Modelos Disponibles en Proveedores Configurados:')}\n`);
556
556
  if (!models || models.length === 0) {
557
557
  console.log(GRAY(' No hay modelos disponibles. Configura tus API Keys con /config-apikey.\n'));
558
558
  return;
559
559
  }
560
560
 
561
561
  for (const m of models) {
562
- console.log(` ${CYAN('•')} ${chalk.bold(m.id)} ${DIM(`[${m.provider}]`)}`);
562
+ console.log(` ${CYAN('•')} ${chalk.bold(m.id)} ${DIM(`[${m.provider}]`)}`);
563
563
  }
564
564
  console.log('');
565
565
  } catch (err) {
@@ -569,11 +569,11 @@ export class HelixRepl {
569
569
 
570
570
  private async _handleStatus(): Promise<void> {
571
571
  console.log('');
572
- console.log(` ${chalk.hex('#FF8C00').bold('⬡ Estado del Sistema')}`);
573
- console.log(` ${chalk.gray('─'.repeat(40))}`);
574
- console.log(` ${chalk.gray('Agente WS')} ${this.client.connected ? chalk.green('● Conectado') : chalk.red('● Desconectado')} ${chalk.gray(this.client.url)}`);
575
- console.log(` ${chalk.gray('Micrófono')} ${this.voiceEnabled ? chalk.green('● Activo') + chalk.gray(' (hey helix)') : chalk.red('● Inactivo')}`);
576
- console.log(` ${chalk.gray('Conversación')} ${chalk.gray(this.conversationId)} ${chalk.gray(`(${this.conversationHistory.length} msgs)`)}`);
572
+ console.log(` ${chalk.hex('#FF8C00').bold('⬡ Estado del Sistema')}`);
573
+ console.log(` ${chalk.gray('─'.repeat(40))}`);
574
+ console.log(` ${chalk.gray('Agente WS')} ${this.client.connected ? chalk.green('● Conectado') : chalk.red('● Desconectado')} ${chalk.gray(this.client.url)}`);
575
+ console.log(` ${chalk.gray('Micrófono')} ${this.voiceEnabled ? chalk.green('● Activo') + chalk.gray(' (hey helix)') : chalk.red('● Inactivo')}`);
576
+ console.log(` ${chalk.gray('Conversación')} ${chalk.gray(this.conversationId)} ${chalk.gray(`(${this.conversationHistory.length} msgs)`)}`);
577
577
  console.log(` ${chalk.gray('Skills')} ${chalk.hex('#FF8C00').bold(this.autocompleter.getSkills().length.toString())} registradas`);
578
578
  console.log(` ${chalk.gray('MCP Tools')} ${chalk.cyan.bold(this.autocompleter.getMcpTools().length.toString())} disponibles`);
579
579
  console.log('');
package/tsconfig.json CHANGED
@@ -1,4 +1,4 @@
1
- {
1
+ {
2
2
  "compilerOptions": {
3
3
  "target": "ES2022",
4
4
  "module": "commonjs",