echo-ai-agent 1.0.67 → 1.0.69

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/cli.js CHANGED
@@ -27,8 +27,6 @@ program
27
27
  .description('Launch Echo AI Agent')
28
28
  .option('-d, --debug', 'Run in debug mode')
29
29
  .action((options) => {
30
- console.log(banner);
31
-
32
30
  // Check if configured
33
31
  if (!config.get('configured')) {
34
32
  console.log(chalk.yellow('⚠️ Echo is not configured yet. Running setup wizard...\n'));
@@ -36,6 +34,7 @@ program
36
34
  launchEcho(options.debug);
37
35
  });
38
36
  } else {
37
+ console.log(banner);
39
38
  launchEcho(options.debug);
40
39
  }
41
40
  });
@@ -44,7 +43,7 @@ program
44
43
  .command('setup')
45
44
  .description('Run the interactive setup wizard')
46
45
  .action(async () => {
47
- console.log(banner);
46
+ // Logo is printed by setupWizard.run() - no need to print here
48
47
  await setupWizard.run();
49
48
  });
50
49
 
@@ -130,24 +129,25 @@ program
130
129
  {
131
130
  type: 'list',
132
131
  name: 'action',
133
- message: 'Echo Configuration Management:',
134
- pageSize: 10,
132
+ message: chalk.cyan.bold('Echo Configuration Management:'),
133
+ pageSize: 12,
135
134
  choices: [
136
- { name: '📋 View Status', value: 'list' },
135
+ { name: '📋 View Current Configuration', value: 'list' },
137
136
  { name: '🎨 Appearance Settings', value: 'appearance' },
138
137
  { name: '👤 Personalization', value: 'personalization' },
139
138
  { name: '🤖 AI Intelligence', value: 'ai' },
140
139
  { name: '🎙️ Voice Settings', value: 'voice' },
141
- { name: '📚 Documentation Hub', value: 'docs' },
142
140
  { name: '🧠 Memory Management', value: 'memory' },
143
141
  { name: '🧩 Plugin Management', value: 'plugins' },
144
142
  { name: '⌨️ Workflow Macros', value: 'workflows' },
145
143
  { name: '🚀 Startup Settings', value: 'startup' },
146
144
  { name: '🔄 Auto-Update Settings', value: 'autoupdate' },
147
145
  { name: '🔔 Notification Settings', value: 'notify' },
146
+ new inquirer.Separator('───'),
147
+ { name: '📚 Documentation Hub', value: 'docs' },
148
148
  { name: '⚠️ Reset All Settings', value: 'reset' },
149
149
  new inquirer.Separator(),
150
- { name: '❌ Exit', value: 'exit' }
150
+ { name: '❌ Exit', value: 'exit', short: 'Exit' }
151
151
  ]
152
152
  }
153
153
  ]);
@@ -158,70 +158,89 @@ program
158
158
  case 'list':
159
159
  listConfig();
160
160
  break;
161
-
161
+
162
162
  case 'docs':
163
163
  const { startServer } = require('./scripts/docs-server');
164
164
  startServer();
165
- return; // Exit config after starting docs as it's a separate process usually
166
-
165
+ return;
166
+
167
167
  case 'appearance':
168
+ console.log(chalk.cyan.bold('\n🎨 Appearance Settings\n'));
168
169
  const appAnswers = await inquirer.prompt([
169
170
  {
170
171
  type: 'list',
171
172
  name: 'theme',
172
173
  message: 'Select Theme:',
173
- choices: ['cyan', 'purple', 'green', 'gold', 'red', 'blue'],
174
- default: config.get('theme')
174
+ choices: [
175
+ { name: '🔵 Cyan (Classic JARVIS)', value: 'cyan', short: 'Cyan' },
176
+ { name: '🟣 Purple (Royal)', value: 'purple', short: 'Purple' },
177
+ { name: '🟢 Green (Matrix)', value: 'green', short: 'Green' },
178
+ { name: '🟡 Gold (Iron Man)', value: 'gold', short: 'Gold' },
179
+ { name: '🔴 Red (Cyberpunk)', value: 'red', short: 'Red' },
180
+ { name: '🔷 Blue (Ocean)', value: 'blue', short: 'Blue' }
181
+ ],
182
+ default: ['cyan', 'purple', 'green', 'gold', 'red', 'blue'].indexOf(config.get('theme')) || 0,
183
+ pageSize: 6
175
184
  },
176
185
  {
177
186
  type: 'list',
178
187
  name: 'size',
179
188
  message: 'Window Size:',
180
- choices: ['small', 'medium', 'large'],
181
- default: config.get('size')
189
+ choices: [
190
+ { name: '📱 Small (Compact)', value: 'small', short: 'Small' },
191
+ { name: '💻 Medium (Balanced)', value: 'medium', short: 'Medium' },
192
+ { name: '🖥️ Large (Full View)', value: 'large', short: 'Large' }
193
+ ],
194
+ default: ['small', 'medium', 'large'].indexOf(config.get('size')) || 1,
195
+ pageSize: 3
182
196
  }
183
197
  ]);
184
198
  config.set('theme', appAnswers.theme);
185
199
  config.set('size', appAnswers.size);
186
- console.log(chalk.green('✓ Appearance updated.'));
200
+ console.log(chalk.green('\n✓ Appearance updated successfully.'));
187
201
  break;
188
202
 
189
203
  case 'personalization':
204
+ console.log(chalk.cyan.bold('\n👤 Personalization\n'));
190
205
  const { newName } = await inquirer.prompt([
191
206
  {
192
207
  type: 'input',
193
208
  name: 'newName',
194
209
  message: 'What should Echo call you?',
195
- default: config.get('userName') || 'Friend'
210
+ default: config.get('userName') || 'Friend',
211
+ validate: (input) => input.trim() ? true : 'Name cannot be empty.'
196
212
  }
197
213
  ]);
198
214
  config.set('userName', newName);
199
- console.log(chalk.green(`✓ Echo will now call you ${newName}.`));
215
+ console.log(chalk.green(`\n✓ Echo will now call you ${chalk.cyan(newName)}.`));
200
216
  break;
201
217
 
202
218
  case 'voice':
219
+ console.log(chalk.cyan.bold('\n🎙️ Voice Recognition Settings\n'));
203
220
  const { voiceProvider } = await inquirer.prompt([
204
221
  {
205
222
  type: 'list',
206
223
  name: 'voiceProvider',
207
224
  message: 'Select Voice Recognition Engine:',
208
225
  choices: [
209
- { name: '🌐 Browser API (Fast, Free, No key needed)', value: 'browser' },
210
- { name: '☁️ Whisper Cloud (Top-tier, Requires OpenAI key)', value: 'whisper' },
211
- { name: '🏠 Whisper Local (Privacy, One-time Setup)', value: 'whisper-local' }
226
+ { name: '🌐 Browser API (Native, Fast, Free)', value: 'browser', short: 'Browser API' },
227
+ { name: '☁️ Whisper Cloud (Best Accuracy, OpenAI Key)', value: 'whisper', short: 'Whisper Cloud' },
228
+ { name: '🏠 Whisper Local (Privacy, Offline)', value: 'whisper-local', short: 'Whisper Local' }
212
229
  ],
213
- default: config.get('voiceProvider') || 'browser'
230
+ default: ['browser', 'whisper', 'whisper-local'].indexOf(config.get('voiceProvider')) || 0,
231
+ pageSize: 3
214
232
  }
215
233
  ]);
216
-
234
+
217
235
  if (voiceProvider === 'whisper' && (!config.get('apiKeys') || !config.get('apiKeys').openai)) {
218
- console.log(chalk.yellow('\n⚠️ Whisper requires an OpenAI API key.'));
236
+ console.log(chalk.yellow('\n⚠️ Whisper Cloud requires an OpenAI API key.\n'));
219
237
  const { openAIKey } = await inquirer.prompt([
220
238
  {
221
239
  type: 'input',
222
240
  name: 'openAIKey',
223
241
  message: 'Enter your OpenAI API Key:',
224
- validate: (i) => i.trim() ? true : 'Key is required for Whisper.'
242
+ validate: (i) => i.trim() ? true : 'Key is required for Whisper.',
243
+ mask: '*'
225
244
  }
226
245
  ]);
227
246
  const keys = config.get('apiKeys') || {};
@@ -234,63 +253,66 @@ program
234
253
  await setup();
235
254
  } else {
236
255
  config.set('voiceProvider', voiceProvider);
237
- console.log(chalk.green(`✓ Voice engine set to ${voiceProvider === 'whisper' ? 'Whisper Cloud' : 'Browser API'}.`));
256
+ console.log(chalk.green(`\n✓ Voice engine set to ${voiceProvider === 'whisper' ? 'Whisper Cloud' : 'Browser API'}.`));
238
257
  }
239
258
  break;
240
259
 
241
260
  case 'memory':
261
+ console.log(chalk.cyan.bold('\n🧠 Memory Management\n'));
262
+ const memEnabled = config.get('memoryEnabled') !== false;
242
263
  const memAction = await inquirer.prompt([
243
264
  {
244
265
  type: 'list',
245
266
  name: 'type',
246
- message: 'Memory Management:',
267
+ message: 'Select Action:',
247
268
  choices: [
248
- { name: config.get('memoryEnabled') !== false ? '🔴 Disable Memory' : '🟢 Enable Memory', value: 'toggle' },
249
- { name: '🗑️ Clear All Memory', value: 'clear' },
250
- { name: '⬅️ Back', value: 'back' }
251
- ]
269
+ { name: memEnabled ? '🔴 Disable Memory' : '🟢 Enable Memory', value: 'toggle', short: memEnabled ? 'Disable' : 'Enable' },
270
+ { name: '🗑️ Clear All Memory', value: 'clear', short: 'Clear Memory' },
271
+ { name: '⬅️ Back', value: 'back', short: 'Back' }
272
+ ],
273
+ pageSize: 3
252
274
  }
253
275
  ]);
254
-
276
+
255
277
  if (memAction.type === 'toggle') {
256
278
  const current = config.get('memoryEnabled') !== false;
257
279
  config.set('memoryEnabled', !current);
258
- console.log(chalk.green(`✓ Conversational memory is now ${!current ? 'Enabled' : 'Disabled'}.`));
280
+ console.log(chalk.green(`\n✓ Conversational memory is now ${!current ? chalk.green('Enabled') : chalk.red('Disabled')}.`));
259
281
  } else if (memAction.type === 'clear') {
260
282
  const confirm = await inquirer.prompt([
261
283
  {
262
284
  type: 'confirm',
263
285
  name: 'sure',
264
- message: chalk.red.bold('Are you absolutely sure? Echo will lose all its personal memory and conversation history about you.'),
286
+ message: chalk.red.bold('⚠️ Are you sure? Echo will lose all memory and conversation history.'),
265
287
  default: false
266
288
  }
267
289
  ]);
268
290
  if (confirm.sure) {
269
291
  const MemoryManager = require('./scripts/memory-manager');
270
292
  new MemoryManager().clearMemory();
271
- console.log(chalk.green('✓ Local memory has been purified, sir.'));
293
+ console.log(chalk.green('\nAll memory has been cleared.'));
272
294
  }
273
295
  }
274
296
  break;
275
297
 
276
298
  case 'plugins':
277
- // Redirect to the existing plugins interactive logic
278
- console.log(chalk.cyan('\nRedirecting to Plugin Manager...'));
299
+ console.log(chalk.cyan.bold('\n🧩 Plugin Management\n'));
279
300
  const PluginManager = require('./scripts/plugin-manager');
280
301
  const generator = require('./scripts/plugin-generator');
281
302
  const pm = new PluginManager();
282
303
  const allPlugins = pm.listPlugins();
283
-
304
+
284
305
  const { pluginAction } = await inquirer.prompt([
285
306
  {
286
307
  type: 'list',
287
308
  name: 'pluginAction',
288
- message: 'Plugin Management:',
309
+ message: 'Select Action:',
289
310
  choices: [
290
- { name: '✅ Toggle Plugins', value: 'toggle' },
291
- { name: '🛠️ Create New Plugin', value: 'create' },
292
- { name: '⬅️ Back', value: 'back' }
293
- ]
311
+ { name: '✅ Toggle Plugins', value: 'toggle', short: 'Toggle' },
312
+ { name: '🛠️ Create New Plugin', value: 'create', short: 'Create' },
313
+ { name: '⬅️ Back', value: 'back', short: 'Back' }
314
+ ],
315
+ pageSize: 3
294
316
  }
295
317
  ]);
296
318
 
@@ -304,104 +326,116 @@ program
304
326
  {
305
327
  type: 'checkbox',
306
328
  name: 'enabledPlugins',
307
- message: 'Toggle Plugins:',
329
+ message: 'Toggle Plugins (Space to select, Enter to confirm):',
308
330
  choices: allPlugins.map(p => ({
309
- name: `${p.name} (${p.description})`,
331
+ name: `${p.name} - ${p.description || 'Plugin'}`,
310
332
  value: p.name,
311
333
  checked: p.enabled
312
- }))
334
+ })),
335
+ pageSize: Math.min(allPlugins.length, 8)
313
336
  }
314
337
  ]);
315
338
  config.set('plugins', pluginAnswers.enabledPlugins);
316
- console.log(chalk.green('✓ Plugin configuration updated.'));
317
- case 'startup':
339
+ console.log(chalk.green('\n✓ Plugin configuration updated.'));
340
+ break;
341
+
342
+ case 'startup':
318
343
  const currentStartup = config.get('startOnBoot') === true;
344
+ console.log(chalk.cyan.bold('\n🚀 Startup Settings\n'));
319
345
  const startupConfirm = await inquirer.prompt([
320
346
  {
321
347
  type: 'confirm',
322
348
  name: 'enable',
323
- message: currentStartup ? 'Echo is set to start on boot. Would you like to disable this?' : 'Would you like Echo to start automatically when you log in?',
349
+ message: currentStartup
350
+ ? 'Echo is set to start on boot. Would you like to disable this?'
351
+ : 'Would you like Echo to start automatically when you log in?',
324
352
  default: !currentStartup
325
353
  }
326
354
  ]);
327
355
  config.set('startOnBoot', currentStartup ? !startupConfirm.enable : startupConfirm.enable);
328
- console.log(chalk.green(`✓ Startup preference updated.`));
356
+ console.log(chalk.green(`\n✓ Startup preference: ${currentStartup && startupConfirm.enable ? chalk.red('Disabled') : chalk.green('Enabled')}.`));
329
357
  break;
330
358
 
331
359
  case 'ai':
332
360
  const AI_MODELS = require('./scripts/ai-models');
333
361
  const currentProvider = config.get('aiProvider') || 'google';
334
362
  const providerData = AI_MODELS[currentProvider];
335
-
363
+
336
364
  if (!providerData) {
337
- console.log(chalk.red('⚠️ Invalid provider configured. Please run "echo-ai setup".'));
365
+ console.log(chalk.red('\n⚠️ Invalid provider configured. Please run "echo-ai setup".'));
338
366
  break;
339
367
  }
340
368
 
369
+ console.log(chalk.cyan.bold(`\n🤖 AI Model Selection - ${providerData.name}\n`));
341
370
  const { selectedModel } = await inquirer.prompt([
342
371
  {
343
372
  type: 'list',
344
373
  name: 'selectedModel',
345
- message: `Select model for ${providerData.name}:`,
374
+ message: `Select Model:`,
346
375
  choices: providerData.models.map(m => ({
347
- name: m.name + (m.id === config.get('model') ? chalk.green(' (Active)') : ''),
348
- value: m.id
376
+ name: m.name + chalk.gray(` - ${m.description || 'Default model'}`),
377
+ value: m.id,
378
+ short: m.name
349
379
  })),
350
- default: config.get('model')
380
+ default: providerData.models.findIndex(m => m.id === config.get('model')) || 0,
381
+ pageSize: providerData.models.length
351
382
  }
352
383
  ]);
353
-
384
+
354
385
  config.set('model', selectedModel);
355
- console.log(chalk.green(`✓ Active model set to ${selectedModel}.`));
386
+ console.log(chalk.green(`\n✓ Active model set to ${chalk.cyan(selectedModel)}.`));
356
387
  break;
357
388
 
358
389
  case 'reset':
390
+ console.log(chalk.cyan.bold('\n⚠️ Reset Configuration\n'));
359
391
  const resetConfirm = await inquirer.prompt([
360
392
  {
361
393
  type: 'confirm',
362
394
  name: 'sure',
363
- message: chalk.red('Reset all settings to factory defaults? (This will NOT clear memory history)'),
395
+ message: chalk.red.bold('Reset all settings to factory defaults? (Memory will be preserved)'),
364
396
  default: false
365
397
  }
366
398
  ]);
367
399
  if (resetConfirm.sure) {
368
400
  config.clear();
369
- console.log(chalk.green('✓ System reset to defaults.'));
401
+ console.log(chalk.green('\n✓ System reset to factory defaults.'));
370
402
  }
371
403
  break;
372
-
404
+
373
405
  case 'autoupdate':
374
406
  const currentAutoUpdate = config.get('autoUpdateCheck') !== false;
407
+ console.log(chalk.cyan.bold('\n🔄 Auto-Update Settings\n'));
375
408
  const autoUpdateConfirm = await inquirer.prompt([
376
409
  {
377
410
  type: 'confirm',
378
411
  name: 'enable',
379
- message: currentAutoUpdate
380
- ? 'Auto-update check is enabled. Would you like to disable it?'
412
+ message: currentAutoUpdate
413
+ ? 'Auto-update check is enabled. Would you like to disable it?'
381
414
  : 'Would you like Echo to automatically check for updates on startup?',
382
415
  default: !currentAutoUpdate
383
416
  }
384
417
  ]);
385
418
  config.set('autoUpdateCheck', currentAutoUpdate ? !autoUpdateConfirm.enable : autoUpdateConfirm.enable);
386
- console.log(chalk.green(`✓ Auto-update check ${currentAutoUpdate && autoUpdateConfirm.enable ? 'disabled' : 'enabled'}.`));
419
+ console.log(chalk.green(`\n✓ Auto-update check ${currentAutoUpdate && autoUpdateConfirm.enable ? chalk.red('Disabled') : chalk.green('Enabled')}.`));
387
420
  break;
388
421
 
389
422
  case 'notify':
390
423
  const currentNotify = config.get('startupNotification') !== false;
424
+ console.log(chalk.cyan.bold('\n🔔 Notification Settings\n'));
391
425
  const notifyConfirm = await inquirer.prompt([
392
426
  {
393
427
  type: 'confirm',
394
428
  name: 'enable',
395
- message: currentNotify
396
- ? 'Startup notifications are enabled. Would you like to disable them?'
429
+ message: currentNotify
430
+ ? 'Startup notifications are enabled. Would you like to disable them?'
397
431
  : 'Would you like Echo to notify you when it starts up?',
398
432
  default: !currentNotify
399
433
  }
400
434
  ]);
401
435
  config.set('startupNotification', currentNotify ? !notifyConfirm.enable : notifyConfirm.enable);
402
- console.log(chalk.green(`✓ Startup notifications ${currentNotify && notifyConfirm.enable ? 'disabled' : 'enabled'}.`));
436
+ console.log(chalk.green(`\n✓ Startup notifications ${currentNotify && notifyConfirm.enable ? chalk.red('Disabled') : chalk.green('Enabled')}.`));
403
437
  break;
404
-
438
+
405
439
  case 'workflows':
406
440
  const workflowManager = require('./scripts/workflow-manager-cli');
407
441
  await workflowManager.run();
@@ -720,7 +754,7 @@ program
720
754
  }
721
755
  });
722
756
 
723
- // Default action (no command)
757
+ // Default action (no command) - show banner and quick help
724
758
  program.action(() => {
725
759
  console.log(banner);
726
760
  console.log(chalk.gray('Run ') + chalk.cyan('echo-ai start') + chalk.gray(' to launch Echo'));
@@ -729,13 +763,6 @@ program.action(() => {
729
763
 
730
764
  program.parse(process.argv);
731
765
 
732
- // If no arguments provided, show banner and help
733
- if (!process.argv.slice(2).length) {
734
- console.log(banner);
735
- console.log(chalk.gray('Run ') + chalk.cyan('echo-ai start') + chalk.gray(' to launch Echo'));
736
- console.log(chalk.gray('Run ') + chalk.cyan('echo-ai --help') + chalk.gray(' for more commands\n'));
737
- }
738
-
739
766
  function launchEcho(debug = false) {
740
767
  console.log(chalk.cyan('🚀 Launching Echo...\n'));
741
768