natureco-cli 5.62.0 → 5.64.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.
Files changed (44) hide show
  1. package/CHANGELOG.md +34 -1
  2. package/bin/natureco.js +10 -3
  3. package/package.json +8 -5
  4. package/scripts/benchmark-startup.js +26 -0
  5. package/src/commands/backup.js +3 -3
  6. package/src/commands/chat.js +17 -17
  7. package/src/commands/code.js +49 -14
  8. package/src/commands/code_v5.js +15 -1
  9. package/src/commands/gateway-server.js +128 -24
  10. package/src/commands/git.js +2 -2
  11. package/src/commands/pairing.js +2 -22
  12. package/src/commands/repl.js +118 -112
  13. package/src/tools/agentic-runner.js +41 -33
  14. package/src/tools/memory_write.js +16 -12
  15. package/src/tools/structural_patch.js +25 -0
  16. package/src/tools/workflow.js +10 -2
  17. package/src/utils/agent-core.js +51 -0
  18. package/src/utils/agent-workspace.js +24 -0
  19. package/src/utils/api.js +12 -8
  20. package/src/utils/channel-sdk.js +212 -0
  21. package/src/utils/code-intelligence.js +69 -0
  22. package/src/utils/coding-session.js +54 -0
  23. package/src/utils/delivery-store.js +34 -0
  24. package/src/utils/i18n.js +7 -1
  25. package/src/utils/json-schema.js +43 -0
  26. package/src/utils/lsp-client.js +129 -0
  27. package/src/utils/memory-record.js +49 -0
  28. package/src/utils/pairing-store.js +55 -0
  29. package/src/utils/pattern-detector.js +13 -3
  30. package/src/utils/plugin-registry.js +3 -3
  31. package/src/utils/process-errors.js +14 -7
  32. package/src/utils/runtime-health.js +28 -0
  33. package/src/utils/secret-store.js +90 -0
  34. package/src/utils/secure-sync.js +63 -0
  35. package/src/utils/skill-lifecycle.js +59 -0
  36. package/src/utils/structural-patch.js +68 -0
  37. package/src/utils/sub-agent.js +13 -2
  38. package/src/utils/test-failure-analyzer.js +64 -0
  39. package/src/utils/tool-execution-gateway.js +56 -0
  40. package/src/utils/tool-manifest.js +31 -0
  41. package/src/utils/tool-path-policy.js +49 -0
  42. package/src/utils/tool-result.js +17 -0
  43. package/src/utils/tool-runner.js +81 -53
  44. package/src/utils/tools.js +30 -42
@@ -46,8 +46,8 @@ function extractPreferenceFacts(content) {
46
46
  }
47
47
  return out;
48
48
  }
49
- const chalk = require('chalk');
50
- const { getLang: _getLang } = require('../utils/i18n');
49
+ const chalk = require('chalk');
50
+ const { getLang: _getLang } = require('../utils/i18n');
51
51
  const L = (tr, en) => (_getLang() === 'en' ? en : tr);
52
52
  const tui = require('../utils/tui');
53
53
  const { loadToolDefinitions, toOpenAIFormat, executeTool } = require('../utils/tools');
@@ -56,7 +56,7 @@ const { createPasteSafeInput, createOutputFilter, enableBracketedPaste, disableB
56
56
  const { getMemoryStore } = require('../utils/memory-store');
57
57
  const { buildSkillIndex } = require('../utils/skill-index');
58
58
  const { buildTiers, assemble, discoverProjectRules } = require('../utils/system-prompt');
59
- const { ToolGuardrails } = require('../utils/tool-guardrails');
59
+ const { AgentCore } = require('../utils/agent-core');
60
60
 
61
61
  // v5.4.6: Model adi sizintisini engelle — global'e ata, callback'lerden erisebilir olsun
62
62
  const MODEL_NAMES_TO_HIDE = ['MiniMax-M2.5', 'MiniMaxM2.5', 'minimaxm25', 'Claude-3', 'GPT-4', 'ChatGPT'];
@@ -128,26 +128,27 @@ function rebuildSystemPrompt(opts) {
128
128
  }
129
129
 
130
130
  // ── Tool Guardrails instance (Hermes-style) ─────────────────────────────
131
- const guardrails = new ToolGuardrails();
131
+ const agentCore = new AgentCore({ maxIterations: 10 });
132
+ const guardrails = agentCore.guardrails;
132
133
 
133
134
  // CLI komutları (REPL içinden çalıştırılabilir)
134
135
  const CLI_COMMANDS = {
135
- '/doctor': { desc: 'Sistem sağlığı kontrolü', run: ['doctor'] },
136
- '/cost': { desc: 'Maliyet takibi (today|week|month|budget)', run: ['cost', 'today'] },
137
- '/audit': { desc: 'Audit log (today|stats|files)', run: ['audit', 'stats'] },
138
- '/team': { desc: 'Multi-agent (list|status)', run: ['team', 'list'] },
139
- '/xp': { desc: 'XP/Level durumu', run: ['xp'] },
140
- '/skills': { desc: 'Yüklü skill listesi', run: ['skills', 'list'] },
141
- '/status': { desc: 'Sistem durumu', run: ['status'] },
142
- '/mcp': { desc: 'MCP sunucuları', run: ['mcp', 'list'] },
143
- '/channels': { desc: 'Bağlı kanallar', run: ['channels'] },
144
- '/crons': { desc: 'Cron görevleri', run: ['cron', 'list'] },
145
- '/bots': { desc: 'Bot listesi', run: ['bots'] },
146
- '/models': { desc: 'Modeller', run: ['models', 'list'] },
147
- '/memory-ls': { desc: 'Memory dosyaları', run: ['memory', 'list'] },
148
- '/seo': { desc: 'SEO denetimi (URL gerek)', needsArg: true, run: ['seo', 'audit'] },
149
- '/naturehub': { desc: 'Bota mesaj gönder (text gerek)', needsArg: true, run: ['naturehub', 'post'] },
150
- '/dashboard': { desc: 'Web dashboard başlat (port 7421)', run: ['dashboard', 'start'] },
136
+ '/doctor': { desc: L('Sistem sağlığı kontrolü', 'System health check'), run: ['doctor'] },
137
+ '/cost': { desc: L('Maliyet takibi (today|week|month|budget)', 'Cost tracking (today|week|month|budget)'), run: ['cost', 'today'] },
138
+ '/audit': { desc: L('Denetim kaydı (today|stats|files)', 'Audit log (today|stats|files)'), run: ['audit', 'stats'] },
139
+ '/team': { desc: L('Çoklu ajan (list|status)', 'Multi-agent (list|status)'), run: ['team', 'list'] },
140
+ '/xp': { desc: L('XP/Seviye durumu', 'XP/level status'), run: ['xp'] },
141
+ '/skills': { desc: L('Yüklü beceri listesi', 'Installed skills'), run: ['skills', 'list'] },
142
+ '/status': { desc: L('Sistem durumu', 'System status'), run: ['status'] },
143
+ '/mcp': { desc: L('MCP sunucuları', 'MCP servers'), run: ['mcp', 'list'] },
144
+ '/channels': { desc: L('Bağlı kanallar', 'Connected channels'), run: ['channels'] },
145
+ '/crons': { desc: L('Zamanlanmış görevler', 'Scheduled tasks'), run: ['cron', 'list'] },
146
+ '/bots': { desc: L('Bot listesi', 'Bot list'), run: ['bots'] },
147
+ '/models': { desc: L('Modeller', 'Models'), run: ['models', 'list'] },
148
+ '/memory-ls': { desc: L('Hafıza dosyaları', 'Memory files'), run: ['memory', 'list'] },
149
+ '/seo': { desc: L('SEO denetimi (URL gerekli)', 'SEO audit (URL required)'), needsArg: true, run: ['seo', 'audit'] },
150
+ '/naturehub': { desc: L('Bota mesaj gönder (metin gerekli)', 'Send a message to a bot (text required)'), needsArg: true, run: ['naturehub', 'post'] },
151
+ '/dashboard': { desc: L('Web panelini başlat (port 7421)', 'Start web dashboard (port 7421)'), run: ['dashboard', 'start'] },
151
152
  };
152
153
 
153
154
  // Profil desteği: --profile <ad> ile ~/.natureco-<ad> kullanılır (config ile tutarlı)
@@ -174,7 +175,7 @@ const { isMiniMax, isGemini, buildChatEndpoint } = require('../utils/provider-de
174
175
 
175
176
  function loadMemory(username) {
176
177
  const uname = (username || 'default').toLowerCase();
177
- const base = { name: username || 'Kullanıcı', nickname: null, botName: null, facts: [], preferences: [], history: [] };
178
+ const base = { name: username || L('Kullanıcı', 'User'), nickname: null, botName: null, facts: [], preferences: [], history: [] };
178
179
  const readJson = (f) => { try { return fs.existsSync(f) ? JSON.parse(fs.readFileSync(f, 'utf8')) : null; } catch { return null; } };
179
180
 
180
181
  const userMem = readJson(path.join(MEMORY_DIR, `${uname}.json`));
@@ -201,7 +202,7 @@ function loadMemory(username) {
201
202
  }
202
203
  }
203
204
 
204
- if (!merged.botName) merged.botName = 'Asistan';
205
+ if (!merged.botName) merged.botName = L('Asistan', 'Assistant');
205
206
  return merged;
206
207
  }
207
208
 
@@ -241,7 +242,7 @@ function saveSession(messages, meta) {
241
242
  const idx = loadSessionsIndex();
242
243
  idx.sessions.unshift({
243
244
  id, file, createdAt: data.createdAt, messageCount: messages.length,
244
- firstUserMessage: messages.find(m => m.role === 'user')?.content?.slice(0, 60) || '(boş)',
245
+ firstUserMessage: messages.find(m => m.role === 'user')?.content?.slice(0, 60) || L('(boş)', '(empty)'),
245
246
  });
246
247
  // Son 50 session tut
247
248
  idx.sessions = idx.sessions.slice(0, 50);
@@ -732,7 +733,7 @@ async function sendStreaming(providerUrl, providerApiKey, messages, model, onChu
732
733
  // Fallback chain: try next model on error
733
734
  const fb = fallbackChain.recordError(body.model, err);
734
735
  if (fb.fallback) {
735
- console.log(tui.C.yellow(`\n ⚠ ${body.model} başarısız → ${fb.nextModel} deneniyor...\n`));
736
+ console.log(tui.C.yellow(`\n ⚠ ${body.model} ${L('başarısız', 'failed')} → ${fb.nextModel} ${L('deneniyor...', 'trying...')}\n`));
736
737
  continue; // Retry with next model
737
738
  }
738
739
  throw err;
@@ -757,12 +758,12 @@ async function sendStreaming(providerUrl, providerApiKey, messages, model, onChu
757
758
  // Plan mode review: plan submitted, wait for user approval
758
759
  if (planMode.inReview()) {
759
760
  const { plan } = planMode.planHistory[planMode.planHistory.length - 1] || {};
760
- console.log('\n' + tui.C.cyan(' 📋 Plan sunuldu — onay bekleniyor...'));
761
+ console.log('\n' + tui.C.cyan(L(' 📋 Plan sunuldu — onay bekleniyor...', ' 📋 Plan submitted — awaiting approval...')));
761
762
  console.log(tui.C.muted(' ' + '─'.repeat(56)));
762
763
  console.log(plan ? `\n ${plan.replace(/\n/g, '\n ')}` : '');
763
764
  console.log('\n' + tui.C.muted(' ─'.repeat(28)));
764
765
  const approved = await new Promise(resolve => {
765
- stdinPrompt(tui.C.yellow(' Planı onaylıyor musun? [Y=exec, n=reddet, e=düzenle]: '), answer => {
766
+ stdinPrompt(tui.C.yellow(L(' Planı onaylıyor musun? [Y=exec, n=reddet, e=düzenle]: ', ' Approve the plan? [Y=exec, n=reject, e=edit]: ')), answer => {
766
767
  const key = answer.trim().toLowerCase();
767
768
  if (key === 'n' || key === 'no') { planMode.reject(); resolve(false); }
768
769
  else if (key === 'e' || key === 'edit') { planMode.reject(); resolve('edit'); }
@@ -770,16 +771,16 @@ async function sendStreaming(providerUrl, providerApiKey, messages, model, onChu
770
771
  });
771
772
  });
772
773
  if (approved === true) {
773
- console.log(tui.C.green(' ✓ Plan onaylandı. Plan uygulanıyor...\n'));
774
+ console.log(tui.C.green(L(' ✓ Plan onaylandı. Plan uygulanıyor...\n', ' ✓ Plan approved. Applying...\n')));
774
775
  // Devam — model cevap versin
775
776
  } else if (approved === 'edit') {
776
- console.log(tui.C.yellow(' 📝 Planı düzenleyin ve /plan ile yeniden gönderin.\n'));
777
+ console.log(tui.C.yellow(L(' 📝 Planı düzenleyin ve /plan ile yeniden gönderin.\n', ' 📝 Edit the plan and resubmit with /plan.\n')));
777
778
  // Plan modunda kal, mesaj ekle
778
- currentMessages.push({ role: 'user', content: 'Planı düzenle ve yeniden sun.' });
779
+ currentMessages.push({ role: 'user', content: L('Planı düzenle ve yeniden sun.', 'Revise the plan and submit it again.') });
779
780
  continue;
780
781
  } else {
781
- console.log(tui.C.amber(' ⨯ Plan reddedildi. Yeniden plan yapılıyor...\n'));
782
- currentMessages.push({ role: 'user', content: 'Plan reddedildi. Lütfen farklı bir yaklaşım dene.' });
782
+ console.log(tui.C.amber(L(' ⨯ Plan reddedildi. Yeniden plan yapılıyor...\n', ' ⨯ Plan rejected. Re-planning...\n')));
783
+ currentMessages.push({ role: 'user', content: L('Plan reddedildi. Lütfen farklı bir yaklaşım dene.', 'The plan was rejected. Please try a different approach.') });
783
784
  continue;
784
785
  }
785
786
  }
@@ -813,7 +814,7 @@ const { getFallbackChain } = require('../utils/fallback-chain');
813
814
  * Returns: true (once), 'session', 'persistent', or false (denied).
814
815
  */
815
816
  async function askPermissionPrompt(question, hint, prompter) {
816
- const full = `${tui.C.yellow('⚠')} ${tui.C.bold('İzin gerekiyor')}: ${question}\n${tui.C.muted(hint)}`;
817
+ const full = `${tui.C.yellow('⚠')} ${tui.C.bold(L('İzin gerekiyor', 'Permission required'))}: ${question}\n${tui.C.muted(hint)}`;
817
818
  return new Promise(resolve => {
818
819
  prompter(full, answer => {
819
820
  const key = answer.trim();
@@ -835,8 +836,9 @@ async function processToolCalls(toolCalls, onToolCall, onAsk) {
835
836
  const results = [];
836
837
 
837
838
  // Parse all tool calls first
838
- const parsed = toolCalls.map(tc => {
839
- const name = tc.function?.name || tc.name;
839
+ const parsed = agentCore.parseToolCalls(toolCalls).map(call => {
840
+ const tc = call.original;
841
+ const name = tc.function?.name || tc.name;
840
842
  const argsStr = tc.function?.arguments || tc.args || '{}';
841
843
  const id = tc.id || `call_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;
842
844
  let args;
@@ -845,11 +847,11 @@ async function processToolCalls(toolCalls, onToolCall, onAsk) {
845
847
  } catch (e) {
846
848
  args = { _parse_error: e.message, _raw: argsStr };
847
849
  }
848
- return { name, args, id };
850
+ return { name, args, id, parseError: call.parseError };
849
851
  });
850
852
 
851
853
  // Filter out blocked tools via guardrails
852
- guardrails.startIteration();
854
+ agentCore.startIteration();
853
855
  const blocked = parsed.filter(p => {
854
856
  const check = guardrails.check(p.name, p.args);
855
857
  if (check.blocked) {
@@ -1005,22 +1007,22 @@ async function processToolCalls(toolCalls, onToolCall, onAsk) {
1005
1007
  }
1006
1008
 
1007
1009
  function printHelp() {
1008
- console.log(chalk.cyan('\n 📚 REPL Komutları:\n'));
1009
- console.log(' ' + chalk.yellow('/help'.padEnd(22)) + chalk.gray('Bu yardım'));
1010
- console.log(' ' + chalk.yellow('/clear'.padEnd(22)) + chalk.gray('Ekranı temizle'));
1011
- console.log(' ' + chalk.yellow('/history'.padEnd(22)) + chalk.gray('Bu oturumun geçmişi'));
1012
- console.log(' ' + chalk.yellow('/memory'.padEnd(22)) + chalk.gray('Memory\'i göster'));
1013
- console.log(' ' + chalk.yellow('/plan [on|off|show]'.padEnd(22)) + chalk.gray('Plan modu'));
1014
- console.log(' ' + chalk.yellow('/forget'.padEnd(22)) + chalk.gray('Memory\'i temizle'));
1015
- console.log(' ' + chalk.yellow('/sessions'.padEnd(22)) + chalk.gray('Geçmiş oturumları listele'));
1016
- console.log(' ' + chalk.yellow('/resume [id|last]'.padEnd(22)) + chalk.gray('Önceki oturuma dön'));
1017
- console.log(' ' + chalk.yellow('/system <text>'.padEnd(22)) + chalk.gray('System prompt değiştir'));
1018
- console.log(' ' + chalk.yellow('/model <name>'.padEnd(22)) + chalk.gray('Model değiştir'));
1019
- console.log(' ' + chalk.yellow('/identity [ad]'.padEnd(22)) + chalk.gray('Bot adını değiştir'));
1020
- console.log(' ' + chalk.yellow('/tokens'.padEnd(22)) + chalk.gray('Token kullanımı'));
1021
- console.log(' ' + chalk.yellow('/save'.padEnd(22)) + chalk.gray('Oturumu manuel kaydet'));
1022
- console.log(' ' + chalk.yellow('/exit veya /quit'.padEnd(22)) + chalk.gray('Çıkış (Ctrl+C de çalışır)'));
1023
- console.log(chalk.cyan('\n 🛠️ Tüm CLI Komutları (REPL içinden):\n'));
1010
+ console.log(chalk.cyan(L('\n 📚 REPL Komutları:\n', '\n 📚 REPL Commands:\n')));
1011
+ console.log(' ' + chalk.yellow('/help'.padEnd(22)) + chalk.gray(L('Bu yardım', 'This help')));
1012
+ console.log(' ' + chalk.yellow('/clear'.padEnd(22)) + chalk.gray(L('Ekranı temizle', 'Clear the screen')));
1013
+ console.log(' ' + chalk.yellow('/history'.padEnd(22)) + chalk.gray(L('Bu oturumun geçmişi', 'This session\'s history')));
1014
+ console.log(' ' + chalk.yellow('/memory'.padEnd(22)) + chalk.gray(L('Hafızayı göster', 'Show memory')));
1015
+ console.log(' ' + chalk.yellow('/plan [on|off|show]'.padEnd(22)) + chalk.gray(L('Plan modu', 'Plan mode')));
1016
+ console.log(' ' + chalk.yellow('/forget'.padEnd(22)) + chalk.gray(L('Hafızayı temizle', 'Clear memory')));
1017
+ console.log(' ' + chalk.yellow('/sessions'.padEnd(22)) + chalk.gray(L('Geçmiş oturumları listele', 'List past sessions')));
1018
+ console.log(' ' + chalk.yellow('/resume [id|last]'.padEnd(22)) + chalk.gray(L('Önceki oturuma dön', 'Return to a previous session')));
1019
+ console.log(' ' + chalk.yellow('/system <text>'.padEnd(22)) + chalk.gray(L('System prompt değiştir', 'Change system prompt')));
1020
+ console.log(' ' + chalk.yellow('/model <name>'.padEnd(22)) + chalk.gray(L('Model değiştir', 'Change model')));
1021
+ console.log(' ' + chalk.yellow('/identity [ad]'.padEnd(22)) + chalk.gray(L('Bot adını değiştir', 'Change bot name')));
1022
+ console.log(' ' + chalk.yellow('/tokens'.padEnd(22)) + chalk.gray(L('Token kullanımı', 'Token usage')));
1023
+ console.log(' ' + chalk.yellow('/save'.padEnd(22)) + chalk.gray(L('Oturumu elle kaydet', 'Save session manually')));
1024
+ console.log(' ' + chalk.yellow(L('/exit veya /quit', '/exit or /quit').padEnd(22)) + chalk.gray(L('Çıkış (Ctrl+C de çalışır)', 'Exit (Ctrl+C also works)')));
1025
+ console.log(chalk.cyan(L('\n 🛠️ Tüm CLI Komutları (REPL içinden):\n', '\n 🛠️ All CLI Commands (from REPL):\n')));
1024
1026
  for (const [cmd, info] of Object.entries(CLI_COMMANDS)) {
1025
1027
  console.log(' ' + chalk.yellow(cmd.padEnd(22)) + chalk.gray(info.desc));
1026
1028
  }
@@ -1053,7 +1055,7 @@ async function startRepl(args) {
1053
1055
  }
1054
1056
 
1055
1057
  if (!providerUrl || !providerApiKey) {
1056
- console.log(chalk.red('\n ❌ Provider ayarlı değil. Önce: natureco setup\n'));
1058
+ console.log(chalk.red(L('\n ❌ Provider ayarlı değil. Önce: natureco setup\n', '\n ❌ Provider not configured. First: natureco setup\n')));
1057
1059
  process.exit(1);
1058
1060
  }
1059
1061
 
@@ -1062,7 +1064,7 @@ async function startRepl(args) {
1062
1064
 
1063
1065
  // v5.6.19: Oncelik config.botName, sonra memory.botName
1064
1066
  if (!memory.botName) {
1065
- memory.botName = cfg.botName || 'Asistan';
1067
+ memory.botName = cfg.botName || L('Asistan', 'Assistant');
1066
1068
  }
1067
1069
  // BotName'i memory'ye persist et (her oturumda ayni kalsin)
1068
1070
  try {
@@ -1117,7 +1119,7 @@ async function startRepl(args) {
1117
1119
  const session = loadSession(resumeId);
1118
1120
  if (session) {
1119
1121
  messages = session.messages || [];
1120
- console.log(chalk.green(`\n ✓ Oturum yüklendi: ${session.id} (${messages.length} mesaj)\n`));
1122
+ console.log(chalk.green(`\n ✓ ${L('Oturum yüklendi', 'Session loaded')}: ${session.id} (${messages.length} ${L('mesaj', 'messages')})\n`));
1121
1123
  } else {
1122
1124
  console.log(chalk.yellow(`\n ⚠️ ${L('Oturum bulunamadı', 'Session not found')}: ${resumeId}\n`));
1123
1125
  }
@@ -1125,7 +1127,7 @@ async function startRepl(args) {
1125
1127
 
1126
1128
  // System prompt oluştur (memory + identity + persistent bağlam)
1127
1129
  // v5.6.5: Kucuk model tespiti (Groq, Mistral Small, Ollama) - SOUL injection skip
1128
- const botName = memory.botName || 'Asistan';
1130
+ const botName = memory.botName || L('Asistan', 'Assistant');
1129
1131
  const userName = memory.name || memory.nickname || cfg.userName;
1130
1132
  const isSmallModel = (cfg.providerUrl || '').includes('groq.com') ||
1131
1133
  (cfg.providerUrl || '').includes('mistral.ai') ||
@@ -1134,7 +1136,7 @@ async function startRepl(args) {
1134
1136
  // Discover project rules (CLAUDE.md)
1135
1137
  const projectRules = discoverProjectRules(process.cwd());
1136
1138
  if (projectRules) {
1137
- console.log(chalk.cyan(` 📋 Proje kurallari bulundu (CLAUDE.md)\n`));
1139
+ console.log(chalk.cyan(` 📋 ${L('Proje kurallari bulundu', 'Project rules found')} (CLAUDE.md)\n`));
1138
1140
  }
1139
1141
 
1140
1142
  // Build system prompt with tier caching (stable+context cached, volatile fresh)
@@ -1161,20 +1163,20 @@ async function startRepl(args) {
1161
1163
 
1162
1164
  // Header
1163
1165
  console.log('');
1164
- console.log(tui.styled(' 🌿 NatureCo REPL · Persistent Sohbet', { color: tui.PALETTE.primary, bold: true }));
1166
+ console.log(tui.styled(L(' 🌿 NatureCo REPL · Persistent Sohbet', ' 🌿 NatureCo REPL · Persistent Chat'), { color: tui.PALETTE.primary, bold: true }));
1165
1167
  console.log(tui.styled(' ' + '─'.repeat(56), { color: tui.PALETTE.border }));
1166
1168
  console.log(tui.C.muted(' Provider: ') + tui.C.brand(providerUrl.replace(/https?:\/\//, '')));
1167
1169
  console.log(tui.C.muted(' Model: ') + tui.C.brand(model));
1168
- const displayUser = memory.nickname || cfg.userName || require('os').userInfo().username || 'Kullanıcı';
1169
- console.log(tui.C.muted(' Kullanıcı: ') + tui.C.brand(displayUser + (memory.nickname && cfg.userName ? ` (${cfg.userName})` : '')));
1170
- console.log(tui.C.muted(' Bot: ') + tui.C.brand(memory.botName || 'Asistan'));
1171
- if (messages.length > 1) {
1172
- console.log(tui.C.muted(' Oturum: ') + tui.C.amber(`${messages.filter(m => m.role === 'user' || m.role === 'assistant').length} mesaj (resume)`));
1173
- }
1174
- console.log(tui.C.muted(' Komutlar: ') + tui.C.yellow('/help') + tui.C.muted(' · ') + tui.C.yellow('/memory') + tui.C.muted(' · ') + tui.C.yellow('/sessions') + tui.C.muted(' · ') + tui.C.yellow('/exit'));
1170
+ const displayUser = memory.nickname || cfg.userName || require('os').userInfo().username || L('Kullanıcı', 'User');
1171
+ console.log(tui.C.muted(L(' Kullanıcı: ', ' User: ')) + tui.C.brand(displayUser + (memory.nickname && cfg.userName ? ` (${cfg.userName})` : '')));
1172
+ console.log(tui.C.muted(' Bot: ') + tui.C.brand(memory.botName || L('Asistan', 'Assistant')));
1173
+ if (messages.length > 1) {
1174
+ console.log(tui.C.muted(L(' Oturum: ', ' Session: ')) + tui.C.amber(`${messages.filter(m => m.role === 'user' || m.role === 'assistant').length} ${L('mesaj', 'messages')} (${L('devam', 'resumed')})`));
1175
+ }
1176
+ console.log(tui.C.muted(L(' Komutlar: ', ' Commands: ')) + tui.C.yellow('/help') + tui.C.muted(' · ') + tui.C.yellow('/memory') + tui.C.muted(' · ') + tui.C.yellow('/sessions') + tui.C.muted(' · ') + tui.C.yellow('/exit'));
1175
1177
  console.log('');
1176
1178
  // v5.4.7: Hard-coded kimlik — v5.14.5: memory fact'lerinden kullanici adini tespit et
1177
- const displayBotName = memory.botName || 'Asistan';
1179
+ const displayBotName = memory.botName || L('Asistan', 'Assistant');
1178
1180
  const nameFromFact = (() => {
1179
1181
  const facts = memory.facts || [];
1180
1182
  for (const f of facts) {
@@ -1186,7 +1188,7 @@ async function startRepl(args) {
1186
1188
  return null;
1187
1189
  })();
1188
1190
  const displayUserName = memory.name || nameFromFact || memory.nickname || cfg.userName;
1189
- console.log(tui.C.brand(' 👋 Ben ' + displayBotName + ', ' + displayUserName + '. Sen nasilsin?'));
1191
+ console.log(tui.C.brand(L(` 👋 Ben ${displayBotName}, ${displayUserName}. Sen nasılsın?`, ` 👋 I am ${displayBotName}, ${displayUserName}. How are you?`)));
1190
1192
  console.log('');
1191
1193
 
1192
1194
  // Theseus deseni: oturum basinda "geçen sefer kalanlari" proaktif hatirlat
@@ -1194,7 +1196,7 @@ async function startRepl(args) {
1194
1196
  try {
1195
1197
  const pending = require('../tools/memory_tree')._internal.getPending(cfg.userName);
1196
1198
  if (pending && pending.length) {
1197
- console.log(tui.C.muted(' 📌 Geçen oturumdan kalanlar:'));
1199
+ console.log(tui.C.muted(L(' 📌 Geçen oturumdan kalanlar:', ' 📌 Left over from last session:')));
1198
1200
  for (const item of pending.slice(0, 6)) console.log(tui.C.muted(' • ' + item));
1199
1201
  console.log('');
1200
1202
  }
@@ -1217,7 +1219,7 @@ async function startRepl(args) {
1217
1219
  const rl = readline.createInterface({
1218
1220
  input: createPasteSafeInput(process.stdin),
1219
1221
  output: createOutputFilter(process.stdout),
1220
- prompt: tui.styled(' 💬 Sen ▸ ', { color: tui.PALETTE.primary, bold: true }),
1222
+ prompt: tui.styled(L(' 💬 Sen ▸ ', ' 💬 You ▸ '), { color: tui.PALETTE.primary, bold: true }),
1221
1223
  terminal: true,
1222
1224
  });
1223
1225
  // Pipe/script kullanımında EOF, yanıt hâlâ üretilirken gelir —
@@ -1239,10 +1241,10 @@ async function startRepl(args) {
1239
1241
  // Bu, Parton'un "oturum sonunda konusmalar kaydedilmiyor" sikayetini cözüyor
1240
1242
  const persistResult = await persistSessionToMemory(messages, memory, cfg);
1241
1243
  if (persistResult && persistResult.factsAdded > 0) {
1242
- console.log(chalk.gray(`\n 🧠 ${persistResult.factsAdded} yeni fact memory'ye kaydedildi`));
1244
+ console.log(chalk.gray(`\n 🧠 ${persistResult.factsAdded} ${L("yeni fact memory'ye kaydedildi", 'new facts saved to memory')}`));
1243
1245
  }
1244
1246
  if (persistResult && persistResult.preferencesAdded > 0) {
1245
- console.log(chalk.gray(` 🎯 ${persistResult.preferencesAdded} yeni tercih kaydedildi`));
1247
+ console.log(chalk.gray(` 🎯 ${persistResult.preferencesAdded} ${L('yeni tercih kaydedildi', 'new preferences saved')}`));
1246
1248
  }
1247
1249
 
1248
1250
  // v5.46: oturum-sonu hafıza-sağlığı ipucu (gürültüsüz). Yinelenen/çelişen kayıt varsa
@@ -1252,19 +1254,19 @@ async function startRepl(args) {
1252
1254
  const { lintUser } = require('../utils/memory-lint');
1253
1255
  const { flatFindings, treeFindings } = lintUser(cfg.userName);
1254
1256
  const n = (flatFindings.length + treeFindings.length);
1255
- if (n > 0) console.log(chalk.gray(` 💡 Hafızada ${n} olası yinelenen/çelişen kayıt — "natureco memory lint" ile gözden geçir.`));
1257
+ if (n > 0) console.log(chalk.gray(` 💡 ${L('Hafızada', 'In memory')} ${n} ${L('olası yinelenen/çelişen kayıt —', 'possible duplicate/conflicting records —')} "natureco memory lint" ${L('ile gözden geçir.', 'to review.')}`));
1256
1258
  } catch {}
1257
1259
 
1258
1260
  const sessId = saveSession(messages, {
1259
1261
  provider: providerUrl, model, user: cfg.userName,
1260
1262
  bot: memory.botName, factCount: memory.facts?.length || 0,
1261
1263
  });
1262
- console.log(chalk.gray(`\n 💾 Oturum kaydedildi: ${sessId}`));
1264
+ console.log(chalk.gray(`\n 💾 ${L('Oturum kaydedildi', 'Session saved')}: ${sessId}`));
1263
1265
  }
1264
1266
  // Global buffer temizle
1265
1267
  if (global._fixBuffer) global._fixBuffer = '';
1266
1268
  disableBracketedPaste(process.stdout);
1267
- console.log(chalk.gray('\n 👋 Görüşürüz!\n'));
1269
+ console.log(chalk.gray(L('\n 👋 Görüşürüz!\n', '\n 👋 See you!\n')));
1268
1270
  process.exit(exitCode);
1269
1271
  };
1270
1272
 
@@ -1392,7 +1394,7 @@ async function startRepl(args) {
1392
1394
  case 'clear': console.clear(); break;
1393
1395
  case 'exit': case 'quit': case 'q': await cleanup(0); return;
1394
1396
  case 'history':
1395
- console.log(chalk.cyan('\n 📜 Bu oturumun geçmişi:\n'));
1397
+ console.log(chalk.cyan(L('\n 📜 Bu oturumun geçmişi:\n', '\n 📜 This session\'s history:\n')));
1396
1398
  for (const m of messages.filter(m => !m._internal)) {
1397
1399
  const role = m.role === 'user' ? chalk.green('You') : chalk.blue('AI ');
1398
1400
  const content = (m.content || '').slice(0, 120) + ((m.content || '').length > 120 ? '...' : '');
@@ -1402,16 +1404,16 @@ async function startRepl(args) {
1402
1404
  break;
1403
1405
  case 'memory':
1404
1406
  console.log(chalk.cyan('\n 🧠 Memory:\n'));
1405
- console.log(' Kullanıcı: ' + chalk.cyan(memory.name));
1406
- console.log(' Nickname: ' + chalk.cyan(memory.nickname || '(yok)'));
1407
- console.log(' Bot: ' + chalk.cyan(memory.botName || 'Asistan'));
1407
+ console.log(L(' Kullanıcı: ', ' User: ') + chalk.cyan(memory.name));
1408
+ console.log(L(' Takma ad: ', ' Nickname: ') + chalk.cyan(memory.nickname || L('(yok)', '(none)')));
1409
+ console.log(' Bot: ' + chalk.cyan(memory.botName || L('Asistan', 'Assistant')));
1408
1410
  if (memory.facts && memory.facts.length > 0) {
1409
1411
  console.log(' Facts (' + memory.facts.length + '):');
1410
1412
  for (const f of memory.facts) {
1411
- console.log(' • ' + chalk.gray((f.value || f) + (f.score ? ' [skor:' + f.score + ']' : '')));
1413
+ console.log(' • ' + chalk.gray((f.value || f) + (f.score ? ` [${L('skor', 'score')}:${f.score}]` : '')));
1412
1414
  }
1413
1415
  } else {
1414
- console.log(chalk.gray(' (Henüz fact yok)'));
1416
+ console.log(chalk.gray(L(' (Henüz fact yok)', ' (No facts yet)')));
1415
1417
  }
1416
1418
  console.log('');
1417
1419
  break;
@@ -1420,26 +1422,26 @@ async function startRepl(args) {
1420
1422
  if (fs.existsSync(path.join(MEMORY_DIR, `${(cfg.userName || 'default').toLowerCase()}.json`))) {
1421
1423
  fs.unlinkSync(path.join(MEMORY_DIR, `${(cfg.userName || 'default').toLowerCase()}.json`));
1422
1424
  }
1423
- memory = { name: cfg.userName, nickname: null, botName: 'Asistan', facts: [], preferences: [], history: [] };
1425
+ memory = { name: cfg.userName, nickname: null, botName: L('Asistan', 'Assistant'), facts: [], preferences: [], history: [] };
1424
1426
  // System prompt'u rebuild with cleared memory
1425
1427
  promptOpts.memoryFacts = [];
1426
1428
  memoryStore.clear();
1427
1429
  promptOpts.memorySnapshotBlock = memoryStore.getSystemPromptBlock();
1428
1430
  systemPrompt = rebuildSystemPrompt(promptOpts);
1429
1431
  messages[0] = { role: 'system', content: systemPrompt, _internal: true };
1430
- console.log(chalk.green(' ✓ Memory temizlendi'));
1432
+ console.log(chalk.green(L(' ✓ Memory temizlendi', ' ✓ Memory cleared')));
1431
1433
  } catch (e) {
1432
1434
  console.log(chalk.red(' ❌ ' + e.message));
1433
1435
  }
1434
1436
  break;
1435
1437
  case 'sessions':
1436
1438
  const idx = loadSessionsIndex();
1437
- console.log(chalk.cyan('\n 📚 Geçmiş Oturumlar (' + idx.sessions.length + ')\n'));
1439
+ console.log(chalk.cyan(L('\n 📚 Geçmiş Oturumlar (', '\n 📚 Past Sessions (') + idx.sessions.length + ')\n'));
1438
1440
  for (let i = 0; i < Math.min(10, idx.sessions.length); i++) {
1439
1441
  const s = idx.sessions[i];
1440
1442
  console.log(` ${chalk.gray((i + 1).toString().padStart(2) + '.')} ${chalk.cyan(s.id)} ${chalk.muted('— ' + s.firstUserMessage)}`);
1441
1443
  }
1442
- console.log(chalk.gray('\n Devam etmek için: /resume <id> veya /resume last\n'));
1444
+ console.log(chalk.gray(L('\n Devam etmek için: /resume <id> veya /resume last\n', '\n To continue: /resume <id> or /resume last\n')));
1443
1445
  break;
1444
1446
  case 'resume':
1445
1447
  if (!arg) { console.log(chalk.yellow(L(' Kullanım: /resume <id> veya /resume last', ' Usage: /resume <id> or /resume last'))); break; }
@@ -1449,7 +1451,7 @@ async function startRepl(args) {
1449
1451
  const sysIdx = messages.findIndex(m => m._internal);
1450
1452
  if (sysIdx >= 0) messages[sysIdx] = { role: 'system', content: systemPrompt, _internal: true };
1451
1453
  else messages.unshift({ role: 'system', content: systemPrompt, _internal: true });
1452
- console.log(chalk.green(` ✓ Oturum yüklendi: ${session.id} (${messages.length} mesaj)`));
1454
+ console.log(chalk.green(` ✓ ${L('Oturum yüklendi', 'Session loaded')}: ${session.id} (${messages.length} ${L('mesaj', 'messages')})`));
1453
1455
  } else {
1454
1456
  console.log(chalk.yellow(` ⚠️ ${L('Oturum bulunamadı', 'Session not found')}: ${arg}`));
1455
1457
  }
@@ -1466,7 +1468,7 @@ async function startRepl(args) {
1466
1468
  const volTiers = buildTiers(volOpts);
1467
1469
  systemPrompt = assemble(_cachedStable, _cachedContext, volTiers.volatile);
1468
1470
  messages[0] = { role: 'system', content: systemPrompt, _internal: true };
1469
- console.log(chalk.green(' ✓ System prompt güncellendi'));
1471
+ console.log(chalk.green(L(' ✓ System prompt güncellendi', ' ✓ System prompt updated')));
1470
1472
  break;
1471
1473
  case 'model':
1472
1474
  if (!arg) { console.log(chalk.yellow(L(' Kullanım: /model <name>', ' Usage: /model <name>'))); break; }
@@ -1474,7 +1476,7 @@ async function startRepl(args) {
1474
1476
  console.log(chalk.green(' ✓ Model: ') + chalk.cyan(model));
1475
1477
  break;
1476
1478
  case 'identity':
1477
- if (!arg) { console.log(chalk.yellow(` Mevcut: ${memory.botName || 'Asistan'}`)); break; }
1479
+ if (!arg) { console.log(chalk.yellow(` ${L('Mevcut', 'Current')}: ${memory.botName || L('Asistan', 'Assistant')}`)); break; }
1478
1480
  memory.botName = arg;
1479
1481
  saveMemory(cfg.userName, memory);
1480
1482
  // Rebuild stable tier with new botName
@@ -1485,29 +1487,29 @@ async function startRepl(args) {
1485
1487
  promptOpts.memoryFacts = memory.facts || [];
1486
1488
  systemPrompt = rebuildSystemPrompt(promptOpts);
1487
1489
  messages[0] = { role: 'system', content: systemPrompt, _internal: true };
1488
- console.log(chalk.green(' ✓ Bot adı: ') + chalk.cyan(arg));
1490
+ console.log(chalk.green(L(' ✓ Bot adı: ', ' ✓ Bot name: ')) + chalk.cyan(arg));
1489
1491
  break;
1490
1492
  case 'tokens':
1491
1493
  console.log(chalk.gray(` Token: ~${totalInputTokens} in / ~${totalOutputTokens} out`));
1492
1494
  break;
1493
1495
  case 'plan':
1494
1496
  if (arg === 'on' || arg === 'enter') {
1495
- if (getPlanMode().enter()) console.log(tui.C.cyan('\n 📋 Plan modu aktif. Plan yapın ve /plan off ile çıkın.\n'));
1496
- else console.log(tui.C.yellow(' Zaten plan modunda.'));
1497
+ if (getPlanMode().enter()) console.log(tui.C.cyan(L('\n 📋 Plan modu aktif. Plan yapın ve /plan off ile çıkın.\n', '\n 📋 Plan mode active. Plan and exit with /plan off.\n')));
1498
+ else console.log(tui.C.yellow(L(' Zaten plan modunda.', ' Already in plan mode.')));
1497
1499
  } else if (arg === 'off' || arg === 'exit') {
1498
1500
  if (getPlanMode().isPlanning()) {
1499
- console.log(tui.C.yellow(' Plan modundan çıkılıyor. Plan yazılıp ExitPlanMode ile sunulmalı.'));
1501
+ console.log(tui.C.yellow(L(' Plan modundan çıkılıyor. Plan yazılıp ExitPlanMode ile sunulmalı.', ' Exiting plan mode. Write a plan and submit with ExitPlanMode.')));
1500
1502
  getPlanMode().approve();
1501
1503
  } else {
1502
- console.log(tui.C.yellow(' Plan modunda değil.'));
1504
+ console.log(tui.C.yellow(L(' Plan modunda değil.', ' Not in plan mode.')));
1503
1505
  }
1504
1506
  } else if (arg === 'show') {
1505
1507
  if (getPlanMode().planHistory.length > 0) {
1506
1508
  const last = getPlanMode().planHistory[getPlanMode().planHistory.length - 1];
1507
- console.log(tui.C.cyan('\n 📋 Son Plan:\n'));
1509
+ console.log(tui.C.cyan(L('\n 📋 Son Plan:\n', '\n 📋 Last Plan:\n')));
1508
1510
  console.log(` ${last.plan.replace(/\n/g, '\n ')}`);
1509
1511
  } else {
1510
- console.log(tui.C.yellow(' Henüz plan yok.'));
1512
+ console.log(tui.C.yellow(L(' Henüz plan yok.', ' No plan yet.')));
1511
1513
  }
1512
1514
  } else {
1513
1515
  console.log(tui.C.yellow(L(' Kullanım: /plan on|off|show', ' Usage: /plan on|off|show')));
@@ -1517,16 +1519,16 @@ async function startRepl(args) {
1517
1519
  const sessId = saveSession(messages, {
1518
1520
  provider: providerUrl, model, user: cfg.userName, bot: memory.botName,
1519
1521
  });
1520
- console.log(chalk.green(' ✓ Kaydedildi: ') + chalk.cyan(sessId));
1522
+ console.log(chalk.green(L(' ✓ Kaydedildi: ', ' ✓ Saved: ')) + chalk.cyan(sessId));
1521
1523
  break;
1522
1524
  default:
1523
1525
  // CLI komutları (REPL içinden)
1524
1526
  if (CLI_COMMANDS['/' + cmd]) {
1525
1527
  const cliCmd = CLI_COMMANDS['/' + cmd];
1526
1528
  if (cliCmd.needsArg && !arg) {
1527
- console.log(chalk.yellow(` ${cmd} bir argüman gerekli: ${cliCmd.desc}`));
1529
+ console.log(chalk.yellow(` ${cmd} ${L('bir argüman gerekli', 'requires an argument')}: ${cliCmd.desc}`));
1528
1530
  } else {
1529
- console.log(chalk.gray(` → ${cmd} çalıştırılıyor...`));
1531
+ console.log(chalk.gray(` → ${cmd} ${L('çalıştırılıyor...', 'running...')}`));
1530
1532
  const args2 = [...cliCmd.run];
1531
1533
  if (arg && (cmd === 'seo' || cmd === 'naturehub')) args2.push(arg);
1532
1534
  await runCliCommand(args2);
@@ -1544,19 +1546,19 @@ async function startRepl(args) {
1544
1546
 
1545
1547
  // Çok satırlı (paste) mesajları gönderildikten sonra ekranda göster
1546
1548
  if (line.indexOf('\n') !== -1) {
1547
- process.stdout.write(tui.styled(' 💬 Sen ▸ ', { color: tui.PALETTE.primary, bold: true }));
1549
+ process.stdout.write(tui.styled(L(' 💬 Sen ▸ ', ' 💬 You ▸ '), { color: tui.PALETTE.primary, bold: true }));
1548
1550
  process.stdout.write(line + '\n');
1549
1551
  }
1550
1552
 
1551
1553
  // v5.6.8: Hard-coded fallback - "sen kimsin?" sorulari icin dinamik botName
1552
1554
  const trimmed = (line || '').toLowerCase();
1553
- const isIdentityQuestion = /(sen\s+kim|adin\s+ne|kendini\s+tan|kendin\s+tanit|kimsin|ne\s+adindasin)/.test(trimmed);
1555
+ const isIdentityQuestion = /(sen\s+kim|adin\s+ne|kendini\s+tan|kendin\s+tanit|kimsin|ne\s+adindasin|who\s+are\s+you|what(?:'s|\s+is)\s+your\s+name|introduce\s+yourself)/.test(trimmed);
1554
1556
  if (isIdentityQuestion) {
1555
1557
  // v5.6.10: Hard-coded prefix minimal - model cevabini bozuyordu
1556
1558
  // Once sadece isim yaz, modelin devamini getirsin
1557
- const displayName = memory.botName || 'Asistan';
1559
+ const displayName = memory.botName || L('Asistan', 'Assistant');
1558
1560
  process.stdout.write(tui.styled('\n AI ', { color: tui.PALETTE.secondary, bold: true }));
1559
- process.stdout.write('Merhaba! Ben ' + displayName + '. ');
1561
+ process.stdout.write(L('Merhaba! Ben ', 'Hello! I am ') + displayName + '. ');
1560
1562
  }
1561
1563
 
1562
1564
  // AI cevabı — v5.13.0: workflow orchestrator ALWAYS first
@@ -1591,7 +1593,7 @@ async function startRepl(args) {
1591
1593
  if (wf.passthrough && wf.reply !== undefined && wf.reply !== null) {
1592
1594
  // Simple chat — workflow handled it directly
1593
1595
  const fullReply = String(wf.reply);
1594
- const displayBotName = memory.botName || 'Asistan';
1596
+ const displayBotName = memory.botName || L('Asistan', 'Assistant');
1595
1597
  let fixedReply = String(fullReply);
1596
1598
  fixedReply = fixedReply.replace(/\bMiniMax[-\s\w\.\d]*/gi, displayBotName);
1597
1599
  fixedReply = fixedReply.replace(/\bM2\.5[-\s\w\.\d]*/gi, displayBotName);
@@ -1623,13 +1625,16 @@ async function startRepl(args) {
1623
1625
  }
1624
1626
  return ` ${s} ${t}: ${summary}`;
1625
1627
  }).join('\n');
1626
- const skillInfo = wf.skillsLoaded && wf.skillsLoaded.length > 0
1627
- ? `\n\nKullanilan skill'ler: ${wf.skillsLoaded.join(', ')}`
1628
- : '';
1628
+ const skillInfo = wf.skillsLoaded && wf.skillsLoaded.length > 0
1629
+ ? `\n\n${L('Kullanılan beceriler', 'Skills used')}: ${wf.skillsLoaded.join(', ')}`
1630
+ : '';
1629
1631
  const preWfLen = messages.length;
1630
1632
  messages.push({
1631
1633
  role: 'system',
1632
- content: `=== WORKFLOW SONUCLARI ===\nSu araclar calisti:\n${report}${skillInfo}\n\nKullaniciya bu sonuclari anlamli bir sekilde ozetle.\n=== SONUC BITTI ===`,
1634
+ content: L(
1635
+ `=== İŞ AKIŞI SONUÇLARI ===\nŞu araçlar çalıştı:\n${report}${skillInfo}\n\nBu sonuçları kullanıcı için anlamlı biçimde özetle.\n=== SONUÇ BİTTİ ===`,
1636
+ `=== WORKFLOW RESULTS ===\nThe following tools ran:\n${report}${skillInfo}\n\nSummarize these results clearly for the user.\n=== END RESULTS ===`,
1637
+ ),
1633
1638
  });
1634
1639
  const reply = await sendStreaming(
1635
1640
  providerUrl,
@@ -1657,7 +1662,7 @@ async function startRepl(args) {
1657
1662
  // v5.6.12: Tam metin 'reply' olarak zaten geldi (non-stream mode)
1658
1663
  const fullReply = String(reply || '');
1659
1664
  // Bot adini al
1660
- const displayBotName = memory.botName || 'Asistan';
1665
+ const displayBotName = memory.botName || L('Asistan', 'Assistant');
1661
1666
  // v5.6.9: Tum model adlarini ve varyasyonlari temizle
1662
1667
  let fixedReply = String(fullReply);
1663
1668
  fixedReply = fixedReply.replace(/\bMiniMax[-\s\w\.\d]*/gi, displayBotName);
@@ -1678,8 +1683,8 @@ async function startRepl(args) {
1678
1683
  totalOutputTokens += Math.ceil((fullReply || '').length / 4);
1679
1684
  } else {
1680
1685
  // Workflow failed or returned unexpected format
1681
- const fullReply = wf.error || JSON.stringify(wf).slice(0, 400) || 'Workflow islenemedi.';
1682
- const displayBotName = memory.botName || 'Asistan';
1686
+ const fullReply = wf.error || JSON.stringify(wf).slice(0, 400) || L('İş akışı işlenemedi.', 'Workflow could not be processed.');
1687
+ const displayBotName = memory.botName || L('Asistan', 'Assistant');
1683
1688
  let fixedReply = fullReply.replace(/\bMiniMax[-\s\w\.\d]*/gi, displayBotName);
1684
1689
  process.stdout.write('\n' + fixedReply + '\n');
1685
1690
  messages.push({ role: 'assistant', content: fixedReply });
@@ -1704,6 +1709,7 @@ async function startRepl(args) {
1704
1709
  });
1705
1710
  }
1706
1711
 
1707
- module.exports = startRepl;
1708
- // v5.40: test icin — cross-session hafiza bozulma regresyonu (kod adı ≠ kullanici adi)
1709
- module.exports.extractPreferenceFacts = extractPreferenceFacts;
1712
+ module.exports = startRepl;
1713
+ // v5.40: test icin — cross-session hafiza bozulma regresyonu (kod adı ≠ kullanici adi)
1714
+ module.exports.extractPreferenceFacts = extractPreferenceFacts;
1715
+ module.exports._internal = { printHelp, CLI_COMMANDS };