natureco-cli 2.23.29 β†’ 2.23.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/README.md +94 -11
  2. package/bin/natureco.js +495 -94
  3. package/package.json +1 -1
  4. package/src/commands/acp.js +39 -0
  5. package/src/commands/admin-rpc.js +302 -0
  6. package/src/commands/agent.js +280 -0
  7. package/src/commands/agents.js +114 -30
  8. package/src/commands/approvals.js +214 -0
  9. package/src/commands/backup.js +124 -0
  10. package/src/commands/bonjour.js +167 -0
  11. package/src/commands/browser.js +815 -0
  12. package/src/commands/capability.js +237 -0
  13. package/src/commands/channels.js +422 -267
  14. package/src/commands/chat.js +5 -8
  15. package/src/commands/clawbot.js +19 -0
  16. package/src/commands/clickclack.js +130 -0
  17. package/src/commands/code.js +3 -2
  18. package/src/commands/commitments.js +148 -0
  19. package/src/commands/completion.js +84 -0
  20. package/src/commands/config.js +219 -30
  21. package/src/commands/configure.js +110 -0
  22. package/src/commands/crestodian.js +92 -0
  23. package/src/commands/cron.js +239 -19
  24. package/src/commands/daemon.js +90 -0
  25. package/src/commands/dashboard.js +47 -374
  26. package/src/commands/device-pair.js +248 -0
  27. package/src/commands/devices.js +137 -0
  28. package/src/commands/directory.js +179 -0
  29. package/src/commands/dns.js +196 -0
  30. package/src/commands/docs.js +136 -0
  31. package/src/commands/doctor.js +143 -492
  32. package/src/commands/exec-policy.js +80 -0
  33. package/src/commands/gateway-server.js +1155 -24
  34. package/src/commands/gateway.js +492 -249
  35. package/src/commands/health.js +148 -0
  36. package/src/commands/help.js +24 -25
  37. package/src/commands/hooks.js +141 -87
  38. package/src/commands/imessage.js +128 -14
  39. package/src/commands/infer.js +1474 -0
  40. package/src/commands/irc.js +64 -15
  41. package/src/commands/logs.js +122 -99
  42. package/src/commands/mattermost.js +114 -12
  43. package/src/commands/mcp.js +121 -309
  44. package/src/commands/memory-cmd.js +134 -1
  45. package/src/commands/memory.js +128 -0
  46. package/src/commands/message.js +720 -134
  47. package/src/commands/migrate.js +213 -2
  48. package/src/commands/models.js +39 -1
  49. package/src/commands/node.js +98 -0
  50. package/src/commands/nodes.js +362 -0
  51. package/src/commands/oc-path.js +200 -0
  52. package/src/commands/onboard.js +129 -0
  53. package/src/commands/open-prose.js +67 -0
  54. package/src/commands/pairing.js +108 -107
  55. package/src/commands/path.js +206 -0
  56. package/src/commands/plugins.js +35 -1
  57. package/src/commands/policy.js +176 -0
  58. package/src/commands/proxy.js +306 -0
  59. package/src/commands/qr.js +70 -0
  60. package/src/commands/reset.js +101 -94
  61. package/src/commands/sandbox.js +125 -0
  62. package/src/commands/secrets.js +201 -0
  63. package/src/commands/sessions.js +110 -51
  64. package/src/commands/setup.js +102 -543
  65. package/src/commands/signal.js +447 -18
  66. package/src/commands/skills.js +67 -1
  67. package/src/commands/sms.js +123 -19
  68. package/src/commands/status.js +101 -127
  69. package/src/commands/system.js +53 -0
  70. package/src/commands/tasks.js +208 -100
  71. package/src/commands/terminal.js +139 -0
  72. package/src/commands/thread-ownership.js +157 -0
  73. package/src/commands/transcripts.js +95 -0
  74. package/src/commands/tui.js +41 -0
  75. package/src/commands/uninstall.js +73 -92
  76. package/src/commands/update.js +146 -91
  77. package/src/commands/voice.js +82 -0
  78. package/src/commands/vydra.js +98 -0
  79. package/src/commands/webhooks.js +58 -66
  80. package/src/commands/wiki.js +783 -0
  81. package/src/commands/workboard.js +207 -0
  82. package/src/tools/audio_understanding.js +154 -0
  83. package/src/tools/browser.js +112 -0
  84. package/src/tools/canvas.js +104 -0
  85. package/src/tools/document_extract.js +84 -0
  86. package/src/tools/duckduckgo.js +54 -0
  87. package/src/tools/exa_search.js +66 -0
  88. package/src/tools/firecrawl.js +104 -0
  89. package/src/tools/image_generation.js +99 -0
  90. package/src/tools/llm_task.js +118 -0
  91. package/src/tools/media_understanding.js +128 -0
  92. package/src/tools/music_generation.js +113 -0
  93. package/src/tools/parallel_search.js +77 -0
  94. package/src/tools/phone_control.js +80 -0
  95. package/src/tools/phone_control_enhanced.js +184 -0
  96. package/src/tools/searxng.js +61 -0
  97. package/src/tools/speech_to_text.js +135 -0
  98. package/src/tools/text_to_speech.js +105 -0
  99. package/src/tools/thread_ownership.js +88 -0
  100. package/src/tools/video_generation.js +72 -0
  101. package/src/tools/web_readability.js +104 -0
  102. package/src/utils/agents-md.js +85 -0
  103. package/src/utils/api.js +39 -40
  104. package/src/utils/format.js +144 -0
  105. package/src/utils/headless.js +2 -1
  106. package/src/utils/memory.js +200 -0
  107. package/src/utils/parallel-tools.js +106 -0
  108. package/src/utils/sub-agent.js +148 -0
  109. package/src/utils/token-budget.js +304 -0
  110. package/src/utils/tool-runner.js +7 -5
  111. package/src/utils/web-fetch.js +107 -0
@@ -1,543 +1,102 @@
1
- const chalk = require('chalk');
2
- const inquirer = require('../utils/inquirer-wrapper');
3
- const fs = require('fs');
4
- const path = require('path');
5
- const os = require('os');
6
- const { saveConfig, CONFIG_DIR, CONFIG_FILE } = require('../utils/config');
7
- const { saveMemory } = require('../utils/memory');
8
-
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',
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
- }
168
-
169
- // ─── Ana fonksiyon ────────────────────────────────────────────────────────────
170
- async function setup() {
171
- console.clear();
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}`));
196
-
197
- // Klasâr oluştur
198
- if (!fs.existsSync(CONFIG_DIR)) {
199
- fs.mkdirSync(CONFIG_DIR, { recursive: true });
200
- }
201
-
202
- // Mevcut config
203
- let existingConfig = {};
204
- if (fs.existsSync(CONFIG_FILE)) {
205
- try { existingConfig = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8')); } catch {}
206
- }
207
-
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
- }]);
218
-
219
- // NatureCo provider seΓ§ildiyse URL'yi ayarla
220
- let providerUrl = providerChoice; // varsayılan: seçilen değer direkt URL
221
- let isNatureCo = false;
222
- if (providerChoice === 'natureco') {
223
- providerUrl = NATURECO_PROVIDER.url;
224
- isNatureCo = true;
225
- } else if (providerChoice === 'custom') {
226
- const { customUrl } = await inquirer.prompt([{
227
- type: 'input',
228
- name: 'customUrl',
229
- message: L.customUrl,
230
- validate: (v) => {
231
- if (!v.trim()) return L.urlRequired;
232
- if (!v.startsWith('http://') && !v.startsWith('https://')) return L.urlInvalid;
233
- return true;
234
- },
235
- }]);
236
- providerUrl = customUrl.trim();
237
- }
238
-
239
- const { providerApiKey } = await inquirer.prompt([{
240
- type: 'password',
241
- name: 'providerApiKey',
242
- message: isNatureCo ? L.apiKeyNatureCo : L.apiKeyQ,
243
- mask: '*',
244
- validate: (v) => v.trim() ? true : L.apiKeyRequired,
245
- }]);
246
-
247
- // Model listesi β€” NatureCo seΓ§ildiyse atla
248
- let providerModel;
249
- if (isNatureCo) {
250
- providerModel = 'natureco-default';
251
- } else {
252
- let modelChoices = [L.customModelEntry];
253
- for (const [domain, models] of Object.entries(COMMON_MODELS)) {
254
- if (providerUrl.includes(domain)) {
255
- modelChoices = [...models, L.customModelEntry];
256
- break;
257
- }
258
- }
259
-
260
- const { modelChoice } = await inquirer.prompt([{
261
- type: 'list',
262
- name: 'modelChoice',
263
- message: L.modelQ,
264
- choices: modelChoices,
265
- }]);
266
-
267
- providerModel = modelChoice;
268
- if (modelChoice === L.customModelEntry) {
269
- const { customModel } = await inquirer.prompt([{
270
- type: 'input',
271
- name: 'customModel',
272
- message: L.customModel,
273
- validate: (v) => v.trim() ? true : L.modelRequired,
274
- }]);
275
- providerModel = customModel.trim();
276
- }
277
- }
278
-
279
- printDone(L, `${providerUrl.replace('https://', '').split('/')[0]} Β· ${providerModel}`);
280
-
281
- // ── ADIM 2: Bot adΔ± β€” NatureCo provider'da API'den Γ§ek ───────────────────
282
- printStep(L, 2, L.botNameTitle);
283
-
284
- let safeBotName = existingConfig.botName || 'NatureBot';
285
-
286
- if (isNatureCo) {
287
- // API'den bot listesini Γ§ek
288
- console.log(chalk.gray(lang === 'tr' ? ' Botlar yΓΌkleniyor...' : ' Loading bots...'));
289
- try {
290
- const res = await fetch('https://api.natureco.me/api/v1/bots', {
291
- headers: { 'Authorization': `Bearer ${providerApiKey.trim()}` },
292
- });
293
- if (res.ok) {
294
- const data = await res.json();
295
- const bots = Array.isArray(data) ? data : (data.bots || data.data || []);
296
- if (bots.length > 0) {
297
- if (bots.length === 1) {
298
- // Tek bot varsa otomatik seΓ§
299
- safeBotName = bots[0].name;
300
- printDone(L, safeBotName);
301
- } else {
302
- // Birden fazla bot varsa seΓ§tir
303
- const { selectedBotName } = await inquirer.prompt([{
304
- type: 'list',
305
- name: 'selectedBotName',
306
- message: lang === 'tr' ? ' Hangi botu kullanmak istiyorsunuz?' : ' Which bot do you want to use?',
307
- choices: bots.map(b => ({ name: b.name, value: b.name })),
308
- }]);
309
- safeBotName = selectedBotName;
310
- printDone(L, safeBotName);
311
- }
312
- } else {
313
- console.log(chalk.yellow(lang === 'tr'
314
- ? ' Bot bulunamadı. developers.natureco.me\'den bot oluşturun.'
315
- : ' No bots found. Create one at developers.natureco.me'));
316
- printDone(L, safeBotName);
317
- }
318
- } else {
319
- console.log(chalk.yellow(lang === 'tr' ? ' Bot listesi alΔ±namadΔ±.' : ' Could not fetch bot list.'));
320
- printDone(L, safeBotName);
321
- }
322
- } catch (e) {
323
- console.log(chalk.yellow(lang === 'tr' ? ' Bağlantı hatası, varsayılan kullanılıyor.' : ' Connection error, using default.'));
324
- printDone(L, safeBotName);
325
- }
326
- } else {
327
- const { botName } = await inquirer.prompt([{
328
- type: 'input',
329
- name: 'botName',
330
- message: L.botNameQ,
331
- default: existingConfig.botName || L.botNameDefault,
332
- validate: (v) => v.trim() ? true : L.nameRequired,
333
- }]);
334
- safeBotName = String(botName || 'NatureBot').trim();
335
- printDone(L, safeBotName);
336
- }
337
-
338
- // ── ADIM 3: KullanΔ±cΔ± adΔ± ──────────────────────────────────────────────────
339
- printStep(L, 3, L.userNameTitle);
340
-
341
- const { userName } = await inquirer.prompt([{
342
- type: 'input',
343
- name: 'userName',
344
- message: L.userNameQ,
345
- default: existingConfig.userName || L.userNameDefault,
346
- validate: (v) => v.trim() ? true : L.nameRequired,
347
- }]);
348
-
349
- printDone(L, userName.trim());
350
-
351
- // ── ADIM 4: Entegrasyonlar ─────────────────────────────────────────────────
352
- printStep(L, 4, L.integTitle);
353
-
354
- const { integrations } = await inquirer.prompt([{
355
- type: 'checkbox',
356
- name: 'integrations',
357
- message: L.integQ,
358
- choices: [
359
- { name: 'Telegram', value: 'Telegram' },
360
- { name: 'WhatsApp', value: 'WhatsApp' },
361
- { name: 'Discord', value: 'Discord' },
362
- { name: 'Slack', value: 'Slack' },
363
- ],
364
- }]);
365
-
366
- // ── Entegrasyon sub-flow'larΔ± ──────────────────────────────────────────────
367
- const integConfig = {};
368
-
369
- if (integrations.includes('Telegram')) {
370
- console.log('');
371
- console.log(chalk.cyan(' Telegram kurulumu:'));
372
- const { tgToken } = await inquirer.prompt([{
373
- type: 'input',
374
- name: 'tgToken',
375
- message: lang === 'tr' ? ' Bot Token girin (BotFather\'dan):' : ' Enter Bot Token (from BotFather):',
376
- validate: (v) => v.trim() ? true : (lang === 'tr' ? 'Token gerekli' : 'Token required'),
377
- }]);
378
- const { tgChatId } = await inquirer.prompt([{
379
- type: 'input',
380
- name: 'tgChatId',
381
- 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):',
382
- validate: (v) => v.trim() ? true : (lang === 'tr' ? 'Chat ID gerekli' : 'Chat ID required'),
383
- }]);
384
- console.log(chalk.gray(lang === 'tr'
385
- ? ' πŸ’‘ Chat ID\'nizi âğrenmek iΓ§in @userinfobot\'a /start yazΔ±n'
386
- : ' πŸ’‘ To find your Chat ID, send /start to @userinfobot'));
387
- integConfig.telegramToken = tgToken.trim();
388
- integConfig.telegramChatId = tgChatId.trim();
389
- // Bağlantı testi
390
- try {
391
- const res = await fetch(`https://api.telegram.org/bot${tgToken.trim()}/getMe`);
392
- const data = await res.json();
393
- if (data.ok) {
394
- printDone(L, `Telegram @${data.result.username}`);
395
- } else {
396
- console.log(chalk.yellow(' ⚠ Token geçersiz gârünüyor, ilerleyebilirsin'));
397
- }
398
- } catch {
399
- console.log(chalk.gray(' (bağlantı testi atlandı)'));
400
- }
401
- }
402
-
403
- if (integrations.includes('WhatsApp')) {
404
- console.log('');
405
- console.log(chalk.cyan(lang === 'tr'
406
- ? ' WhatsApp için gateway başlatılması gerekiyor.'
407
- : ' WhatsApp requires the gateway to be running.'));
408
- console.log(chalk.gray(lang === 'tr'
409
- ? ' Kurulum sonunda gateway başlatılacak, ardından QR kodu taratman gerekecek.'
410
- : ' The gateway will start after setup β€” you\'ll need to scan the QR code.'));
411
- printDone(L, 'WhatsApp');
412
- }
413
-
414
- if (integrations.includes('Discord')) {
415
- console.log('');
416
- console.log(chalk.cyan(' Discord kurulumu:'));
417
- const { discordToken } = await inquirer.prompt([{
418
- type: 'password',
419
- name: 'discordToken',
420
- message: lang === 'tr' ? ' Discord Bot Token girin:' : ' Enter Discord Bot Token:',
421
- mask: '*',
422
- validate: (v) => v.trim() ? true : (lang === 'tr' ? 'Token gerekli' : 'Token required'),
423
- }]);
424
- integConfig.discordToken = discordToken.trim();
425
- printDone(L, 'Discord');
426
- }
427
-
428
- if (integrations.length > 0) {
429
- if (!integrations.includes('Telegram') && !integrations.includes('WhatsApp') && !integrations.includes('Discord')) {
430
- printDone(L, integrations.join(', '));
431
- }
432
- console.log('');
433
- if (integrations.includes('Slack')) {
434
- console.log(chalk.gray(` β†’ natureco slack connect`));
435
- }
436
- } else {
437
- printDone(L, L.integSkip);
438
- }
439
-
440
- // ── ADIM 5: Gateway ────────────────────────────────────────────────────────
441
- printStep(L, 5, L.gatewayTitle);
442
- const { startGateway } = await inquirer.prompt([{
443
- type: 'confirm',
444
- name: 'startGateway',
445
- message: L.gatewayQ,
446
- default: integrations.includes('WhatsApp'),
447
- }]);
448
-
449
- // ── Config kaydet ──────────────────────────────────────────────────────────
450
- const config = {
451
- ...existingConfig,
452
- setupCompleted: true,
453
- setupDate: new Date().toISOString(),
454
- language: lang,
455
- providerUrl,
456
- providerApiKey: providerApiKey.trim(),
457
- botName: safeBotName,
458
- userName: userName.trim(),
459
- debug: existingConfig.debug || false,
460
- skills: existingConfig.skills || { enabled: true, list: [] },
461
- mcpServers: existingConfig.mcpServers || {},
462
- // Entegrasyon config'leri
463
- ...(integConfig.telegramToken && { telegramToken: integConfig.telegramToken }),
464
- ...(integConfig.telegramChatId && { telegramChatId: integConfig.telegramChatId }),
465
- ...(integConfig.discordToken && { discordToken: integConfig.discordToken }),
466
- };
467
-
468
- saveConfig(config);
469
-
470
- // HafΔ±zaya kullanΔ±cΔ± adΔ± ve bot adΔ± kaydet
471
- const botId = 'universal-provider';
472
- try {
473
- saveMemory(botId, {
474
- name: userName.trim(),
475
- botName: safeBotName,
476
- nickname: '',
477
- preferences: [],
478
- facts: [],
479
- lastSeen: new Date().toISOString(),
480
- });
481
- } catch {}
482
-
483
- // ── Γ–zet ───────────────────────────────────────────────────────────────────
484
- console.log('');
485
- console.log(chalk.gray('─'.repeat(50)));
486
- console.log(chalk.green.bold(` ${L.summaryTitle}`));
487
- console.log('');
488
- console.log(chalk.gray(` ${L.summaryProvider}:`), chalk.white(providerUrl.replace('https://', '').split('/')[0]));
489
- console.log(chalk.gray(` ${L.summaryModel}:`), chalk.white(providerModel));
490
- console.log(chalk.gray(` ${L.summaryBot}:`), chalk.cyan(safeBotName));
491
- console.log(chalk.gray(` ${L.summaryUser}:`), chalk.white(userName.trim()));
492
- console.log(chalk.gray(` ${L.summaryConfig}:`), chalk.gray(CONFIG_FILE));
493
- console.log('');
494
-
495
- // Gateway başlat
496
- if (startGateway) {
497
- console.log(chalk.cyan(` ${L.gatewayYes}`));
498
- try {
499
- const { spawn } = require('child_process');
500
- const gatewayBin = path.join(__dirname, '..', '..', 'bin', 'natureco.js');
501
- spawn(process.execPath, [gatewayBin, 'gateway', 'start'], {
502
- detached: true,
503
- stdio: 'ignore',
504
- }).unref();
505
- printDone(L, 'Gateway');
506
- if (integrations.includes('WhatsApp')) {
507
- console.log('');
508
- console.log(chalk.yellow(lang === 'tr'
509
- ? ' πŸ“± WhatsApp QR kodunu taratmak iΓ§in: natureco whatsapp connect'
510
- : ' πŸ“± To scan WhatsApp QR code: natureco whatsapp connect'));
511
- }
512
- } catch (e) {
513
- console.log(chalk.yellow(` ⚠ ${e.message}`));
514
- }
515
- } else {
516
- console.log(chalk.gray(` ${L.gatewaySkip}`));
517
- }
518
-
519
- // ── ADIM 6: Chat ───────────────────────────────────────────────────────────
520
- printStep(L, 6, L.chatTitle);
521
-
522
- const { startChat } = await inquirer.prompt([{
523
- type: 'confirm',
524
- name: 'startChat',
525
- message: L.chatQ,
526
- default: true,
527
- }]);
528
-
529
- console.log('');
530
-
531
- if (startChat) {
532
- console.log(chalk.cyan(` ${L.chatStart}`));
533
- console.log('');
534
- const chat = require('./chat');
535
- // NatureCo provider'da seçilen bot adıyla başlat
536
- await chat(safeBotName, {});
537
- } else {
538
- console.log(chalk.gray(` ${L.chatSkip}`));
539
- console.log('');
540
- }
541
- }
542
-
543
- module.exports = setup;
1
+ const chalk = require('chalk');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const os = require('os');
5
+
6
+ const BASE_DIR = path.join(os.homedir(), '.natureco');
7
+ const CONFIG_FILE = path.join(BASE_DIR, 'config.json');
8
+
9
+ const DIRS = ['sources', 'concepts', 'cache', 'skills', 'memory', 'sessions', 'backups'];
10
+
11
+ function setup(params) {
12
+ try {
13
+ const [action] = params || [];
14
+
15
+ if (!action || action === 'status') return cmdStatus();
16
+ if (action === 'config') return cmdConfig();
17
+ if (action === 'workspace') return cmdWorkspace();
18
+ if (action === 'dirs') return cmdDirs();
19
+
20
+ console.log(chalk.red(`\n Unknown setup action: ${action}\n`));
21
+ console.log(chalk.gray(' Usage: natureco setup [config|workspace|dirs|status]\n'));
22
+ } catch (err) {
23
+ console.log(chalk.red(`\n Setup error: ${err.message}\n`));
24
+ }
25
+ }
26
+
27
+ function cmdStatus() {
28
+ console.log(chalk.cyan('\n Setup Status\n'));
29
+
30
+ const configExists = fs.existsSync(CONFIG_FILE);
31
+ const dirExists = fs.existsSync(BASE_DIR);
32
+
33
+ console.log(chalk.white(' Config: ') + (configExists ? chalk.green('exists') : chalk.yellow('missing')));
34
+ console.log(chalk.white(' Directory: ') + (dirExists ? chalk.green('exists') : chalk.yellow('missing')));
35
+
36
+ if (dirExists) {
37
+ const existing = fs.readdirSync(BASE_DIR).filter(f => fs.statSync(path.join(BASE_DIR, f)).isDirectory());
38
+ const present = DIRS.filter(d => existing.includes(d));
39
+ const absent = DIRS.filter(d => !existing.includes(d));
40
+ if (present.length) console.log(chalk.white(' Dirs: ') + chalk.green(present.join(', ')));
41
+ if (absent.length) console.log(chalk.white(' Missing: ') + chalk.yellow(absent.join(', ')));
42
+ }
43
+
44
+ console.log('');
45
+ }
46
+
47
+ function cmdConfig() {
48
+ if (!fs.existsSync(BASE_DIR)) fs.mkdirSync(BASE_DIR, { recursive: true });
49
+
50
+ const defaults = {
51
+ version: 1,
52
+ created: new Date().toISOString(),
53
+ updated: new Date().toISOString(),
54
+ setupCompleted: false,
55
+ skills: { enabled: true, list: [] },
56
+ mcpServers: {},
57
+ };
58
+
59
+ if (fs.existsSync(CONFIG_FILE)) {
60
+ console.log(chalk.yellow('\n Config already exists at: ' + CONFIG_FILE + '\n'));
61
+ return;
62
+ }
63
+
64
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(defaults, null, 2), 'utf8');
65
+ console.log(chalk.green('\n Config created at: ' + CONFIG_FILE + '\n'));
66
+ }
67
+
68
+ function cmdWorkspace() {
69
+ if (!fs.existsSync(BASE_DIR)) fs.mkdirSync(BASE_DIR, { recursive: true });
70
+
71
+ const workspaceDir = path.join(BASE_DIR, 'workspace');
72
+ const logsDir = path.join(BASE_DIR, 'logs');
73
+
74
+ if (!fs.existsSync(workspaceDir)) fs.mkdirSync(workspaceDir, { recursive: true });
75
+ if (!fs.existsSync(logsDir)) fs.mkdirSync(logsDir, { recursive: true });
76
+
77
+ console.log(chalk.green('\n Workspace directories created:\n'));
78
+ console.log(chalk.gray(' ' + workspaceDir));
79
+ console.log(chalk.gray(' ' + logsDir));
80
+ console.log('');
81
+ }
82
+
83
+ function cmdDirs() {
84
+ if (!fs.existsSync(BASE_DIR)) fs.mkdirSync(BASE_DIR, { recursive: true });
85
+
86
+ let created = 0;
87
+ for (const dir of DIRS) {
88
+ const p = path.join(BASE_DIR, dir);
89
+ if (!fs.existsSync(p)) {
90
+ fs.mkdirSync(p, { recursive: true });
91
+ created++;
92
+ }
93
+ }
94
+
95
+ console.log(chalk.green(`\n Created ${created} data director${created === 1 ? 'y' : 'ies'}`));
96
+ if (created > 0) {
97
+ console.log(chalk.gray(' Location: ' + BASE_DIR));
98
+ }
99
+ console.log('');
100
+ }
101
+
102
+ module.exports = setup;