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 +1 -1
- package/src/commands/repl.js +37 -10
- package/src/tools/soul.js +102 -44
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "natureco-cli",
|
|
3
|
-
"version": "5.4.
|
|
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"
|
package/src/commands/repl.js
CHANGED
|
@@ -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(
|
|
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
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
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.
|
|
510
|
-
soulSummary ? `===
|
|
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
|
-
|
|
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.
|
|
2
|
+
* soul - SOUL.md, IDENTITY.md, AGENTS.md okuyucu (v5.4.12)
|
|
3
3
|
*
|
|
4
|
-
* Parton'un vizyonu: "
|
|
4
|
+
* Parton'un vizyonu: "Uc dosya birlestir, beni tam tanisin"
|
|
5
5
|
*
|
|
6
|
-
* 3
|
|
7
|
-
* 1.
|
|
8
|
-
* 2.
|
|
9
|
-
* 3.
|
|
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
|
-
*
|
|
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
|
|
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
|
-
|
|
25
|
-
|
|
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
|
|
35
|
-
|
|
36
|
-
return
|
|
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
|
-
*
|
|
41
|
-
* ~
|
|
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 =
|
|
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.
|
|
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
|
|
119
|
+
const all = findAll();
|
|
120
|
+
const loaded = Object.keys(all).length;
|
|
66
121
|
|
|
67
122
|
if (action === "show") {
|
|
68
|
-
if (
|
|
123
|
+
if (loaded === 0) {
|
|
69
124
|
return {
|
|
70
125
|
success: false,
|
|
71
|
-
error: "SOUL
|
|
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
|
-
|
|
77
|
-
content:
|
|
78
|
-
summary: summarizeSoul(
|
|
79
|
-
|
|
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
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
|
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.
|
|
179
|
+
module.exports.buildSoulContext = buildSoulContext;
|
|
180
|
+
module.exports.findFile = findFile;
|
|
181
|
+
module.exports.findAll = findAll;
|