natureco-cli 2.14.0 → 2.14.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "natureco-cli",
3
- "version": "2.14.0",
3
+ "version": "2.14.2",
4
4
  "description": "NatureCo AI Bot Terminal Interface",
5
5
  "main": "bin/natureco.js",
6
6
  "bin": {
@@ -83,11 +83,85 @@ async function chat(botName, options = {}) {
83
83
  }
84
84
  }
85
85
 
86
+ // Startup animation
87
+ console.clear();
88
+
89
+ // ASCII art rabbit
90
+ console.log('');
91
+ console.log(chalk.cyan(' (\\\_/)'));
92
+ console.log(chalk.cyan(' (•ᴥ•)'));
93
+ console.log(chalk.cyan(' />🌿'));
94
+ console.log('');
95
+
96
+ // Helper function for progress bar
97
+ function progressBar(percent, width = 20) {
98
+ const filled = Math.round(width * percent);
99
+ return chalk.green('█'.repeat(filled)) + chalk.gray('░'.repeat(width - filled));
100
+ }
101
+
102
+ // Helper function to check gateway status
103
+ function checkGateway() {
104
+ try {
105
+ const fs2 = require('fs');
106
+ const gatewayPidFile = path.join(os.homedir(), '.natureco', 'gateway.pid');
107
+ if (fs2.existsSync(gatewayPidFile)) {
108
+ const pid = parseInt(fs2.readFileSync(gatewayPidFile, 'utf8'));
109
+ process.kill(pid, 0);
110
+ return true;
111
+ }
112
+ } catch {
113
+ return false;
114
+ }
115
+ return false;
116
+ }
117
+
118
+ // Startup steps with animation
119
+ const steps = [
120
+ { label: 'Memory', fn: () => loadMemory(bot.id) },
121
+ { label: 'Skills', fn: () => getSkillPrompts() },
122
+ { label: 'Gateway', fn: () => checkGateway() },
123
+ ];
124
+
125
+ // Execute steps with progress animation
126
+ const results = {};
127
+ for (let i = 0; i < steps.length; i++) {
128
+ const step = steps[i];
129
+ const percent = (i + 1) / steps.length;
130
+
131
+ process.stdout.write(`[${progressBar(percent)}] ${step.label}...`);
132
+
133
+ // Execute step
134
+ const result = step.fn();
135
+ results[step.label.toLowerCase()] = result;
136
+
137
+ // Show result
138
+ let info = '';
139
+ if (step.label === 'Memory' && result) {
140
+ const factCount = (result.facts || []).length;
141
+ info = factCount > 0 ? ` · ${factCount} facts` : '';
142
+ } else if (step.label === 'Skills' && result) {
143
+ const skillCount = getSkills().length;
144
+ info = skillCount > 0 ? ` · ${skillCount} skills` : '';
145
+ } else if (step.label === 'Gateway') {
146
+ info = result ? ' · running' : ' · offline';
147
+ }
148
+
149
+ process.stdout.write(`\r[${progressBar(percent)}] ${step.label} loaded${info}\n`);
150
+
151
+ // Wait 300ms
152
+ await new Promise(resolve => setTimeout(resolve, 300));
153
+ }
154
+
155
+ console.log('');
156
+
157
+ // Wait a bit before clearing
158
+ await new Promise(resolve => setTimeout(resolve, 500));
159
+
86
160
  // Chat başlat
87
161
  console.clear();
88
162
 
89
163
  // Get botName from memory
90
- const memory = loadMemory(bot.id);
164
+ const memory = results.memory || loadMemory(bot.id);
91
165
  const displayBotName = memory.botName || bot.name;
92
166
 
93
167
  // Get provider model (short name)
@@ -96,10 +170,70 @@ async function chat(botName, options = {}) {
96
170
  const providerModel = config.providerModel || 'unknown';
97
171
  const shortModel = providerModel.split('/').pop().split('-').slice(0, 2).join('-'); // e.g., "llama-3.1" from "llama-3.1-8b-instant"
98
172
 
99
- // Minimal header with separator
100
- const separator = '─'.repeat(40);
173
+ // Get terminal width
174
+ const terminalWidth = process.stdout.columns || 80;
175
+ const separator = '─'.repeat(terminalWidth);
176
+
177
+ // Rabbit ASCII art
178
+ const rabbit = chalk.cyan(' (\\\_/)\n') +
179
+ chalk.cyan(' (•ᴥ•)\n') +
180
+ chalk.cyan(' />🌿');
181
+
182
+ // Full UI header with rabbit
183
+ console.log(rabbit);
184
+ console.log('');
185
+ console.log(chalk.gray(separator));
186
+
187
+ // Line 1: NatureCo · botName · model · timezone
188
+ const timezone = memory.facts?.find(f => {
189
+ const val = typeof f === 'string' ? f : f.value;
190
+ return val?.includes('Timezone:');
191
+ });
192
+ const tzStr = timezone ? (typeof timezone === 'string' ? timezone : timezone.value).replace('Timezone:', '').trim() : '';
193
+ const line1 = chalk.white.bold('NatureCo') +
194
+ chalk.gray(' · ') +
195
+ chalk.cyan(displayBotName) +
196
+ chalk.gray(' · ') +
197
+ chalk.gray(shortModel) +
198
+ (tzStr ? chalk.gray(' · ') + chalk.gray(tzStr) : '');
199
+ console.log(line1);
200
+
201
+ console.log(chalk.gray(separator));
202
+
203
+ // Line 2: Session · Commands · Ctrl+C
204
+ const line2 = chalk.gray('Session') +
205
+ chalk.gray(' · ') +
206
+ chalk.gray('/clear /bot /skills /memory /help') +
207
+ chalk.gray(' · ') +
208
+ chalk.gray('Ctrl+C to exit');
209
+ console.log(line2);
210
+
101
211
  console.log(chalk.gray(separator));
102
- console.log(chalk.white('NatureCo') + chalk.gray(' · ') + chalk.cyan(displayBotName) + chalk.gray(' · ') + chalk.gray(shortModel));
212
+
213
+ // Line 3: Memory info · Skills · Crons
214
+ const userName = memory.name || 'User';
215
+ const factCount = (memory.facts || []).length;
216
+ const skillCount = getSkills().length;
217
+
218
+ // Get active cron count
219
+ let cronCount = 0;
220
+ try {
221
+ const fs2 = require('fs');
222
+ const cronsFile = path.join(os.homedir(), '.natureco', 'crons.json');
223
+ if (fs2.existsSync(cronsFile)) {
224
+ const crons = JSON.parse(fs2.readFileSync(cronsFile, 'utf8'));
225
+ cronCount = crons.filter(c => c.enabled).length;
226
+ }
227
+ } catch {}
228
+
229
+ const memoryInfo = `Memory: ${userName}`;
230
+ const line3 = chalk.gray(memoryInfo + (factCount > 0 ? ` · ${factCount} facts` : '')) +
231
+ chalk.gray(' ') +
232
+ chalk.gray(`Skills: ${skillCount}`) +
233
+ chalk.gray(' ') +
234
+ chalk.gray(`Crons: ${cronCount} active`);
235
+ console.log(line3);
236
+
103
237
  console.log(chalk.gray(separator));
104
238
  console.log('');
105
239
 
@@ -142,11 +276,8 @@ async function chat(botName, options = {}) {
142
276
  } else {
143
277
  // Create new session
144
278
  session = createSession(bot.id, bot.name);
145
- console.log(chalk.gray(`Session: ${session.id}\n`));
146
279
  }
147
280
 
148
- console.log(chalk.gray('Commands: /clear /bot /skills /memory /help · Ctrl+C to exit\n'));
149
-
150
281
  // Run on-start hooks
151
282
  await runHooks('on-start', null, { botId: bot.id, botName: bot.name });
152
283
 
@@ -244,12 +375,21 @@ async function chat(botName, options = {}) {
244
375
  switch (command.toLowerCase()) {
245
376
  case 'clear':
246
377
  console.clear();
247
- const separator2 = '─'.repeat(40);
378
+
379
+ // Rabbit
380
+ const rabbitClear = chalk.cyan(' (\\\_/)\n') +
381
+ chalk.cyan(' (•ᴥ•)\n') +
382
+ chalk.cyan(' />🌿');
383
+ console.log(rabbitClear);
384
+ console.log('');
385
+
386
+ const terminalWidth2 = process.stdout.columns || 80;
387
+ const separator2 = '─'.repeat(terminalWidth2);
388
+
248
389
  console.log(chalk.gray(separator2));
249
- console.log(chalk.white('NatureCo') + chalk.gray(' · ') + chalk.cyan(displayBotName) + chalk.gray(' · ') + chalk.gray(shortModel));
390
+ console.log(chalk.white.bold('NatureCo') + chalk.gray(' · ') + chalk.cyan(displayBotName) + chalk.gray(' · ') + chalk.gray(shortModel));
250
391
  console.log(chalk.gray(separator2));
251
392
  console.log('');
252
- console.log(chalk.gray('Commands: /clear /bot /skills /memory /help\n'));
253
393
  rl.prompt();
254
394
  return;
255
395
 
@@ -429,7 +569,9 @@ ${lastCodeBlock}
429
569
  addMessageToSession(bot.id, session.id, '/ultrareview', botReply);
430
570
  } catch (err) {
431
571
  stopLoadingAnimation(loadingInterval);
432
- console.log(chalk.red(`Error: ${err.message}\n`));
572
+ // Extract clean error message
573
+ const errorMsg = err.message.split('"message":"')[1]?.split('"')[0] || err.message;
574
+ console.log(chalk.red(`Error: ${errorMsg}\n`));
433
575
  }
434
576
 
435
577
  rl.prompt();
@@ -464,7 +606,9 @@ ${lastCodeBlock}
464
606
  addMessageToSession(bot.id, session.id, userMessage, botReply);
465
607
  } catch (err) {
466
608
  stopLoadingAnimation(loadingInterval);
467
- console.log(chalk.red(`Error: ${err.message}\n`));
609
+ // Extract clean error message
610
+ const errorMsg = err.message.split('"message":"')[1]?.split('"')[0] || err.message;
611
+ console.log(chalk.red(`Error: ${errorMsg}\n`));
468
612
  }
469
613
 
470
614
  rl.prompt();
@@ -568,7 +712,9 @@ ${lastCodeBlock}
568
712
  }
569
713
  } catch (err) {
570
714
  stopLoadingAnimation(loadingInterval);
571
- console.log(chalk.red(`Error: ${err.message}\n`));
715
+ // Extract clean error message
716
+ const errorMsg = err.message.split('"message":"')[1]?.split('"')[0] || err.message;
717
+ console.log(chalk.red(`Error: ${errorMsg}\n`));
572
718
  }
573
719
 
574
720
  currentMessage = '';
@@ -211,7 +211,7 @@ body::before{
211
211
  <div class="header-bot-name" id="header-bot-name">Nature Bot</div>
212
212
  <div class="header-bot-model" id="header-bot-model">NatureCo</div>
213
213
  </div>
214
- <div class="version-badge" id="version-badge">v2.14.0</div>
214
+ <div class="version-badge" id="version-badge">v2.14.2</div>
215
215
  </div>
216
216
  <div class="messages" id="messages"></div>
217
217
  <div class="input-area">
@@ -341,7 +341,7 @@ function dashboard(action) {
341
341
  apiKey: cfg.apiKey,
342
342
  defaultBot: cfg.defaultBot,
343
343
  defaultBotId: cfg.defaultBotId,
344
- version: 'v2.14.0',
344
+ version: 'v2.14.2',
345
345
  bots: cfg.bots || [],
346
346
  telegramToken: cfg.telegramToken || null,
347
347
  whatsappConnected: cfg.whatsappConnected || false,