natureco-cli 2.13.30 → 2.14.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "natureco-cli",
3
- "version": "2.13.30",
3
+ "version": "2.14.1",
4
4
  "description": "NatureCo AI Bot Terminal Interface",
5
5
  "main": "bin/natureco.js",
6
6
  "bin": {
@@ -83,11 +83,152 @@ 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
- console.log(chalk.green.bold(`╭─ NatureCo Terminal ─╮`));
89
- console.log(chalk.green(`│ ${bot.name.padEnd(18)} │`));
90
- console.log(chalk.green(`╰─────────────────────╯\n`));
162
+
163
+ // Get botName from memory
164
+ const memory = results.memory || loadMemory(bot.id);
165
+ const displayBotName = memory.botName || bot.name;
166
+
167
+ // Get provider model (short name)
168
+ const { getConfig } = require('../utils/config');
169
+ const config = getConfig();
170
+ const providerModel = config.providerModel || 'unknown';
171
+ const shortModel = providerModel.split('/').pop().split('-').slice(0, 2).join('-'); // e.g., "llama-3.1" from "llama-3.1-8b-instant"
172
+
173
+ // Get terminal width
174
+ const terminalWidth = process.stdout.columns || 80;
175
+ const separator = '─'.repeat(terminalWidth);
176
+
177
+ // Full UI header
178
+ console.log(chalk.gray(separator));
179
+
180
+ // Line 1: NatureCo · botName · model · timezone
181
+ const timezone = memory.facts?.find(f => {
182
+ const val = typeof f === 'string' ? f : f.value;
183
+ return val?.includes('Timezone:');
184
+ });
185
+ const tzStr = timezone ? (typeof timezone === 'string' ? timezone : timezone.value).replace('Timezone:', '').trim() : '';
186
+ const line1 = chalk.white.bold('NatureCo') +
187
+ chalk.gray(' · ') +
188
+ chalk.cyan(displayBotName) +
189
+ chalk.gray(' · ') +
190
+ chalk.gray(shortModel) +
191
+ (tzStr ? chalk.gray(' · ') + chalk.gray(tzStr) : '');
192
+ console.log(line1);
193
+
194
+ console.log(chalk.gray(separator));
195
+
196
+ // Line 2: Session · Commands · Ctrl+C
197
+ const line2 = chalk.gray('Session') +
198
+ chalk.gray(' · ') +
199
+ chalk.gray('Commands: /clear /bot /skills /memory /help') +
200
+ chalk.gray(' · ') +
201
+ chalk.gray('Ctrl+C to exit');
202
+ console.log(line2);
203
+
204
+ console.log(chalk.gray(separator));
205
+
206
+ // Line 3: Memory info · Skills · Crons
207
+ const userName = memory.name || '';
208
+ const factCount = (memory.facts || []).length;
209
+ const skillCount = getSkills().length;
210
+
211
+ // Get cron count
212
+ let cronCount = 0;
213
+ try {
214
+ const fs2 = require('fs');
215
+ const cronsFile = path.join(os.homedir(), '.natureco', 'crons.json');
216
+ if (fs2.existsSync(cronsFile)) {
217
+ const crons = JSON.parse(fs2.readFileSync(cronsFile, 'utf8'));
218
+ cronCount = crons.filter(c => c.enabled).length;
219
+ }
220
+ } catch {}
221
+
222
+ const memoryInfo = userName ? `Memory: ${userName}` : 'Memory';
223
+ const line3 = chalk.gray(memoryInfo + (factCount > 0 ? ` · ${factCount} facts` : '')) +
224
+ chalk.gray(' ') +
225
+ chalk.gray(`Skills: ${skillCount}`) +
226
+ chalk.gray(' ') +
227
+ chalk.gray(`Crons: ${cronCount} active`);
228
+ console.log(line3);
229
+
230
+ console.log(chalk.gray(separator));
231
+ console.log('');
91
232
 
92
233
  // Session management
93
234
  let session;
@@ -96,42 +237,40 @@ async function chat(botName, options = {}) {
96
237
  // Resume latest session
97
238
  session = getLatestSession(bot.id);
98
239
  if (session) {
99
- console.log(chalk.blue(`📂 Resumed session: ${session.id}\n`));
240
+ console.log(chalk.blue(`Resumed: ${session.id}\n`));
100
241
  // Display last few messages
101
242
  const lastMessages = session.messages.slice(-3);
102
243
  lastMessages.forEach(msg => {
103
- console.log(chalk.cyan(`siz ${msg.user}`));
104
- console.log(chalk.green(`bot ${msg.bot}\n`));
244
+ console.log(chalk.gray('You ') + msg.user);
245
+ console.log(chalk.cyan(displayBotName + ' ') + msg.bot);
246
+ console.log('');
105
247
  });
106
248
  } else {
107
- console.log(chalk.gray('No previous session found. Starting new session.\n'));
249
+ console.log(chalk.gray('No previous session. Starting new.\n'));
108
250
  session = createSession(bot.id, bot.name);
109
251
  }
110
252
  } else {
111
253
  // Resume specific session
112
254
  session = loadSession(bot.id, options.resume);
113
255
  if (session) {
114
- console.log(chalk.blue(`📂 Resumed session: ${session.id}\n`));
256
+ console.log(chalk.blue(`Resumed: ${session.id}\n`));
115
257
  // Display last few messages
116
258
  const lastMessages = session.messages.slice(-3);
117
259
  lastMessages.forEach(msg => {
118
- console.log(chalk.cyan(`siz ${msg.user}`));
119
- console.log(chalk.green(`bot ${msg.bot}\n`));
260
+ console.log(chalk.gray('You ') + msg.user);
261
+ console.log(chalk.cyan(displayBotName + ' ') + msg.bot);
262
+ console.log('');
120
263
  });
121
264
  } else {
122
- console.log(chalk.red(`❌ Session not found: ${options.resume}\n`));
265
+ console.log(chalk.red(`Session not found: ${options.resume}\n`));
123
266
  process.exit(1);
124
267
  }
125
268
  }
126
269
  } else {
127
270
  // Create new session
128
271
  session = createSession(bot.id, bot.name);
129
- console.log(chalk.gray(`Session ID: ${session.id} · Resume with: --resume ${session.id}\n`));
130
272
  }
131
273
 
132
- console.log(chalk.gray('Chat komutları: /clear /bot /skills /memory /commands /help\n'));
133
- console.log(chalk.gray('Ctrl+B: Arka plana al | Ctrl+C: Çık\n'));
134
-
135
274
  // Run on-start hooks
136
275
  await runHooks('on-start', null, { botId: bot.id, botName: bot.name });
137
276
 
@@ -162,7 +301,7 @@ async function chat(botName, options = {}) {
162
301
  const rl = readline.createInterface({
163
302
  input: process.stdin,
164
303
  output: process.stdout,
165
- prompt: chalk.cyan('siz › '),
304
+ prompt: chalk.gray('You '),
166
305
  historySize: 100,
167
306
  });
168
307
 
@@ -229,10 +368,13 @@ async function chat(botName, options = {}) {
229
368
  switch (command.toLowerCase()) {
230
369
  case 'clear':
231
370
  console.clear();
232
- console.log(chalk.green.bold(`╭─ NatureCo Terminal ─╮`));
233
- console.log(chalk.green(`│ ${bot.name.padEnd(18)} │`));
234
- console.log(chalk.green(`╰─────────────────────╯\n`));
235
- console.log(chalk.gray('Chat komutları: /clear /bot /skills /commands /help\n'));
371
+ const terminalWidth2 = process.stdout.columns || 80;
372
+ const separator2 = '─'.repeat(terminalWidth2);
373
+
374
+ console.log(chalk.gray(separator2));
375
+ console.log(chalk.white.bold('NatureCo') + chalk.gray(' · ') + chalk.cyan(displayBotName) + chalk.gray(' · ') + chalk.gray(shortModel));
376
+ console.log(chalk.gray(separator2));
377
+ console.log('');
236
378
  rl.prompt();
237
379
  return;
238
380
 
@@ -262,8 +404,13 @@ async function chat(botName, options = {}) {
262
404
  bot = newBot;
263
405
  conversationId = null;
264
406
  session = createSession(bot.id, bot.name);
265
- console.log(chalk.green(`\n✅ Bot değiştirildi: ${bot.name}\n`));
266
- console.log(chalk.gray(`Session ID: ${session.id}\n`));
407
+
408
+ // Update displayBotName
409
+ const newMemory = loadMemory(bot.id);
410
+ const newDisplayBotName = newMemory.botName || bot.name;
411
+
412
+ console.log(chalk.green(`\nBot changed: ${newDisplayBotName}\n`));
413
+ console.log(chalk.gray(`Session: ${session.id}\n`));
267
414
  rl.prompt();
268
415
  return;
269
416
 
@@ -401,13 +548,13 @@ ${lastCodeBlock}
401
548
  }
402
549
 
403
550
  const botReply = response.reply || response.message || 'No response';
404
- console.log(chalk.green(`bot ${botReply}\n`));
551
+ console.log(chalk.cyan(`${displayBotName} `) + botReply + '\n');
405
552
 
406
553
  addToHistory(bot.id, '/ultrareview', botReply, conversationId);
407
554
  addMessageToSession(bot.id, session.id, '/ultrareview', botReply);
408
555
  } catch (err) {
409
556
  stopLoadingAnimation(loadingInterval);
410
- console.log(chalk.red(`\n❌ Error: ${err.message}\n`));
557
+ console.log(chalk.red(`Error: ${err.message}\n`));
411
558
  }
412
559
 
413
560
  rl.prompt();
@@ -436,13 +583,13 @@ ${lastCodeBlock}
436
583
  }
437
584
 
438
585
  const botReply = response.reply || response.message || 'No response';
439
- console.log(chalk.green(`bot ${botReply}\n`));
586
+ console.log(chalk.cyan(`${displayBotName} `) + botReply + '\n');
440
587
 
441
588
  addToHistory(bot.id, userMessage, botReply, conversationId);
442
589
  addMessageToSession(bot.id, session.id, userMessage, botReply);
443
590
  } catch (err) {
444
591
  stopLoadingAnimation(loadingInterval);
445
- console.log(chalk.red(`\n❌ Error: ${err.message}\n`));
592
+ console.log(chalk.red(`Error: ${err.message}\n`));
446
593
  }
447
594
 
448
595
  rl.prompt();
@@ -532,7 +679,7 @@ ${lastCodeBlock}
532
679
  // Run post-message hooks
533
680
  botReply = await runHooks('post-message', botReply, { botId: bot.id, botName: bot.name });
534
681
 
535
- console.log(chalk.green(`bot ${botReply}\n`));
682
+ console.log(chalk.cyan(`${displayBotName} `) + botReply + '\n');
536
683
 
537
684
  // Save to history and session
538
685
  addToHistory(bot.id, userMessage, botReply, conversationId);
@@ -546,7 +693,7 @@ ${lastCodeBlock}
546
693
  }
547
694
  } catch (err) {
548
695
  stopLoadingAnimation(loadingInterval);
549
- console.log(chalk.red(`\n❌ Error: ${err.message}\n`));
696
+ console.log(chalk.red(`Error: ${err.message}\n`));
550
697
  }
551
698
 
552
699
  currentMessage = '';
@@ -568,15 +715,16 @@ ${lastCodeBlock}
568
715
  }
569
716
 
570
717
  function startLoadingAnimation() {
571
- const frames = ['', '', '', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
718
+ const frames = ['●○○', '○●○', '○○●'];
572
719
  let i = 0;
573
720
 
574
- process.stdout.write(chalk.yellow('bot '));
721
+ // Get displayBotName from current context (will be passed as parameter)
722
+ process.stdout.write(chalk.cyan('... '));
575
723
 
576
724
  return setInterval(() => {
577
- process.stdout.write(`\r${chalk.yellow('bot ›')} ${chalk.yellow(frames[i])}`);
725
+ process.stdout.write(`\r${chalk.cyan(frames[i] + ' ')}`);
578
726
  i = (i + 1) % frames.length;
579
- }, 80);
727
+ }, 300);
580
728
  }
581
729
 
582
730
  function stopLoadingAnimation(interval) {
@@ -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.13.30</div>
214
+ <div class="version-badge" id="version-badge">v2.14.1</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.13.30',
344
+ version: 'v2.14.1',
345
345
  bots: cfg.bots || [],
346
346
  telegramToken: cfg.telegramToken || null,
347
347
  whatsappConnected: cfg.whatsappConnected || false,