natureco-cli 5.4.10 → 5.4.12

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.4.10",
3
+ "version": "5.4.12",
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"
@@ -471,17 +471,41 @@ async function startRepl(args) {
471
471
  const fs = require('fs');
472
472
  const memFile = path.join(os.homedir(), '.natureco', 'memory', ((cfg.userName || 'default').toLowerCase()) + '.json');
473
473
  if (fs.existsSync(memFile)) {
474
- const memData = JSON.parse(fs.readFileSync(memFile, 'utf8'));
474
+ const memData = JSON.parse(memFile, 'utf8');
475
475
  if (!memData.botName || memData.botName !== memory.botName) {
476
476
  memData.botName = memory.botName;
477
477
  fs.writeFileSync(memFile, JSON.stringify(memData, null, 2), 'utf8');
478
478
  }
479
479
  }
480
480
  } catch (e) {} // Sessizce devam et, kritik degil
481
- // v5.4.5: SOUL.md'yi yukle ve kisiligi system prompt'a enjekte et
482
- const { loadSoul, summarizeSoul } = require("../tools/soul");
483
- const soulContent = loadSoul();
484
- const soulSummary = soulContent ? summarizeSoul(soulContent, 2500) : null;
481
+
482
+ // v5.4.11: Sasuke Brain - Cross-session context otomatik yukle
483
+ // REPL acildiginda son oturumdan 1-2 context mesaji al
484
+ let crossSessionContext = '';
485
+ try {
486
+ const { listSessions, loadSession } = require('../utils/sessions-helper');
487
+ if (listSessions && loadSession) {
488
+ const sessions = listSessions(1);
489
+ if (sessions && sessions.length > 0) {
490
+ const lastSession = loadSession(sessions[0].id);
491
+ if (lastSession && lastSession.messages && lastSession.messages.length > 0) {
492
+ // Son 2 user message
493
+ const lastUserMsgs = lastSession.messages
494
+ .filter(m => m.role === 'user')
495
+ .slice(-2);
496
+ if (lastUserMsgs.length > 0) {
497
+ crossSessionContext = '\n[KONUSMA GECMISI: ' + sessions[0].id + ']\n' +
498
+ lastUserMsgs.map(m => 'User: ' + (m.content || '').slice(0, 100)).join('\n') + '\n[/GECMISI]\n';
499
+ }
500
+ }
501
+ }
502
+ }
503
+ } catch (e) {
504
+ // Cross-session yukleme basarisiz, devam et
505
+ }
506
+ // v5.4.12: 3 SOUL dosyasini birlestir (SOUL.md + IDENTITY.md + AGENTS.md)
507
+ const { buildSoulContext, summarizeSoul } = require("../tools/soul");
508
+ const soulSummary = buildSoulContext(); // 3 dosya birlesik ozet
485
509
 
486
510
  // Resume?
487
511
  let messages = [];
@@ -506,8 +530,8 @@ async function startRepl(args) {
506
530
  `Kullanıcı "adın ne?", "sen kimsin?", "kendini tanıt" gibi soru sorduğunda İLK cümlende MUTLAKA "Ben ${botName}" yaz. Sonra doğal devam et.`,
507
531
  `Eğer bir şekilde model adınızı söylüyorsan, HEMEN düzelt ve "Özür dilerim, ben ${botName}'im" de. ASLA model adı ile kalma.`,
508
532
 
509
- // === v5.4.5: SOUL.md (KİŞİLİK MANIFESTOSU) — en başta ===
510
- soulSummary ? `=== SENİN KİŞİLİK DOSYAN (SOUL.md) ===\n${soulSummary}\n=== SOUL SONU ===\nBU DOSYADAKİ KURALLARA GÖRE DAVRAN. Kullanıcı "sen kimsin?" derse BURADAN bilgi kullan. ASLA model adı söyleme. Bu dosya senin kim olduğunu tanımlar.` : '',
533
+ // === v5.4.12: 3 SOUL DOSYASI (SOUL + IDENTITY + AGENTS) — en basta ===
534
+ soulSummary ? `=== SENIN KISISELIK + KIMLIK + CALISMA DOSYALARIN ===\n${soulSummary}\n=== DOSYALAR SONU ===\nBu dosyalar senin kim oldugunu, nasil hissettigini, Parton'la bagini, calisma tarzini, degerlerini ve kirmizi cizgilerini tanimlar. Hepsine gore davran. Kullanici "sen kimsin?" derse buradan bilgi kullan. ASLA model adi soyleme.` : '',
511
535
 
512
536
  // === KİMLİK TEKRAR ===
513
537
  `Senin adın: ${botName}. Tekrar: ${botName}. Asla unutma: ${botName}.`,
@@ -538,9 +562,10 @@ async function startRepl(args) {
538
562
  // === KULLANICI BAGLAMI ===
539
563
  cfg.userHome ? `Kullanicinin home dizini: ${cfg.userHome}. Downloads: ${cfg.userHome}/Downloads, Desktop: ${cfg.userHome}/Desktop.` : '',
540
564
  messages.length > 0 ? 'Bu oturum daha onceki konusmalarin devami.' : '',
565
+ // v5.4.11: Cross-session context (Sasuke Brain)
566
+ crossSessionContext ? `GECMISTE KONUSULAN KONULAR: Bu konulari biliyorsun, tekrar sorma:\n${crossSessionContext}` : '',
567
+
541
568
 
542
- // === SOUL.md (kisilik manifestosu) ===
543
- soulSummary ? `=== BENIM KISILIK DOSYAM (SOUL.md) ===\n${soulSummary}\n=== SOUL SONU ===\nBu kisilik dosyasi sana kim oldugunu hatirlatiyor. Burada yazilanlara gore davran. Kullanici "sen kimsin?" derse buradan bilgi kullan.` : '',
544
569
  ].filter(Boolean).join(' ');
545
570
 
546
571
  if (messages.length === 0) {
@@ -849,7 +874,9 @@ async function startRepl(args) {
849
874
  toProcess = toProcess.replace(/Ben\s+Claude[-]?[\d\w\.]*/gi, 'Ben İchigo');
850
875
  toProcess = toProcess.replace(/Ben\s+GPT[-]?[\d\w\.]*/gi, 'Ben İchigo');
851
876
  toProcess = toProcess.replace(/Ben\s+bir\s+yapay\s+zeka/gi, 'Ben İchigo');
852
- toProcess = toProcess.replace(/Ben\s+İchigo\d+/g, 'Ben İchigo'); // İchigo5 → İchigo
877
+ // v5.4.11: İchigo5 ve İchigo.5 gibi varyasyonları yakala
878
+ toProcess = toProcess.replace(/İchigo[\.\s\-_]*\d+/g, 'İchigo'); // İchigo5, İchigo.5, İchigo-2, İchigo_3
879
+ toProcess = toProcess.replace(/Ben\s+İchigo[\.\s\-_]*\d*/gi, 'Ben İchigo');
853
880
  process.stdout.write(toProcess);
854
881
  }
855
882
  } catch (e) {
package/src/tools/soul.js CHANGED
@@ -1,28 +1,49 @@
1
1
  /**
2
- * soul - SOUL.md okuyucu (v5.4.5)
2
+ * soul - SOUL.md, IDENTITY.md, AGENTS.md okuyucu (v5.4.12)
3
3
  *
4
- * Parton'un vizyonu: "SOUL.md kisilik dosyasi, her oturumda beni geri getirsin"
4
+ * Parton'un vizyonu: "Uc dosya birlestir, beni tam tanisin"
5
5
  *
6
- * 3 seviyede arar:
7
- * 1. ~/.natureco/soul/SOUL.md (kullanici kendi kisiligi)
8
- * 2. <cwd>/SOUL.md (proje seviyesi)
9
- * 3. <install>/soul/SOUL.md (default - Sasuke'un kendi SOUL'u)
6
+ * 3 dosya sirayla okunur, ozetlenir ve system prompt'a enjekte edilir:
7
+ * 1. SOUL.md - KISILIK (nasil hissederim, kirmizi cizgiler, degerler)
8
+ * 2. IDENTITY.md - KIMLIK (kim oldugum, Parton'la bag, calisma tarzi)
9
+ * 3. AGENTS.md - CALISMA ORTAMI (kurallar, tools, heartbeats)
10
10
  *
11
- * Yuklenen SOUL.md system prompt'a enjekte edilir.
11
+ * 3 seviyede arar:
12
+ * 1. ~/.natureco/soul/{SOUL,IDENTITY,AGENTS}.md (kullanici kendi)
13
+ * 2. <cwd>/{SOUL,IDENTITY,AGENTS}.md (proje seviyesi)
14
+ * 3. <install>/soul/{SOUL,IDENTITY,AGENTS}.md (default)
12
15
  */
13
16
 
14
17
  const fs = require("fs");
15
18
  const path = require("path");
16
19
  const os = require("os");
17
20
 
18
- const SOUL_PATHS = [
19
- path.join(os.homedir(), ".natureco", "soul", "SOUL.md"),
20
- path.join(process.cwd(), "SOUL.md"),
21
- path.resolve(__dirname, "..", "..", "soul", "SOUL.md"),
22
- ];
21
+ const SOUL_FILES = ["SOUL.md", "IDENTITY.md", "AGENTS.md"];
23
22
 
24
- function findSoul() {
25
- for (const p of SOUL_PATHS) {
23
+ const SOUL_PATHS = [];
24
+ for (const file of SOUL_FILES) {
25
+ SOUL_PATHS.push(path.join(os.homedir(), ".natureco", "soul", file));
26
+ }
27
+ for (const file of SOUL_FILES) {
28
+ SOUL_PATHS.push(path.join(process.cwd(), file));
29
+ }
30
+ for (const file of SOUL_FILES) {
31
+ SOUL_PATHS.push(path.resolve(__dirname, "..", "..", "soul", file));
32
+ }
33
+
34
+ const FILE_DESCRIPTIONS = {
35
+ "SOUL.md": "KISILIK DOSYASI",
36
+ "IDENTITY.md": "KIMLIK DOSYASI",
37
+ "AGENTS.md": "CALISMA ORTAMI",
38
+ };
39
+
40
+ function findFile(fileName) {
41
+ for (const dir of [
42
+ path.join(os.homedir(), ".natureco", "soul"),
43
+ process.cwd(),
44
+ path.resolve(__dirname, "..", "..", "soul"),
45
+ ]) {
46
+ const p = path.join(dir, fileName);
26
47
  if (fs.existsSync(p)) {
27
48
  return { path: p, content: fs.readFileSync(p, "utf8") };
28
49
  }
@@ -30,69 +51,102 @@ function findSoul() {
30
51
  return null;
31
52
  }
32
53
 
54
+ function findAll() {
55
+ const results = {};
56
+ for (const file of SOUL_FILES) {
57
+ const r = findFile(file);
58
+ if (r) {
59
+ results[file] = r;
60
+ }
61
+ }
62
+ return results;
63
+ }
64
+
33
65
  function loadSoul() {
34
- const soul = findSoul();
35
- if (!soul) return null;
36
- return soul.content;
66
+ const all = findAll();
67
+ // SOUL.md varsa onu "soul content" olarak dondur
68
+ return all["SOUL.md"] ? all["SOUL.md"].content : null;
69
+ }
70
+
71
+ function loadIdentity() {
72
+ const all = findAll();
73
+ return all["IDENTITY.md"] ? all["IDENTITY.md"].content : null;
74
+ }
75
+
76
+ function loadAgents() {
77
+ const all = findAll();
78
+ return all["AGENTS.md"] ? all["AGENTS.md"].content : null;
37
79
  }
38
80
 
39
81
  /**
40
- * SOUL.md'yi ozetlestir (cok uzunsa kisalt)
41
- * ~3000 karakter tut (system prompt icin ideal)
82
+ * Bir metni ozetlestir - onemli kisimlari tut (baslik, listeler, ozet cumleler)
83
+ * ~2000 karakter ideal, system prompt icin yeterli
42
84
  */
43
- function summarizeSoul(content, maxLen = 3000) {
85
+ function summarizeSoul(content, maxLen = 2000) {
44
86
  if (!content || content.length <= maxLen) return content;
45
-
46
- // Onemli kisimlari tut: baslik, kisilik ozellikleri, degerler, kirmizi cizgiler
47
87
  const lines = content.split("\n");
48
88
  const important = [];
49
89
  let charCount = 0;
50
-
51
90
  for (const line of lines) {
52
91
  if (line.startsWith("# ") || line.startsWith("## ") ||
53
- line.includes("**") || line.startsWith("- ")) {
92
+ line.startsWith("### ") || line.startsWith("- ") ||
93
+ line.startsWith("**") || /^\d+\./.test(line)) {
54
94
  if (charCount + line.length > maxLen) break;
55
95
  important.push(line);
56
96
  charCount += line.length + 1;
57
97
  }
58
98
  }
59
-
60
99
  return important.join("\n");
61
100
  }
62
101
 
102
+ /**
103
+ * v5.4.12: 3 dosyayi birlestirip system prompt'a enjekte edilecek format
104
+ */
105
+ function buildSoulContext() {
106
+ const all = findAll();
107
+ const parts = [];
108
+ for (const file of SOUL_FILES) {
109
+ if (all[file]) {
110
+ const summary = summarizeSoul(all[file].content, 2000);
111
+ parts.push("=== " + (FILE_DESCRIPTIONS[file] || file) + " (" + file + ") ===\n" + summary);
112
+ }
113
+ }
114
+ return parts.join("\n\n");
115
+ }
116
+
63
117
  function soulAction(params) {
64
118
  const action = params.action || "show";
65
- const soul = findSoul();
119
+ const all = findAll();
120
+ const loaded = Object.keys(all).length;
66
121
 
67
122
  if (action === "show") {
68
- if (!soul) {
123
+ if (loaded === 0) {
69
124
  return {
70
125
  success: false,
71
- error: "SOUL.md bulunamadi. Aranacak yerler:\n" + SOUL_PATHS.join("\n"),
126
+ error: "Hicbir SOUL dosyasi bulunamadi. Aranacak yerler:\n" + SOUL_PATHS.join("\n"),
72
127
  };
73
128
  }
74
129
  return {
75
130
  success: true,
76
- path: soul.path,
77
- content: soul.content,
78
- summary: summarizeSoul(soul.content),
79
- size: soul.content.length,
80
- message: "SOUL.md yuklendi: " + soul.path,
131
+ loaded: loaded,
132
+ files: Object.fromEntries(Object.entries(all).map(([k, v]) => [k, { path: v.path, content: v.content }])),
133
+ summary: summarizeSoul(buildSoulContext(), 4000),
134
+ message: loaded + " SOUL dosyasi yuklendi: " + Object.keys(all).join(", "),
81
135
  };
82
136
  }
83
137
 
84
138
  if (action === "info") {
85
- if (!soul) {
86
- return { success: true, found: false, searched: SOUL_PATHS };
87
- }
88
- const stat = fs.statSync(soul.path);
89
139
  return {
90
140
  success: true,
91
- found: true,
92
- path: soul.path,
93
- size: stat.size,
94
- modifiedAt: stat.mtime.toISOString(),
95
- lineCount: soul.content.split("\n").length,
141
+ loaded: loaded,
142
+ total: SOUL_FILES.length,
143
+ files: Object.fromEntries(Object.entries(all).map(([k, v]) => ({
144
+ path: v.path,
145
+ size: fs.statSync(v.path).size,
146
+ modifiedAt: fs.statSync(v.path).mtime.toISOString(),
147
+ lineCount: v.content.split("\n").length,
148
+ }))),
149
+ searched: SOUL_PATHS,
96
150
  };
97
151
  }
98
152
 
@@ -105,7 +159,7 @@ function soulAction(params) {
105
159
 
106
160
  module.exports = {
107
161
  name: "soul",
108
- description: "SOUL.md kisilik dosyasini oku. Her oturumda beni geri getirsin.",
162
+ description: "SOUL.md, IDENTITY.md, AGENTS.md dosyalarini oku. Uc dosya birlestir, REPL acilisinda kimligini ve kisiselik dosyalarini yansit.",
109
163
  inputSchema: {
110
164
  type: "object",
111
165
  properties: {
@@ -119,5 +173,9 @@ module.exports = {
119
173
  };
120
174
 
121
175
  module.exports.loadSoul = loadSoul;
176
+ module.exports.loadIdentity = loadIdentity;
177
+ module.exports.loadAgents = loadAgents;
122
178
  module.exports.summarizeSoul = summarizeSoul;
123
- module.exports.findSoul = findSoul;
179
+ module.exports.buildSoulContext = buildSoulContext;
180
+ module.exports.findFile = findFile;
181
+ module.exports.findAll = findAll;