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 +1 -1
- package/src/commands/dashboard.js +2 -2
- package/src/commands/setup.js +444 -172
package/package.json
CHANGED
|
@@ -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.
|
|
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.
|
|
344
|
+
version: 'v2.15.1',
|
|
345
345
|
bots: cfg.bots || [],
|
|
346
346
|
telegramToken: cfg.telegramToken || null,
|
|
347
347
|
whatsappConnected: cfg.whatsappConnected || false,
|
package/src/commands/setup.js
CHANGED
|
@@ -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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
{
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
console.log(
|
|
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
|
|
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
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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
|
-
//
|
|
95
|
-
|
|
96
|
-
|
|
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: '
|
|
100
|
-
message:
|
|
101
|
-
validate: (
|
|
102
|
-
if (!
|
|
103
|
-
|
|
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
|
-
|
|
138
|
-
|
|
139
|
-
|
|
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,
|
|
249
|
+
modelChoices = [...models, L.customModelEntry];
|
|
143
250
|
break;
|
|
144
251
|
}
|
|
145
252
|
}
|
|
146
253
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
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
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
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
|
-
|
|
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
|
-
|
|
403
|
+
language: lang,
|
|
404
|
+
providerUrl,
|
|
193
405
|
providerApiKey: providerApiKey.trim(),
|
|
194
|
-
providerModel
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
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
|
-
//
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
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.
|
|
436
|
+
console.log(chalk.gray('─'.repeat(50)));
|
|
437
|
+
console.log(chalk.green.bold(` ${L.summaryTitle}`));
|
|
210
438
|
console.log('');
|
|
211
|
-
console.log(chalk.gray('
|
|
212
|
-
console.log(chalk.
|
|
213
|
-
console.log(chalk.
|
|
214
|
-
console.log(chalk.
|
|
215
|
-
console.log(chalk.
|
|
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
|
-
|
|
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;
|