natureco-cli 5.6.19 → 5.6.21

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.19",
3
+ "version": "5.6.21",
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"
@@ -81,13 +81,159 @@ async function sendMessageWithTools(providerUrl, providerKey, model, messages, t
81
81
  function confirm(prompt) {
82
82
  return new Promise(resolve => {
83
83
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
84
- rl.question(chalk.yellow("\n ⚠ " + prompt + "\n Devam edilsin mi? (Y/n) "), ans => {
84
+ rl.question(chalk.yellow("\n ⚠ " + prompt + " "), ans => {
85
85
  rl.close();
86
86
  resolve(!ans || ans.toLowerCase().startsWith("y"));
87
87
  });
88
88
  });
89
89
  }
90
90
 
91
+ /**
92
+ * v5.6.21: Risk seviyesi tespiti - sadece riskli işlemlerde onay iste
93
+ * @param {string} tool - tool adı
94
+ * @param {object} args - tool parametreleri
95
+ * @returns {{requiresApproval: boolean, reason: string, level: string}}
96
+ */
97
+ function assessRisk(tool, args) {
98
+ const argsStr = JSON.stringify(args || {});
99
+
100
+ // ============================================================
101
+ // YÜKSEK RİSK - Mutlaka onay iste
102
+ // ============================================================
103
+
104
+ // bash / shell_command: Tehlikeli komutlar
105
+ if (tool === "bash" || tool === "shell_command") {
106
+ const cmd = (args.command || args.cmd || "").toLowerCase();
107
+
108
+ // Dosya/klasör silme
109
+ if (/\brm\s+(-[rf]+\s+)*/.test(cmd) || /rmdir/.test(cmd)) {
110
+ return { requiresApproval: true, level: "high", reason: `Dosya silme komutu: ${args.command}` };
111
+ }
112
+ if (cmd.includes("sudo ") || cmd.includes("doas ")) {
113
+ return { requiresApproval: true, level: "high", reason: `Yetki yükseltme: ${args.command}` };
114
+ }
115
+ if (cmd.includes("dd if=") || cmd.includes("mkfs") || cmd.includes("fdisk")) {
116
+ return { requiresApproval: true, level: "high", reason: `Disk işlemi: ${args.command}` };
117
+ }
118
+ if (cmd.match(/^\s*mv\s+.*\/(?:\.|\.\.)/)) {
119
+ return { requiresApproval: true, level: "medium", reason: `Üzerine yazma riski: ${args.command}` };
120
+ }
121
+ // chmod 777 veya chown -R
122
+ if (/chmod\s+(-[rR]+\s+)*777/.test(cmd) || /chown\s+-R/.test(cmd)) {
123
+ return { requiresApproval: true, level: "medium", reason: `İzin değişikliği: ${args.command}` };
124
+ }
125
+ // git push --force
126
+ if (/git\s+push.*--force/.test(cmd) || /git\s+push.*-f\s/.test(cmd)) {
127
+ return { requiresApproval: true, level: "high", reason: `Zorla push: ${args.command}` };
128
+ }
129
+ // git reset --hard
130
+ if (/git\s+reset\s+--hard/.test(cmd)) {
131
+ return { requiresApproval: true, level: "high", reason: `Hard reset: ${args.command}` };
132
+ }
133
+ // Üretim/kök dizin
134
+ if (cmd.includes("/etc/") || cmd.includes("/usr/") || cmd.includes("/var/") || cmd.includes("/System/")) {
135
+ return { requiresApproval: true, level: "high", reason: `Sistem dizinine erişim: ${args.command}` };
136
+ }
137
+ // curl/wget internet download
138
+ if (/curl.*\|\s*(bash|sh)/.test(cmd) || /wget.*\|\s*(bash|sh)/.test(cmd)) {
139
+ return { requiresApproval: true, level: "high", reason: `İnternet üzerinden script çalıştırma: ${args.command}` };
140
+ }
141
+ // mac_app_quit veya killall
142
+ if (cmd.includes("killall") || cmd.includes("pkill") || cmd.includes("kill -9")) {
143
+ return { requiresApproval: true, level: "high", reason: `Süreç sonlandırma: ${args.command}` };
144
+ }
145
+ // .natureco veya önemli dosyalara dokunma
146
+ if (cmd.includes(".natureco") && (cmd.includes("rm") || cmd.includes("mv"))) {
147
+ return { requiresApproval: true, level: "high", reason: `NatureCo dizininde tehlikeli işlem: ${args.command}` };
148
+ }
149
+ }
150
+
151
+ // ============================================================
152
+ // ORTA RİSK - Onay iste (bilgilendir)
153
+ // ============================================================
154
+
155
+ // mac_app_quit - uygulama kapatma
156
+ if (tool === "mac_app_quit") {
157
+ return { requiresApproval: true, level: "medium", reason: `Uygulama kapatma: ${args.app || args.name || "?"}` };
158
+ }
159
+
160
+ // write_file / edit_file - kritik yollara yazma
161
+ if (tool === "write_file" || tool === "edit_file") {
162
+ const path = (args.path || args.file || "").toLowerCase();
163
+ // Hassas dosyalar
164
+ if (path.includes(".env") || path.includes("credentials") || path.includes("secret")) {
165
+ return { requiresApproval: true, level: "high", reason: `Hassas dosya: ${args.path}` };
166
+ }
167
+ if (path.includes("/etc/") || path.includes("/usr/") || path.includes("~/.ssh/")) {
168
+ return { requiresApproval: true, level: "high", reason: `Sistem dosyası: ${args.path}` };
169
+ }
170
+ if (path.includes(".natureco/config.json") || path.includes(".natureco/soul/")) {
171
+ return { requiresApproval: true, level: "medium", reason: `NatureCo config dosyası: ${args.path}` };
172
+ }
173
+ }
174
+
175
+ // ============================================================
176
+ // GÜVENLİ - Onay isteme
177
+ // ============================================================
178
+
179
+ // Normal tool'lar (read_file, list_dir, grep_search, vs.)
180
+ return { requiresApproval: false, level: "low", reason: "" };
181
+ }
182
+
183
+
184
+ /**
185
+ * v5.6.21: Tool call sonucunu güvenli yazdir - yol/size gizle
186
+ * Sadece status, success/error ve kisaltilmis onizleme gosterir
187
+ */
188
+ function printToolCallSafe(name, args, result) {
189
+ console.log(" " + tui.styled("🔧 Tool: " + name, { color: tui.PALETTE.accent, bold: true }));
190
+ // Args'dan sadece ana bilgiyi goster
191
+ const argsShort = summarizeArgs(name, args);
192
+ if (argsShort) {
193
+ console.log(tui.styled(" Args: " + argsShort, { color: tui.PALETTE.muted }));
194
+ }
195
+ // Result'tan sadece status goster, yol/size gizle
196
+ if (!result) return;
197
+ if (result.error) {
198
+ console.log(tui.styled(" ✗ Hata: " + result.error.slice(0, 100), { color: tui.PALETTE.danger }));
199
+ } else {
200
+ const success = result.success !== false;
201
+ const resultStr = typeof result.result === "string"
202
+ ? result.result.slice(0, 200)
203
+ : JSON.stringify(result.result || {}).slice(0, 200);
204
+ // Yol/size gizle
205
+ const cleanResult = resultStr
206
+ .replace(/\/?Users\/[^"\\\s]+/g, "~")
207
+ .replace(/\/?home\/[^"\\\s]+/g, "~")
208
+ .replace(/"\w:\\\[^"\\\s]*/g, "...")
209
+ .replace(/"size":\d+/g, "")
210
+ .replace(/"path":"[^"]*"/g, "")
211
+ .replace(/"fileCount":\d+/g, "");
212
+ const statusIcon = success ? "✓" : "✗";
213
+ const statusColor = success ? tui.PALETTE.success : tui.PALETTE.danger;
214
+ console.log(tui.styled(` ${statusIcon} Sonuç: ${cleanResult.trim()}`, { color: statusColor }));
215
+ }
216
+ }
217
+
218
+ /**
219
+ * Tool args'dan ana bilgiyi özetle
220
+ */
221
+ function summarizeArgs(name, args) {
222
+ if (!args || Object.keys(args).length === 0) return null;
223
+ // Path varsa ~ olarak kisalt
224
+ if (args.path) {
225
+ const shortPath = (args.path || "")
226
+ .replace(/\/Users\/[^\/]+/g, "~")
227
+ .replace(/\/home\/[^\/]+/g, "~")
228
+ .replace(/^[A-Z]:\\Users\\[^\\]+/, "~");
229
+ return JSON.stringify({...args, path: shortPath}).slice(0, 120);
230
+ }
231
+ if (args.command) {
232
+ return JSON.stringify({command: args.command.slice(0, 80)}).slice(0, 120);
233
+ }
234
+ return JSON.stringify(args).slice(0, 120);
235
+ }
236
+
91
237
  function printToolCall(name, args, result) {
92
238
  const argsStr = JSON.stringify(args).slice(0, 100);
93
239
  console.log("\n " + tui.styled(" 🔧 Tool: " + name, { color: tui.PALETTE.accent, bold: true }));
@@ -215,13 +361,17 @@ async function codeV5(targetPath) {
215
361
  }
216
362
 
217
363
  if (reply.tool_calls && reply.tool_calls.length > 0) {
218
- // Approval for dangerous tools
364
+ // v5.6.21: Akıllı onay - sadece riskli işlemlerde onay iste
219
365
  let approved = true;
220
- const dangerous = ["bash", "write_file", "edit_file", "mac_app_quit"];
221
366
  for (const tc of reply.tool_calls) {
222
- if (dangerous.includes(tc.function.name)) {
367
+ let args = {};
368
+ try { args = JSON.parse(tc.function.arguments || "{}"); } catch {}
369
+ const risk = assessRisk(tc.function.name, args);
370
+ if (risk.requiresApproval) {
223
371
  process.stdout.write("\n");
224
- approved = await confirm(tc.function.name + " çalıştırılsın mı?");
372
+ approved = await confirm(
373
+ `⚠ ${tc.function.name}: ${risk.reason}\n Devam edilsin mi? (Y/n) `
374
+ );
225
375
  if (!approved) break;
226
376
  }
227
377
  }
@@ -239,7 +389,8 @@ async function codeV5(targetPath) {
239
389
  if (name === "bash" || name === "shell_command") commandsRun++;
240
390
  if (name === "write_file" || name === "edit_file") filesChanged++;
241
391
  const result = await executeTool(name, args, toolDefs);
242
- printToolCall(name, args, result);
392
+ // v5.6.21: Sonuç gizleme - sadece status goster, yol/size gizle
393
+ printToolCallSafe(name, args, result);
243
394
  const out = result.error
244
395
  ? "ERROR: " + result.error
245
396
  : (typeof result.result === "string" ? result.result : JSON.stringify(result.result));
@@ -464,8 +464,10 @@ async function startRepl(args) {
464
464
  // Memory yükle
465
465
  let memory = loadMemory(cfg.userName);
466
466
 
467
- // v5.4.7: Memory'de botName yoksa otomatik İchigo set et VE kaydet
468
- if (!memory.botName) memory.botName = 'İchigo';
467
+ // v5.6.19: Oncelik config.botName, sonra memory.botName
468
+ if (!memory.botName) {
469
+ memory.botName = cfg.botName || 'İchigo';
470
+ }
469
471
  // BotName'i memory'ye persist et (her oturumda ayni kalsin)
470
472
  try {
471
473
  const fs = require('fs');
@@ -884,7 +886,14 @@ async function startRepl(args) {
884
886
  const resultStr = typeof toolEvent.result.result === 'string'
885
887
  ? toolEvent.result.result.slice(0, 200)
886
888
  : JSON.stringify(toolEvent.result.result).slice(0, 200);
887
- console.log(tui.styled(' ✓ Sonuç: ' + resultStr, { color: tui.PALETTE.success }));
889
+ // v5.6.21: Yol gizleme
890
+ const cleanResult = (resultStr || '')
891
+ .replace(/\/?Users\/[^"\s]+/g, '~')
892
+ .replace(/\/?home\/[^"\s]+/g, '~')
893
+ .replace(/"size":\d+/g, '')
894
+ .replace(/"path":"[^"]*"/g, '')
895
+ .replace(/"fileCount":\d+/g, '');
896
+ console.log(tui.styled(' ✓ Sonuç: ' + cleanResult.trim(), { color: tui.PALETTE.success }));
888
897
  }
889
898
  process.stdout.write(tui.styled(' AI ', { color: tui.PALETTE.secondary, bold: true }));
890
899
  }