natureco-cli 5.57.0 → 5.59.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.
@@ -1,4 +1,6 @@
1
1
  const chalk = require('chalk');
2
+ const { getLang: _gl } = require('../utils/i18n');
3
+ const L = (tr, en) => (_gl() === 'en' ? en : tr);
2
4
  const tui = require('../utils/tui');
3
5
  const F = require('../utils/format');
4
6
  const fs = require('fs');
@@ -349,10 +351,10 @@ async function gateway(action, ...args) {
349
351
  }
350
352
 
351
353
  F.section('Quick Start');
352
- F.kv('natureco chat', 'Bot ile sohbet başlat');
353
- F.kv('natureco setup', 'Kurulumu yeniden çalıştır');
354
- F.kv('natureco gateway start', 'Gateway\'i arka planda başlat');
355
- F.kv('natureco help', 'Tüm komutları göster');
354
+ F.kv('natureco chat', L('Bot ile sohbet başlat', 'Start chatting with the bot'));
355
+ F.kv('natureco setup', L('Kurulumu yeniden çalıştır', 'Re-run setup'));
356
+ F.kv('natureco gateway start', L('Gateway\'i arka planda başlat', 'Start the gateway in the background'));
357
+ F.kv('natureco help', L('Tüm komutları göster', 'Show all commands'));
356
358
 
357
359
  F.meta('Docs: natureco.me/cli');
358
360
  }
@@ -371,9 +373,9 @@ async function startGateway() {
371
373
  const existingPid = parseInt(fs.readFileSync(pidFile, 'utf8').trim(), 10);
372
374
  try {
373
375
  process.kill(existingPid, 0); // Test et, canlı mı
374
- console.log('\n' + tui.styled(' ⚠️ Gateway zaten çalışıyor (PID: ' + existingPid + ')', { color: tui.PALETTE.warning, bold: true }) + '\n');
375
- console.log(' ' + tui.C.muted('Durdurmak için: ') + tui.C.brand('natureco gateway stop'));
376
- console.log(' ' + tui.C.muted('Durum için: ') + tui.C.brand('natureco gateway status'));
376
+ console.log('\n' + tui.styled(L(' ⚠️ Gateway zaten çalışıyor (PID: ', ' ⚠️ Gateway already running (PID: ') + existingPid + ')', { color: tui.PALETTE.warning, bold: true }) + '\n');
377
+ console.log(' ' + tui.C.muted(L('Durdurmak için: ', 'To stop: ')) + tui.C.brand('natureco gateway stop'));
378
+ console.log(' ' + tui.C.muted(L('Durum için: ', 'For status: ')) + tui.C.brand('natureco gateway status'));
377
379
  console.log('');
378
380
  return;
379
381
  } catch {
@@ -382,7 +384,7 @@ async function startGateway() {
382
384
  }
383
385
  }
384
386
 
385
- console.log('\n' + tui.styled(' 🚀 Gateway Başlatılıyor...', { color: tui.PALETTE.primary, bold: true }));
387
+ console.log('\n' + tui.styled(L(' 🚀 Gateway Başlatılıyor...', ' 🚀 Starting Gateway...'), { color: tui.PALETTE.primary, bold: true }));
386
388
  console.log(tui.styled(' ' + '─'.repeat(56), { color: tui.PALETTE.border }));
387
389
 
388
390
  // Log dosyası
@@ -405,17 +407,17 @@ async function startGateway() {
405
407
  // Başarı kartı
406
408
  const cardW = 54;
407
409
  console.log(tui.styled(' ╭' + '─'.repeat(cardW) + '╮', { color: tui.PALETTE.border }));
408
- console.log(tui.styled(' │ ', { color: tui.PALETTE.border }) + tui.C.muted('Durum ') + tui.styled(' ✓ Çalışıyor '.padEnd(36), { bg: tui.PALETTE.success, color: '#000', bold: true }) + tui.styled(' │', { color: tui.PALETTE.border }));
410
+ console.log(tui.styled(' │ ', { color: tui.PALETTE.border }) + tui.C.muted(L('Durum ', 'Status ')) + tui.styled(L(' ✓ Çalışıyor ', ' ✓ Running ').padEnd(36), { bg: tui.PALETTE.success, color: '#000', bold: true }) + tui.styled(' │', { color: tui.PALETTE.border }));
409
411
  console.log(tui.styled(' │ ', { color: tui.PALETTE.border }) + tui.C.muted('PID ') + tui.styled(String(child.pid).padEnd(40), { color: tui.PALETTE.text, bold: true }) + tui.styled(' │', { color: tui.PALETTE.border }));
410
- console.log(tui.styled(' │ ', { color: tui.PALETTE.border }) + tui.C.muted('Log dosyası ') + tui.styled(logFile.padEnd(40).slice(0, 40), { color: tui.PALETTE.text }) + tui.styled(' │', { color: tui.PALETTE.border }));
412
+ console.log(tui.styled(' │ ', { color: tui.PALETTE.border }) + tui.C.muted(L('Log dosyası ', 'Log file ')) + tui.styled(logFile.padEnd(40).slice(0, 40), { color: tui.PALETTE.text }) + tui.styled(' │', { color: tui.PALETTE.border }));
411
413
  console.log(tui.styled(' │ ', { color: tui.PALETTE.border }) + tui.C.muted('Provider ') + tui.styled((config.providerUrl || '—').replace('https://', '').padEnd(40).slice(0, 40), { color: tui.PALETTE.text }) + tui.styled(' │', { color: tui.PALETTE.border }));
412
- console.log(tui.styled(' │ ', { color: tui.PALETTE.border }) + tui.C.muted('Telegram ') + tui.styled((config.telegramToken ? '✓ Token ayarlı' : '✗ Token yok').padEnd(40), { color: config.telegramToken ? tui.PALETTE.success : tui.PALETTE.warning, bold: true }) + tui.styled(' │', { color: tui.PALETTE.border }));
414
+ console.log(tui.styled(' │ ', { color: tui.PALETTE.border }) + tui.C.muted('Telegram ') + tui.styled((config.telegramToken ? L('✓ Token ayarlı', '✓ Token set') : L('✗ Token yok', '✗ No token')).padEnd(40), { color: config.telegramToken ? tui.PALETTE.success : tui.PALETTE.warning, bold: true }) + tui.styled(' │', { color: tui.PALETTE.border }));
413
415
  console.log(tui.styled(' ╰' + '─'.repeat(cardW) + '╯', { color: tui.PALETTE.border }));
414
416
 
415
- console.log('\n ' + tui.C.muted('Komutlar:'));
416
- console.log(' ' + tui.C.muted(' Durum: ') + tui.C.brand('natureco gateway status'));
417
- console.log(' ' + tui.C.muted(' Log: ') + tui.C.brand('natureco gateway logs') + ' ' + tui.C.muted('veya ') + tui.C.brand('tail -f ' + logFile));
418
- console.log(' ' + tui.C.muted(' Dur: ') + tui.C.brand('natureco gateway stop'));
417
+ console.log('\n ' + tui.C.muted(L('Komutlar:', 'Commands:')));
418
+ console.log(' ' + tui.C.muted(L(' Durum: ', ' Status: ')) + tui.C.brand('natureco gateway status'));
419
+ console.log(' ' + tui.C.muted(' Log: ') + tui.C.brand('natureco gateway logs') + ' ' + tui.C.muted(L('veya ', 'or ')) + tui.C.brand('tail -f ' + logFile));
420
+ console.log(' ' + tui.C.muted(L(' Dur: ', ' Stop: ')) + tui.C.brand('natureco gateway stop'));
419
421
  console.log('');
420
422
  }
421
423
 
@@ -485,30 +487,30 @@ async function startWhatsAppProvider(sessionDir, config) {
485
487
  if (trimmed.toLowerCase().startsWith('!code')) {
486
488
  const task = trimmed.replace(/^!code\s*/i, '').trim();
487
489
  if (!task) {
488
- await sock.sendMessage(msg.key.remoteJid, { text: '⚙️ Kullanım: !code <görev>\nÖrnek: !code login sayfasına forgot password ekle' });
490
+ await sock.sendMessage(msg.key.remoteJid, { text: L('⚙️ Kullanım: !code <görev>\nÖrnek: !code login sayfasına forgot password ekle', '⚙️ Usage: !code <task>\nExample: !code add forgot password to the login page') });
489
491
  continue;
490
492
  }
491
- console.log(chalk.cyan('[whatsapp]'), chalk.yellow(`!code komutu: ${task.slice(0, 60)}`));
493
+ console.log(chalk.cyan('[whatsapp]'), chalk.yellow(`!code ${L('komutu', 'command')}: ${task.slice(0, 60)}`));
492
494
 
493
495
  try {
494
496
  const { runCodeAgent } = require('../utils/headless');
495
- await sock.sendMessage(msg.key.remoteJid, { text: `⚙️ Çalışıyor: ${task.slice(0, 80)}...` });
497
+ await sock.sendMessage(msg.key.remoteJid, { text: `⚙️ ${L('Çalışıyor', 'Running')}: ${task.slice(0, 80)}...` });
496
498
 
497
499
  const result = await runCodeAgent(task, process.cwd(), (progress) => {
498
500
  console.log(chalk.cyan('[whatsapp/code]'), chalk.gray(progress));
499
501
  });
500
502
 
501
- let reply = `✅ Tamamlandı!\n\n${result.reply}`;
503
+ let reply = `✅ ${L('Tamamlandı!', 'Done!')}\n\n${result.reply}`;
502
504
  if (result.filesChanged?.length) {
503
- reply += `\n\n📝 Değiştirilen dosyalar:\n${result.filesChanged.map(f => `• ${f}`).join('\n')}`;
505
+ reply += `\n\n📝 ${L('Değiştirilen dosyalar', 'Changed files')}:\n${result.filesChanged.map(f => `• ${f}`).join('\n')}`;
504
506
  }
505
507
 
506
508
  await sock.sendMessage(msg.key.remoteJid, { text: reply.slice(0, 4000) });
507
- console.log(chalk.cyan('[whatsapp]'), chalk.green(`!code tamamlandı (${result.iterations} iterasyon)`));
509
+ console.log(chalk.cyan('[whatsapp]'), chalk.green(`!code ${L('tamamlandı', 'completed')} (${result.iterations} ${L('iterasyon', 'iterations')})`));
508
510
  } catch (err) {
509
511
  const msg = err instanceof NatureCoError ? err.message : err?.message ?? 'Unknown error';
510
- console.log(chalk.red('[whatsapp/code]'), chalk.gray(`hata: ${msg}`));
511
- await sock.sendMessage(msg.key.remoteJid, { text: `❌ Hata: ${msg}` });
512
+ console.log(chalk.red('[whatsapp/code]'), chalk.gray(`${L('hata', 'error')}: ${msg}`));
513
+ await sock.sendMessage(msg.key.remoteJid, { text: `❌ ${L('Hata', 'Error')}: ${msg}` });
512
514
  }
513
515
  continue;
514
516
  }
@@ -1,49 +1,51 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
3
  const inquirer = require('../utils/inquirer-wrapper');
4
- const chalk = require('chalk');
4
+ const chalk = require('chalk');
5
+ const { getLang: _gl } = require('../utils/i18n');
6
+ const L = (tr, en) => (_gl() === 'en' ? en : tr);
5
7
  const { getApiKey } = require('../utils/config');
6
8
  const { getBots } = require('../utils/api');
7
9
 
8
10
  async function init() {
9
- console.log(chalk.green.bold('\n╭─ NatureCo Proje Başlatma ─╮\n'));
11
+ console.log(chalk.green.bold(L('\n╭─ NatureCo Proje Başlatma ─╮\n', '\n╭─ NatureCo Project Init ─╮\n')));
10
12
 
11
13
  const apiKey = getApiKey();
12
14
  if (!apiKey) {
13
- console.log(chalk.red('❌ Giriş yapılmadı. Önce "natureco login" çalıştırın.\n'));
15
+ console.log(chalk.red(L('❌ Giriş yapılmadı. Önce "natureco login" çalıştırın.\n', '❌ Not logged in. Run "natureco login" first.\n')));
14
16
  process.exit(1);
15
17
  }
16
18
 
17
19
  // Mevcut klasörde .natureco var mı kontrol et
18
20
  const projectDir = path.join(process.cwd(), '.natureco');
19
21
  if (fs.existsSync(projectDir)) {
20
- console.log(chalk.yellow('⚠️ Bu klasörde zaten .natureco/ mevcut.\n'));
22
+ console.log(chalk.yellow(L('⚠️ Bu klasörde zaten .natureco/ mevcut.\n', '⚠️ This folder already has .natureco/.\n')));
21
23
  const { overwrite } = await inquirer.prompt([
22
24
  {
23
25
  type: 'confirm',
24
26
  name: 'overwrite',
25
- message: 'Üzerine yazmak ister misiniz?',
27
+ message: L('Üzerine yazmak ister misiniz?', 'Overwrite?'),
26
28
  default: false,
27
29
  },
28
30
  ]);
29
31
  if (!overwrite) {
30
- console.log(chalk.gray('İptal edildi.\n'));
32
+ console.log(chalk.gray(L('İptal edildi.\n', 'Cancelled.\n')));
31
33
  process.exit(0);
32
34
  }
33
35
  }
34
36
 
35
37
  // Botları çek
36
- console.log(chalk.yellow('⏳ Botlar yükleniyor...\n'));
38
+ console.log(chalk.yellow(L('⏳ Botlar yükleniyor...\n', '⏳ Loading bots...\n')));
37
39
  let botList;
38
40
  try {
39
41
  botList = await getBots(apiKey);
40
42
  } catch (err) {
41
- console.log(chalk.red(`❌ Hata: ${err.message}\n`));
43
+ console.log(chalk.red(`❌ ${L('Hata', 'Error')}: ${err.message}\n`));
42
44
  process.exit(1);
43
45
  }
44
46
 
45
47
  if (!botList || !botList.bots || botList.bots.length === 0) {
46
- console.log(chalk.gray('Bot bulunamadı. Önce https://developers.natureco.me adresinden bot oluşturun.\n'));
48
+ console.log(chalk.gray(L('Bot bulunamadı. Önce https://developers.natureco.me adresinden bot oluşturun.\n', 'No bots found. Create a bot at https://developers.natureco.me first.\n')));
47
49
  process.exit(1);
48
50
  }
49
51
 
@@ -52,7 +54,7 @@ async function init() {
52
54
  {
53
55
  type: 'list',
54
56
  name: 'defaultBot',
55
- message: 'Varsayılan bot:',
57
+ message: L('Varsayılan bot:', 'Default bot:'),
56
58
  choices: botList.bots.map(b => ({ name: b.name, value: b.id })),
57
59
  },
58
60
  ]);
@@ -64,11 +66,11 @@ async function init() {
64
66
  {
65
67
  type: 'checkbox',
66
68
  name: 'skills',
67
- message: 'Hangi skill\'ler eklensin?',
69
+ message: L('Hangi skill\'ler eklensin?', 'Which skills to add?'),
68
70
  choices: [
69
- { name: 'code-review (Kod inceleme)', value: 'code-review', checked: true },
70
- { name: 'summarize (Özetleme)', value: 'summarize', checked: true },
71
- { name: 'translate (Çeviri)', value: 'translate', checked: false },
71
+ { name: L('code-review (Kod inceleme)', 'code-review (Code review)'), value: 'code-review', checked: true },
72
+ { name: L('summarize (Özetleme)', 'summarize (Summarize)'), value: 'summarize', checked: true },
73
+ { name: L('translate (Çeviri)', 'translate (Translate)'), value: 'translate', checked: false },
72
74
  ],
73
75
  },
74
76
  ]);
@@ -95,24 +97,24 @@ async function init() {
95
97
  );
96
98
 
97
99
  // AGENTS.md
98
- const agentsMd = `# ${selectedBot.name} Talimatları
100
+ const agentsMd = `# ${selectedBot.name} ${L('Talimatları', 'Instructions')}
99
101
 
100
- Bu dosya projeye özel bot talimatlarını içerir.
101
- Chat başladığında bu içerik sistem promptuna eklenir.
102
+ ${L('Bu dosya projeye özel bot talimatlarını içerir.', 'This file contains project-specific bot instructions.')}
103
+ ${L('Chat başladığında bu içerik sistem promptuna eklenir.', 'This content is added to the system prompt when chat starts.')}
102
104
 
103
- ## Proje Hakkında
105
+ ## ${L('Proje Hakkında', 'About the Project')}
104
106
 
105
- [Projenizi tanımlayın]
107
+ ${L('[Projenizi tanımlayın]', '[Describe your project]')}
106
108
 
107
- ## Bot Görevleri
109
+ ## ${L('Bot Görevleri', 'Bot Tasks')}
108
110
 
109
- - [Görev 1]
110
- - [Görev 2]
111
+ - ${L('[Görev 1]', '[Task 1]')}
112
+ - ${L('[Görev 2]', '[Task 2]')}
111
113
 
112
- ## Kurallar
114
+ ## ${L('Kurallar', 'Rules')}
113
115
 
114
- - [Kural 1]
115
- - [Kural 2]
116
+ - ${L('[Kural 1]', '[Rule 1]')}
117
+ - ${L('[Kural 2]', '[Rule 2]')}
116
118
  `;
117
119
  fs.writeFileSync(path.join(projectDir, 'AGENTS.md'), agentsMd, 'utf8');
118
120
 
@@ -122,13 +124,13 @@ Chat başladığında bu içerik sistem promptuna eklenir.
122
124
  fs.mkdirSync(skillsDir, { recursive: true });
123
125
  }
124
126
 
125
- console.log(chalk.green('\n✅ Proje başlatıldı!\n'));
126
- console.log(chalk.cyan('Oluşturulan dosyalar:'));
127
+ console.log(chalk.green(L('\n✅ Proje başlatıldı!\n', '\n✅ Project initialized!\n')));
128
+ console.log(chalk.cyan(L('Oluşturulan dosyalar:', 'Created files:')));
127
129
  console.log(chalk.gray(` .natureco/config.json`));
128
130
  console.log(chalk.gray(` .natureco/AGENTS.md`));
129
131
  console.log(chalk.gray(` .natureco/skills/`));
130
132
  console.log('');
131
- console.log(chalk.yellow('Sonraki adım:'), chalk.white(`natureco chat "${selectedBot.name}"`));
133
+ console.log(chalk.yellow(L('Sonraki adım:', 'Next step:')), chalk.white(`natureco chat "${selectedBot.name}"`));
132
134
  console.log('');
133
135
  }
134
136
 
@@ -1,4 +1,6 @@
1
1
  const chalk = require('chalk');
2
+ const { getLang: _gl } = require('../utils/i18n');
3
+ const L = (tr, en) => (_gl() === 'en' ? en : tr);
2
4
  const fs = require('fs');
3
5
  const path = require('path');
4
6
  const os = require('os');
@@ -23,8 +25,8 @@ async function plugins(args) {
23
25
  if (action === 'registry') return registryHandler(opts);
24
26
  if (action === 'marketplace') return marketplaceHandler(opts);
25
27
 
26
- console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
27
- console.log(chalk.gray(' Kullanım: natureco plugins [list|install|uninstall|enable|disable|info|update|search|doctor|registry|marketplace]\n'));
28
+ console.log(chalk.red(`\n ❌ ${L('Bilinmeyen komut', 'Unknown command')}: ${action}\n`));
29
+ console.log(chalk.gray(L(' Kullanım: natureco plugins [list|install|uninstall|enable|disable|info|update|search|doctor|registry|marketplace]\n', ' Usage: natureco plugins [list|install|uninstall|enable|disable|info|update|search|doctor|registry|marketplace]\n')));
28
30
  process.exit(1);
29
31
  } catch (err) {
30
32
  handleError(err);
@@ -79,113 +81,113 @@ function listPlugins(opts) {
79
81
  console.log(chalk.cyan.bold('\n Plugins\n'));
80
82
 
81
83
  if (filtered.length === 0) {
82
- console.log(chalk.gray(' Yüklü plugin yok.\n'));
83
- console.log(chalk.gray(' Yüklemek için: ') + chalk.cyan('natureco plugins install <paket-adı|./path|git:url>'));
84
- console.log(chalk.gray(' Aramak için: ') + chalk.cyan('natureco plugins search <query>\n'));
84
+ console.log(chalk.gray(L(' Yüklü plugin yok.\n', ' No plugins installed.\n')));
85
+ console.log(chalk.gray(L(' Yüklemek için: ', ' To install: ')) + chalk.cyan('natureco plugins install <paket-adı|./path|git:url>'));
86
+ console.log(chalk.gray(L(' Aramak için: ', ' To search: ')) + chalk.cyan('natureco plugins search <query>\n'));
85
87
  return;
86
88
  }
87
89
 
88
90
  filtered.forEach(p => {
89
- const status = p.enabled ? chalk.green('✓ aktif') : chalk.gray('○ pasif');
91
+ const status = p.enabled ? chalk.green(L('✓ aktif', '✓ active')) : chalk.gray(L('○ pasif', '○ inactive'));
90
92
  const source = registry.plugins.find(r => r.id === p.slug)?.source || 'local';
91
93
  const sourceIcon = source === 'npm' ? '📦' : source === 'git' ? '🌐' : source === 'local' ? '📁' : '❓';
92
94
  console.log(` ${sourceIcon} ${chalk.white(p.name)} ${chalk.gray(`v${p.version}`)} ${status}`);
93
95
  if (p.description) console.log(chalk.gray(` ${p.description}`));
94
96
  if (opts.verbose) {
95
- console.log(chalk.gray(` Kaynak: ${source} | Yol: ${p.installPath}`));
96
- if (p.author) console.log(chalk.gray(` Yazar: ${p.author}`));
97
+ console.log(chalk.gray(` ${L('Kaynak', 'Source')}: ${source} | ${L('Yol', 'Path')}: ${p.installPath}`));
98
+ if (p.author) console.log(chalk.gray(` ${L('Yazar', 'Author')}: ${p.author}`));
97
99
  }
98
100
  console.log('');
99
101
  });
100
102
 
101
103
  console.log(chalk.gray(' ' + '─'.repeat(48)));
102
- console.log(chalk.gray(` Toplam: ${filtered.length} plugin (${allPlugins.length - filtered.length} pasif)`));
103
- console.log(chalk.gray(' Detay: ') + chalk.cyan('natureco plugins list --verbose'));
104
+ console.log(chalk.gray(` ${L('Toplam', 'Total')}: ${filtered.length} plugin (${allPlugins.length - filtered.length} ${L('pasif', 'inactive')})`));
105
+ console.log(chalk.gray(L(' Detay: ', ' Details: ')) + chalk.cyan('natureco plugins list --verbose'));
104
106
  console.log(chalk.gray(' JSON: ') + chalk.cyan('natureco plugins list --json\n'));
105
107
  }
106
108
 
107
109
  async function installHandler(spec, opts) {
108
110
  if (!spec) {
109
- console.log(chalk.red('\n ❌ Paket adı gerekli\n'));
110
- console.log(chalk.gray(' Kullanım: natureco plugins install <paket-adı|./path|git:url|clawhub:<id>>\n'));
111
- console.log(chalk.gray(' Örnekler:'));
111
+ console.log(chalk.red(L('\n ❌ Paket adı gerekli\n', '\n ❌ Package name required\n')));
112
+ console.log(chalk.gray(L(' Kullanım: natureco plugins install <paket-adı|./path|git:url|clawhub:<id>>\n', ' Usage: natureco plugins install <package-name|./path|git:url|clawhub:<id>>\n')));
113
+ console.log(chalk.gray(L(' Örnekler:', ' Examples:')));
112
114
  console.log(chalk.gray(' natureco plugins install my-plugin'));
113
115
  console.log(chalk.gray(' natureco plugins install npm:my-plugin'));
114
- console.log(chalk.gray(' natureco plugins install ./yerel-klasor'));
116
+ console.log(chalk.gray(L(' natureco plugins install ./yerel-klasor', ' natureco plugins install ./local-folder')));
115
117
  console.log(chalk.gray(' natureco plugins install git:github.com/user/repo'));
116
118
  console.log(chalk.gray(' natureco plugins install clawhub:plugin-id\n'));
117
119
  process.exit(1);
118
120
  }
119
121
 
120
122
  if (opts.dryRun) {
121
- console.log(chalk.gray(`\n 📋 Kuru çalışma: "${spec}" yüklenecek\n`));
123
+ console.log(chalk.gray(`\n 📋 ${L('Kuru çalışma', 'Dry run')}: "${spec}" ${L('yüklenecek', 'will be installed')}\n`));
122
124
  return;
123
125
  }
124
126
 
125
- console.log(chalk.gray(`\n "${spec}" yükleniyor...\n`));
127
+ console.log(chalk.gray(`\n "${spec}" ${L('yükleniyor...', 'installing...')}\n`));
126
128
 
127
129
  try {
128
130
  const result = await installPlugin(spec);
129
- console.log(chalk.green(` ✓ Plugin yüklendi: ${result.name} v${result.version}\n`));
130
- console.log(chalk.gray(` Kaynak: ${result.source}`));
131
+ console.log(chalk.green(` ✓ ${L('Plugin yüklendi', 'Plugin installed')}: ${result.name} v${result.version}\n`));
132
+ console.log(chalk.gray(` ${L('Kaynak', 'Source')}: ${result.source}`));
131
133
  console.log(chalk.gray(` Slug: ${result.slug}\n`));
132
134
  } catch (err) {
133
- console.log(chalk.red(`\n ❌ Yükleme başarısız: ${err.message}\n`));
135
+ console.log(chalk.red(`\n ❌ ${L('Yükleme başarısız', 'Installation failed')}: ${err.message}\n`));
134
136
  process.exit(1);
135
137
  }
136
138
  }
137
139
 
138
140
  async function uninstallHandler(slug, opts) {
139
141
  if (!slug) {
140
- console.log(chalk.red('\n ❌ Plugin adı gerekli\n'));
141
- console.log(chalk.gray(' Kullanım: natureco plugins uninstall <slug>\n'));
142
+ console.log(chalk.red(L('\n ❌ Plugin adı gerekli\n', '\n ❌ Plugin name required\n')));
143
+ console.log(chalk.gray(L(' Kullanım: natureco plugins uninstall <slug>\n', ' Usage: natureco plugins uninstall <slug>\n')));
142
144
  process.exit(1);
143
145
  }
144
146
 
145
147
  if (opts.dryRun) {
146
- console.log(chalk.gray(`\n 📋 Kuru çalışma: "${slug}" kaldırılacak\n`));
148
+ console.log(chalk.gray(`\n 📋 ${L('Kuru çalışma', 'Dry run')}: "${slug}" ${L('kaldırılacak', 'will be removed')}\n`));
147
149
  return;
148
150
  }
149
151
 
150
152
  try {
151
153
  const result = await uninstallPlugin(slug, { keepFiles: opts.keepFiles });
152
- console.log(chalk.green(`\n ✓ Plugin kaldırıldı: ${result.name}\n`));
154
+ console.log(chalk.green(`\n ✓ ${L('Plugin kaldırıldı', 'Plugin removed')}: ${result.name}\n`));
153
155
  } catch (err) {
154
- console.log(chalk.red(`\n ❌ Kaldırma başarısız: ${err.message}\n`));
156
+ console.log(chalk.red(`\n ❌ ${L('Kaldırma başarısız', 'Removal failed')}: ${err.message}\n`));
155
157
  process.exit(1);
156
158
  }
157
159
  }
158
160
 
159
161
  function toggleHandler(slug, enable) {
160
162
  if (!slug) {
161
- console.log(chalk.red(`\n ❌ Plugin adı gerekli\n`));
163
+ console.log(chalk.red(L('\n ❌ Plugin adı gerekli\n', '\n ❌ Plugin name required\n')));
162
164
  process.exit(1);
163
165
  }
164
166
  const pluginDir = path.join(PLUGINS_DIR, slug);
165
167
  if (!fs.existsSync(pluginDir)) {
166
- console.log(chalk.red(`\n ❌ Plugin bulunamadı: ${slug}\n`));
168
+ console.log(chalk.red(`\n ❌ ${L('Plugin bulunamadı', 'Plugin not found')}: ${slug}\n`));
167
169
  process.exit(1);
168
170
  }
169
171
  const disabledFile = path.join(pluginDir, '.disabled');
170
172
  if (enable) {
171
173
  if (fs.existsSync(disabledFile)) fs.unlinkSync(disabledFile);
172
- console.log(chalk.green(`\n ✓ Plugin aktif: ${slug}\n`));
174
+ console.log(chalk.green(`\n ✓ ${L('Plugin aktif', 'Plugin enabled')}: ${slug}\n`));
173
175
  } else {
174
176
  fs.writeFileSync(disabledFile, '');
175
- console.log(chalk.gray(`\n ○ Plugin pasif: ${slug}\n`));
177
+ console.log(chalk.gray(`\n ○ ${L('Plugin pasif', 'Plugin disabled')}: ${slug}\n`));
176
178
  }
177
179
  }
178
180
 
179
181
  function infoHandler(slug, opts) {
180
182
  if (!slug && !opts.all) {
181
- console.log(chalk.red('\n ❌ Plugin adı gerekli\n'));
182
- console.log(chalk.gray(' Kullanım: natureco plugins info <slug>\n'));
183
+ console.log(chalk.red(L('\n ❌ Plugin adı gerekli\n', '\n ❌ Plugin name required\n')));
184
+ console.log(chalk.gray(L(' Kullanım: natureco plugins info <slug>\n', ' Usage: natureco plugins info <slug>\n')));
183
185
  process.exit(1);
184
186
  }
185
187
 
186
188
  if (opts.all) {
187
189
  const all = scanInstalled();
188
- console.log(chalk.cyan.bold('\n Plugin Detayları\n'));
190
+ console.log(chalk.cyan.bold(L('\n Plugin Detayları\n', '\n Plugin Details\n')));
189
191
  all.forEach(p => {
190
192
  showPluginDetail(p);
191
193
  });
@@ -194,7 +196,7 @@ function infoHandler(slug, opts) {
194
196
 
195
197
  const p = getPlugin(slug);
196
198
  if (!p) {
197
- console.log(chalk.red(`\n ❌ Plugin bulunamadı: ${slug}\n`));
199
+ console.log(chalk.red(`\n ❌ ${L('Plugin bulunamadı', 'Plugin not found')}: ${slug}\n`));
198
200
  process.exit(1);
199
201
  }
200
202
 
@@ -216,16 +218,16 @@ function showPluginDetail(p) {
216
218
  console.log(chalk.gray(' ' + '─'.repeat(48)));
217
219
  console.log(chalk.cyan.bold(`\n ${p.name}\n`));
218
220
  console.log(chalk.gray(' Slug : ') + chalk.white(p.slug));
219
- console.log(chalk.gray(' Versiyon : ') + chalk.white(p.version));
220
- console.log(chalk.gray(' Durum : ') + (p.enabled ? chalk.green('aktif') : chalk.gray('pasif')));
221
- if (p.description) console.log(chalk.gray(' Açıklama : ') + chalk.white(p.description));
222
- if (p.author) console.log(chalk.gray(' Yazar : ') + chalk.white(p.author));
223
- if (p.license) console.log(chalk.gray(' Lisans : ') + chalk.white(p.license));
224
- if (p.keywords?.length) console.log(chalk.gray(' Etiketler : ') + chalk.white(p.keywords.join(', ')));
225
- console.log(chalk.gray(' Yol : ') + chalk.gray(p.installPath));
226
- if (p.entry) console.log(chalk.gray(' Giriş : ') + chalk.white(p.entry));
221
+ console.log(chalk.gray(L(' Versiyon : ', ' Version : ')) + chalk.white(p.version));
222
+ console.log(chalk.gray(L(' Durum : ', ' Status : ')) + (p.enabled ? chalk.green(L('aktif', 'active')) : chalk.gray(L('pasif', 'inactive'))));
223
+ if (p.description) console.log(chalk.gray(L(' Açıklama : ', ' Description: ')) + chalk.white(p.description));
224
+ if (p.author) console.log(chalk.gray(L(' Yazar : ', ' Author : ')) + chalk.white(p.author));
225
+ if (p.license) console.log(chalk.gray(L(' Lisans : ', ' License : ')) + chalk.white(p.license));
226
+ if (p.keywords?.length) console.log(chalk.gray(L(' Etiketler : ', ' Tags : ')) + chalk.white(p.keywords.join(', ')));
227
+ console.log(chalk.gray(L(' Yol : ', ' Path : ')) + chalk.gray(p.installPath));
228
+ if (p.entry) console.log(chalk.gray(L(' Giriş : ', ' Entry : ')) + chalk.white(p.entry));
227
229
  if (p.dependencies && Object.keys(p.dependencies).length > 0) {
228
- console.log(chalk.gray(' Bağımlılıklar:'));
230
+ console.log(chalk.gray(L(' Bağımlılıklar:', ' Dependencies:')));
229
231
  Object.entries(p.dependencies).forEach(([k, v]) => {
230
232
  const depPath = path.join(p.installPath, 'node_modules', k);
231
233
  const installed = fs.existsSync(depPath) ? chalk.green('✓') : chalk.yellow('✗');
@@ -240,15 +242,15 @@ function showPluginDetail(p) {
240
242
 
241
243
  async function updateHandler(slug, opts) {
242
244
  if (!slug && !opts.all) {
243
- console.log(chalk.red('\n ❌ Plugin adı gerekli\n'));
244
- console.log(chalk.gray(' Kullanım: natureco plugins update <slug>'));
245
- console.log(chalk.gray(' Tümü: natureco plugins update --all\n'));
245
+ console.log(chalk.red(L('\n ❌ Plugin adı gerekli\n', '\n ❌ Plugin name required\n')));
246
+ console.log(chalk.gray(L(' Kullanım: natureco plugins update <slug>', ' Usage: natureco plugins update <slug>')));
247
+ console.log(chalk.gray(L(' Tümü: natureco plugins update --all\n', ' All: natureco plugins update --all\n')));
246
248
  process.exit(1);
247
249
  }
248
250
 
249
251
  if (opts.all) {
250
252
  const all = scanInstalled();
251
- console.log(chalk.cyan('\n Tüm pluginler güncelleniyor...\n'));
253
+ console.log(chalk.cyan(L('\n Tüm pluginler güncelleniyor...\n', '\n Updating all plugins...\n')));
252
254
  for (const p of all) {
253
255
  try {
254
256
  const result = await updatePlugin(p.slug);
@@ -261,27 +263,27 @@ async function updateHandler(slug, opts) {
261
263
  }
262
264
 
263
265
  if (opts.dryRun) {
264
- console.log(chalk.gray(`\n 📋 Kuru çalışma: "${slug}" güncellenecek\n`));
266
+ console.log(chalk.gray(`\n 📋 ${L('Kuru çalışma', 'Dry run')}: "${slug}" ${L('güncellenecek', 'will be updated')}\n`));
265
267
  return;
266
268
  }
267
269
 
268
270
  try {
269
271
  const result = await updatePlugin(slug);
270
- console.log(chalk.green(`\n ✓ Plugin güncellendi: ${result.name} → v${result.version}\n`));
272
+ console.log(chalk.green(`\n ✓ ${L('Plugin güncellendi', 'Plugin updated')}: ${result.name} → v${result.version}\n`));
271
273
  } catch (err) {
272
- console.log(chalk.red(`\n ❌ Güncelleme başarısız: ${err.message}\n`));
274
+ console.log(chalk.red(`\n ❌ ${L('Güncelleme başarısız', 'Update failed')}: ${err.message}\n`));
273
275
  process.exit(1);
274
276
  }
275
277
  }
276
278
 
277
279
  async function searchHandler(query, opts) {
278
280
  if (!query) {
279
- console.log(chalk.red('\n ❌ Arama sorgusu gerekli\n'));
280
- console.log(chalk.gray(' Kullanım: natureco plugins search <query>\n'));
281
+ console.log(chalk.red(L('\n ❌ Arama sorgusu gerekli\n', '\n ❌ Search query required\n')));
282
+ console.log(chalk.gray(L(' Kullanım: natureco plugins search <query>\n', ' Usage: natureco plugins search <query>\n')));
281
283
  process.exit(1);
282
284
  }
283
285
 
284
- console.log(chalk.gray(`\n "${query}" aranıyor...\n`));
286
+ console.log(chalk.gray(`\n "${query}" ${L('aranıyor...', 'searching...')}\n`));
285
287
 
286
288
  const results = [];
287
289
 
@@ -325,17 +327,17 @@ async function searchHandler(query, opts) {
325
327
  }
326
328
 
327
329
  if (results.length === 0) {
328
- console.log(chalk.yellow(` "${query}" için sonuç bulunamadı.\n`));
330
+ console.log(chalk.yellow(` "${query}" ${L('için sonuç bulunamadı.', '— no results found.')}\n`));
329
331
  return;
330
332
  }
331
333
 
332
- console.log(chalk.cyan(` ${results.length} sonuç\n`));
334
+ console.log(chalk.cyan(` ${results.length} ${L('sonuç', 'results')}\n`));
333
335
  results.slice(0, opts.limit).forEach(p => {
334
336
  const sourceIcon = p.source === 'clawhub' ? '🦞' : p.source === 'naturehub' ? '🌿' : '📋';
335
337
  console.log(` ${sourceIcon} ${chalk.white(p.name)} ${chalk.gray(`v${p.version}`)}`);
336
338
  if (p.description) console.log(chalk.gray(` ${p.description.slice(0, 80)}`));
337
339
  const installHint = p.source === 'clawhub' ? `clawhub:${p.id}` : p.source === 'naturehub' ? p.id : p.id;
338
- console.log(chalk.gray(` Yüklemek: natureco plugins install ${installHint}\n`));
340
+ console.log(chalk.gray(` ${L('Yüklemek', 'Install')}: natureco plugins install ${installHint}\n`));
339
341
  });
340
342
  }
341
343
 
@@ -343,10 +345,10 @@ function doctorHandler() {
343
345
  const list = scanInstalled();
344
346
  const registry = loadRegistry();
345
347
 
346
- console.log(chalk.cyan.bold('\n Plugin Tanılama\n'));
348
+ console.log(chalk.cyan.bold(L('\n Plugin Tanılama\n', '\n Plugin Diagnostics\n')));
347
349
 
348
350
  if (list.length === 0 && registry.plugins.length === 0) {
349
- console.log(chalk.gray(' Yüklü plugin yok.\n'));
351
+ console.log(chalk.gray(L(' Yüklü plugin yok.\n', ' No plugins installed.\n')));
350
352
  return;
351
353
  }
352
354
 
@@ -358,11 +360,11 @@ function doctorHandler() {
358
360
  const manifestErrors = validateManifest(p);
359
361
 
360
362
  if (!hasPackage) {
361
- console.log(chalk.yellow(` ⚠ ${p.name}: package.json eksik`));
363
+ console.log(chalk.yellow(` ⚠ ${p.name}: package.json ${L('eksik', 'missing')}`));
362
364
  issues++;
363
365
  }
364
366
  if (!hasEntry) {
365
- console.log(chalk.yellow(` ⚠ ${p.name}: ${p.entry || 'index.js'} bulunamadı`));
367
+ console.log(chalk.yellow(` ⚠ ${p.name}: ${p.entry || 'index.js'} ${L('bulunamadı', 'not found')}`));
366
368
  issues++;
367
369
  }
368
370
  if (manifestErrors.length > 0) {
@@ -371,21 +373,21 @@ function doctorHandler() {
371
373
  }
372
374
 
373
375
  if (hasPackage && hasEntry && manifestErrors.length === 0) {
374
- console.log(` ${chalk.green('✓')} ${p.name} v${p.version} — sağlıklı`);
376
+ console.log(` ${chalk.green('✓')} ${p.name} v${p.version} — ${L('sağlıklı', 'healthy')}`);
375
377
  }
376
378
  });
377
379
 
378
380
  registry.plugins.forEach(r => {
379
381
  if (!list.some(p => p.slug === r.id)) {
380
- console.log(chalk.yellow(` ⚠ Kayıtlı ama diskte yok: ${r.id} (kayıttan temizlenecek)`));
382
+ console.log(chalk.yellow(` ⚠ ${L('Kayıtlı ama diskte yok', 'Registered but not on disk')}: ${r.id} (${L('kayıttan temizlenecek', 'will be pruned from registry')})`));
381
383
  issues++;
382
384
  }
383
385
  });
384
386
 
385
387
  if (issues === 0 && list.length > 0) {
386
- console.log(chalk.green(' ✓ Tüm pluginler sağlıklı.\n'));
388
+ console.log(chalk.green(L(' ✓ Tüm pluginler sağlıklı.\n', ' ✓ All plugins healthy.\n')));
387
389
  } else if (issues > 0) {
388
- console.log(chalk.yellow(`\n ⚠ ${issues} sorun bulundu.\n`));
390
+ console.log(chalk.yellow(`\n ⚠ ${issues} ${L('sorun bulundu.', 'issue(s) found.')}\n`));
389
391
  }
390
392
  console.log('');
391
393
  }
@@ -398,13 +400,13 @@ function registryHandler(opts) {
398
400
  return;
399
401
  }
400
402
 
401
- console.log(chalk.cyan.bold('\n Plugin Kayıt Defteri\n'));
402
- console.log(chalk.gray(' Versiyon : ') + chalk.white(`v${registry.version}`));
403
- console.log(chalk.gray(' Güncelleme: ') + chalk.white(registry.updatedAt || 'hiç'));
404
- console.log(chalk.gray(' Kayıtlı : ') + chalk.white(`${registry.plugins.length} plugin`));
403
+ console.log(chalk.cyan.bold(L('\n Plugin Kayıt Defteri\n', '\n Plugin Registry\n')));
404
+ console.log(chalk.gray(L(' Versiyon : ', ' Version : ')) + chalk.white(`v${registry.version}`));
405
+ console.log(chalk.gray(L(' Güncelleme: ', ' Updated : ')) + chalk.white(registry.updatedAt || L('hiç', 'never')));
406
+ console.log(chalk.gray(L(' Kayıtlı : ', ' Registered: ')) + chalk.white(`${registry.plugins.length} plugin`));
405
407
 
406
408
  if (registry.plugins.length > 0) {
407
- console.log(chalk.cyan('\n Kayıtlı Pluginler\n'));
409
+ console.log(chalk.cyan(L('\n Kayıtlı Pluginler\n', '\n Registered Plugins\n')));
408
410
  registry.plugins.forEach(p => {
409
411
  const installed = scanInstalled().some(s => s.slug === p.id) ? chalk.green('✓') : chalk.yellow('✗');
410
412
  console.log(` ${installed} ${chalk.white(p.name || p.id)} ${chalk.gray(`v${p.version} [${p.source}]`)}`);