echo-ai-agent 1.0.70 → 1.0.71

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
@@ -126,14 +126,13 @@ program
126
126
 
127
127
  const mainMenu = async () => {
128
128
  console.log(chalk.cyan.bold('\n⚙️ Echo Configuration Management\n'));
129
- console.log(chalk.gray(' Use ↑↓ arrow keys to navigate, Enter to select\n'));
130
-
129
+
131
130
  const { action } = await inquirer.prompt([
132
131
  {
133
132
  type: 'list',
134
133
  name: 'action',
135
134
  message: 'Select an option:',
136
- pageSize: 12,
135
+ pageSize: 15,
137
136
  choices: [
138
137
  { name: '📋 View Current Configuration', value: 'list', short: 'View Config' },
139
138
  { name: '🎨 Appearance Settings', value: 'appearance', short: 'Appearance' },
@@ -209,6 +208,7 @@ program
209
208
 
210
209
  case 'personalization':
211
210
  console.log(chalk.cyan.bold('\n👤 Personalization\n'));
211
+ console.log(chalk.gray(' Type your name and press Enter\n'));
212
212
  const { newName } = await inquirer.prompt([
213
213
  {
214
214
  type: 'input',
@@ -245,11 +245,10 @@ program
245
245
  console.log(chalk.yellow('\n⚠️ Whisper Cloud requires an OpenAI API key.\n'));
246
246
  const { openAIKey } = await inquirer.prompt([
247
247
  {
248
- type: 'input',
248
+ type: 'password',
249
249
  name: 'openAIKey',
250
250
  message: 'Enter your OpenAI API Key:',
251
- validate: (i) => i.trim() ? true : 'Key is required for Whisper.',
252
- mask: '*'
251
+ validate: (i) => i.trim() ? true : 'Key is required for Whisper.'
253
252
  }
254
253
  ]);
255
254
  const keys = config.get('apiKeys') || {};
@@ -308,30 +307,14 @@ program
308
307
 
309
308
  case 'plugins':
310
309
  console.log(chalk.cyan.bold('\n🧩 Plugin Management\n'));
311
- console.log(chalk.gray(' Use ↑↓ arrow keys to navigate, Enter to select\n'));
310
+ console.log(chalk.gray(' Use ↑↓ arrows to navigate, Space to toggle, Enter to confirm\n'));
312
311
  const PluginManager = require('./scripts/plugin-manager');
313
- const generator = require('./scripts/plugin-generator');
314
312
  const pm = new PluginManager();
315
313
  const allPlugins = pm.listPlugins();
316
314
 
317
- const { pluginAction } = await inquirer.prompt([
318
- {
319
- type: 'list',
320
- name: 'pluginAction',
321
- message: 'Select Action:',
322
- choices: [
323
- { name: '✅ Toggle Plugins', value: 'toggle', short: 'Toggle' },
324
- { name: '🛠️ Create New Plugin', value: 'create', short: 'Create' },
325
- { name: '⬅️ Back', value: 'back', short: 'Back' }
326
- ],
327
- pageSize: 3,
328
- loop: false
329
- }
330
- ]);
331
-
332
- if (pluginAction === 'back') break;
333
- if (pluginAction === 'create') {
334
- await generator.run();
315
+ if (allPlugins.length === 0) {
316
+ console.log(chalk.yellow('⚠️ No plugins found.'));
317
+ console.log(chalk.gray('Drop .js files into the "plugins" folder to extend Echo.\n'));
335
318
  break;
336
319
  }
337
320
 
@@ -339,7 +322,7 @@ program
339
322
  {
340
323
  type: 'checkbox',
341
324
  name: 'enabledPlugins',
342
- message: 'Toggle Plugins (Space to select, Enter to confirm):',
325
+ message: 'Select plugins to enable:',
343
326
  choices: allPlugins.map(p => ({
344
327
  name: `${p.name} - ${p.description || 'Plugin'}`,
345
328
  value: p.name,
@@ -355,12 +338,13 @@ program
355
338
  case 'startup':
356
339
  const currentStartup = config.get('startOnBoot') === true;
357
340
  console.log(chalk.cyan.bold('\n🚀 Startup Settings\n'));
341
+ console.log(chalk.gray(' Use ← → arrow keys or Y/N, then press Enter\n'));
358
342
  const startupConfirm = await inquirer.prompt([
359
343
  {
360
344
  type: 'confirm',
361
345
  name: 'enable',
362
- message: currentStartup
363
- ? 'Echo is set to start on boot. Would you like to disable this?'
346
+ message: currentStartup
347
+ ? 'Echo is set to start on boot. Would you like to disable this?'
364
348
  : 'Would you like Echo to start automatically when you log in?',
365
349
  default: !currentStartup
366
350
  }
@@ -420,6 +404,7 @@ program
420
404
  case 'autoupdate':
421
405
  const currentAutoUpdate = config.get('autoUpdateCheck') !== false;
422
406
  console.log(chalk.cyan.bold('\n🔄 Auto-Update Settings\n'));
407
+ console.log(chalk.gray(' Use ← → arrow keys or Y/N, then press Enter\n'));
423
408
  const autoUpdateConfirm = await inquirer.prompt([
424
409
  {
425
410
  type: 'confirm',
@@ -437,6 +422,7 @@ program
437
422
  case 'notify':
438
423
  const currentNotify = config.get('startupNotification') !== false;
439
424
  console.log(chalk.cyan.bold('\n🔔 Notification Settings\n'));
425
+ console.log(chalk.gray(' Use ← → arrow keys or Y/N, then press Enter\n'));
440
426
  const notifyConfirm = await inquirer.prompt([
441
427
  {
442
428
  type: 'confirm',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "echo-ai-agent",
3
- "version": "1.0.70",
3
+ "version": "1.0.71",
4
4
  "description": "A premium JARVIS-inspired AI assistant for your desktop - voice-controlled, intelligent, and beautiful",
5
5
  "main": "main/main.js",
6
6
  "bin": {
@@ -25,7 +25,7 @@
25
25
  "dotenv": "^17.3.1",
26
26
  "electron": "^40.4.1",
27
27
  "electron-log": "^5.4.3",
28
- "inquirer": "^13.2.4",
28
+ "inquirer": "^8.0.0",
29
29
  "node-notifier": "^10.0.1",
30
30
  "node-record-lpcm16": "^1.0.1",
31
31
  "ora": "^9.3.0",
@@ -12,10 +12,22 @@ const config = new ConfigManager();
12
12
  async function run() {
13
13
  printLogo();
14
14
  console.log(chalk.gray(' Configure your AI brain and start your journey...\n'));
15
+ console.log(chalk.yellow(' 💡 Navigation: Use ↑↓ arrows to move, Enter to select/edit, Tab to skip\n'));
16
+
17
+ // Collect all configuration in one flow
18
+ const setupConfig = {
19
+ provider: null,
20
+ apiKey: null,
21
+ model: null,
22
+ userName: null,
23
+ voiceProvider: null,
24
+ whisperKey: null,
25
+ startOnBoot: false,
26
+ plugins: []
27
+ };
15
28
 
16
29
  // ========== STEP 1: AI Provider Selection ==========
17
- console.log(chalk.cyan.bold('\n🧠 Step 1: AI Intelligence Provider\n'));
18
- console.log(chalk.gray(' Use ↑↓ arrow keys to navigate, Enter to select\n'));
30
+ console.log(chalk.cyan.bold('🧠 AI Intelligence Provider\n'));
19
31
  const { provider } = await inquirer.prompt([
20
32
  {
21
33
  type: 'list',
@@ -47,32 +59,31 @@ async function run() {
47
59
  loop: false
48
60
  }
49
61
  ]);
62
+ setupConfig.provider = provider;
50
63
 
51
64
  // ========== STEP 2: API Key ==========
52
- console.log(chalk.cyan.bold('\n🔑 Step 2: API Credentials\n'));
65
+ console.log(chalk.cyan.bold('\n🔑 API Credentials\n'));
53
66
  const providerName = AI_MODELS[provider].name;
54
67
  const apiKeyInstructions = AI_MODELS[provider].apiKeyUrl || `Get your API key from ${providerName}`;
55
-
56
- console.log(chalk.yellow(` ℹ️ ${apiKeyInstructions}`));
57
- console.log(chalk.gray(' Use arrow keys to navigate, then Enter to confirm\n'));
58
-
68
+
69
+ console.log(chalk.yellow(` ℹ️ ${apiKeyInstructions}\n`));
70
+
59
71
  const { apiKey } = await inquirer.prompt([
60
72
  {
61
- type: 'input',
73
+ type: 'password',
62
74
  name: 'apiKey',
63
75
  message: `Enter your ${providerName} API Key:`,
64
76
  validate: (input) => {
65
77
  if (!input.trim()) return 'API Key is required.';
66
78
  if (input.trim().length < 10) return 'API Key seems too short. Please check.';
67
79
  return true;
68
- },
69
- mask: '*'
80
+ }
70
81
  }
71
82
  ]);
83
+ setupConfig.apiKey = apiKey;
72
84
 
73
85
  // ========== STEP 3: Model Selection ==========
74
- console.log(chalk.cyan.bold('\n🤖 Step 3: AI Model\n'));
75
- console.log(chalk.gray(' Use ↑↓ arrow keys to navigate, Enter to select\n'));
86
+ console.log(chalk.cyan.bold('\n🤖 AI Model\n'));
76
87
  const models = AI_MODELS[provider].models;
77
88
  const { model } = await inquirer.prompt([
78
89
  {
@@ -89,9 +100,10 @@ async function run() {
89
100
  loop: false
90
101
  }
91
102
  ]);
103
+ setupConfig.model = model;
92
104
 
93
105
  // ========== STEP 4: Personalization ==========
94
- console.log(chalk.cyan.bold('\n👤 Step 4: Personalization\n'));
106
+ console.log(chalk.cyan.bold('\n👤 Personalization\n'));
95
107
  const { userName } = await inquirer.prompt([
96
108
  {
97
109
  type: 'input',
@@ -101,10 +113,10 @@ async function run() {
101
113
  validate: (input) => input.trim() ? true : 'Name cannot be empty.'
102
114
  }
103
115
  ]);
116
+ setupConfig.userName = userName;
104
117
 
105
118
  // ========== STEP 5: Voice Engine ==========
106
- console.log(chalk.cyan.bold('\n🎙️ Step 5: Voice Recognition\n'));
107
- console.log(chalk.gray(' Use ↑↓ arrow keys to navigate, Enter to select\n'));
119
+ console.log(chalk.cyan.bold('\n🎙️ Voice Recognition\n'));
108
120
  const { voiceProvider } = await inquirer.prompt([
109
121
  {
110
122
  type: 'list',
@@ -132,32 +144,31 @@ async function run() {
132
144
  loop: false
133
145
  }
134
146
  ]);
147
+ setupConfig.voiceProvider = voiceProvider;
135
148
 
136
149
  // Handle Whisper Cloud API Key if needed
137
- let whisperKey = null;
138
150
  if (voiceProvider === 'whisper') {
139
151
  const existingKeys = config.get('apiKeys') || {};
140
152
  if (!existingKeys.openai) {
141
153
  console.log(chalk.yellow('\n⚠️ Whisper Cloud requires an OpenAI API key.\n'));
142
154
  const { openaiKey } = await inquirer.prompt([
143
155
  {
144
- type: 'input',
156
+ type: 'password',
145
157
  name: 'openaiKey',
146
158
  message: 'Enter your OpenAI API Key:',
147
159
  validate: (input) => {
148
160
  if (!input.trim()) return 'API Key is required.';
149
161
  if (input.trim().length < 10) return 'API Key seems too short.';
150
162
  return true;
151
- },
152
- mask: '*'
163
+ }
153
164
  }
154
165
  ]);
155
- whisperKey = openaiKey;
166
+ setupConfig.whisperKey = openaiKey;
156
167
  }
157
168
  }
158
169
 
159
170
  // ========== STEP 6: Startup Preference ==========
160
- console.log(chalk.cyan.bold('\n🚀 Step 6: Startup Settings\n'));
171
+ console.log(chalk.cyan.bold('\n🚀 Startup Settings\n'));
161
172
  const { startOnBoot } = await inquirer.prompt([
162
173
  {
163
174
  type: 'confirm',
@@ -166,20 +177,20 @@ async function run() {
166
177
  default: false
167
178
  }
168
179
  ]);
180
+ setupConfig.startOnBoot = startOnBoot;
169
181
 
170
182
  // ========== STEP 7: Plugin Selection ==========
171
- console.log(chalk.cyan.bold('\n🧩 Step 7: Plugins\n'));
183
+ console.log(chalk.cyan.bold('\n🧩 Plugins\n'));
172
184
  const PluginManager = require('./plugin-manager');
173
185
  const pm = new PluginManager();
174
186
  const allPlugins = pm.listPlugins();
175
187
 
176
- let selectedPlugins = [];
177
188
  if (allPlugins.length > 0) {
178
189
  const { plugins } = await inquirer.prompt([
179
190
  {
180
191
  type: 'checkbox',
181
192
  name: 'plugins',
182
- message: 'Enable Plugins (use Space to toggle, Enter to confirm):',
193
+ message: 'Enable Plugins (Space to toggle, Enter to confirm):',
183
194
  choices: allPlugins.map(p => ({
184
195
  name: `${p.name} - ${p.description || 'Plugin'}`,
185
196
  value: p.name,
@@ -188,31 +199,31 @@ async function run() {
188
199
  pageSize: Math.min(allPlugins.length, 8)
189
200
  }
190
201
  ]);
191
- selectedPlugins = plugins;
202
+ setupConfig.plugins = plugins;
192
203
  }
193
204
 
194
205
  // ========== Save Configuration ==========
195
206
  console.log(chalk.cyan.bold('\n💾 Saving Configuration...\n'));
196
-
207
+
197
208
  const apiKeys = config.get('apiKeys') || {};
198
- apiKeys[provider] = apiKey;
199
- if (whisperKey) {
200
- apiKeys.openai = whisperKey;
209
+ apiKeys[setupConfig.provider] = setupConfig.apiKey;
210
+ if (setupConfig.whisperKey) {
211
+ apiKeys.openai = setupConfig.whisperKey;
201
212
  }
202
213
 
203
214
  config.set('apiKeys', apiKeys);
204
- config.set('aiProvider', provider);
205
- config.set('model', model);
206
- config.set('userName', userName);
207
- config.set('voiceProvider', voiceProvider);
208
- config.set('startOnBoot', startOnBoot);
209
- config.set('plugins', selectedPlugins);
215
+ config.set('aiProvider', setupConfig.provider);
216
+ config.set('model', setupConfig.model);
217
+ config.set('userName', setupConfig.userName);
218
+ config.set('voiceProvider', setupConfig.voiceProvider);
219
+ config.set('startOnBoot', setupConfig.startOnBoot);
220
+ config.set('plugins', setupConfig.plugins);
210
221
  config.set('configured', true);
211
222
 
212
223
  // Create/update .env for backward compatibility
213
- if (provider === 'google') {
224
+ if (setupConfig.provider === 'google') {
214
225
  const envPath = path.join(__dirname, '..', '.env');
215
- fs.writeFileSync(envPath, `GOOGLE_AI_API_KEY=${apiKey}\n`);
226
+ fs.writeFileSync(envPath, `GOOGLE_AI_API_KEY=${setupConfig.apiKey}\n`);
216
227
  }
217
228
 
218
229
  // ========== Summary ==========
@@ -221,11 +232,11 @@ async function run() {
221
232
  console.log(chalk.white(' │ 📊 Configuration Summary │'));
222
233
  console.log(chalk.white(' ├─────────────────────────────────────────┤'));
223
234
  console.log(chalk.white(` │ 🧠 AI Provider: ${chalk.cyan(providerName.padEnd(22))}│`));
224
- console.log(chalk.white(` │ 🤖 Model: ${chalk.cyan(model.padEnd(22))}│`));
225
- console.log(chalk.white(` │ 👤 Your Name: ${chalk.cyan(userName.padEnd(22))}│`));
226
- console.log(chalk.white(` │ 🎙️ Voice Engine: ${chalk.cyan(voiceProvider.padEnd(22))}│`));
227
- console.log(chalk.white(` │ 🚀 Startup: ${chalk.cyan((startOnBoot ? 'Auto-start' : 'Manual').padEnd(22))}│`));
228
- console.log(chalk.white(` │ 🧩 Plugins: ${chalk.cyan(selectedPlugins.length.toString().padEnd(22))}│`));
235
+ console.log(chalk.white(` │ 🤖 Model: ${chalk.cyan(setupConfig.model.padEnd(22))}│`));
236
+ console.log(chalk.white(` │ 👤 Your Name: ${chalk.cyan(setupConfig.userName.padEnd(22))}│`));
237
+ console.log(chalk.white(` │ 🎙️ Voice Engine: ${chalk.cyan(setupConfig.voiceProvider.padEnd(22))}│`));
238
+ console.log(chalk.white(` │ 🚀 Startup: ${chalk.cyan((setupConfig.startOnBoot ? 'Auto-start' : 'Manual').padEnd(22))}│`));
239
+ console.log(chalk.white(` │ 🧩 Plugins: ${chalk.cyan(setupConfig.plugins.length.toString().padEnd(22))}│`));
229
240
  console.log(chalk.white(' └─────────────────────────────────────────┘'));
230
241
 
231
242
  console.log(chalk.gray('\n✨ Echo is ready to serve you!\n'));
@@ -238,7 +249,7 @@ async function run() {
238
249
  const { spawn } = require('child_process');
239
250
 
240
251
  // Setup Local Whisper if selected
241
- if (voiceProvider === 'whisper-local') {
252
+ if (setupConfig.voiceProvider === 'whisper-local') {
242
253
  try {
243
254
  const { setup: setupWhisper } = require('./whisper-setup');
244
255
  console.log(chalk.yellow('🏠 Initializing Local Whisper environment...'));