natureco-cli 5.6.16 → 5.6.18

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": "5.6.16",
3
+ "version": "5.6.18",
4
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
5
  "bin": {
6
6
  "natureco": "bin/natureco.js"
@@ -2,6 +2,7 @@ const chalk = require('chalk');
2
2
  const fs = require('fs');
3
3
  const path = require('path');
4
4
  const os = require('os');
5
+ const memoryStore = require('../utils/memory-store');
5
6
  const { loadMemory, saveMemory, clearMemory } = require('../utils/memory');
6
7
  const { getConfig } = require('../utils/config');
7
8
 
@@ -213,7 +214,7 @@ function indexMemory() {
213
214
  // ── Export Memory ──────────────────────────────────────────────────────────────
214
215
  function exportMemoryCmd(botId, outputFile) {
215
216
  const id = botId || 'universal-provider';
216
- const mem = exportMemory(id);
217
+ const mem = memoryStore.loadMemory(id);
217
218
  const filePath = outputFile || path.join(process.cwd(), `memory-${id}.json`);
218
219
  fs.writeFileSync(filePath, JSON.stringify(mem, null, 2));
219
220
  console.log(chalk.green(`\n ✓ Hafıza dışa aktarıldı: ${filePath}\n`));
@@ -233,8 +234,11 @@ function importMemoryCmd(botId, sourceFile) {
233
234
  }
234
235
  try {
235
236
  const data = JSON.parse(fs.readFileSync(resolvedPath, 'utf-8'));
236
- importMemory(botId || 'universal-provider', data);
237
- console.log(chalk.green(`\n ✓ Hafıza içe aktarıldı: ${botId || 'universal-provider'}\n`));
237
+ // v5.6.16: memoryStore.saveMemory kullan
238
+ const importId = botId || 'universal-provider';
239
+ memoryStore.saveMemory(importId, data);
240
+ console.log(chalk.green(`\n ✓ Hafıza içe aktarıldı: ${importId}\n`));
241
+ console.log(chalk.green(`\n ✓ Hafıza içe aktarıldı: ${id}\n`));
238
242
  } catch (err) {
239
243
  console.log(chalk.red(`\n ❌ Hata: ${err.message}\n`));
240
244
  }
@@ -335,4 +339,70 @@ function wikiSearchCmd(query) {
335
339
  });
336
340
  }
337
341
 
342
+ // ── Wiki Page Functions (v5.6.16 inline) ─────────────────────────────
343
+ function listWikiPages() {
344
+ const WIKI_DIR = path.join(os.homedir(), '.natureco', 'wiki');
345
+ if (!fs.existsSync(WIKI_DIR)) {
346
+ console.log(chalk.gray('\n Wiki bos.\n'));
347
+ return;
348
+ }
349
+ const files = fs.readdirSync(WIKI_DIR).filter(f => f.endsWith('.md'));
350
+ console.log(chalk.cyan(`\n Wiki Sayfalari (${files.length}):\n`));
351
+ files.forEach(f => console.log(` ${chalk.white(f.replace('.md',''))}`));
352
+ console.log();
353
+ }
354
+
355
+ function getWikiPage(slug) {
356
+ if (!slug) return;
357
+ const WIKI_DIR = path.join(os.homedir(), '.natureco', 'wiki');
358
+ const filePath = path.join(WIKI_DIR, `${slug}.md`);
359
+ if (!fs.existsSync(filePath)) {
360
+ console.log(chalk.red(`\n ❌ Wiki sayfasi bulunamadi: ${slug}\n`));
361
+ return;
362
+ }
363
+ console.log(chalk.cyan(`\n ${slug}\n`));
364
+ console.log(chalk.gray(' ' + '─'.repeat(60)));
365
+ console.log(fs.readFileSync(filePath, 'utf-8'));
366
+ }
367
+
368
+ function saveWikiPage(slug, content) {
369
+ if (!slug) return;
370
+ const WIKI_DIR = path.join(os.homedir(), '.natureco', 'wiki');
371
+ if (!fs.existsSync(WIKI_DIR)) fs.mkdirSync(WIKI_DIR, { recursive: true });
372
+ const filePath = path.join(WIKI_DIR, `${slug}.md`);
373
+ fs.writeFileSync(filePath, content);
374
+ console.log(chalk.green(`\n ✓ Wiki sayfasi kaydedildi: ${slug}\n`));
375
+ }
376
+
377
+ function searchWikiPages(query) {
378
+ if (!query) return [];
379
+ const WIKI_DIR = path.join(os.homedir(), '.natureco', 'wiki');
380
+ if (!fs.existsSync(WIKI_DIR)) return [];
381
+ const lower = query.toLowerCase();
382
+ return fs.readdirSync(WIKI_DIR)
383
+ .filter(f => f.endsWith('.md'))
384
+ .map(f => ({
385
+ slug: f.replace('.md', ''),
386
+ content: fs.readFileSync(path.join(WIKI_DIR, f), 'utf-8'),
387
+ }))
388
+ .filter(p => p.content.toLowerCase().includes(lower));
389
+ }
390
+
391
+ // ── Semantic Search (v5.6.16 inline - basit keyword-based) ───────────
392
+ function semanticSearchMemory(query, botId) {
393
+ const id = botId || 'universal-provider';
394
+ const mem = memoryStore.loadMemory(id);
395
+ if (!query) return [];
396
+ const lower = query.toLowerCase();
397
+ const results = [];
398
+ // facts icinde ara
399
+ (mem.facts || []).forEach(f => {
400
+ const text = (typeof f === 'string' ? f : f.value) || '';
401
+ if (text.toLowerCase().includes(lower)) {
402
+ results.push({ type: 'fact', value: text, score: f.score || 5 });
403
+ }
404
+ });
405
+ return results;
406
+ }
407
+
338
408
  module.exports = memoryCmd;
@@ -4,6 +4,7 @@ const path = require('path');
4
4
  const os = require('os');
5
5
  const { execSync } = require('child_process');
6
6
  const readline = require('readline');
7
+ const { requireApproval, RISK } = require('../utils/dangerous');
7
8
 
8
9
  const BASE_DIR = path.join(os.homedir(), '.natureco');
9
10
 
@@ -46,12 +47,16 @@ function cmdDryRun() {
46
47
  async function cmdRun() {
47
48
  console.log(chalk.cyan('\n Uninstall NatureCo\n'));
48
49
 
49
- const answer = await rlQuestion(chalk.red(' This will remove all NatureCo data. Continue? [y/N]: '));
50
- if (answer !== 'y' && answer !== 'yes') {
50
+ // v5.6.16: Dangerous approval (CRITICAL)
51
+ const approved = await requireApproval('natureco uninstall', {}, RISK.CRITICAL,
52
+ 'NatureCo CLI ve tum kisisel veriler silinecek (geri alinamaz)');
53
+ if (!approved) {
51
54
  console.log(chalk.gray('\n Cancelled.\n'));
52
55
  return;
53
56
  }
54
57
 
58
+ // Eski onay mekanizmasini kaldirdik, dangerous approval yeterli
59
+
55
60
  if (fs.existsSync(BASE_DIR)) {
56
61
  console.log(chalk.gray(' Removing ~/.natureco/...'));
57
62
  fs.rmSync(BASE_DIR, { recursive: true, force: true });
@@ -0,0 +1,185 @@
1
+ /**
2
+ * memory_write - Memory'ye fact/kayit yaz (v5.1.1)
3
+ *
4
+ * REPL'in extractMemoryFromMessage ozelligini tool olarak expose eder.
5
+ * Parton'un vizyonu: "Benim asistanim, her seyimi hatirlayacak"
6
+ */
7
+
8
+ const fs = require("fs");
9
+ const path = require("path");
10
+ const os = require("os");
11
+
12
+ const MEMORY_DIR = path.join(os.homedir(), ".natureco", "memory");
13
+
14
+ function getMemoryFile(username) {
15
+ const name = (username || "default").toLowerCase();
16
+ return path.join(MEMORY_DIR, `${name}.json`);
17
+ }
18
+
19
+ function loadMemory(username) {
20
+ const file = getMemoryFile(username);
21
+ try {
22
+ if (!fs.existsSync(file)) {
23
+ return { name: username || "User", nickname: null, botName: null, facts: [], preferences: [] };
24
+ }
25
+ return JSON.parse(fs.readFileSync(file, "utf8"));
26
+ } catch {
27
+ return { name: username || "User", nickname: null, botName: null, facts: [], preferences: [] };
28
+ }
29
+ }
30
+
31
+ function saveMemory(username, memory) {
32
+ if (!fs.existsSync(MEMORY_DIR)) fs.mkdirSync(MEMORY_DIR, { recursive: true });
33
+ memory.lastUpdated = new Date().toISOString();
34
+ fs.writeFileSync(getMemoryFile(username), JSON.stringify(memory, null, 2), "utf8");
35
+ return memory;
36
+ }
37
+
38
+ /**
39
+ * Score azalt (eski fact'ler zamanla unutuluyor)
40
+ */
41
+ function decayFacts(memory) {
42
+ if (!memory.facts) return memory;
43
+ const now = Date.now();
44
+ memory.facts = memory.facts.map(f => {
45
+ if (!f.score) f.score = 5;
46
+ // 1 haftadan eski -1, 1 aydan eski -3
47
+ const ageMs = now - new Date(f.updatedAt || f.createdAt || now).getTime();
48
+ const ageDays = ageMs / (1000 * 60 * 60 * 24);
49
+ if (ageDays > 30) f.score = Math.max(0, f.score - 3);
50
+ else if (ageDays > 7) f.score = Math.max(0, f.score - 1);
51
+ return f;
52
+ });
53
+ // score 0 olanlari sil
54
+ memory.facts = memory.facts.filter(f => (f.score || 0) > 0);
55
+ // max 15 fact tut
56
+ memory.facts.sort((a, b) => (b.score || 0) - (a.score || 0));
57
+ memory.facts = memory.facts.slice(0, 15);
58
+ return memory;
59
+ }
60
+
61
+
62
+ /**
63
+ * v5.4.9: Memory yazma sonrasi verification — geri oku ve gercekten yazildigini dogrula
64
+ * Self-validation mekanizmasi: tool cagirip "success" demesine ragmen dosya bos olabilir
65
+ */
66
+ function verifyMemoryWrite(username, expectedFact, expectedBotName) {
67
+ try {
68
+ const memFile = getMemoryFile(username);
69
+ if (!fs.existsSync(memFile)) {
70
+ return { success: false, error: "Memory dosyasi olusturulamadi: " + memFile };
71
+ }
72
+ const mem = JSON.parse(fs.readFileSync(memFile, "utf8"));
73
+
74
+ // Fact verification
75
+ if (expectedFact) {
76
+ const found = (mem.facts || []).some(f => f.value === expectedFact);
77
+ if (!found) {
78
+ return { success: false, error: "Fact memory'de bulunamadi: " + expectedFact };
79
+ }
80
+ }
81
+
82
+ // BotName verification
83
+ if (expectedBotName && mem.botName !== expectedBotName) {
84
+ return { success: false, error: "BotName guncellenmedi: " + mem.botName };
85
+ }
86
+
87
+ return { success: true, message: "Memory dogrulandi" };
88
+ } catch (e) {
89
+ return { success: false, error: e.message };
90
+ }
91
+ }
92
+
93
+
94
+ function addMemory({ username, fact, score = 5, category = "general", botName, nickname, name }) {
95
+ // Username yoksa ve 'name' parametresi varsa, onu username olarak kullan
96
+ // (Parton'un "patron" diye hitap etmesi durumu icin)
97
+ const effectiveUsername = username || (name && name.toLowerCase()) || 'default';
98
+ if (!effectiveUsername || effectiveUsername === 'default') {
99
+ // Hicbir username yok, default.json'a yaz
100
+ }
101
+
102
+ let memory = loadMemory(effectiveUsername);
103
+ memory = decayFacts(memory);
104
+
105
+ // identity updates (botName, nickname, name) — name sadece memory.name, username degil
106
+ if (botName) memory.botName = botName;
107
+ if (nickname !== undefined) memory.nickname = nickname;
108
+ if (name) memory.name = name; // Bu memory.name (kullanici gercek adi), username degil
109
+
110
+ if (fact) {
111
+ // duplicate kontrol
112
+ const existing = memory.facts.find(f => (f.value || f).toLowerCase() === fact.toLowerCase());
113
+ if (existing) {
114
+ existing.score = Math.min(10, (existing.score || 5) + 2);
115
+ existing.updatedAt = new Date().toISOString();
116
+ } else {
117
+ memory.facts.push({
118
+ value: fact,
119
+ score,
120
+ category,
121
+ updatedAt: new Date().toISOString(),
122
+ createdAt: new Date().toISOString(),
123
+ });
124
+ }
125
+ }
126
+
127
+ if (!memory.preferences) memory.preferences = [];
128
+ memory = saveMemory(effectiveUsername, memory);
129
+
130
+ // v5.4.9: Verification - geri oku ve dogrula
131
+ const verifyResult = verifyMemoryWrite(effectiveUsername, fact, botName);
132
+ if (!verifyResult.success) {
133
+ return {
134
+ success: false,
135
+ error: "Memory yazildi ama dogrulanamadi: " + verifyResult.error,
136
+ username: effectiveUsername,
137
+ };
138
+ }
139
+
140
+ return {
141
+ success: true,
142
+ message: "Memory guncellendi ve dogrulandi",
143
+ username: effectiveUsername,
144
+ verified: true,
145
+ totalFacts: memory.facts.length,
146
+ facts: memory.facts.map(f => ({ value: f.value, score: f.score, category: f.category })),
147
+ botName: memory.botName,
148
+ nickname: memory.nickname,
149
+ name: memory.name,
150
+ };
151
+ }
152
+
153
+ function clearMemory({ username }) {
154
+ if (!username) return { success: false, error: "username gerekli" };
155
+ const file = getMemoryFile(username);
156
+ if (fs.existsSync(file)) fs.unlinkSync(file);
157
+ return { success: true, message: `Memory temizlendi: ${username}` };
158
+ }
159
+
160
+ function showMemory({ username }) {
161
+ if (!username) return { success: false, error: "username gerekli" };
162
+ const memory = loadMemory(username);
163
+ return {
164
+ success: true,
165
+ username,
166
+ name: memory.name,
167
+ nickname: memory.nickname,
168
+ botName: memory.botName,
169
+ totalFacts: (memory.facts || []).length,
170
+ facts: memory.facts || [],
171
+ preferences: memory.preferences || [],
172
+ };
173
+ }
174
+
175
+
176
+ module.exports = {
177
+ getMemoryFile,
178
+ loadMemory,
179
+ saveMemory,
180
+ decayFacts,
181
+ verifyMemoryWrite,
182
+ addMemory,
183
+ clearMemory,
184
+ showMemory,
185
+ };