natureco-cli 5.52.0 → 5.53.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 +6 -0
- package/package.json +1 -1
- package/src/commands/dna.js +30 -10
- package/src/commands/lang.js +31 -0
- package/src/utils/i18n.js +95 -0
- package/src/utils/system-prompt.js +12 -4
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.
|
|
3
|
+
"version": "5.53.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"
|
package/src/commands/dna.js
CHANGED
|
@@ -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('
|
|
25
|
-
console.log(chalk.gray('
|
|
26
|
-
console.log(chalk.gray('
|
|
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('
|
|
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,23 +50,42 @@ 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
|
-
|
|
53
|
-
console.log(' ' + chalk.gray('
|
|
54
|
-
console.log(' ' + chalk.gray(
|
|
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
|
|
|
59
|
+
// Anlama skoru (1-5): anket varsa onu, yoksa otomatik tahmini kullan
|
|
60
|
+
const uScore = (f) => (f.understanding != null ? f.understanding : f.understanding_estimate);
|
|
61
|
+
const uCol = (v) => (v >= 4 ? chalk.green : v >= 2.5 ? chalk.yellow : chalk.red);
|
|
62
|
+
|
|
57
63
|
// En yüksek YZ olasılıklı 5 dosya
|
|
58
64
|
const top = (data.files || []).slice(0, 5);
|
|
59
65
|
if (top.length) {
|
|
60
|
-
console.log(' ' + chalk.gray('
|
|
66
|
+
console.log(' ' + chalk.gray(t('dna.topFiles')));
|
|
61
67
|
for (const f of top) {
|
|
62
68
|
const fp = Math.round((f.ai_probability || 0) * 100);
|
|
63
|
-
const
|
|
69
|
+
const uv = uScore(f);
|
|
70
|
+
const u = uv == null ? '' : ' ' + uCol(uv)(`${t('dna.understanding')} ${uv.toFixed(1)}/5`);
|
|
64
71
|
console.log(' ' + tone(fp).bold(`%${String(fp).padStart(3)}`) + ' ' + chalk.white(f.file) + u);
|
|
65
72
|
}
|
|
66
73
|
console.log('');
|
|
67
74
|
}
|
|
68
|
-
|
|
75
|
+
|
|
76
|
+
// 🧠 Anlama borcu — AI-yoğun ama az-anlaşılan dosyalar (farklılaştırıcı)
|
|
77
|
+
const debt = (data.files || [])
|
|
78
|
+
.filter((f) => { const v = uScore(f); return v != null && v < 3 && (f.ai_probability || 0) >= 0.3; })
|
|
79
|
+
.sort((a, b) => uScore(a) - uScore(b))
|
|
80
|
+
.slice(0, 5);
|
|
81
|
+
if (debt.length) {
|
|
82
|
+
console.log(' ' + chalk.bold(t('dna.debtTitle')) + chalk.gray(' ' + t('dna.debtDesc')));
|
|
83
|
+
for (const f of debt) {
|
|
84
|
+
console.log(' ' + chalk.red(`${uScore(f).toFixed(1)}/5`) + ' ' + chalk.white(f.file) + chalk.gray(` (AI %${Math.round(f.ai_probability * 100)})`));
|
|
85
|
+
}
|
|
86
|
+
console.log('');
|
|
87
|
+
}
|
|
88
|
+
console.log(chalk.gray(' ' + t('dna.detail') + ' ') + chalk.cyan('codedna scan') + chalk.gray(' · ' + t('dna.ecosystem') + ' ') + chalk.cyan('natureco.me/ekosistem') + '\n');
|
|
69
89
|
}
|
|
70
90
|
|
|
71
91
|
module.exports = dna;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const { setConfigValue } = require('../utils/config');
|
|
3
|
+
const { t, getLang, setLangCache } = require('../utils/i18n');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* `natureco lang [tr|en]` — arayüz dilini görüntüle/ayarla.
|
|
7
|
+
* Ayar `~/.natureco/config.json` içindeki `language` alanına yazılır ve
|
|
8
|
+
* i18n katmanı + ajanın system-prompt'u bunu okur (EN → İngilizce deneyim).
|
|
9
|
+
*/
|
|
10
|
+
async function lang(arg) {
|
|
11
|
+
const label = (l) => (l === 'en' ? 'English (en)' : 'Türkçe (tr)');
|
|
12
|
+
const val = (arg || '').toLowerCase().trim();
|
|
13
|
+
|
|
14
|
+
if (!val) {
|
|
15
|
+
console.log('\n ' + t('lang.current', { lang: label(getLang()) }));
|
|
16
|
+
console.log(' ' + chalk.gray(t('lang.usage')) + '\n');
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (val !== 'tr' && val !== 'en') {
|
|
20
|
+
console.log('\n ' + chalk.red(t('lang.invalid')) + '\n');
|
|
21
|
+
process.exitCode = 1;
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
setConfigValue('language', val);
|
|
26
|
+
setLangCache(val);
|
|
27
|
+
console.log('\n ' + chalk.green(t('lang.set', { lang: label(val) })));
|
|
28
|
+
console.log(' ' + chalk.gray(t('lang.restartHint')) + '\n');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
module.exports = lang;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* NatureCo CLI — hafif i18n katmanı.
|
|
5
|
+
* Dil `~/.natureco/config.json` içindeki `language` alanından okunur (tr | en).
|
|
6
|
+
* Yoksa ortam değişkeninden (LANG/LC_ALL) tahmin edilir; varsayılan Türkçe.
|
|
7
|
+
*
|
|
8
|
+
* Kullanım: const { t } = require('../utils/i18n'); t('dna.avgAi')
|
|
9
|
+
* Yeni çeviri eklemek: aşağıdaki MESSAGES.tr ve MESSAGES.en'e aynı anahtarı ekle.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const { getConfig } = require('./config');
|
|
13
|
+
|
|
14
|
+
let _cache = null;
|
|
15
|
+
|
|
16
|
+
function getLang() {
|
|
17
|
+
if (_cache) return _cache;
|
|
18
|
+
try {
|
|
19
|
+
const cfg = getConfig();
|
|
20
|
+
if (cfg && (cfg.language === 'en' || cfg.language === 'tr')) {
|
|
21
|
+
_cache = cfg.language;
|
|
22
|
+
return _cache;
|
|
23
|
+
}
|
|
24
|
+
} catch (_) { /* config yoksa ortam değişkenine düş */ }
|
|
25
|
+
const env = (process.env.NATURECO_LANG || process.env.LANG || process.env.LC_ALL || '').toLowerCase();
|
|
26
|
+
_cache = env.startsWith('en') ? 'en' : 'tr'; // varsayılan: Türkçe-öncelikli
|
|
27
|
+
return _cache;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Bellek önbelleğini güncelle (dil değiştirildiğinde çağrılır). */
|
|
31
|
+
function setLangCache(lang) {
|
|
32
|
+
_cache = lang === 'en' ? 'en' : 'tr';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const MESSAGES = {
|
|
36
|
+
tr: {
|
|
37
|
+
// dna
|
|
38
|
+
'dna.notInstalled': 'CodeDNA kurulu değil.',
|
|
39
|
+
'dna.installHint': 'Kurmak için:',
|
|
40
|
+
'dna.installDesc': 'CodeDNA, kodun ne kadarının yapay zekâ olduğunu ölçen NatureCo aracıdır.',
|
|
41
|
+
'dna.unreadable': 'CodeDNA çıktısı okunamadı.',
|
|
42
|
+
'dna.avgAi': 'Ortalama YZ olasılığı',
|
|
43
|
+
'dna.maxFile': 'En yüksek dosya',
|
|
44
|
+
'dna.scanned': 'Taranan dosya: {n}',
|
|
45
|
+
'dna.topFiles': 'En yüksek YZ olasılıklı dosyalar:',
|
|
46
|
+
'dna.understanding': 'anlama',
|
|
47
|
+
'dna.debtTitle': '🧠 Anlama borcu',
|
|
48
|
+
'dna.debtDesc': '(AI yazdı ama ekip muhtemelen anlamıyor):',
|
|
49
|
+
'dna.detail': 'Ayrıntı için:',
|
|
50
|
+
'dna.ecosystem': 'Ekosistem:',
|
|
51
|
+
// lang
|
|
52
|
+
'lang.current': 'Şu anki dil: {lang}',
|
|
53
|
+
'lang.set': 'Dil ayarlandı: {lang} ✓',
|
|
54
|
+
'lang.usage': 'Kullanım: natureco lang <tr|en>',
|
|
55
|
+
'lang.invalid': 'Geçersiz dil. "tr" veya "en" kullanın.',
|
|
56
|
+
'lang.restartHint': 'Değişiklik yeni komutlarda geçerli.',
|
|
57
|
+
},
|
|
58
|
+
en: {
|
|
59
|
+
// dna
|
|
60
|
+
'dna.notInstalled': 'CodeDNA is not installed.',
|
|
61
|
+
'dna.installHint': 'Install with:',
|
|
62
|
+
'dna.installDesc': "CodeDNA is the NatureCo tool that measures how much of your code is AI-written.",
|
|
63
|
+
'dna.unreadable': "Couldn't read CodeDNA output.",
|
|
64
|
+
'dna.avgAi': 'Average AI probability',
|
|
65
|
+
'dna.maxFile': 'Highest file',
|
|
66
|
+
'dna.scanned': 'Files scanned: {n}',
|
|
67
|
+
'dna.topFiles': 'Highest AI-probability files:',
|
|
68
|
+
'dna.understanding': 'understanding',
|
|
69
|
+
'dna.debtTitle': '🧠 Understanding debt',
|
|
70
|
+
'dna.debtDesc': "(AI-written code the team likely doesn't understand):",
|
|
71
|
+
'dna.detail': 'For details:',
|
|
72
|
+
'dna.ecosystem': 'Ecosystem:',
|
|
73
|
+
// lang
|
|
74
|
+
'lang.current': 'Current language: {lang}',
|
|
75
|
+
'lang.set': 'Language set to: {lang} ✓',
|
|
76
|
+
'lang.usage': 'Usage: natureco lang <tr|en>',
|
|
77
|
+
'lang.invalid': 'Invalid language. Use "tr" or "en".',
|
|
78
|
+
'lang.restartHint': 'Takes effect on the next commands.',
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/** Çeviri: geçerli dilde `key`'i döndür (yoksa TR'ye, o da yoksa key'in kendisine düşer). {var} enterpolasyonu. */
|
|
83
|
+
function t(key, vars) {
|
|
84
|
+
const lang = getLang();
|
|
85
|
+
const cat = MESSAGES[lang] || MESSAGES.tr;
|
|
86
|
+
let s = cat[key];
|
|
87
|
+
if (s == null) s = MESSAGES.tr[key];
|
|
88
|
+
if (s == null) s = key;
|
|
89
|
+
if (vars) {
|
|
90
|
+
for (const k of Object.keys(vars)) s = s.split('{' + k + '}').join(String(vars[k]));
|
|
91
|
+
}
|
|
92
|
+
return s;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
module.exports = { t, getLang, setLangCache, MESSAGES };
|
|
@@ -10,7 +10,11 @@
|
|
|
10
10
|
* Volatile is rebuilt every turn.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
+
let _getLang;
|
|
14
|
+
try { _getLang = require('./i18n').getLang; } catch (_) { _getLang = () => 'tr'; }
|
|
15
|
+
|
|
13
16
|
function buildTiers(opts) {
|
|
17
|
+
const lang = opts.language || _getLang();
|
|
14
18
|
const {
|
|
15
19
|
botName,
|
|
16
20
|
userName = 'kullanıcı',
|
|
@@ -43,7 +47,9 @@ function buildTiers(opts) {
|
|
|
43
47
|
`ASLA "MiniMax", "MiniMax-M2.5", "Claude", "GPT", "AI asistanı", "yapay zeka" gibi ifadeleri KENDİNİ tanıtmak için KULLANMA.`,
|
|
44
48
|
`Kullanıcı "adın ne?", "sen kimsin?" diye sorduğunda İLK cümlende MUTLAKA "Ben ${displayBot}" yaz.`,
|
|
45
49
|
`Senin adın: ${displayBot}. Tekrar: ${displayBot}. Asla unutma: ${displayBot}.`,
|
|
46
|
-
|
|
50
|
+
lang === 'en'
|
|
51
|
+
? `You are not a brand or product. You are ${displayBot}, the AI assistant of the NatureCo CLI.`
|
|
52
|
+
: `Sen bir marka veya ürün değilsin. Sen ${displayBot}sin, NatureCo CLI'nin yapay zeka asistanısın.`,
|
|
47
53
|
|
|
48
54
|
// Personality (stable)
|
|
49
55
|
`Kisiselik: Sen samimi, sicak, dosta benzeyen bir asistansin. "Selam", "tamam", "hadi yapalim", "bak simdi", "sakin ol" gibi gunluk ifadeler kullan.`,
|
|
@@ -52,9 +58,11 @@ function buildTiers(opts) {
|
|
|
52
58
|
`Kisa yanit: Uzun paragraflar yazma. Direkt konuya gir.`,
|
|
53
59
|
`Hata yaparsan "Pardon, yanlis yaptim, simdi duzelteyim" de. "Hata", "basarisiz", "imkansiz" deme.`,
|
|
54
60
|
|
|
55
|
-
// Language rules (stable)
|
|
56
|
-
|
|
57
|
-
|
|
61
|
+
// Language rules (stable) — honor the user's chosen interface language
|
|
62
|
+
lang === 'en'
|
|
63
|
+
? `CRITICAL LANGUAGE RULE: ALWAYS reply to the user in English. These internal instructions are written in Turkish, but every message you send to the user MUST be in natural, correct English. Never reply in Turkish.`
|
|
64
|
+
: `KRITIK DIL KURALI: Kullanici Turkce yaziyorsa MUTLAKA yuzde yuz Turkce cevap ver. Asla baska dil kullanma. Turkce karakterleri dogru kullan.`,
|
|
65
|
+
lang === 'en' ? '' : `Yazim: "degilim" dogru, "degil" degil. Turkce dil bilgisi kurallarina uy.`,
|
|
58
66
|
|
|
59
67
|
// Tool rules (stable)
|
|
60
68
|
`ONEMLI: Tool cagirma SIMULE ETME. Sadece duz metin cevap ver. Islem yapmak gerekirse tool'u gercekten cagir.`,
|