natureco-cli 2.2.6 → 2.2.8

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/README.md CHANGED
@@ -8,17 +8,13 @@ Terminal-native AI agent CLI — chat with your bots, automate workflows, and co
8
8
 
9
9
  ## ✨ Features
10
10
 
11
- - **🤖 Multi-Bot Chat** — Interactive conversations with AI bots, support for multi-word bot names, auto-selection when no default
12
- - **🛠️ Local Tool Execution** — Bash commands, file operations, HTTP requestsbots can execute tools locally with automatic retry loop
13
- - **🔌 Multi-Platform Integration** — Telegram, Discord, Slack, WhatsApp (QR code auth with Baileys)
14
- - **🎯 Skill System** — Extend capabilities with NatureHub and ClawHub skills
15
- - **🔧 MCP Support** — Model Context Protocol servers for filesystem, GitHub, databases
11
+ - **🤖 Universal LLM Provider Support** — Connect to any OpenAI-compatible API (Groq, OpenAI, Together, Fireworks, DeepSeek, OpenRouter, Ollama, LM Studio) or Anthropic
12
+ - **🛠️ Local Tool Execution** — Bash commands, file operations (read_file, write_file, list_dir)AI executes tools locally with automatic retry loop
13
+ - **🔒 Security Layer** — Base64 encoding for tool results, dangerous command blocking, content truncation
14
+ - **🎯 Smart Tool Selection** — AI automatically chooses the right tool based on file type and task
16
15
  - **🌐 Web Dashboard** — Beautiful glassmorphism UI at localhost:3848 with animated gradients
17
- - **⚡ Gateway Server** — Background process with WhatsApp auto-start, OpenClaw-style logging
18
- - **🎨 Custom AI Providers** — OpenAI, Anthropic, Groq, Gemini with model selection
19
16
  - **📝 Code Analysis** — Deep code review with security, performance, quality scoring
20
- - **🔄 Automation** — Cron jobs, hooks, custom commands, background tasks
21
- - **💾 Memory System** — Persistent conversation memory per bot
17
+ - **💾 Memory System** — Persistent conversation memory per session
22
18
  - **📊 System Health** — Built-in doctor command with auto-fix
23
19
 
24
20
  ## 🚀 Quick Start
@@ -27,11 +23,11 @@ Terminal-native AI agent CLI — chat with your bots, automate workflows, and co
27
23
  # Install globally
28
24
  npm install -g natureco-cli
29
25
 
30
- # Run setup wizard
31
- natureco setup
26
+ # Run setup wizard (v2.x - universal provider support)
27
+ natureco setup # provider URL, API key, model seç
32
28
 
33
29
  # Start chatting
34
- natureco chat
30
+ natureco chat # terminal agent hazır
35
31
  ```
36
32
 
37
33
  ## 📋 Commands
@@ -282,23 +278,43 @@ natureco config set aiModel gpt-4o
282
278
 
283
279
  Config dosyası: `~/.natureco/config.json`
284
280
 
285
- **Örnek Config:**
281
+ **v2.x Örnek Config (Universal Provider):**
286
282
  ```json
287
283
  {
288
- "apiKey": "nc_...",
289
- "defaultBot": "Nature Bot",
290
- "defaultBotId": "bot_123",
291
- "aiProvider": "openai",
292
- "aiModel": "gpt-4o",
293
- "telegramToken": "...",
294
- "discordToken": "...",
295
- "whatsappConnected": true,
296
- "whatsappBotId": "bot_123",
297
- "whatsappPhone": "905551234567@s.whatsapp.net",
298
- "whatsappAllowedNumbers": ["905551234567", "905422842631"]
284
+ "providerUrl": "https://api.groq.com/openai/v1",
285
+ "providerApiKey": "gsk_xxx",
286
+ "providerModel": "llama-3.3-70b-versatile",
287
+ "debug": false,
288
+ "skills": { "enabled": true, "list": [] },
289
+ "mcpServers": {}
299
290
  }
300
291
  ```
301
292
 
293
+ **Desteklenen Provider'lar:**
294
+ - Groq: `https://api.groq.com/openai/v1`
295
+ - OpenAI: `https://api.openai.com/v1`
296
+ - Anthropic: `https://api.anthropic.com`
297
+ - Together AI: `https://api.together.xyz/v1`
298
+ - Fireworks AI: `https://api.fireworks.ai/inference/v1`
299
+ - DeepSeek: `https://api.deepseek.com/v1`
300
+ - OpenRouter: `https://openrouter.ai/api/v1`
301
+ - Ollama (local): `http://localhost:11434/v1`
302
+ - LM Studio (local): `http://localhost:1234/v1`
303
+
304
+ **Config Komutları:**
305
+ ```bash
306
+ # Provider değiştir
307
+ natureco config set providerUrl https://api.openai.com/v1
308
+ natureco config set providerApiKey sk-xxx
309
+ natureco config set providerModel gpt-4o
310
+
311
+ # Debug mode
312
+ natureco config set debug true
313
+
314
+ # Tüm ayarları göster
315
+ natureco config list
316
+ ```
317
+
302
318
  ## 📚 Support
303
319
 
304
320
  - **Documentation:** [natureco.me/docs](https://natureco.me/docs)
@@ -313,5 +329,5 @@ MIT © NatureCo
313
329
 
314
330
  ---
315
331
 
316
- **Version:** 1.0.51 | **Node.js:** >=16.0.0 | **Platform:** macOS, Windows, Linux
332
+ **Version:** 2.2.7 | **Node.js:** >=16.0.0 | **Platform:** macOS, Windows, Linux
317
333
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "natureco-cli",
3
- "version": "2.2.6",
3
+ "version": "2.2.8",
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.2.6</div>
214
+ <div class="version-badge" id="version-badge">v2.2.8</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.2.6',
344
+ version: 'v2.2.8',
345
345
  bots: cfg.bots || [],
346
346
  telegramToken: cfg.telegramToken || null,
347
347
  whatsappConnected: cfg.whatsappConnected || false,
@@ -22,39 +22,16 @@ async function discord(action) {
22
22
  }
23
23
 
24
24
  async function connectDiscord() {
25
- const apiKey = getApiKey();
26
-
27
- if (!apiKey) {
28
- console.log(chalk.red('\n❌ Not logged in. Run "natureco login" first.\n'));
29
- process.exit(1);
30
- }
31
-
32
25
  const config = getConfig();
33
26
 
34
- console.log(chalk.yellow('\n⏳ Loading bots...\n'));
35
-
36
- let botList;
37
- try {
38
- botList = await getBots(apiKey);
39
- } catch (err) {
40
- console.log(chalk.red(`\n❌ Error: ${err.message}\n`));
41
- process.exit(1);
42
- }
43
-
44
- if (!botList || !botList.bots || botList.bots.length === 0) {
45
- console.log(chalk.gray('No bots found. Create one at https://developers.natureco.me\n'));
27
+ if (!config.providerUrl) {
28
+ console.log(chalk.red('\n❌ Setup yapılmamış. Önce "natureco setup" çalıştırın.\n'));
46
29
  process.exit(1);
47
30
  }
48
31
 
49
32
  process.stdin.resume();
50
33
 
51
34
  const answers = await inquirer.prompt([
52
- {
53
- type: 'list',
54
- name: 'botId',
55
- message: 'Select bot to connect:',
56
- choices: botList.bots.map(b => ({ name: b.name, value: b.id })),
57
- },
58
35
  {
59
36
  type: 'input',
60
37
  name: 'token',
@@ -63,44 +40,22 @@ async function connectDiscord() {
63
40
  },
64
41
  ]);
65
42
 
66
- const selectedBot = botList.bots.find(b => b.id === answers.botId);
67
-
68
- console.log(chalk.yellow('\n⏳ Connecting to Discord...\n'));
69
-
70
- try {
71
- const response = await fetch('https://api.natureco.me/api/agent/discord/connect', {
72
- method: 'POST',
73
- headers: {
74
- 'Content-Type': 'application/json',
75
- 'Authorization': `Bearer ${apiKey}`,
76
- },
77
- body: JSON.stringify({
78
- agent_id: answers.botId,
79
- discord_bot_token: answers.token.trim(),
80
- }),
81
- });
82
-
83
- if (!response.ok) {
84
- const error = await response.text();
85
- throw new Error(error);
86
- }
87
-
88
- const data = await response.json();
89
-
90
- console.log(chalk.green('✅ Discord connected successfully!\n'));
91
- console.log(chalk.cyan('Bot:'), chalk.white(selectedBot.name));
92
- console.log(chalk.cyan('Discord Bot:'), chalk.white(data.bot_username || 'Unknown'));
93
- console.log(chalk.gray('\nYour bot is now active on Discord.'));
94
- console.log(chalk.gray('Users can interact with /sor command.\n'));
95
-
96
- // Save to config
97
- config.discordToken = answers.token.trim();
98
- config.discordBotId = answers.botId;
99
- saveConfig(config);
100
- } catch (err) {
101
- console.log(chalk.red(`\n❌ Connection failed: ${err.message}\n`));
102
- process.exit(1);
103
- }
43
+ // Discord için bot ID oluştur (timestamp-based)
44
+ const botId = `discord_${Date.now()}`;
45
+ const selectedBot = { name: 'Discord Bot', id: botId };
46
+
47
+ console.log(chalk.yellow('\n⏳ Discord bağlantısı kaydediliyor...\n'));
48
+
49
+ // Save to config (v2.x - no backend call)
50
+ config.discordToken = answers.token.trim();
51
+ config.discordBotId = botId;
52
+ saveConfig(config);
53
+
54
+ console.log(chalk.green('✅ Discord token kaydedildi!\n'));
55
+ console.log(chalk.cyan('Bot ID:'), chalk.white(botId));
56
+ console.log(chalk.cyan('Token:'), chalk.white(answers.token.slice(0, 20) + '...'));
57
+ console.log(chalk.gray('\nNot: Discord botunuzu Discord Developer Portal\'dan yapılandırmanız gerekiyor.'));
58
+ console.log(chalk.gray('Token config\'e kaydedildi: ~/.natureco/config.json\n'));
104
59
  }
105
60
 
106
61
  async function disconnectDiscord() {
@@ -3,13 +3,12 @@ const boxen = require('boxen');
3
3
  const inquirer = require('inquirer');
4
4
  const fs = require('fs');
5
5
  const { saveConfig, CONFIG_DIR, CONFIG_FILE } = require('../utils/config');
6
- const { getBots } = require('../utils/api');
7
6
 
8
7
  async function setup() {
9
8
  // Kurulum ekranı
10
9
  const welcomeBox = boxen(
11
10
  chalk.green.bold('🌿 NatureCo Terminal\n') +
12
- chalk.green.bold(' İlk Kurulum\n'),
11
+ chalk.green.bold(' İlk Kurulum v2.x\n'),
13
12
  {
14
13
  padding: 1,
15
14
  margin: 1,
@@ -21,8 +20,8 @@ async function setup() {
21
20
 
22
21
  console.clear();
23
22
  console.log(welcomeBox);
24
- console.log(chalk.yellow('Hoş geldiniz! NatureCo CLI\'yi ilk kez'));
25
- console.log(chalk.yellow('kullanıyorsunuz.\n'));
23
+ console.log(chalk.yellow('Hoş geldiniz! NatureCo CLI v2.x\'e'));
24
+ console.log(chalk.yellow('hoş geldiniz.\n'));
26
25
 
27
26
  // Klasör oluştur
28
27
  console.log(chalk.cyan('✦ ~/.natureco/ klasörü oluşturuluyor...'));
@@ -31,9 +30,6 @@ async function setup() {
31
30
  }
32
31
  console.log(chalk.green(' ✓ Klasör oluşturuldu\n'));
33
32
 
34
- console.log(chalk.cyan('✦ Varsayılan ayarlar yükleniyor...'));
35
- console.log(chalk.green(' ✓ Ayarlar hazır\n'));
36
-
37
33
  // Mevcut config'i kontrol et
38
34
  let existingConfig = {};
39
35
  if (fs.existsSync(CONFIG_FILE)) {
@@ -45,696 +41,181 @@ async function setup() {
45
41
  }
46
42
  }
47
43
 
48
- // AI sağlayıcı seç
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
+
49
60
  process.stdin.resume();
50
- const { aiProvider } = await inquirer.prompt([
61
+ const { providerChoice } = await inquirer.prompt([
51
62
  {
52
63
  type: 'list',
53
- name: 'aiProvider',
54
- message: 'AI sağlayıcı seçin:',
55
- choices: [
56
- { name: 'NatureCo (önerilen)', value: 'natureco' },
57
- { name: 'OpenAI', value: 'openai' },
58
- { name: 'Anthropic Claude', value: 'anthropic' },
59
- { name: 'Groq', value: 'groq' },
60
- { name: 'Google Gemini', value: 'gemini' },
61
- ],
62
- default: 'natureco',
64
+ name: 'providerChoice',
65
+ message: 'Hangi AI provider kullanmak istiyorsunuz?',
66
+ choices: PROVIDER_PRESETS,
67
+ default: PROVIDER_PRESETS[0].value,
63
68
  },
64
69
  ]);
65
70
 
66
- // Model listesi
67
- const MODELS = {
68
- anthropic: [
69
- { name: 'Claude Opus 4.7', value: 'claude-opus-4-7' },
70
- { name: 'Claude Opus 4.6', value: 'claude-opus-4-6' },
71
- { name: 'Claude Opus 4.5', value: 'claude-opus-4-5-20251101' },
72
- { name: 'Claude Sonnet 4.6', value: 'claude-sonnet-4-6' },
73
- { name: 'Claude Sonnet 4.5', value: 'claude-sonnet-4-5-20251001' },
74
- { name: 'Claude Haiku 4.5', value: 'claude-haiku-4-5-20251001' },
75
- { name: 'Claude Haiku 3.5', value: 'claude-haiku-3-5-20241022' },
76
- ],
77
- openai: [
78
- { name: 'GPT-5.5', value: 'gpt-5.5' },
79
- { name: 'GPT-5.4', value: 'gpt-5.4' },
80
- { name: 'GPT-5.4 Mini', value: 'gpt-5.4-mini' },
81
- { name: 'GPT-5.4 Nano', value: 'gpt-5.4-nano' },
82
- { name: 'GPT-5', value: 'gpt-5' },
83
- { name: 'GPT-5 Mini', value: 'gpt-5-mini' },
84
- { name: 'GPT-4.1', value: 'gpt-4.1' },
85
- { name: 'GPT-4.1 Mini', value: 'gpt-4.1-mini' },
86
- { name: 'GPT-4.1 Nano', value: 'gpt-4.1-nano' },
87
- { name: 'GPT-4o', value: 'gpt-4o' },
88
- { name: 'GPT-4o Mini', value: 'gpt-4o-mini' },
89
- { name: 'o3', value: 'o3' },
90
- { name: 'o3 Mini', value: 'o3-mini' },
91
- { name: 'o4 Mini', value: 'o4-mini' },
92
- ],
93
- groq: [
94
- { name: 'Llama 3.3 70B', value: 'llama-3.3-70b-versatile' },
95
- { name: 'Llama 3.1 8B', value: 'llama-3.1-8b-instant' },
96
- { name: 'Llama 3.1 70B', value: 'llama-3.1-70b-versatile' },
97
- { name: 'Mixtral 8x7B', value: 'mixtral-8x7b-32768' },
98
- { name: 'Gemma 2 9B', value: 'gemma2-9b-it' },
99
- ],
100
- gemini: [
101
- { name: 'Gemini 2.5 Pro', value: 'gemini-2.5-pro' },
102
- { name: 'Gemini 2.5 Flash', value: 'gemini-2.5-flash' },
103
- { name: 'Gemini 2.0 Flash', value: 'gemini-2.0-flash' },
104
- { name: 'Gemini 1.5 Pro', value: 'gemini-1.5-pro' },
105
- { name: 'Gemini 1.5 Flash', value: 'gemini-1.5-flash' },
106
- ],
107
- };
108
-
109
- let aiApiKey = null;
110
- let aiModel = null;
111
- let naturecoApiKey = null;
112
-
113
- // NatureCo dışı sağlayıcı seçildiyse key ve model sor
114
- if (aiProvider !== 'natureco') {
115
- const providerInfo = {
116
- openai: { name: 'OpenAI', prefix: 'sk-', example: 'sk-...' },
117
- anthropic: { name: 'Anthropic', prefix: 'sk-ant-', example: 'sk-ant-...' },
118
- groq: { name: 'Groq', prefix: 'gsk_', example: 'gsk_...' },
119
- gemini: { name: 'Google Gemini', prefix: 'AIza', example: 'AIza...' },
120
- };
121
-
122
- const info = providerInfo[aiProvider];
71
+ let providerUrl = providerChoice;
123
72
 
73
+ if (providerChoice === 'custom') {
124
74
  process.stdin.resume();
125
- const { customApiKey } = await inquirer.prompt([
75
+ const { customUrl } = await inquirer.prompt([
126
76
  {
127
77
  type: 'input',
128
- name: 'customApiKey',
129
- message: `${info.name} API key girin (${info.example}):`,
78
+ name: 'customUrl',
79
+ message: 'Provider URL girin (örn: https://api.example.com/v1):',
130
80
  validate: (input) => {
131
81
  if (!input || input.trim().length === 0) {
132
- return 'API key gerekli';
82
+ return 'URL gerekli';
133
83
  }
134
- if (!input.trim().startsWith(info.prefix)) {
135
- return `API key ${info.prefix} ile başlamalı`;
84
+ if (!input.startsWith('http://') && !input.startsWith('https://')) {
85
+ return 'URL http:// veya https:// ile başlamalı';
136
86
  }
137
87
  return true;
138
88
  },
139
89
  },
140
90
  ]);
141
-
142
- aiApiKey = customApiKey.trim();
143
-
144
- // Model seçimi
145
- process.stdin.resume();
146
- const { selectedModel } = await inquirer.prompt([
147
- {
148
- type: 'list',
149
- name: 'selectedModel',
150
- message: 'Model seçin:',
151
- choices: MODELS[aiProvider],
152
- },
153
- ]);
154
-
155
- aiModel = selectedModel;
156
-
157
- // NatureCo API key de sor (opsiyonel)
158
- process.stdin.resume();
159
- const { wantNaturecoKey } = await inquirer.prompt([
160
- {
161
- type: 'confirm',
162
- name: 'wantNaturecoKey',
163
- message: 'NatureCo API key de girmek ister misiniz? (Bot yönetimi için)',
164
- default: false,
165
- },
166
- ]);
167
-
168
- if (wantNaturecoKey) {
169
- // Kayıtlı NatureCo key varsa hatırlat
170
- if (existingConfig.apiKey) {
171
- const maskedKey = existingConfig.apiKey.slice(0, 6) + '...';
172
- process.stdin.resume();
173
- const { useExistingNcKey } = await inquirer.prompt([
174
- {
175
- type: 'confirm',
176
- name: 'useExistingNcKey',
177
- message: `Kayıtlı NatureCo API key bulundu: ${maskedKey}. Bunu kullanmak ister misiniz?`,
178
- default: true,
179
- },
180
- ]);
181
-
182
- if (useExistingNcKey) {
183
- naturecoApiKey = existingConfig.apiKey;
184
- }
185
- }
186
-
187
- if (!naturecoApiKey) {
188
- process.stdin.resume();
189
- const { ncKey } = await inquirer.prompt([
190
- {
191
- type: 'input',
192
- name: 'ncKey',
193
- message: 'NatureCo API key:',
194
- validate: (input) => {
195
- const trimmed = input.trim();
196
- if (trimmed.length === 0) return true; // Opsiyonel
197
- if (!trimmed.startsWith('nc_') && !trimmed.startsWith('nco_')) {
198
- return 'API key nc_ veya nco_ ile başlamalı';
199
- }
200
- return true;
201
- },
202
- },
203
- ]);
204
- if (ncKey.trim().length > 0) {
205
- naturecoApiKey = ncKey.trim();
206
- }
207
- }
208
- }
209
- } else {
210
- // NatureCo seçildiyse
211
- // Kayıtlı API key varsa hatırlat
212
- if (existingConfig.apiKey) {
213
- const maskedKey = existingConfig.apiKey.slice(0, 6) + '...';
214
- process.stdin.resume();
215
- const { useExistingKey } = await inquirer.prompt([
216
- {
217
- type: 'confirm',
218
- name: 'useExistingKey',
219
- message: `Kayıtlı API key bulundu: ${maskedKey}. Bunu kullanmak ister misiniz?`,
220
- default: true,
221
- },
222
- ]);
223
-
224
- if (useExistingKey) {
225
- // Mevcut key'i doğrula
226
- console.log(chalk.yellow('\n ⏳ API key doğrulanıyor...'));
227
- try {
228
- const response = await fetch('https://api.natureco.me/api/v1/bots', {
229
- headers: {
230
- 'Authorization': `Bearer ${existingConfig.apiKey}`,
231
- 'Content-Type': 'application/json',
232
- },
233
- });
234
-
235
- if (response.ok) {
236
- const data = await response.json();
237
- if (data.bots && data.bots.length > 0) {
238
- console.log(chalk.green(' ✓ API key doğrulandı\n'));
239
- naturecoApiKey = existingConfig.apiKey;
240
- } else {
241
- console.log(chalk.red(' ✗ Bu API key ile bot bulunamadı\n'));
242
- }
243
- } else {
244
- console.log(chalk.red(' ✗ Geçersiz API key\n'));
245
- }
246
- } catch (err) {
247
- console.log(chalk.red(` ✗ API hatası: ${err.message}\n`));
248
- }
249
- }
250
- }
251
-
252
- // Yeni key sor
253
- if (!naturecoApiKey) {
254
- process.stdin.resume();
255
- const { apiKey } = await inquirer.prompt([
256
- {
257
- type: 'input',
258
- name: 'apiKey',
259
- message: 'NatureCo API key girin:',
260
- validate: async (input) => {
261
- if (!input || input.trim().length === 0) {
262
- return 'API key gerekli';
263
- }
264
-
265
- const trimmed = input.trim();
266
- if (!trimmed.startsWith('nc_') && !trimmed.startsWith('nco_')) {
267
- return 'API key nc_ veya nco_ ile başlamalı';
268
- }
269
-
270
- console.log(chalk.yellow('\n ⏳ API key doğrulanıyor...'));
271
- try {
272
- const response = await fetch('https://api.natureco.me/api/v1/bots', {
273
- headers: {
274
- 'Authorization': `Bearer ${trimmed}`,
275
- 'Content-Type': 'application/json',
276
- },
277
- });
278
-
279
- if (!response.ok) {
280
- return 'Geçersiz API key';
281
- }
282
-
283
- const data = await response.json();
284
- if (!data.bots || data.bots.length === 0) {
285
- return 'Bu API key ile bot bulunamadı';
286
- }
287
-
288
- console.log(chalk.green(' ✓ API key doğrulandı\n'));
289
- return true;
290
- } catch (err) {
291
- return `API hatası: ${err.message}`;
292
- }
293
- },
294
- },
295
- ]);
296
-
297
- naturecoApiKey = apiKey.trim();
298
- }
91
+ providerUrl = customUrl.trim();
299
92
  }
300
93
 
301
- // Bot seçimi (sadece NatureCo key varsa)
302
- let selectedBot = null;
303
- let selectedBotId = null;
304
-
305
- if (naturecoApiKey) {
306
- // Kayıtlı bot varsa hatırlat
307
- if (existingConfig.defaultBot && existingConfig.defaultBotId) {
308
- process.stdin.resume();
309
- const { useExistingBot } = await inquirer.prompt([
310
- {
311
- type: 'confirm',
312
- name: 'useExistingBot',
313
- message: `Kayıtlı bot bulundu: ${existingConfig.defaultBot}. Bunu kullanmak ister misiniz?`,
314
- default: true,
315
- },
316
- ]);
317
-
318
- if (useExistingBot) {
319
- selectedBot = { name: existingConfig.defaultBot };
320
- selectedBotId = existingConfig.defaultBotId;
321
- }
322
- }
323
-
324
- if (!selectedBot) {
325
- console.log(chalk.yellow('⏳ Botlar yükleniyor...\n'));
326
- try {
327
- const botList = await getBots(naturecoApiKey);
328
-
329
- if (botList && botList.bots && botList.bots.length > 0) {
330
- process.stdin.resume();
331
- const { botId } = await inquirer.prompt([
332
- {
333
- type: 'list',
334
- name: 'botId',
335
- message: 'Varsayılan bot seçin:',
336
- choices: botList.bots.map(b => ({ name: b.name, value: b.id })),
337
- },
338
- ]);
339
-
340
- selectedBotId = botId;
341
- selectedBot = botList.bots.find(b => b.id === botId);
94
+ // API Key
95
+ process.stdin.resume();
96
+ const { providerApiKey } = await inquirer.prompt([
97
+ {
98
+ 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';
342
104
  }
343
- } catch (err) {
344
- console.log(chalk.yellow(`⚠️ Bot listesi alınamadı: ${err.message}\n`));
345
- }
346
- }
347
- }
348
-
349
- // Telegram entegrasyonu (NatureCo seçildiyse veya NatureCo key varsa)
350
- let telegramToken = null;
351
- let telegramUserId = null;
352
-
353
- if (naturecoApiKey && selectedBotId) {
354
- // Kayıtlı Telegram botu varsa hatırlat
355
- if (existingConfig.telegramToken) {
356
- process.stdin.resume();
357
- const { useExistingTelegram } = await inquirer.prompt([
358
- {
359
- type: 'confirm',
360
- name: 'useExistingTelegram',
361
- message: 'Kayıtlı Telegram botu bulundu. Bunu kullanmak ister misiniz?',
362
- default: true,
363
- },
364
- ]);
365
-
366
- if (useExistingTelegram) {
367
- telegramToken = existingConfig.telegramToken;
368
- telegramUserId = existingConfig.telegramUserId;
369
- }
370
- }
371
-
372
- if (!telegramToken) {
373
- process.stdin.resume();
374
- const { wantTelegram } = await inquirer.prompt([
375
- {
376
- type: 'confirm',
377
- name: 'wantTelegram',
378
- message: 'Telegram entegrasyonu eklemek ister misiniz?',
379
- default: false,
380
- },
381
- ]);
382
-
383
- if (wantTelegram) {
384
- process.stdin.resume();
385
- const telegramAnswers = await inquirer.prompt([
386
- {
387
- type: 'input',
388
- name: 'token',
389
- message: 'Telegram bot token:',
390
- validate: (val) => val.trim() !== '' || 'Token boş olamaz',
391
- },
392
- {
393
- type: 'input',
394
- name: 'userId',
395
- message: 'Telegram kullanıcı ID\'niz (t.me/userinfobot ile öğrenebilirsiniz):',
396
- validate: (val) => val.trim() !== '' || 'Kullanıcı ID boş olamaz',
397
- },
398
- ]);
399
-
400
- telegramToken = telegramAnswers.token.trim();
401
- telegramUserId = telegramAnswers.userId.trim();
105
+ return true;
106
+ },
107
+ },
108
+ ]);
402
109
 
403
- // Telegram'ı bağla
404
- try {
405
- const response = await fetch('https://api.natureco.me/api/agent/telegram/connect', {
406
- method: 'POST',
407
- headers: {
408
- 'Content-Type': 'application/json',
409
- 'Authorization': `Bearer ${naturecoApiKey}`,
410
- },
411
- body: JSON.stringify({
412
- agent_id: selectedBotId,
413
- telegram_bot_token: telegramToken,
414
- telegram_user_id: telegramUserId,
415
- }),
416
- });
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
+ };
417
136
 
418
- if (response.ok) {
419
- console.log(chalk.green('\n✅ Telegram bağlantısı başarılı!\n'));
420
- } else {
421
- console.log(chalk.yellow('\n⚠️ Telegram bağlantısı kurulamadı\n'));
422
- }
423
- } catch (err) {
424
- console.log(chalk.yellow(`\n⚠️ Telegram bağlantı hatası: ${err.message}\n`));
425
- }
426
- }
137
+ let modelChoices = ['Özel model adı gir'];
138
+
139
+ // Provider URL'den model listesi çıkar
140
+ for (const [domain, models] of Object.entries(COMMON_MODELS)) {
141
+ if (providerUrl.includes(domain)) {
142
+ modelChoices = [...models, 'Özel model adı gir'];
143
+ break;
427
144
  }
428
145
  }
429
146
 
430
- // Discord entegrasyonu (NatureCo seçildiyse veya NatureCo key varsa)
431
- let discordToken = null;
432
-
433
- if (naturecoApiKey && selectedBotId) {
434
- // Kayıtlı Discord botu varsa hatırlat
435
- if (existingConfig.discordToken) {
436
- process.stdin.resume();
437
- const { useExistingDiscord } = await inquirer.prompt([
438
- {
439
- type: 'confirm',
440
- name: 'useExistingDiscord',
441
- message: 'Kayıtlı Discord botu bulundu. Bunu kullanmak ister misiniz?',
442
- default: true,
443
- },
444
- ]);
445
-
446
- if (useExistingDiscord) {
447
- discordToken = existingConfig.discordToken;
448
- }
449
- }
450
-
451
- if (!discordToken) {
452
- process.stdin.resume();
453
- const { wantDiscord } = await inquirer.prompt([
454
- {
455
- type: 'confirm',
456
- name: 'wantDiscord',
457
- message: 'Discord entegrasyonu eklemek ister misiniz?',
458
- default: false,
459
- },
460
- ]);
461
-
462
- if (wantDiscord) {
463
- process.stdin.resume();
464
- const discordAnswers = await inquirer.prompt([
465
- {
466
- type: 'input',
467
- name: 'token',
468
- message: 'Discord bot token:',
469
- validate: (val) => val.trim() !== '' || 'Token boş olamaz',
470
- },
471
- ]);
472
-
473
- discordToken = discordAnswers.token.trim();
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
+ ]);
474
156
 
475
- // Discord'u bağla
476
- try {
477
- const response = await fetch('https://api.natureco.me/api/agent/discord/connect', {
478
- method: 'POST',
479
- headers: {
480
- 'Content-Type': 'application/json',
481
- 'Authorization': `Bearer ${naturecoApiKey}`,
482
- },
483
- body: JSON.stringify({
484
- agent_id: selectedBotId,
485
- discord_bot_token: discordToken,
486
- }),
487
- });
157
+ let providerModel = modelChoice;
488
158
 
489
- if (response.ok) {
490
- console.log(chalk.green('\n✅ Discord bağlantısı başarılı!\n'));
491
- } else {
492
- console.log(chalk.yellow('\n⚠️ Discord bağlantısı kurulamadı\n'));
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';
493
169
  }
494
- } catch (err) {
495
- console.log(chalk.yellow(`\n⚠️ Discord bağlantı hatası: ${err.message}\n`));
496
- }
497
- }
498
- }
499
- }
500
-
501
- // Slack entegrasyonu (NatureCo seçildiyse veya NatureCo key varsa)
502
- let slackToken = null;
503
-
504
- if (naturecoApiKey && selectedBotId) {
505
- // Kayıtlı Slack botu varsa hatırlat
506
- if (existingConfig.slackToken) {
507
- process.stdin.resume();
508
- const { useExistingSlack } = await inquirer.prompt([
509
- {
510
- type: 'confirm',
511
- name: 'useExistingSlack',
512
- message: 'Kayıtlı Slack botu bulundu. Bunu kullanmak ister misiniz?',
513
- default: true,
514
- },
515
- ]);
516
-
517
- if (useExistingSlack) {
518
- slackToken = existingConfig.slackToken;
519
- }
520
- }
521
-
522
- if (!slackToken) {
523
- process.stdin.resume();
524
- const { wantSlack } = await inquirer.prompt([
525
- {
526
- type: 'confirm',
527
- name: 'wantSlack',
528
- message: 'Slack entegrasyonu eklemek ister misiniz?',
529
- default: false,
170
+ return true;
530
171
  },
531
- ]);
532
-
533
- if (wantSlack) {
534
- process.stdin.resume();
535
- const slackAnswers = await inquirer.prompt([
536
- {
537
- type: 'input',
538
- name: 'token',
539
- message: 'Slack bot token (xoxb- ile başlar):',
540
- validate: (val) => {
541
- const trimmed = val.trim();
542
- if (trimmed === '') return 'Token boş olamaz';
543
- if (!trimmed.startsWith('xoxb-')) return 'Slack bot token xoxb- ile başlamalı';
544
- return true;
545
- },
546
- },
547
- ]);
548
-
549
- slackToken = slackAnswers.token.trim();
550
-
551
- // Slack'i bağla
552
- try {
553
- const response = await fetch('https://api.natureco.me/api/agent/slack/connect', {
554
- method: 'POST',
555
- headers: {
556
- 'Content-Type': 'application/json',
557
- 'Authorization': `Bearer ${naturecoApiKey}`,
558
- },
559
- body: JSON.stringify({
560
- agent_id: selectedBotId,
561
- slack_bot_token: slackToken,
562
- }),
563
- });
564
-
565
- if (response.ok) {
566
- console.log(chalk.green('\n✅ Slack bağlantısı başarılı!\n'));
567
- } else {
568
- console.log(chalk.yellow('\n⚠️ Slack bağlantısı kurulamadı\n'));
569
- }
570
- } catch (err) {
571
- console.log(chalk.yellow(`\n⚠️ Slack bağlantı hatası: ${err.message}\n`));
572
- }
573
- }
574
- }
172
+ },
173
+ ]);
174
+ providerModel = customModel.trim();
575
175
  }
576
176
 
577
- // WhatsApp entegrasyonu (NatureCo seçildiyse veya NatureCo key varsa)
578
- let whatsappConnected = false;
579
-
580
- if (naturecoApiKey && selectedBotId) {
581
- // Kayıtlı WhatsApp bağlantısı varsa hatırlat
582
- if (existingConfig.whatsappConnected) {
583
- process.stdin.resume();
584
- const { useExistingWhatsApp } = await inquirer.prompt([
585
- {
586
- type: 'confirm',
587
- name: 'useExistingWhatsApp',
588
- message: 'Kayıtlı WhatsApp bağlantısı bulundu. Bunu kullanmak ister misiniz?',
589
- default: true,
590
- },
591
- ]);
592
-
593
- if (useExistingWhatsApp) {
594
- whatsappConnected = true;
595
- }
596
- }
597
-
598
- if (!whatsappConnected) {
599
- process.stdin.resume();
600
- const { wantWhatsApp } = await inquirer.prompt([
601
- {
602
- type: 'confirm',
603
- name: 'wantWhatsApp',
604
- message: 'WhatsApp entegrasyonu eklemek ister misiniz?',
605
- default: false,
606
- },
607
- ]);
608
-
609
- if (wantWhatsApp) {
610
- console.log(chalk.cyan('\n📱 WhatsApp bağlantısı QR kod ile yapılır.'));
611
- console.log(chalk.gray('Telefonunuzda WhatsApp\'ı açın ve QR kodu taratın.\n'));
612
- console.log(chalk.yellow('⏳ QR kod alınıyor...\n'));
613
-
614
- // WhatsApp'ı bağla
615
- try {
616
- const response = await fetch('https://api.natureco.me/api/agent/whatsapp/connect', {
617
- method: 'POST',
618
- headers: {
619
- 'Content-Type': 'application/json',
620
- 'Authorization': `Bearer ${naturecoApiKey}`,
621
- },
622
- body: JSON.stringify({
623
- agent_id: selectedBotId,
624
- }),
625
- });
626
-
627
- if (response.ok) {
628
- const data = await response.json();
629
-
630
- if (data.qr_code) {
631
- console.log(chalk.green('✅ QR kod hazır!\n'));
632
- console.log(chalk.cyan('QR Kod:'));
633
- console.log(data.qr_code);
634
- console.log('');
635
-
636
- if (data.qr_url) {
637
- console.log(chalk.cyan('QR URL:'), chalk.white(data.qr_url));
638
- }
639
-
640
- console.log(chalk.gray('\n1. WhatsApp\'ı açın'));
641
- console.log(chalk.gray('2. Ayarlar > Bağlı Cihazlar > Cihaz Bağla'));
642
- console.log(chalk.gray('3. Bu QR kodu taratın\n'));
643
- } else if (data.connection_url) {
644
- console.log(chalk.green('✅ Bağlantı linki hazır!\n'));
645
- console.log(chalk.cyan('Bağlantı URL:'), chalk.white(data.connection_url));
646
- console.log(chalk.gray('\nBu linki tarayıcıda açın ve QR kodu taratın.\n'));
647
- } else {
648
- console.log(chalk.green('✅ WhatsApp bağlantısı başlatıldı!\n'));
649
- }
650
-
651
- whatsappConnected = true;
652
- } else {
653
- console.log(chalk.yellow('\n⚠️ WhatsApp bağlantısı kurulamadı\n'));
654
- }
655
- } catch (err) {
656
- console.log(chalk.yellow(`\n⚠️ WhatsApp bağlantı hatası: ${err.message}\n`));
657
- }
658
- }
659
- }
660
- }
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
+ ]);
661
187
 
662
188
  // Config kaydet
663
189
  const config = {
664
190
  setupCompleted: true,
665
191
  setupDate: new Date().toISOString(),
192
+ providerUrl: providerUrl,
193
+ providerApiKey: providerApiKey.trim(),
194
+ providerModel: providerModel,
195
+ debug: enableDebug,
666
196
  skills: { enabled: true, list: [] },
667
197
  mcpServers: {},
668
198
  };
669
199
 
670
- if (aiProvider !== 'natureco') {
671
- config.aiProvider = aiProvider;
672
- config.aiApiKey = aiApiKey;
673
- config.aiModel = aiModel;
674
- }
675
-
676
- if (naturecoApiKey) {
677
- config.apiKey = naturecoApiKey;
678
- }
679
-
680
- if (selectedBot) {
681
- config.defaultBot = selectedBot.name;
682
- config.defaultBotId = selectedBotId;
683
- }
684
-
685
- if (telegramToken) {
686
- config.telegramToken = telegramToken;
687
- config.telegramUserId = telegramUserId;
688
- }
689
-
690
- if (discordToken) {
691
- config.discordToken = discordToken;
692
- config.discordBotId = selectedBotId;
693
- }
694
-
695
- if (slackToken) {
696
- config.slackToken = slackToken;
697
- config.slackBotId = selectedBotId;
698
- }
699
-
700
- if (whatsappConnected) {
701
- config.whatsappConnected = true;
702
- config.whatsappBotId = selectedBotId;
703
- }
704
-
705
200
  saveConfig(config);
706
201
 
707
202
  // Kurulum tamamlandı
708
203
  console.log(chalk.green.bold('\n✅ Kurulum tamamlandı!\n'));
709
-
710
- if (aiProvider !== 'natureco') {
711
- console.log(chalk.cyan('AI Sağlayıcı:'), chalk.white(aiProvider));
712
- }
713
-
714
- if (selectedBot) {
715
- console.log(chalk.cyan('Varsayılan Bot:'), chalk.white(selectedBot.name));
716
- }
717
-
718
- if (telegramToken) {
719
- console.log(chalk.cyan('Telegram:'), chalk.green('✓ Bağlı'));
720
- }
721
-
722
- if (discordToken) {
723
- console.log(chalk.cyan('Discord:'), chalk.green('✓ Bağlı'));
724
- }
725
-
726
- if (slackToken) {
727
- console.log(chalk.cyan('Slack:'), chalk.green('✓ Bağlı'));
728
- }
729
-
730
- if (whatsappConnected) {
731
- console.log(chalk.cyan('WhatsApp:'), chalk.green('✓ Bağlı'));
732
- }
733
-
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ı'));
734
207
  console.log(chalk.cyan('Config:'), chalk.white(CONFIG_FILE));
735
208
  console.log('');
736
209
  console.log(chalk.yellow('Başlamak için:'), chalk.cyan('natureco chat'));
737
210
  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'));
216
+ console.log('');
217
+ console.log(chalk.gray('Tüm komutlar için:'), chalk.cyan('natureco help'));
218
+ console.log('');
738
219
  }
739
220
 
740
221
  module.exports = setup;
@@ -22,39 +22,16 @@ async function slack(action) {
22
22
  }
23
23
 
24
24
  async function connectSlack() {
25
- const apiKey = getApiKey();
26
-
27
- if (!apiKey) {
28
- console.log(chalk.red('\n❌ Not logged in. Run "natureco login" first.\n'));
29
- process.exit(1);
30
- }
31
-
32
25
  const config = getConfig();
33
26
 
34
- console.log(chalk.yellow('\n⏳ Loading bots...\n'));
35
-
36
- let botList;
37
- try {
38
- botList = await getBots(apiKey);
39
- } catch (err) {
40
- console.log(chalk.red(`\n❌ Error: ${err.message}\n`));
41
- process.exit(1);
42
- }
43
-
44
- if (!botList || !botList.bots || botList.bots.length === 0) {
45
- console.log(chalk.gray('No bots found. Create one at https://developers.natureco.me\n'));
27
+ if (!config.providerUrl) {
28
+ console.log(chalk.red('\n❌ Setup yapılmamış. Önce "natureco setup" çalıştırın.\n'));
46
29
  process.exit(1);
47
30
  }
48
31
 
49
32
  process.stdin.resume();
50
33
 
51
34
  const answers = await inquirer.prompt([
52
- {
53
- type: 'list',
54
- name: 'botId',
55
- message: 'Select bot to connect:',
56
- choices: botList.bots.map(b => ({ name: b.name, value: b.id })),
57
- },
58
35
  {
59
36
  type: 'input',
60
37
  name: 'token',
@@ -68,44 +45,22 @@ async function connectSlack() {
68
45
  },
69
46
  ]);
70
47
 
71
- const selectedBot = botList.bots.find(b => b.id === answers.botId);
48
+ // Slack için bot ID oluştur (timestamp-based)
49
+ const botId = `slack_${Date.now()}`;
50
+ const selectedBot = { name: 'Slack Bot', id: botId };
72
51
 
73
- console.log(chalk.yellow('\n⏳ Connecting to Slack...\n'));
52
+ console.log(chalk.yellow('\n⏳ Slack bağlantısı kaydediliyor...\n'));
74
53
 
75
- try {
76
- const response = await fetch('https://api.natureco.me/api/agent/slack/connect', {
77
- method: 'POST',
78
- headers: {
79
- 'Content-Type': 'application/json',
80
- 'Authorization': `Bearer ${apiKey}`,
81
- },
82
- body: JSON.stringify({
83
- agent_id: answers.botId,
84
- slack_bot_token: answers.token.trim(),
85
- }),
86
- });
87
-
88
- if (!response.ok) {
89
- const error = await response.text();
90
- throw new Error(error);
91
- }
92
-
93
- const data = await response.json();
94
-
95
- console.log(chalk.green('✅ Slack connected successfully!\n'));
96
- console.log(chalk.cyan('Bot:'), chalk.white(selectedBot.name));
97
- console.log(chalk.cyan('Slack Bot:'), chalk.white(data.bot_name || 'Unknown'));
98
- console.log(chalk.gray('\nYour bot is now active on Slack.'));
99
- console.log(chalk.gray('Users can mention the bot or use slash commands.\n'));
100
-
101
- // Save to config
102
- config.slackToken = answers.token.trim();
103
- config.slackBotId = answers.botId;
104
- saveConfig(config);
105
- } catch (err) {
106
- console.log(chalk.red(`\n❌ Connection failed: ${err.message}\n`));
107
- process.exit(1);
108
- }
54
+ // Save to config (v2.x - no backend call)
55
+ config.slackToken = answers.token.trim();
56
+ config.slackBotId = botId;
57
+ saveConfig(config);
58
+
59
+ console.log(chalk.green(' Slack token kaydedildi!\n'));
60
+ console.log(chalk.cyan('Bot ID:'), chalk.white(botId));
61
+ console.log(chalk.cyan('Token:'), chalk.white(answers.token.slice(0, 20) + '...'));
62
+ console.log(chalk.gray('\nNot: Slack botunuzu Slack App settings\'ten yapılandırmanız gerekiyor.'));
63
+ console.log(chalk.gray('Token config\'e kaydedildi: ~/.natureco/config.json\n'));
109
64
  }
110
65
 
111
66
  async function disconnectSlack() {
@@ -58,42 +58,18 @@ async function whatsapp(action) {
58
58
  }
59
59
 
60
60
  async function connectWhatsApp() {
61
- const apiKey = getApiKey();
62
-
63
- if (!apiKey) {
64
- console.log(chalk.red('\n❌ Not logged in. Run "natureco login" first.\n'));
65
- process.exit(1);
66
- }
67
-
68
61
  const config = getConfig();
69
62
 
70
- console.log(chalk.yellow('\n⏳ Loading bots...\n'));
71
-
72
- let botList;
73
- try {
74
- botList = await getBots(apiKey);
75
- } catch (err) {
76
- console.log(chalk.red(`\n❌ Error: ${err.message}\n`));
77
- process.exit(1);
78
- }
79
-
80
- if (!botList || !botList.bots || botList.bots.length === 0) {
81
- console.log(chalk.gray('No bots found. Create one at https://developers.natureco.me\n'));
63
+ if (!config.providerUrl) {
64
+ console.log(chalk.red('\n❌ Setup yapılmamış. Önce "natureco setup" çalıştırın.\n'));
82
65
  process.exit(1);
83
66
  }
84
67
 
85
- process.stdin.resume();
86
-
87
- const { botId } = await inquirer.prompt([
88
- {
89
- type: 'list',
90
- name: 'botId',
91
- message: 'Select bot to connect:',
92
- choices: botList.bots.map(b => ({ name: b.name, value: b.id })),
93
- },
94
- ]);
68
+ console.log(chalk.yellow('\n⏳ WhatsApp bağlantısı hazırlanıyor...\n'));
95
69
 
96
- const selectedBot = botList.bots.find(b => b.id === botId);
70
+ // WhatsApp için bot ID oluştur (timestamp-based)
71
+ const botId = `whatsapp_${Date.now()}`;
72
+ const selectedBot = { name: 'WhatsApp Bot', id: botId };
97
73
 
98
74
  console.log(chalk.cyan('\n📱 WhatsApp bağlantısı başlatılıyor...'));
99
75
  console.log(chalk.gray('Telefonunuzda WhatsApp\'ı açın ve QR kodu taratın.\n'));