natureco-cli 5.52.1 → 5.54.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/bin/natureco.js CHANGED
@@ -14,6 +14,7 @@ const login = require('../src/commands/login');
14
14
  const logout = require('../src/commands/logout');
15
15
  const account = require('../src/commands/account');
16
16
  const dna = require('../src/commands/dna');
17
+ const lang = require('../src/commands/lang');
17
18
  const bots = require('../src/commands/bots');
18
19
  const chat = require('../src/commands/chat');
19
20
  const help = require('../src/commands/help');
@@ -213,6 +214,11 @@ program
213
214
  .option('--max <n>', 'En fazla taranacak dosya sayısı')
214
215
  .action(dna);
215
216
 
217
+ program
218
+ .command('lang [code]')
219
+ .description('Arayüz dili / Interface language (tr | en)')
220
+ .action(lang);
221
+
216
222
  program
217
223
  .command('setup [action]')
218
224
  .description('Run initial setup wizard (wizard|config|workspace|dirs|status)')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "natureco-cli",
3
- "version": "5.52.1",
3
+ "version": "5.54.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"
@@ -1,11 +1,15 @@
1
1
  const inquirer = require('../utils/inquirer-wrapper');
2
2
  const chalk = require('chalk');
3
3
  const acc = require('../utils/natureco-account');
4
+ const { getLang } = require('../utils/i18n');
5
+
6
+ const L = (tr, en) => (getLang() === 'en' ? en : tr);
4
7
 
5
8
  /**
6
- * `natureco account [login|logout|whoami]` — tek NatureCo hesabı (SSO).
7
- * developers.natureco.me API-KEY girişinden (`natureco login`) AYRIDIR:
8
- * bu, natureco.me hesabınla kişi kimliği; ekosistem geneli paylaşılır.
9
+ * `natureco account [login|logout|whoami]` — one NatureCo account (SSO).
10
+ * Separate from the developers.natureco.me API-KEY login (`natureco login`):
11
+ * this is your personal identity with your natureco.me account, shared
12
+ * across the whole ecosystem.
9
13
  */
10
14
  async function account(action) {
11
15
  const sub = (action || 'whoami').toLowerCase();
@@ -20,42 +24,42 @@ async function doLogin() {
20
24
  console.log(chalk.green.bold(' (•ᴥ•)'));
21
25
  console.log(chalk.green(' />🌿'));
22
26
  console.log('');
23
- console.log(chalk.green.bold(' NatureCo Hesabı — Giriş'));
24
- console.log(chalk.gray(' natureco.me hesabınla ekosistemin her yerinde tek kimlik.\n'));
27
+ console.log(chalk.green.bold(' ' + L('NatureCo Hesabı — Giriş', 'NatureCo Account — Sign in')));
28
+ console.log(chalk.gray(' ' + L('natureco.me hesabınla ekosistemin her yerinde tek kimlik.', 'One identity across the whole ecosystem with your natureco.me account.') + '\n'));
25
29
  console.log(chalk.gray(' ' + '─'.repeat(48)) + '\n');
26
30
 
27
31
  const { email } = await inquirer.prompt([{
28
32
  type: 'input',
29
33
  name: 'email',
30
- message: ' E-posta:',
31
- validate: (v) => (/.+@.+\..+/.test((v || '').trim()) ? true : 'Geçerli bir e-posta gir'),
34
+ message: L(' E-posta:', ' Email:'),
35
+ validate: (v) => (/.+@.+\..+/.test((v || '').trim()) ? true : L('Geçerli bir e-posta gir', 'Enter a valid email')),
32
36
  }]);
33
37
 
34
38
  const { method } = await inquirer.prompt([{
35
39
  type: 'list',
36
40
  name: 'method',
37
- message: ' Giriş yöntemi:',
41
+ message: L(' Giriş yöntemi:', ' Sign-in method:'),
38
42
  choices: [
39
- { name: 'Şifre', value: 'password' },
40
- { name: 'E-postama kod gönder (OTP)', value: 'otp' },
43
+ { name: L('Şifre', 'Password'), value: 'password' },
44
+ { name: L('E-postama kod gönder (OTP)', 'Email me a code (OTP)'), value: 'otp' },
41
45
  ],
42
46
  }]);
43
47
 
44
48
  try {
45
49
  if (method === 'password') {
46
- const { password } = await inquirer.prompt([{ type: 'password', name: 'password', message: ' Şifre:', mask: '*' }]);
47
- console.log(chalk.gray('\n Doğrulanıyor...'));
50
+ const { password } = await inquirer.prompt([{ type: 'password', name: 'password', message: L(' Şifre:', ' Password:'), mask: '*' }]);
51
+ console.log(chalk.gray('\n ' + L('Doğrulanıyor...', 'Verifying...')));
48
52
  await acc.loginWithPassword(email.trim(), password);
49
53
  } else {
50
- console.log(chalk.gray('\n Gönderiliyor...'));
54
+ console.log(chalk.gray('\n ' + L('Gönderiliyor...', 'Sending...')));
51
55
  await acc.sendOtp(email.trim());
52
- console.log(chalk.gray(' ') + chalk.cyan(email.trim()) + chalk.gray(' adresine e-posta gönderildi.'));
53
- console.log(chalk.gray(' 6 haneli kod geldiyse kodu, giriş linki geldiyse linki yapıştır.'));
56
+ console.log(chalk.gray(' ') + chalk.cyan(email.trim()) + chalk.gray(L(' adresine e-posta gönderildi.', ' — email sent.')));
57
+ console.log(chalk.gray(' ' + L('6 haneli kod geldiyse kodu, giriş linki geldiyse linki yapıştır.', 'Paste the 6-digit code, or the login link if you got one.')));
54
58
  const { token } = await inquirer.prompt([{
55
- type: 'input', name: 'token', message: ' Kod veya giriş linki:',
56
- validate: (v) => ((v || '').trim().length >= 6 ? true : 'Kodu ya da linki gir'),
59
+ type: 'input', name: 'token', message: L(' Kod veya giriş linki:', ' Code or login link:'),
60
+ validate: (v) => ((v || '').trim().length >= 6 ? true : L('Kodu ya da linki gir', 'Enter the code or link')),
57
61
  }]);
58
- console.log(chalk.gray('\n Doğrulanıyor...'));
62
+ console.log(chalk.gray('\n ' + L('Doğrulanıyor...', 'Verifying...')));
59
63
  const val = token.trim();
60
64
  if (/^https?:\/\//i.test(val) || val.includes('token')) {
61
65
  await acc.verifyLink(val);
@@ -64,41 +68,41 @@ async function doLogin() {
64
68
  }
65
69
  }
66
70
  } catch (err) {
67
- console.log(chalk.red(`\n ❌ ${err.message || 'Giriş başarısız'}\n`));
71
+ console.log(chalk.red(`\n ❌ ${err.message || L('Giriş başarısız', 'Sign-in failed')}\n`));
68
72
  process.exit(1);
69
73
  }
70
74
 
71
75
  const me = await acc.whoami();
72
- console.log(chalk.green('\n ✓ Giriş başarılı!'));
73
- if (me && me.email) console.log(chalk.gray(' Hoş geldin, ') + chalk.white(me.email));
74
- console.log(chalk.gray(' Oturum: ~/.natureco/auth.json'));
76
+ console.log(chalk.green('\n ✓ ' + L('Giriş başarılı!', 'Signed in!')));
77
+ if (me && me.email) console.log(chalk.gray(' ' + L('Hoş geldin, ', 'Welcome, ')) + chalk.white(me.email));
78
+ console.log(chalk.gray(' ' + L('Oturum: ', 'Session: ') + '~/.natureco/auth.json'));
75
79
  console.log('');
76
80
  }
77
81
 
78
82
  async function doLogout() {
79
83
  if (!acc.isLoggedIn()) {
80
- console.log(chalk.gray('\n Zaten giriş yapılmamış.\n'));
84
+ console.log(chalk.gray('\n ' + L('Zaten giriş yapılmamış.', 'Not signed in.') + '\n'));
81
85
  return;
82
86
  }
83
87
  const who = acc.currentEmail();
84
88
  acc.logout();
85
- console.log(chalk.green(`\n ✓ Çıkış yapıldı${who ? ' (' + who + ')' : ''}.\n`));
89
+ console.log(chalk.green('\n ✓ ' + L('Çıkış yapıldı', 'Signed out') + `${who ? ' (' + who + ')' : ''}.\n`));
86
90
  }
87
91
 
88
92
  async function doWhoami() {
89
93
  if (!acc.isLoggedIn()) {
90
- console.log(chalk.gray('\n NatureCo hesabına giriş yapılmamış.'));
91
- console.log(chalk.gray(' Giriş: ') + chalk.cyan('natureco account login') + '\n');
94
+ console.log(chalk.gray('\n ' + L('NatureCo hesabına giriş yapılmamış.', 'Not signed in to a NatureCo account.')));
95
+ console.log(chalk.gray(' ' + L('Giriş: ', 'Sign in: ')) + chalk.cyan('natureco account login') + '\n');
92
96
  return;
93
97
  }
94
- console.log(chalk.gray('\n Doğrulanıyor...'));
98
+ console.log(chalk.gray('\n ' + L('Doğrulanıyor...', 'Verifying...')));
95
99
  const me = await acc.whoami();
96
100
  if (!me) {
97
- console.log(chalk.yellow('\n ⚠ Oturum süresi dolmuş görünüyor. Tekrar giriş yap: ') + chalk.cyan('natureco account login') + '\n');
101
+ console.log(chalk.yellow('\n ⚠ ' + L('Oturum süresi dolmuş görünüyor. Tekrar giriş yap: ', 'Your session looks expired. Sign in again: ')) + chalk.cyan('natureco account login') + '\n');
98
102
  return;
99
103
  }
100
- console.log(chalk.green.bold('\n ⬡ NatureCo Hesabı'));
101
- console.log(chalk.gray(' E-posta: ') + chalk.white(me.email || '-'));
104
+ console.log(chalk.green.bold('\n ⬡ ' + L('NatureCo Hesabı', 'NatureCo Account')));
105
+ console.log(chalk.gray(' ' + L('E-posta: ', 'Email: ')) + chalk.white(me.email || '-'));
102
106
  console.log(chalk.gray(' ID: ') + chalk.gray(me.id || '-'));
103
107
  console.log('');
104
108
  }
@@ -1,4 +1,6 @@
1
- const chalk = require('chalk');
1
+ const chalk = require('chalk');
2
+ const { getLang: _getLang } = require('../utils/i18n');
3
+ const L = (tr, en) => (_getLang() === 'en' ? en : tr);
2
4
  const { getApiKey, getConfig } = require('../utils/config');
3
5
  const { getBots, sendMessage } = require('../utils/api');
4
6
  const { getSkillPrompts } = require('../utils/skills');
@@ -9,7 +11,7 @@ async function ask(question, options = {}) {
9
11
  const apiKey = getApiKey();
10
12
 
11
13
  if (!apiKey) {
12
- console.log(chalk.red('\n❌ Giriş yapılmamış. Önce "natureco login" çalıştırın.\n'));
14
+ console.log(chalk.red(L('\n❌ Giriş yapılmamış. Önce "natureco login" çalıştırın.\n', '\n❌ Not signed in. Run "natureco login" first.\n')));
13
15
  process.exit(1);
14
16
  }
15
17
 
@@ -26,7 +28,7 @@ async function ask(question, options = {}) {
26
28
  }
27
29
 
28
30
  if (!defaultBotId) {
29
- console.log(chalk.red('\n❌ Hiç bot bulunamadı. "natureco chat" ile yerel sağlayıcıyı kullanabilir ya da bir bot oluşturabilirsiniz.\n'));
31
+ console.log(chalk.red(L('\n❌ Hiç bot bulunamadı. "natureco chat" ile yerel sağlayıcıyı kullanabilir ya da bir bot oluşturabilirsiniz.\n', '\n❌ No bots found. Use "natureco chat" for the local provider, or create a bot.\n')));
30
32
  process.exit(1);
31
33
  }
32
34
 
@@ -5,7 +5,9 @@ const readline = require('readline');
5
5
  const inquirer = require('../utils/inquirer-wrapper');
6
6
  const TB = require('../utils/token-budget');
7
7
  const tui = require('../utils/tui');
8
- const chalk = require('chalk');
8
+ const chalk = require('chalk');
9
+ const { getLang: _getLang } = require('../utils/i18n');
10
+ const L = (tr, en) => (_getLang() === 'en' ? en : tr);
9
11
  const { getApiKey, getConfig } = require('../utils/config');
10
12
  const repl = require('./repl');
11
13
  const { getSkillPrompts, getSkills } = require('../utils/skills');
@@ -273,7 +275,7 @@ async function chat(botName, options = {}) {
273
275
  session = createSession(bot.id, bot.name);
274
276
  console.log(chalk.green(`Bot değişti: ${newBot.name}`));
275
277
  } else {
276
- console.log(chalk.red(`Bot bulunamadı: ${newName}`));
278
+ console.log(chalk.red(`${L('Bot bulunamadı', 'Bot not found')}: ${newName}`));
277
279
  }
278
280
  }
279
281
  console.log();
@@ -300,7 +302,7 @@ async function chat(botName, options = {}) {
300
302
  console.log();
301
303
  return;
302
304
  case 'help':
303
- console.log(chalk.yellow('Chat Komutları:'));
305
+ console.log(chalk.yellow(L('Chat Komutları:', 'Chat commands:')));
304
306
  [
305
307
  ['/clear', 'Ekranı temizle'],
306
308
  ['/bot [ad]', 'Bot değiştir'],
@@ -1,5 +1,6 @@
1
1
  const chalk = require('chalk');
2
2
  const { spawnSync } = require('child_process');
3
+ const { t } = require('../utils/i18n');
3
4
 
4
5
  /**
5
6
  * `natureco dna [path]` — CodeDNA ile kod şeffaflığı.
@@ -21,9 +22,9 @@ async function dna(pathArg, opts = {}) {
21
22
 
22
23
  if (res.error && res.error.code === 'ENOENT') {
23
24
  console.log('');
24
- console.log(chalk.yellow(' CodeDNA kurulu değil.'));
25
- console.log(chalk.gray(' Kurmak için: ') + chalk.cyan('pip install codedna') + chalk.gray(' (veya ') + chalk.cyan('uv tool install codedna') + chalk.gray(')'));
26
- console.log(chalk.gray(' CodeDNA, kodun ne kadarının yapay zekâ olduğunu ölçen NatureCo aracıdır.\n'));
25
+ console.log(chalk.yellow(' ' + t('dna.notInstalled')));
26
+ console.log(chalk.gray(' ' + t('dna.installHint') + ' ') + chalk.cyan('pip install codedna') + chalk.gray(' (uv tool install codedna)'));
27
+ console.log(chalk.gray(' ' + t('dna.installDesc') + '\n'));
27
28
  process.exitCode = 1;
28
29
  return;
29
30
  }
@@ -32,7 +33,7 @@ async function dna(pathArg, opts = {}) {
32
33
  try {
33
34
  data = JSON.parse(res.stdout);
34
35
  } catch (_e) {
35
- console.log(chalk.red(' CodeDNA çıktısı okunamadı.'));
36
+ console.log(chalk.red(' ' + t('dna.unreadable')));
36
37
  if (res.stderr) console.log(chalk.gray(res.stderr.trim().split('\n').slice(0, 4).join('\n')));
37
38
  process.exitCode = 1;
38
39
  return;
@@ -49,9 +50,10 @@ async function dna(pathArg, opts = {}) {
49
50
  console.log('');
50
51
  console.log(' ' + chalk.bold.cyan('🧬 CodeDNA') + chalk.gray(' · ' + (data.repo || target)));
51
52
  console.log('');
52
- console.log(' ' + chalk.gray('Ortalama YZ olasılığı ') + tone(pct)(bar(pct)) + ' ' + tone(pct).bold(`%${pct}`));
53
- console.log(' ' + chalk.gray('En yüksek dosya ') + tone(maxPct)(bar(maxPct)) + ' ' + tone(maxPct).bold(`%${maxPct}`));
54
- console.log(' ' + chalk.gray(`Taranan dosya: ${data.file_count || 0}`));
53
+ const pad = (s) => (s + ' ').slice(0, 22);
54
+ console.log(' ' + chalk.gray(pad(t('dna.avgAi'))) + tone(pct)(bar(pct)) + ' ' + tone(pct).bold(`%${pct}`));
55
+ console.log(' ' + chalk.gray(pad(t('dna.maxFile'))) + tone(maxPct)(bar(maxPct)) + ' ' + tone(maxPct).bold(`%${maxPct}`));
56
+ console.log(' ' + chalk.gray(t('dna.scanned', { n: data.file_count || 0 })));
55
57
  console.log('');
56
58
 
57
59
  // Anlama skoru (1-5): anket varsa onu, yoksa otomatik tahmini kullan
@@ -61,11 +63,11 @@ async function dna(pathArg, opts = {}) {
61
63
  // En yüksek YZ olasılıklı 5 dosya
62
64
  const top = (data.files || []).slice(0, 5);
63
65
  if (top.length) {
64
- console.log(' ' + chalk.gray('En yüksek YZ olasılıklı dosyalar:'));
66
+ console.log(' ' + chalk.gray(t('dna.topFiles')));
65
67
  for (const f of top) {
66
68
  const fp = Math.round((f.ai_probability || 0) * 100);
67
69
  const uv = uScore(f);
68
- const u = uv == null ? '' : ' ' + uCol(uv)(`anlama ${uv.toFixed(1)}/5`);
70
+ const u = uv == null ? '' : ' ' + uCol(uv)(`${t('dna.understanding')} ${uv.toFixed(1)}/5`);
69
71
  console.log(' ' + tone(fp).bold(`%${String(fp).padStart(3)}`) + ' ' + chalk.white(f.file) + u);
70
72
  }
71
73
  console.log('');
@@ -77,13 +79,13 @@ async function dna(pathArg, opts = {}) {
77
79
  .sort((a, b) => uScore(a) - uScore(b))
78
80
  .slice(0, 5);
79
81
  if (debt.length) {
80
- console.log(' ' + chalk.bold('🧠 Anlama borcu') + chalk.gray(' (AI yazdı ama ekip muhtemelen anlamıyor):'));
82
+ console.log(' ' + chalk.bold(t('dna.debtTitle')) + chalk.gray(' ' + t('dna.debtDesc')));
81
83
  for (const f of debt) {
82
- console.log(' ' + chalk.red(`${uScore(f).toFixed(1)}/5`) + ' ' + chalk.white(f.file) + chalk.gray(` (YZ %${Math.round(f.ai_probability * 100)})`));
84
+ console.log(' ' + chalk.red(`${uScore(f).toFixed(1)}/5`) + ' ' + chalk.white(f.file) + chalk.gray(` (AI %${Math.round(f.ai_probability * 100)})`));
83
85
  }
84
86
  console.log('');
85
87
  }
86
- console.log(chalk.gray(' Ayrıntı için: ') + chalk.cyan('codedna scan') + chalk.gray(' · Ekosistem: ') + chalk.cyan('natureco.me/ekosistem') + '\n');
88
+ console.log(chalk.gray(' ' + t('dna.detail') + ' ') + chalk.cyan('codedna scan') + chalk.gray(' · ' + t('dna.ecosystem') + ' ') + chalk.cyan('natureco.me/ekosistem') + '\n');
87
89
  }
88
90
 
89
91
  module.exports = dna;