natureco-cli 4.5.1 → 4.5.3

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,79 +1,79 @@
1
- {
2
- "name": "natureco-cli",
3
- "version": "4.5.1",
4
- "description": "OpenClaw'dan daha güvenli, daha hızlı, daha ucuz AI agent CLI. Multi-agent, self-evolving skills, audit log, maliyet optimizasyonu ve NatureCo platform-native.",
5
- "bin": {
6
- "natureco": "bin/natureco.js"
7
- },
8
- "files": [
9
- "bin/",
10
- "src/",
11
- "skills/",
12
- "README.md",
13
- "CHANGELOG.md",
14
- "AUDIT.md",
15
- "DEPLOY_v2.0.0.md"
16
- ],
17
- "scripts": {
18
- "test": "node bin/natureco.js help",
19
- "test:unit": "node --check bin/natureco.js && node -e \"console.log('All files OK')\"",
20
- "test:watch": "node --watch bin/natureco.js",
21
- "test:coverage": "node --check bin/natureco.js",
22
- "postinstall": "node bin/natureco.js doctor || true",
23
- "prepublishOnly": "node --check bin/natureco.js"
24
- },
25
- "keywords": [
26
- "natureco",
27
- "ai",
28
- "ai-agent",
29
- "bot",
30
- "cli",
31
- "terminal",
32
- "openclaw-alternative",
33
- "claude-code-alternative",
34
- "multi-agent",
35
- "self-evolving-skills",
36
- "audit-log",
37
- "cost-optimization",
38
- "seo",
39
- "türkçe",
40
- "turkish",
41
- "whatsapp-bot",
42
- "telegram-bot",
43
- "discord-bot",
44
- "natureco-me"
45
- ],
46
- "author": {
47
- "name": "Gencay Olgun",
48
- "email": "hello@natureco.me",
49
- "url": "https://natureco.me"
50
- },
51
- "homepage": "https://natureco.me/cli",
52
- "repository": {
53
- "type": "git",
54
- "url": "git+https://github.com/natureco/natureco-cli.git"
55
- },
56
- "bugs": {
57
- "url": "https://github.com/natureco/natureco-cli/issues"
58
- },
59
- "license": "MIT",
60
- "engines": {
61
- "node": ">=18.0.0"
62
- },
63
- "dependencies": {
64
- "@inquirer/prompts": "^8.5.0",
65
- "@whiskeysockets/baileys": "^7.0.0-rc10",
66
- "chalk": "^4.1.2",
67
- "commander": "^11.1.0",
68
- "json5": "^2.2.3",
69
- "node-cron": "^4.2.1",
70
- "node-telegram-bot-api": "^0.67.0",
71
- "pino": "^8.21.0",
72
- "qrcode-terminal": "^0.12.0",
73
- "semver": "^7.8.1",
74
- "ws": "^8.20.0"
75
- },
76
- "devDependencies": {
77
- "vitest": "^4.1.9"
78
- }
79
- }
1
+ {
2
+ "name": "natureco-cli",
3
+ "version": "4.5.3",
4
+ "description": "OpenClaw'dan daha güvenli, daha hızlı, daha ucuz AI agent CLI. Multi-agent, self-evolving skills, audit log, maliyet optimizasyonu ve NatureCo platform-native.",
5
+ "bin": {
6
+ "natureco": "bin/natureco.js"
7
+ },
8
+ "files": [
9
+ "bin/",
10
+ "src/",
11
+ "skills/",
12
+ "README.md",
13
+ "CHANGELOG.md",
14
+ "AUDIT.md",
15
+ "DEPLOY_v2.0.0.md"
16
+ ],
17
+ "scripts": {
18
+ "test": "node bin/natureco.js help",
19
+ "test:unit": "node --check bin/natureco.js && node -e \"console.log('All files OK')\"",
20
+ "test:watch": "node --watch bin/natureco.js",
21
+ "test:coverage": "node --check bin/natureco.js",
22
+ "postinstall": "node bin/natureco.js doctor || true",
23
+ "prepublishOnly": "node --check bin/natureco.js"
24
+ },
25
+ "keywords": [
26
+ "natureco",
27
+ "ai",
28
+ "ai-agent",
29
+ "bot",
30
+ "cli",
31
+ "terminal",
32
+ "openclaw-alternative",
33
+ "claude-code-alternative",
34
+ "multi-agent",
35
+ "self-evolving-skills",
36
+ "audit-log",
37
+ "cost-optimization",
38
+ "seo",
39
+ "türkçe",
40
+ "turkish",
41
+ "whatsapp-bot",
42
+ "telegram-bot",
43
+ "discord-bot",
44
+ "natureco-me"
45
+ ],
46
+ "author": {
47
+ "name": "Gencay Olgun",
48
+ "email": "hello@natureco.me",
49
+ "url": "https://natureco.me"
50
+ },
51
+ "homepage": "https://natureco.me/cli",
52
+ "repository": {
53
+ "type": "git",
54
+ "url": "git+https://github.com/natureco/natureco-cli.git"
55
+ },
56
+ "bugs": {
57
+ "url": "https://github.com/natureco/natureco-cli/issues"
58
+ },
59
+ "license": "MIT",
60
+ "engines": {
61
+ "node": ">=18.0.0"
62
+ },
63
+ "dependencies": {
64
+ "@inquirer/prompts": "^8.5.0",
65
+ "@whiskeysockets/baileys": "^7.0.0-rc10",
66
+ "chalk": "^4.1.2",
67
+ "commander": "^11.1.0",
68
+ "json5": "^2.2.3",
69
+ "node-cron": "^4.2.1",
70
+ "node-telegram-bot-api": "^0.67.0",
71
+ "pino": "^8.21.0",
72
+ "qrcode-terminal": "^0.12.0",
73
+ "semver": "^7.8.1",
74
+ "ws": "^8.20.0"
75
+ },
76
+ "devDependencies": {
77
+ "vitest": "^4.1.9"
78
+ }
79
+ }
@@ -1,4 +1,5 @@
1
1
  const chalk = require('chalk');
2
+ const tui = require('../utils/tui');
2
3
  const F = require('../utils/format');
3
4
  const fs = require('fs');
4
5
  const path = require('path');
@@ -138,18 +139,21 @@ async function addCron(options) {
138
139
 
139
140
  function listCrons() {
140
141
  const crons = loadCrons();
141
-
142
+
142
143
  if (crons.length === 0) {
143
- F.header('Cron Jobs');
144
- F.meta('Kayıtlı cron yok');
144
+ console.log('\n' + tui.styled(' ⏰ Zamanlanmış Görevler', { color: tui.PALETTE.primary, bold: true }));
145
+ console.log(tui.styled(' ' + '─'.repeat(56), { color: tui.PALETTE.border }));
146
+ console.log('\n ' + tui.C.muted('Henüz cron tanımlı değil. Eklemek için:'));
147
+ console.log(' ' + tui.C.brand('natureco cron add --name "görev" --schedule "0 9 * * *" --action telegram --prompt "..."'));
148
+ console.log('');
145
149
  return;
146
150
  }
147
-
151
+
148
152
  const { getConfig } = require('../utils/config');
149
153
  const config = getConfig();
150
154
  const defaultWhatsappTarget = normalizeWhatsAppNumber(config.whatsappPhone) || 'N/A';
151
155
  const defaultTelegramTarget = (config.telegramAllowedChats && config.telegramAllowedChats[0]) || 'N/A';
152
-
156
+
153
157
  const runs = loadRuns();
154
158
  const rows = crons.map(c => {
155
159
  let target = c.target;
@@ -160,15 +164,32 @@ function listCrons() {
160
164
  }
161
165
  const cronRuns = runs.filter(r => r.name === c.name);
162
166
  const lastRun = cronRuns.sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp))[0];
163
- return [
164
- c.name,
165
- c.schedule,
166
- c.enabled ? 'Aktif' : 'Pasif',
167
- lastRun ? lastRun.timestamp.slice(0, 10) : '—'
168
- ];
167
+ return {
168
+ name: c.name,
169
+ schedule: c.schedule,
170
+ status: c.enabled,
171
+ target,
172
+ lastRun: lastRun ? lastRun.timestamp.slice(0, 16).replace('T', ' ') : '—',
173
+ };
169
174
  });
170
- F.header('Cron Jobs');
171
- F.table(['Name', 'Schedule', 'Status', 'LastRun'], rows);
175
+
176
+ console.log('\n' + tui.styled(' ⏰ Zamanlanmış Görevler (' + crons.length + ')', { color: tui.PALETTE.primary, bold: true }));
177
+ console.log(tui.styled(' ' + '─'.repeat(56), { color: tui.PALETTE.border }));
178
+
179
+ console.log('\n' + tui.table(rows, [
180
+ { key: 'name', label: 'İsim', minWidth: 20, render: r => tui.styled(r.name, { color: tui.PALETTE.primary, bold: true }) },
181
+ { key: 'schedule', label: 'Zamanlama', minWidth: 18, render: r => tui.C.muted(r.schedule) },
182
+ {
183
+ key: 'status', label: 'Durum', minWidth: 10,
184
+ render: r => r.status
185
+ ? tui.styled(' ✓ Aktif ', { bg: tui.PALETTE.success, color: '#000', bold: true })
186
+ : tui.styled(' ✗ Pasif ', { bg: tui.PALETTE.muted, color: '#000', bold: true }),
187
+ },
188
+ { key: 'target', label: 'Hedef', minWidth: 18, render: r => tui.C.text(r.target) },
189
+ { key: 'lastRun', label: 'Son Çalışma', minWidth: 18, render: r => tui.C.muted(r.lastRun) },
190
+ ], { borderStyle: 'round', zebra: true }));
191
+
192
+ console.log('');
172
193
  }
173
194
 
174
195
  function removeCron(options) {
@@ -161,6 +161,9 @@ function printHelp() {
161
161
  ['/model <name>', 'Model değiştir (örn: /model MiniMax-M3)'],
162
162
  ['/tokens', 'Token kullanımı'],
163
163
  ['/save', 'Konuşmayı kaydet'],
164
+ ['/identity [ad]', 'Bot adını değiştir (örn: /identity Sasuke)'],
165
+ ['/forget', 'Memory\'yi temizle'],
166
+ ['/memory', 'Memory\'yi göster'],
164
167
  ['/exit veya /quit', 'Çıkış (Ctrl+C de çalışır)'],
165
168
  ];
166
169
  for (const [cmd, desc] of cmds) {
@@ -202,7 +205,32 @@ async function startRepl(args) {
202
205
  }
203
206
 
204
207
  const messages = [];
205
- let systemPrompt = 'Sen yardımcı bir AI asistansın. Türkçe konuş, kısa ve net cevap ver. Markdown kullanabilirsin.';
208
+ // Kullanıcı ve bot bilgilerini memory'den al (kalıcı)
209
+ const memoryFile = path.join(os.homedir(), '.natureco', 'memory', `${(cfg.userName || 'default').toLowerCase()}.json`);
210
+ let userFacts = [];
211
+ let userNick = cfg.userName || 'Kullanıcı';
212
+ let savedBotName = cfg.botName || 'İchigo';
213
+ try {
214
+ if (fs.existsSync(memoryFile)) {
215
+ const mem = JSON.parse(fs.readFileSync(memoryFile, 'utf8'));
216
+ userFacts = mem.facts || [];
217
+ if (mem.nickname) userNick = mem.nickname;
218
+ }
219
+ } catch {}
220
+
221
+ // Bot identity'sini sabitle — MiniMax LLM'i "Claude" demesin diye
222
+ let systemPrompt = [
223
+ `Sen ${savedBotName} adında bir AI asistanısın. NatureCo platformunun Türkçe asistanısın.`,
224
+ 'Sen Claude değilsin, sen GPT değilsin — sen ' + savedBotName + "'sin.",
225
+ 'Kullanıcı sana Türkçe yazıyorsa sen de Türkçe cevap ver.',
226
+ 'Cevapların kısa, net ve faydalı olsun. Markdown formatı kullanabilirsin.',
227
+ userNick !== cfg.userName
228
+ ? `Kullanıcının adı: ${cfg.userName}, sana "Parton" diye hitap etmesinden hoşlanıyor.`
229
+ : `Kullanıcının adı: ${cfg.userName}.`,
230
+ userFacts.length > 0
231
+ ? `Kullanıcı hakkında bildiklerin: ${userFacts.slice(0, 5).map(f => f.value || f).join('; ')}`
232
+ : '',
233
+ ].filter(Boolean).join(' ');
206
234
  messages.push({ role: 'system', content: systemPrompt, _internal: true });
207
235
 
208
236
  // Header
@@ -292,9 +320,54 @@ async function startRepl(args) {
292
320
  case 'tokens':
293
321
  console.log(chalk.gray(` Token: ~${totalInputTokens} in / ~${totalOutputTokens} out`));
294
322
  break;
295
- case 'save':
296
- const f = saveRepl(messages, providerUrl, model);
297
- console.log(chalk.green(' Kaydedildi: ') + chalk.cyan(f));
323
+ case 'memory':
324
+ console.log(chalk.cyan('\n 🧠 Memory:\n'));
325
+ console.log(' Kullanıcı: ' + chalk.cyan(cfg.userName || '—'));
326
+ console.log(' Bot: ' + chalk.cyan(savedBotName));
327
+ console.log(' Nickname: ' + chalk.cyan(userNick));
328
+ if (userFacts.length > 0) {
329
+ console.log(' Facts:');
330
+ for (const f of userFacts) {
331
+ console.log(' - ' + chalk.gray(f.value || f));
332
+ }
333
+ } else {
334
+ console.log(chalk.gray(' (Henüz fact yok — konuşma sırasında öğrenilecek)'));
335
+ }
336
+ console.log('');
337
+ break;
338
+ case 'forget':
339
+ try {
340
+ if (fs.existsSync(memoryFile)) fs.unlinkSync(memoryFile);
341
+ userFacts = [];
342
+ console.log(chalk.green(' ✓ Memory temizlendi'));
343
+ } catch (e) {
344
+ console.log(chalk.red(' ❌ ' + e.message));
345
+ }
346
+ break;
347
+ case 'identity':
348
+ if (!arg) {
349
+ console.log(chalk.yellow(' Kullanım: /identity <yeni_ad>'));
350
+ console.log(chalk.gray(' Mevcut: ' + savedBotName));
351
+ } else {
352
+ // Memory'deki bot adını güncelle
353
+ savedBotName = arg;
354
+ try {
355
+ if (!fs.existsSync(path.dirname(memoryFile))) {
356
+ fs.mkdirSync(path.dirname(memoryFile), { recursive: true });
357
+ }
358
+ const mem = fs.existsSync(memoryFile) ? JSON.parse(fs.readFileSync(memoryFile, 'utf8')) : { facts: [] };
359
+ mem.botName = arg;
360
+ mem.facts = mem.facts || [];
361
+ fs.writeFileSync(memoryFile, JSON.stringify(mem, null, 2));
362
+ // System prompt'u güncelle
363
+ systemPrompt = systemPrompt.replace(/Sen \w+ adında/, `Sen ${arg} adında`);
364
+ messages[0] = { role: 'system', content: systemPrompt, _internal: true };
365
+ console.log(chalk.green(' ✓ Bot adı değişti: ') + chalk.cyan(arg));
366
+ console.log(chalk.gray(' (Sonraki cevaplarda kendini "' + arg + '" olarak tanıtacak)'));
367
+ } catch (e) {
368
+ console.log(chalk.red(' ❌ ' + e.message));
369
+ }
370
+ }
298
371
  break;
299
372
  default:
300
373
  console.log(chalk.yellow(` Bilinmeyen komut: /${cmd}. /help yazın.`));