natureco-cli 2.14.10 → 2.15.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "natureco-cli",
3
- "version": "2.14.10",
3
+ "version": "2.15.1",
4
4
  "description": "NatureCo AI Bot Terminal Interface",
5
5
  "main": "bin/natureco.js",
6
6
  "bin": {
@@ -211,7 +211,7 @@ body::before{
211
211
  <div class="header-bot-name" id="header-bot-name">Nature Bot</div>
212
212
  <div class="header-bot-model" id="header-bot-model">NatureCo</div>
213
213
  </div>
214
- <div class="version-badge" id="version-badge">v2.14.10</div>
214
+ <div class="version-badge" id="version-badge">v2.15.1</div>
215
215
  </div>
216
216
  <div class="messages" id="messages"></div>
217
217
  <div class="input-area">
@@ -341,7 +341,7 @@ function dashboard(action) {
341
341
  apiKey: cfg.apiKey,
342
342
  defaultBot: cfg.defaultBot,
343
343
  defaultBotId: cfg.defaultBotId,
344
- version: 'v2.14.10',
344
+ version: 'v2.15.1',
345
345
  bots: cfg.bots || [],
346
346
  telegramToken: cfg.telegramToken || null,
347
347
  whatsappConnected: cfg.whatsappConnected || false,
@@ -1,221 +1,493 @@
1
1
  const chalk = require('chalk');
2
- const boxen = require('boxen');
3
2
  const inquirer = require('inquirer');
4
3
  const fs = require('fs');
4
+ const path = require('path');
5
+ const os = require('os');
5
6
  const { saveConfig, CONFIG_DIR, CONFIG_FILE } = require('../utils/config');
7
+ const { saveMemory } = require('../utils/memory');
6
8
 
7
- async function setup() {
8
- // Kurulum ekranı
9
- const welcomeBox = boxen(
10
- chalk.green.bold('🌿 NatureCo Terminal\n') +
11
- chalk.green.bold(' İlk Kurulum v2.x\n'),
12
- {
13
- padding: 1,
14
- margin: 1,
15
- borderStyle: 'round',
16
- borderColor: 'green',
17
- align: 'center',
18
- }
19
- );
9
+ // ─── Dil metinleri ────────────────────────────────────────────────────────────
10
+ const LANG = {
11
+ tr: {
12
+ welcome: '🌿 NatureCo CLI — Kurulum',
13
+ welcomeSub: 'Birkaç adımda hazır olacaksın.',
14
+ step: (n, t) => chalk.gray(`[${n}/6]`) + ' ' + chalk.cyan.bold(t),
15
+ done: '✓',
16
+ // Adım 1
17
+ providerTitle: 'AI Provider seç',
18
+ providerQ: 'Hangi AI provider kullanmak istiyorsunuz?',
19
+ customUrl: 'Provider URL girin (örn: https://api.example.com/v1):',
20
+ apiKeyQ: 'API Key girin:',
21
+ apiKeyNatureCo: 'natureco.me → Geliştirici Paneli → API Keys bölümünden aldığın key\'i gir:',
22
+ modelQ: 'Model seç:',
23
+ customModel: 'Model adı girin (örn: llama-3.3-70b-versatile):',
24
+ customEntry: 'Özel URL gir',
25
+ customModelEntry: 'Özel model adı gir',
26
+ // Adım 2
27
+ botNameTitle: 'Bot adı',
28
+ botNameQ: 'Botunun adı ne olsun?',
29
+ botNameDefault: 'NatureBot',
30
+ // Adım 3
31
+ userNameTitle: 'Kullanıcı adı',
32
+ userNameQ: 'Senin adın ne? (hafıza için)',
33
+ userNameDefault:'Kullanıcı',
34
+ // Adım 4
35
+ integTitle: 'Entegrasyonlar',
36
+ integQ: 'Hangi entegrasyonları kurmak istiyorsunuz?',
37
+ integSkip: 'Şimdilik atla',
38
+ integNote: (list) => `Seçilen: ${list.join(', ')} — kurulum için ilgili komutu çalıştır.`,
39
+ integCmds: {
40
+ Telegram: 'natureco telegram connect',
41
+ WhatsApp: 'natureco whatsapp connect',
42
+ Discord: 'natureco discord connect',
43
+ Slack: 'natureco slack connect',
44
+ },
45
+ // Adım 5
46
+ gatewayTitle: 'Gateway',
47
+ gatewayQ: 'Gateway şimdi başlatılsın mı? (arka planda çalışır)',
48
+ gatewayYes: 'Gateway başlatılıyor...',
49
+ gatewaySkip: 'Sonra başlatmak için: natureco gateway start',
50
+ // Adım 6
51
+ chatTitle: 'Hazır!',
52
+ chatQ: 'Hemen chat başlatmak ister misin?',
53
+ chatStart: 'Chat başlatılıyor...',
54
+ chatSkip: 'Başlamak için: natureco chat',
55
+ // Özet
56
+ summaryTitle: '✅ Kurulum tamamlandı!',
57
+ summaryProvider:'Provider',
58
+ summaryModel: 'Model',
59
+ summaryBot: 'Bot adı',
60
+ summaryUser: 'Kullanıcı',
61
+ summaryConfig: 'Config',
62
+ // Hata
63
+ urlRequired: 'URL gerekli',
64
+ urlInvalid: 'URL http:// veya https:// ile başlamalı',
65
+ apiKeyRequired: 'API key gerekli',
66
+ modelRequired: 'Model adı gerekli',
67
+ nameRequired: 'İsim gerekli',
68
+ },
69
+ en: {
70
+ welcome: '🌿 NatureCo CLI — Setup',
71
+ welcomeSub: 'You\'ll be ready in a few steps.',
72
+ step: (n, t) => chalk.gray(`[${n}/6]`) + ' ' + chalk.cyan.bold(t),
73
+ done: '✓',
74
+ // Step 1
75
+ providerTitle: 'AI Provider',
76
+ providerQ: 'Which AI provider do you want to use?',
77
+ customUrl: 'Enter provider URL (e.g. https://api.example.com/v1):',
78
+ apiKeyQ: 'Enter API Key:',
79
+ apiKeyNatureCo: 'natureco.me → Developer Panel → API Keys section — paste your key:',
80
+ modelQ: 'Select model:',
81
+ customModel: 'Enter model name (e.g. llama-3.3-70b-versatile):',
82
+ customEntry: 'Enter custom URL',
83
+ customModelEntry: 'Enter custom model name',
84
+ // Step 2
85
+ botNameTitle: 'Bot name',
86
+ botNameQ: 'What should your bot be called?',
87
+ botNameDefault: 'NatureBot',
88
+ // Step 3
89
+ userNameTitle: 'Your name',
90
+ userNameQ: 'What is your name? (for memory)',
91
+ userNameDefault:'User',
92
+ // Step 4
93
+ integTitle: 'Integrations',
94
+ integQ: 'Which integrations do you want to set up?',
95
+ integSkip: 'Skip for now',
96
+ integNote: (list) => `Selected: ${list.join(', ')} — run the relevant command to connect.`,
97
+ integCmds: {
98
+ Telegram: 'natureco telegram connect',
99
+ WhatsApp: 'natureco whatsapp connect',
100
+ Discord: 'natureco discord connect',
101
+ Slack: 'natureco slack connect',
102
+ },
103
+ // Step 5
104
+ gatewayTitle: 'Gateway',
105
+ gatewayQ: 'Start the gateway now? (runs in background)',
106
+ gatewayYes: 'Starting gateway...',
107
+ gatewaySkip: 'To start later: natureco gateway start',
108
+ // Step 6
109
+ chatTitle: 'All set!',
110
+ chatQ: 'Start chatting now?',
111
+ chatStart: 'Starting chat...',
112
+ chatSkip: 'To start: natureco chat',
113
+ // Summary
114
+ summaryTitle: '✅ Setup complete!',
115
+ summaryProvider:'Provider',
116
+ summaryModel: 'Model',
117
+ summaryBot: 'Bot name',
118
+ summaryUser: 'User',
119
+ summaryConfig: 'Config',
120
+ // Errors
121
+ urlRequired: 'URL is required',
122
+ urlInvalid: 'URL must start with http:// or https://',
123
+ apiKeyRequired: 'API key is required',
124
+ modelRequired: 'Model name is required',
125
+ nameRequired: 'Name is required',
126
+ },
127
+ };
128
+
129
+ // ─── Provider presets ─────────────────────────────────────────────────────────
130
+ const NATURECO_PROVIDER = {
131
+ name: 'NatureCo (natureco.me — kendi platformun)',
132
+ value: 'natureco',
133
+ url: 'https://api.natureco.me/v1',
134
+ };
135
+
136
+ const PROVIDER_PRESETS = (customLabel) => [
137
+ NATURECO_PROVIDER,
138
+ { name: 'Groq (recommended — fast & free)', value: 'https://api.groq.com/openai/v1' },
139
+ { name: 'OpenAI', value: 'https://api.openai.com/v1' },
140
+ { name: 'Anthropic', value: 'https://api.anthropic.com' },
141
+ { name: 'Together AI', value: 'https://api.together.xyz/v1' },
142
+ { name: 'Fireworks AI', value: 'https://api.fireworks.ai/inference/v1' },
143
+ { name: 'DeepSeek', value: 'https://api.deepseek.com/v1' },
144
+ { name: 'OpenRouter', value: 'https://openrouter.ai/api/v1' },
145
+ { name: 'Ollama (local)', value: 'http://localhost:11434/v1' },
146
+ { name: 'LM Studio (local)', value: 'http://localhost:1234/v1' },
147
+ { name: customLabel, value: 'custom' },
148
+ ];
149
+
150
+ const COMMON_MODELS = {
151
+ 'api.groq.com': ['llama-3.3-70b-versatile','llama-3.1-8b-instant','llama-3.1-70b-versatile','mixtral-8x7b-32768','gemma2-9b-it'],
152
+ 'api.openai.com': ['gpt-4o','gpt-4o-mini','gpt-4-turbo','gpt-3.5-turbo'],
153
+ 'api.anthropic.com': ['claude-opus-4-7','claude-sonnet-4-6','claude-haiku-4-5-20251001'],
154
+ 'api.together.xyz': ['meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo','meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo','mistralai/Mixtral-8x7B-Instruct-v0.1'],
155
+ };
156
+
157
+ // ─── Yardımcı: adım başlığı ───────────────────────────────────────────────────
158
+ function printStep(L, n, title) {
159
+ console.log('');
160
+ console.log(chalk.gray('─'.repeat(50)));
161
+ console.log(L.step(n, title));
162
+ console.log('');
163
+ }
164
+
165
+ function printDone(L, msg) {
166
+ console.log(chalk.green(` ${L.done} ${msg}`));
167
+ }
20
168
 
169
+ // ─── Ana fonksiyon ────────────────────────────────────────────────────────────
170
+ async function setup() {
21
171
  console.clear();
22
- console.log(welcomeBox);
23
- console.log(chalk.yellow('Hoş geldiniz! NatureCo CLI v2.x\'e'));
24
- console.log(chalk.yellow('hoş geldiniz.\n'));
172
+
173
+ // ── Karşılama ──────────────────────────────────────────────────────────────
174
+ console.log('');
175
+ console.log(chalk.green.bold(' (\\_/)'));
176
+ console.log(chalk.green.bold(' (•ᴥ•)'));
177
+ console.log(chalk.green(' />🌿'));
178
+ console.log('');
179
+
180
+ // ── ADIM 0: Dil seçimi ─────────────────────────────────────────────────────
181
+ const { lang } = await inquirer.prompt([{
182
+ type: 'list',
183
+ name: 'lang',
184
+ message: 'Language / Dil:',
185
+ choices: [
186
+ { name: '🇹🇷 Türkçe', value: 'tr' },
187
+ { name: '🇬🇧 English', value: 'en' },
188
+ ],
189
+ }]);
190
+
191
+ const L = LANG[lang];
192
+
193
+ console.log('');
194
+ console.log(chalk.green.bold(` ${L.welcome}`));
195
+ console.log(chalk.gray(` ${L.welcomeSub}`));
25
196
 
26
197
  // Klasör oluştur
27
- console.log(chalk.cyan('✦ ~/.natureco/ klasörü oluşturuluyor...'));
28
198
  if (!fs.existsSync(CONFIG_DIR)) {
29
199
  fs.mkdirSync(CONFIG_DIR, { recursive: true });
30
200
  }
31
- console.log(chalk.green(' ✓ Klasör oluşturuldu\n'));
32
201
 
33
- // Mevcut config'i kontrol et
202
+ // Mevcut config
34
203
  let existingConfig = {};
35
204
  if (fs.existsSync(CONFIG_FILE)) {
36
- try {
37
- const data = fs.readFileSync(CONFIG_FILE, 'utf-8');
38
- existingConfig = JSON.parse(data);
39
- } catch {
40
- existingConfig = {};
41
- }
205
+ try { existingConfig = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8')); } catch {}
42
206
  }
43
207
 
44
- // Provider URL seçimi
45
- console.log(chalk.cyan('✦ AI Provider yapılandırması\n'));
46
-
47
- const PROVIDER_PRESETS = [
48
- { name: 'Groq (önerilen - hızlı ve ücretsiz)', value: 'https://api.groq.com/openai/v1' },
49
- { name: 'OpenAI', value: 'https://api.openai.com/v1' },
50
- { name: 'Anthropic', value: 'https://api.anthropic.com' },
51
- { name: 'Together AI', value: 'https://api.together.xyz/v1' },
52
- { name: 'Fireworks AI', value: 'https://api.fireworks.ai/inference/v1' },
53
- { name: 'DeepSeek', value: 'https://api.deepseek.com/v1' },
54
- { name: 'OpenRouter', value: 'https://openrouter.ai/api/v1' },
55
- { name: 'Ollama (local)', value: 'http://localhost:11434/v1' },
56
- { name: 'LM Studio (local)', value: 'http://localhost:1234/v1' },
57
- { name: 'Özel URL gir', value: 'custom' },
58
- ];
59
-
60
- process.stdin.resume();
61
- const { providerChoice } = await inquirer.prompt([
62
- {
63
- type: 'list',
64
- name: 'providerChoice',
65
- message: 'Hangi AI provider kullanmak istiyorsunuz?',
66
- choices: PROVIDER_PRESETS,
67
- default: PROVIDER_PRESETS[0].value,
68
- },
69
- ]);
70
-
71
- let providerUrl = providerChoice;
72
-
73
- if (providerChoice === 'custom') {
74
- process.stdin.resume();
75
- const { customUrl } = await inquirer.prompt([
76
- {
77
- type: 'input',
78
- name: 'customUrl',
79
- message: 'Provider URL girin (örn: https://api.example.com/v1):',
80
- validate: (input) => {
81
- if (!input || input.trim().length === 0) {
82
- return 'URL gerekli';
83
- }
84
- if (!input.startsWith('http://') && !input.startsWith('https://')) {
85
- return 'URL http:// veya https:// ile başlamalı';
86
- }
87
- return true;
88
- },
89
- },
90
- ]);
91
- providerUrl = customUrl.trim();
92
- }
208
+ // ── ADIM 1: Provider + API key + Model ────────────────────────────────────
209
+ printStep(L, 1, L.providerTitle);
210
+
211
+ const { providerChoice } = await inquirer.prompt([{
212
+ type: 'list',
213
+ name: 'providerChoice',
214
+ message: L.providerQ,
215
+ choices: PROVIDER_PRESETS(L.customEntry),
216
+ default: 'https://api.groq.com/openai/v1',
217
+ }]);
93
218
 
94
- // API Key
95
- process.stdin.resume();
96
- const { providerApiKey } = await inquirer.prompt([
97
- {
219
+ // NatureCo provider seçildiyse URL'yi ayarla
220
+ let isNatureCo = false;
221
+ if (providerChoice === 'natureco') {
222
+ providerUrl = NATURECO_PROVIDER.url;
223
+ isNatureCo = true;
224
+ } else if (providerChoice === 'custom') {
225
+ const { customUrl } = await inquirer.prompt([{
98
226
  type: 'input',
99
- name: 'providerApiKey',
100
- message: 'API Key girin:',
101
- validate: (input) => {
102
- if (!input || input.trim().length === 0) {
103
- return 'API key gerekli';
104
- }
227
+ name: 'customUrl',
228
+ message: L.customUrl,
229
+ validate: (v) => {
230
+ if (!v.trim()) return L.urlRequired;
231
+ if (!v.startsWith('http://') && !v.startsWith('https://')) return L.urlInvalid;
105
232
  return true;
106
233
  },
107
- },
108
- ]);
109
-
110
- // Model seçimi
111
- const COMMON_MODELS = {
112
- 'api.groq.com': [
113
- 'llama-3.3-70b-versatile',
114
- 'llama-3.1-8b-instant',
115
- 'llama-3.1-70b-versatile',
116
- 'mixtral-8x7b-32768',
117
- 'gemma2-9b-it',
118
- ],
119
- 'api.openai.com': [
120
- 'gpt-4o',
121
- 'gpt-4o-mini',
122
- 'gpt-4-turbo',
123
- 'gpt-3.5-turbo',
124
- ],
125
- 'api.anthropic.com': [
126
- 'claude-opus-4-7',
127
- 'claude-sonnet-4-6',
128
- 'claude-haiku-4-5-20251001',
129
- ],
130
- 'api.together.xyz': [
131
- 'meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo',
132
- 'meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo',
133
- 'mistralai/Mixtral-8x7B-Instruct-v0.1',
134
- ],
135
- };
234
+ }]);
235
+ providerUrl = customUrl.trim();
236
+ }
136
237
 
137
- let modelChoices = ['Özel model adı gir'];
138
-
139
- // Provider URL'den model listesi çıkar
238
+ const { providerApiKey } = await inquirer.prompt([{
239
+ type: 'password',
240
+ name: 'providerApiKey',
241
+ message: isNatureCo ? L.apiKeyNatureCo : L.apiKeyQ,
242
+ mask: '*',
243
+ validate: (v) => v.trim() ? true : L.apiKeyRequired,
244
+ }]);
245
+ // Model listesi
246
+ let modelChoices = [L.customModelEntry];
140
247
  for (const [domain, models] of Object.entries(COMMON_MODELS)) {
141
248
  if (providerUrl.includes(domain)) {
142
- modelChoices = [...models, 'Özel model adı gir'];
249
+ modelChoices = [...models, L.customModelEntry];
143
250
  break;
144
251
  }
145
252
  }
146
253
 
147
- process.stdin.resume();
148
- const { modelChoice } = await inquirer.prompt([
149
- {
150
- type: 'list',
151
- name: 'modelChoice',
152
- message: 'Hangi modeli kullanmak istiyorsunuz?',
153
- choices: modelChoices,
154
- },
155
- ]);
254
+ const { modelChoice } = await inquirer.prompt([{
255
+ type: 'list',
256
+ name: 'modelChoice',
257
+ message: L.modelQ,
258
+ choices: modelChoices,
259
+ }]);
156
260
 
157
261
  let providerModel = modelChoice;
158
-
159
- if (modelChoice === 'Özel model adı gir') {
160
- process.stdin.resume();
161
- const { customModel } = await inquirer.prompt([
162
- {
163
- type: 'input',
164
- name: 'customModel',
165
- message: 'Model adı girin (örn: llama-3.3-70b-versatile):',
166
- validate: (input) => {
167
- if (!input || input.trim().length === 0) {
168
- return 'Model adı gerekli';
169
- }
170
- return true;
171
- },
172
- },
173
- ]);
262
+ if (modelChoice === L.customModelEntry) {
263
+ const { customModel } = await inquirer.prompt([{
264
+ type: 'input',
265
+ name: 'customModel',
266
+ message: L.customModel,
267
+ validate: (v) => v.trim() ? true : L.modelRequired,
268
+ }]);
174
269
  providerModel = customModel.trim();
175
270
  }
176
271
 
177
- // Debug mode
178
- process.stdin.resume();
179
- const { enableDebug } = await inquirer.prompt([
180
- {
181
- type: 'confirm',
182
- name: 'enableDebug',
183
- message: 'Debug mode aktif edilsin mi? (detaylı loglar)',
184
- default: false,
185
- },
186
- ]);
272
+ printDone(L, `${providerUrl.replace('https://', '').split('/')[0]} · ${providerModel}`);
273
+
274
+ // ── ADIM 2: Bot adı ────────────────────────────────────────────────────────
275
+ printStep(L, 2, L.botNameTitle);
276
+
277
+ const { botName } = await inquirer.prompt([{
278
+ type: 'input',
279
+ name: 'botName',
280
+ message: L.botNameQ,
281
+ default: existingConfig.botName || L.botNameDefault,
282
+ validate: (v) => v.trim() ? true : L.nameRequired,
283
+ }]);
284
+
285
+ printDone(L, botName.trim());
286
+
287
+ // ── ADIM 3: Kullanıcı adı ──────────────────────────────────────────────────
288
+ printStep(L, 3, L.userNameTitle);
289
+
290
+ const { userName } = await inquirer.prompt([{
291
+ type: 'input',
292
+ name: 'userName',
293
+ message: L.userNameQ,
294
+ default: existingConfig.userName || L.userNameDefault,
295
+ validate: (v) => v.trim() ? true : L.nameRequired,
296
+ }]);
297
+
298
+ printDone(L, userName.trim());
299
+
300
+ // ── ADIM 4: Entegrasyonlar ─────────────────────────────────────────────────
301
+ printStep(L, 4, L.integTitle);
302
+
303
+ const { integrations } = await inquirer.prompt([{
304
+ type: 'checkbox',
305
+ name: 'integrations',
306
+ message: L.integQ,
307
+ choices: [
308
+ { name: 'Telegram', value: 'Telegram' },
309
+ { name: 'WhatsApp', value: 'WhatsApp' },
310
+ { name: 'Discord', value: 'Discord' },
311
+ { name: 'Slack', value: 'Slack' },
312
+ ],
313
+ }]);
314
+
315
+ // ── Entegrasyon sub-flow'ları ──────────────────────────────────────────────
316
+ const integConfig = {};
317
+
318
+ if (integrations.includes('Telegram')) {
319
+ console.log('');
320
+ console.log(chalk.cyan(' Telegram kurulumu:'));
321
+ const { tgToken } = await inquirer.prompt([{
322
+ type: 'input',
323
+ name: 'tgToken',
324
+ message: lang === 'tr' ? ' Bot Token girin (BotFather\'dan):' : ' Enter Bot Token (from BotFather):',
325
+ validate: (v) => v.trim() ? true : (lang === 'tr' ? 'Token gerekli' : 'Token required'),
326
+ }]);
327
+ const { tgChatId } = await inquirer.prompt([{
328
+ type: 'input',
329
+ name: 'tgChatId',
330
+ message: lang === 'tr' ? ' Chat ID girin (sadece bu ID\'den gelen mesajlara cevap verilir):' : ' Enter Chat ID (only messages from this ID will be answered):',
331
+ validate: (v) => v.trim() ? true : (lang === 'tr' ? 'Chat ID gerekli' : 'Chat ID required'),
332
+ }]);
333
+ console.log(chalk.gray(lang === 'tr'
334
+ ? ' 💡 Chat ID\'nizi öğrenmek için @userinfobot\'a /start yazın'
335
+ : ' 💡 To find your Chat ID, send /start to @userinfobot'));
336
+ integConfig.telegramToken = tgToken.trim();
337
+ integConfig.telegramChatId = tgChatId.trim();
338
+ // Bağlantı testi
339
+ try {
340
+ const res = await fetch(`https://api.telegram.org/bot${tgToken.trim()}/getMe`);
341
+ const data = await res.json();
342
+ if (data.ok) {
343
+ printDone(L, `Telegram @${data.result.username}`);
344
+ } else {
345
+ console.log(chalk.yellow(' ⚠ Token geçersiz görünüyor, ilerleyebilirsin'));
346
+ }
347
+ } catch {
348
+ console.log(chalk.gray(' (bağlantı testi atlandı)'));
349
+ }
350
+ }
187
351
 
188
- // Config kaydet
352
+ if (integrations.includes('WhatsApp')) {
353
+ console.log('');
354
+ console.log(chalk.cyan(lang === 'tr'
355
+ ? ' WhatsApp için gateway başlatılması gerekiyor.'
356
+ : ' WhatsApp requires the gateway to be running.'));
357
+ console.log(chalk.gray(lang === 'tr'
358
+ ? ' Kurulum sonunda gateway başlatılacak, ardından QR kodu taratman gerekecek.'
359
+ : ' The gateway will start after setup — you\'ll need to scan the QR code.'));
360
+ printDone(L, 'WhatsApp');
361
+ }
362
+
363
+ if (integrations.includes('Discord')) {
364
+ console.log('');
365
+ console.log(chalk.cyan(' Discord kurulumu:'));
366
+ const { discordToken } = await inquirer.prompt([{
367
+ type: 'password',
368
+ name: 'discordToken',
369
+ message: lang === 'tr' ? ' Discord Bot Token girin:' : ' Enter Discord Bot Token:',
370
+ mask: '*',
371
+ validate: (v) => v.trim() ? true : (lang === 'tr' ? 'Token gerekli' : 'Token required'),
372
+ }]);
373
+ integConfig.discordToken = discordToken.trim();
374
+ printDone(L, 'Discord');
375
+ }
376
+
377
+ if (integrations.length > 0) {
378
+ if (!integrations.includes('Telegram') && !integrations.includes('WhatsApp') && !integrations.includes('Discord')) {
379
+ printDone(L, integrations.join(', '));
380
+ }
381
+ console.log('');
382
+ if (integrations.includes('Slack')) {
383
+ console.log(chalk.gray(` → natureco slack connect`));
384
+ }
385
+ } else {
386
+ printDone(L, L.integSkip);
387
+ }
388
+
389
+ // ── ADIM 5: Gateway ────────────────────────────────────────────────────────
390
+ printStep(L, 5, L.gatewayTitle);
391
+ const { startGateway } = await inquirer.prompt([{
392
+ type: 'confirm',
393
+ name: 'startGateway',
394
+ message: L.gatewayQ,
395
+ default: integrations.includes('WhatsApp'),
396
+ }]);
397
+
398
+ // ── Config kaydet ──────────────────────────────────────────────────────────
189
399
  const config = {
400
+ ...existingConfig,
190
401
  setupCompleted: true,
191
402
  setupDate: new Date().toISOString(),
192
- providerUrl: providerUrl,
403
+ language: lang,
404
+ providerUrl,
193
405
  providerApiKey: providerApiKey.trim(),
194
- providerModel: providerModel,
195
- debug: enableDebug,
196
- skills: { enabled: true, list: [] },
197
- mcpServers: {},
406
+ providerModel,
407
+ apiKey: providerApiKey.trim(), // login bypass — chat doğrudan çalışsın
408
+ botName: botName.trim(),
409
+ userName: userName.trim(),
410
+ debug: existingConfig.debug || false,
411
+ skills: existingConfig.skills || { enabled: true, list: [] },
412
+ mcpServers: existingConfig.mcpServers || {},
413
+ // Entegrasyon config'leri
414
+ ...(integConfig.telegramToken && { telegramToken: integConfig.telegramToken }),
415
+ ...(integConfig.telegramChatId && { telegramChatId: integConfig.telegramChatId }),
416
+ ...(integConfig.discordToken && { discordToken: integConfig.discordToken }),
198
417
  };
199
418
 
200
419
  saveConfig(config);
201
420
 
202
- // Kurulum tamamlandı
203
- console.log(chalk.green.bold('\n✅ Kurulum tamamlandı!\n'));
204
- console.log(chalk.cyan('Provider URL:'), chalk.white(providerUrl));
205
- console.log(chalk.cyan('Model:'), chalk.white(providerModel));
206
- console.log(chalk.cyan('Debug Mode:'), enableDebug ? chalk.green('✓ Aktif') : chalk.gray('✗ Kapalı'));
207
- console.log(chalk.cyan('Config:'), chalk.white(CONFIG_FILE));
421
+ // Hafızaya kullanıcı adı ve bot adı kaydet
422
+ const botId = 'universal-provider';
423
+ try {
424
+ saveMemory(botId, {
425
+ name: userName.trim(),
426
+ botName: botName.trim(),
427
+ nickname: '',
428
+ preferences: [],
429
+ facts: [],
430
+ lastSeen: new Date().toISOString(),
431
+ });
432
+ } catch {}
433
+
434
+ // ── Özet ───────────────────────────────────────────────────────────────────
208
435
  console.log('');
209
- console.log(chalk.yellow('Başlamak için:'), chalk.cyan('natureco chat'));
436
+ console.log(chalk.gray(''.repeat(50)));
437
+ console.log(chalk.green.bold(` ${L.summaryTitle}`));
210
438
  console.log('');
211
- console.log(chalk.gray('İsteğe bağlı entegrasyonlar:'));
212
- console.log(chalk.cyan(' natureco telegram connect'), chalk.gray(' — Telegram botu bağla'));
213
- console.log(chalk.cyan(' natureco discord connect'), chalk.gray(' — Discord bağla'));
214
- console.log(chalk.cyan(' natureco whatsapp connect'), chalk.gray(' — WhatsApp bağla'));
215
- console.log(chalk.cyan(' natureco slack connect'), chalk.gray(' — Slack bağla'));
439
+ console.log(chalk.gray(` ${L.summaryProvider}:`), chalk.white(providerUrl.replace('https://', '').split('/')[0]));
440
+ console.log(chalk.gray(` ${L.summaryModel}:`), chalk.white(providerModel));
441
+ console.log(chalk.gray(` ${L.summaryBot}:`), chalk.cyan(botName.trim()));
442
+ console.log(chalk.gray(` ${L.summaryUser}:`), chalk.white(userName.trim()));
443
+ console.log(chalk.gray(` ${L.summaryConfig}:`), chalk.gray(CONFIG_FILE));
216
444
  console.log('');
217
- console.log(chalk.gray('Tüm komutlar için:'), chalk.cyan('natureco help'));
445
+
446
+ // Gateway başlat
447
+ if (startGateway) {
448
+ console.log(chalk.cyan(` ${L.gatewayYes}`));
449
+ try {
450
+ const { spawn } = require('child_process');
451
+ const gatewayBin = path.join(__dirname, '..', '..', 'bin', 'natureco.js');
452
+ spawn(process.execPath, [gatewayBin, 'gateway', 'start'], {
453
+ detached: true,
454
+ stdio: 'ignore',
455
+ }).unref();
456
+ printDone(L, 'Gateway');
457
+ if (integrations.includes('WhatsApp')) {
458
+ console.log('');
459
+ console.log(chalk.yellow(lang === 'tr'
460
+ ? ' 📱 WhatsApp QR kodunu taratmak için: natureco whatsapp connect'
461
+ : ' 📱 To scan WhatsApp QR code: natureco whatsapp connect'));
462
+ }
463
+ } catch (e) {
464
+ console.log(chalk.yellow(` ⚠ ${e.message}`));
465
+ }
466
+ } else {
467
+ console.log(chalk.gray(` ${L.gatewaySkip}`));
468
+ }
469
+
470
+ // ── ADIM 6: Chat ───────────────────────────────────────────────────────────
471
+ printStep(L, 6, L.chatTitle);
472
+
473
+ const { startChat } = await inquirer.prompt([{
474
+ type: 'confirm',
475
+ name: 'startChat',
476
+ message: L.chatQ,
477
+ default: true,
478
+ }]);
479
+
218
480
  console.log('');
481
+
482
+ if (startChat) {
483
+ console.log(chalk.cyan(` ${L.chatStart}`));
484
+ console.log('');
485
+ const chat = require('./chat');
486
+ await chat([], {});
487
+ } else {
488
+ console.log(chalk.gray(` ${L.chatSkip}`));
489
+ console.log('');
490
+ }
219
491
  }
220
492
 
221
493
  module.exports = setup;