natureco-cli 2.16.5 → 2.17.2

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/bin/natureco.js CHANGED
@@ -244,6 +244,105 @@ program
244
244
  doctorCmd(args);
245
245
  });
246
246
 
247
+ program
248
+ .command('channels [action] [params...]')
249
+ .description('Manage connected channels (list|status|remove|logs)')
250
+ .action((action, params) => {
251
+ const channelsCmd = require('../src/commands/channels');
252
+ channelsCmd([action, ...(params || [])]);
253
+ });
254
+
255
+ program
256
+ .command('models [action] [params...]')
257
+ .description('Manage AI models (list|set|scan|aliases)')
258
+ .action((action, params) => {
259
+ const modelsCmd = require('../src/commands/models');
260
+ modelsCmd([action, ...(params || [])]);
261
+ });
262
+
263
+ program
264
+ .command('memory [action] [params...]')
265
+ .description('Manage memory (status|list|search|show|clear|index)')
266
+ .action((action, params) => {
267
+ const memoryCmd = require('../src/commands/memory-cmd');
268
+ memoryCmd([action, ...(params || [])]);
269
+ });
270
+
271
+ program
272
+ .command('logs')
273
+ .description('View and follow gateway logs')
274
+ .option('--follow, -f', 'Follow logs in real-time')
275
+ .option('--json', 'JSON output')
276
+ .option('--plain', 'Plain text output')
277
+ .option('--limit <n>', 'Number of lines to show', '50')
278
+ .action(() => {
279
+ const logsCmd = require('../src/commands/logs');
280
+ logsCmd(process.argv.slice(3));
281
+ });
282
+
283
+ program
284
+ .command('status')
285
+ .description('Show overall system status')
286
+ .action(() => {
287
+ const statusCmd = require('../src/commands/status');
288
+ statusCmd();
289
+ });
290
+
291
+ program
292
+ .command('reset')
293
+ .description('Reset local config/state')
294
+ .option('--scope <scope>', 'Scope: config|memory|sessions|full', 'config')
295
+ .option('--yes, -y', 'Skip confirmation')
296
+ .action(() => {
297
+ const resetCmd = require('../src/commands/reset');
298
+ resetCmd(process.argv.slice(3));
299
+ });
300
+
301
+ program
302
+ .command('security [action]')
303
+ .description('Security audit (audit)')
304
+ .option('--fix', 'Auto-fix issues')
305
+ .option('--json', 'JSON output')
306
+ .action((action) => {
307
+ const securityCmd = require('../src/commands/security');
308
+ securityCmd(process.argv.slice(3));
309
+ });
310
+
311
+ program
312
+ .command('agents [action] [params...]')
313
+ .description('Manage agents/bots (list|set|info|add)')
314
+ .action((action, params) => {
315
+ const agentsCmd = require('../src/commands/agents');
316
+ agentsCmd([action, ...(params || [])]);
317
+ });
318
+
319
+ program
320
+ .command('plugins [action] [params...]')
321
+ .description('Manage plugins (list|install|enable|disable|info|doctor)')
322
+ .action((action, params) => {
323
+ const pluginsCmd = require('../src/commands/plugins');
324
+ pluginsCmd([action, ...(params || [])]);
325
+ });
326
+
327
+ program
328
+ .command('pairing [action] [params...]')
329
+ .description('Manage device pairings (list|approve|reject)')
330
+ .action((action, params) => {
331
+ const pairingCmd = require('../src/commands/pairing');
332
+ pairingCmd([action, ...(params || [])]);
333
+ });
334
+
335
+ program
336
+ .command('uninstall')
337
+ .description('Uninstall NatureCo CLI data')
338
+ .option('--all', 'Remove all data including config')
339
+ .option('--yes, -y', 'Skip confirmation')
340
+ .option('--dry-run', 'Preview actions without executing')
341
+ .action(() => {
342
+ const uninstallCmd = require('../src/commands/uninstall');
343
+ uninstallCmd(process.argv.slice(3));
344
+ });
345
+
247
346
  program
248
347
  .command('help')
249
348
  .description('Show help information')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "natureco-cli",
3
- "version": "2.16.5",
3
+ "version": "2.17.2",
4
4
  "description": "NatureCo AI Bot Terminal Interface",
5
5
  "main": "bin/natureco.js",
6
6
  "bin": {
@@ -0,0 +1,141 @@
1
+ const chalk = require('chalk');
2
+ const inquirer = require('inquirer');
3
+ const { getConfig, saveConfig } = require('../utils/config');
4
+ const { getBots } = require('../utils/api');
5
+
6
+ async function agents(args) {
7
+ const [action, ...params] = (args || []);
8
+
9
+ if (!action || action === 'list') return listAgents();
10
+ if (action === 'set') return setActiveAgent(params[0]);
11
+ if (action === 'info') return agentInfo(params[0]);
12
+ if (action === 'add') return addAgent();
13
+
14
+ console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
15
+ console.log(chalk.gray(' Kullanım: natureco agents [list|set|info|add]\n'));
16
+ process.exit(1);
17
+ }
18
+
19
+ async function listAgents() {
20
+ const config = getConfig();
21
+ const apiKey = config.providerApiKey || config.apiKey || '';
22
+
23
+ console.log(chalk.gray('\n Agentlar yükleniyor...\n'));
24
+
25
+ let botList = { bots: [] };
26
+ try {
27
+ botList = await getBots(apiKey);
28
+ } catch {}
29
+
30
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
31
+ console.log(chalk.cyan.bold('\n Agentlar (Botlar)\n'));
32
+
33
+ if (!botList.bots?.length) {
34
+ console.log(chalk.gray(' Agent bulunamadı.'));
35
+ console.log(chalk.gray(' Oluşturmak için: ') + chalk.cyan('developers.natureco.me\n'));
36
+ return;
37
+ }
38
+
39
+ botList.bots.forEach((bot, i) => {
40
+ const active = config.botName === bot.name ? chalk.green(' ← aktif') : '';
41
+ console.log(chalk.white(` ${i + 1}. ${bot.name}`) + active);
42
+ console.log(chalk.gray(` ID : ${bot.id}`));
43
+ console.log(chalk.gray(` Provider: ${bot.ai_provider || 'groq'}`));
44
+ if (bot.model) console.log(chalk.gray(` Model : ${bot.model}`));
45
+ console.log('');
46
+ });
47
+
48
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
49
+ console.log(chalk.gray(' Değiştirmek için: ') + chalk.cyan('natureco agents set <bot-adı>\n'));
50
+ }
51
+
52
+ async function setActiveAgent(botName) {
53
+ const config = getConfig();
54
+ const apiKey = config.providerApiKey || config.apiKey || '';
55
+
56
+ let botList = { bots: [] };
57
+ try {
58
+ botList = await getBots(apiKey);
59
+ } catch {}
60
+
61
+ if (!botName) {
62
+ if (!botList.bots?.length) {
63
+ console.log(chalk.gray('\n Agent bulunamadı.\n'));
64
+ return;
65
+ }
66
+ const { selected } = await inquirer.prompt([{
67
+ type: 'list',
68
+ name: 'selected',
69
+ message: ' Aktif agent seç:',
70
+ choices: botList.bots.map(b => ({ name: b.name, value: b.name })),
71
+ }]);
72
+ botName = selected;
73
+ }
74
+
75
+ const bot = botList.bots?.find(b => b.name === botName || b.id === botName);
76
+ if (!bot && botList.bots?.length) {
77
+ console.log(chalk.red(`\n ❌ Agent bulunamadı: ${botName}\n`));
78
+ process.exit(1);
79
+ }
80
+
81
+ config.botName = botName;
82
+ if (bot?.id) config.defaultBotId = bot.id;
83
+ saveConfig(config);
84
+
85
+ console.log(chalk.green(`\n ✓ Aktif agent: ${botName}\n`));
86
+ }
87
+
88
+ async function agentInfo(botName) {
89
+ const config = getConfig();
90
+ const apiKey = config.providerApiKey || config.apiKey || '';
91
+ const name = botName || config.botName;
92
+
93
+ if (!name) {
94
+ console.log(chalk.gray('\n Agent adı belirtin: natureco agents info <bot-adı>\n'));
95
+ return;
96
+ }
97
+
98
+ let botList = { bots: [] };
99
+ try {
100
+ botList = await getBots(apiKey);
101
+ } catch {}
102
+
103
+ const bot = botList.bots?.find(b => b.name === name || b.id === name);
104
+
105
+ console.log('');
106
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
107
+ console.log(chalk.cyan.bold(`\n Agent: ${name}\n`));
108
+
109
+ if (bot) {
110
+ console.log(chalk.gray(' ID : ') + chalk.white(bot.id));
111
+ console.log(chalk.gray(' Provider: ') + chalk.white(bot.ai_provider || 'groq'));
112
+ if (bot.model) console.log(chalk.gray(' Model : ') + chalk.white(bot.model));
113
+ if (bot.system_prompt) {
114
+ console.log(chalk.gray(' Prompt : ') + chalk.white(bot.system_prompt.slice(0, 80) + (bot.system_prompt.length > 80 ? '...' : '')));
115
+ }
116
+ } else {
117
+ console.log(chalk.gray(' (Detay alınamadı)'));
118
+ }
119
+
120
+ // Hafıza bilgisi
121
+ try {
122
+ const { loadMemory } = require('../utils/memory');
123
+ const mem = loadMemory(bot?.id || 'universal-provider');
124
+ if (mem.name || mem.facts?.length) {
125
+ console.log('');
126
+ if (mem.name) console.log(chalk.gray(' Kullanıcı: ') + chalk.white(mem.name));
127
+ console.log(chalk.gray(' Hafıza : ') + chalk.white(`${(mem.facts || []).length} bilgi`));
128
+ }
129
+ } catch {}
130
+
131
+ console.log('');
132
+ }
133
+
134
+ async function addAgent() {
135
+ console.log('');
136
+ console.log(chalk.gray(' Yeni agent oluşturmak için Developers Portal\'ı kullanın:'));
137
+ console.log(chalk.cyan(' developers.natureco.me\n'));
138
+ console.log(chalk.gray(' Oluşturduktan sonra: ') + chalk.cyan('natureco agents list\n'));
139
+ }
140
+
141
+ module.exports = agents;
@@ -3,37 +3,38 @@ const { getApiKey } = require('../utils/config');
3
3
  const { getBots } = require('../utils/api');
4
4
 
5
5
  async function bots() {
6
- const apiKey = getApiKey();
6
+ const { getConfig } = require('../utils/config');
7
+ const config = getConfig();
8
+ const apiKey = getApiKey() || config.providerApiKey || '';
7
9
 
8
- if (!apiKey) {
9
- console.log(chalk.red('\n❌ Not logged in. Run "natureco login" first.\n'));
10
- process.exit(1);
11
- }
12
-
13
- console.log(chalk.yellow('\n⏳ Fetching your bots...\n'));
10
+ console.log(chalk.gray('\n Botlar yükleniyor...\n'));
14
11
 
15
12
  try {
16
13
  const botList = await getBots(apiKey);
17
14
 
18
15
  if (!botList || !botList.bots || botList.bots.length === 0) {
19
- console.log(chalk.gray('No bots found. Create one at https://developers.natureco.me\n'));
16
+ console.log(chalk.gray(' Bot bulunamadı.'));
17
+ console.log(chalk.gray(' Oluşturmak için: ') + chalk.cyan('developers.natureco.me\n'));
20
18
  return;
21
19
  }
22
20
 
23
- console.log(chalk.green.bold('╭─ Your Bots ─╮\n'));
21
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
22
+ console.log(chalk.cyan.bold('\n Botlarım\n'));
24
23
 
25
24
  botList.bots.forEach((bot, index) => {
26
- console.log(chalk.cyan(`${index + 1}. ${bot.name}`));
27
- console.log(chalk.gray(` ID: ${bot.id}`));
28
- console.log(chalk.gray(` Provider: ${bot.ai_provider || 'openai'}`));
29
- console.log(chalk.gray(` Public: ${bot.is_public ? 'Yes' : 'No'}`));
25
+ const active = config.botName === bot.name ? chalk.green(' ← aktif') : '';
26
+ console.log(chalk.white(` ${index + 1}. ${bot.name}`) + active);
27
+ console.log(chalk.gray(` ID : ${bot.id}`));
28
+ console.log(chalk.gray(` Provider: ${bot.ai_provider || 'groq'}`));
29
+ if (bot.model) console.log(chalk.gray(` Model : ${bot.model}`));
30
30
  console.log('');
31
31
  });
32
32
 
33
- console.log(chalk.green('╰──────────────╯\n'));
34
- console.log(chalk.gray(`Total: ${botList.bots.length} bot(s)\n`));
33
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
34
+ console.log(chalk.gray(` Toplam: ${botList.bots.length} bot`));
35
+ console.log(chalk.gray(' Chat başlatmak için: ') + chalk.cyan('natureco chat\n'));
35
36
  } catch (err) {
36
- console.log(chalk.red(`\n❌ Error: ${err.message}\n`));
37
+ console.log(chalk.red(`\n Hata: ${err.message}\n`));
37
38
  process.exit(1);
38
39
  }
39
40
  }
@@ -0,0 +1,177 @@
1
+ const chalk = require('chalk');
2
+ const { getConfig, saveConfig } = require('../utils/config');
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const os = require('os');
6
+
7
+ async function channels(args) {
8
+ const [action, ...params] = (args || []);
9
+
10
+ if (!action || action === 'list') return listChannels();
11
+ if (action === 'status') return statusChannels();
12
+ if (action === 'remove') return removeChannel(params[0]);
13
+ if (action === 'logs') return channelLogs(params[0]);
14
+
15
+ console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
16
+ console.log(chalk.gray(' Kullanım: natureco channels [list|status|remove|logs]\n'));
17
+ process.exit(1);
18
+ }
19
+
20
+ function listChannels() {
21
+ const config = getConfig();
22
+ const channels = [];
23
+
24
+ if (config.telegramToken) {
25
+ channels.push({
26
+ name: 'Telegram',
27
+ icon: '✈',
28
+ status: 'bağlı',
29
+ detail: `token: ${config.telegramToken.slice(0, 12)}...`,
30
+ chats: (config.telegramAllowedChats || []).length,
31
+ });
32
+ }
33
+
34
+ if (config.whatsappConnected) {
35
+ channels.push({
36
+ name: 'WhatsApp',
37
+ icon: '📱',
38
+ status: 'bağlı',
39
+ detail: config.whatsappPhone ? `+${config.whatsappPhone.split(':')[0]}` : 'bağlı',
40
+ chats: (config.whatsappAllowedNumbers || []).length,
41
+ });
42
+ }
43
+
44
+ if (config.discordToken) {
45
+ channels.push({
46
+ name: 'Discord',
47
+ icon: '🎮',
48
+ status: 'bağlı',
49
+ detail: `token: ${config.discordToken.slice(0, 12)}...`,
50
+ chats: 0,
51
+ });
52
+ }
53
+
54
+ if (config.slackToken) {
55
+ channels.push({
56
+ name: 'Slack',
57
+ icon: '💼',
58
+ status: 'bağlı',
59
+ detail: `token: ${config.slackToken.slice(0, 12)}...`,
60
+ chats: 0,
61
+ });
62
+ }
63
+
64
+ console.log('');
65
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
66
+ console.log(chalk.cyan.bold('\n Kanallar\n'));
67
+
68
+ if (channels.length === 0) {
69
+ console.log(chalk.gray(' Bağlı kanal yok.\n'));
70
+ console.log(chalk.gray(' Bağlamak için:'));
71
+ console.log(chalk.cyan(' natureco telegram connect'));
72
+ console.log(chalk.cyan(' natureco whatsapp connect'));
73
+ console.log(chalk.cyan(' natureco discord connect'));
74
+ console.log(chalk.cyan(' natureco slack connect\n'));
75
+ return;
76
+ }
77
+
78
+ channels.forEach(ch => {
79
+ console.log(chalk.white(` ${ch.icon} ${ch.name}`) + chalk.green(' ✓ ' + ch.status));
80
+ console.log(chalk.gray(` ${ch.detail}`));
81
+ if (ch.chats > 0) console.log(chalk.gray(` İzin listesi: ${ch.chats} kayıt`));
82
+ console.log('');
83
+ });
84
+
85
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
86
+ console.log(chalk.gray(` Toplam: ${channels.length} kanal bağlı`));
87
+ console.log(chalk.gray(' Kaldırmak için: ') + chalk.cyan('natureco channels remove <kanal>\n'));
88
+ }
89
+
90
+ function statusChannels() {
91
+ const config = getConfig();
92
+ console.log('');
93
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
94
+ console.log(chalk.cyan.bold('\n Kanal Durumu\n'));
95
+
96
+ const checks = [
97
+ { name: 'Telegram', ok: !!config.telegramToken },
98
+ { name: 'WhatsApp', ok: !!config.whatsappConnected },
99
+ { name: 'Discord', ok: !!config.discordToken },
100
+ { name: 'Slack', ok: !!config.slackToken },
101
+ ];
102
+
103
+ checks.forEach(ch => {
104
+ const icon = ch.ok ? chalk.green('✓') : chalk.gray('○');
105
+ const label = ch.ok ? chalk.white(ch.name) : chalk.gray(ch.name);
106
+ const status = ch.ok ? chalk.green('bağlı') : chalk.gray('bağlı değil');
107
+ console.log(` ${icon} ${label.padEnd(12)} ${status}`);
108
+ });
109
+
110
+ const connected = checks.filter(c => c.ok).length;
111
+ console.log('');
112
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
113
+ console.log(chalk.gray(` ${connected}/4 kanal aktif\n`));
114
+ }
115
+
116
+ function removeChannel(channel) {
117
+ if (!channel) {
118
+ console.log(chalk.red('\n ❌ Kanal adı gerekli\n'));
119
+ console.log(chalk.gray(' Kullanım: natureco channels remove <telegram|whatsapp|discord|slack>\n'));
120
+ process.exit(1);
121
+ }
122
+
123
+ const config = getConfig();
124
+ const ch = channel.toLowerCase();
125
+
126
+ if (ch === 'telegram') {
127
+ delete config.telegramToken;
128
+ delete config.telegramBotId;
129
+ delete config.telegramAllowedChats;
130
+ } else if (ch === 'whatsapp') {
131
+ // Session dosyalarını sil
132
+ if (config.whatsappBotId) {
133
+ const sessionDir = path.join(os.homedir(), '.natureco', 'whatsapp-sessions', config.whatsappBotId);
134
+ if (fs.existsSync(sessionDir)) {
135
+ fs.rmSync(sessionDir, { recursive: true, force: true });
136
+ }
137
+ }
138
+ delete config.whatsappConnected;
139
+ delete config.whatsappBotId;
140
+ delete config.whatsappPhone;
141
+ delete config.whatsappAllowedNumbers;
142
+ } else if (ch === 'discord') {
143
+ delete config.discordToken;
144
+ delete config.discordBotId;
145
+ } else if (ch === 'slack') {
146
+ delete config.slackToken;
147
+ delete config.slackBotId;
148
+ } else {
149
+ console.log(chalk.red(`\n ❌ Bilinmeyen kanal: ${channel}\n`));
150
+ process.exit(1);
151
+ }
152
+
153
+ saveConfig(config);
154
+ console.log(chalk.green(`\n ✓ ${channel} kaldırıldı\n`));
155
+ }
156
+
157
+ function channelLogs(channel) {
158
+ const logFile = path.join(os.homedir(), '.natureco', 'gateway.log');
159
+ if (!fs.existsSync(logFile)) {
160
+ console.log(chalk.gray('\n Log dosyası bulunamadı.\n'));
161
+ return;
162
+ }
163
+
164
+ const lines = fs.readFileSync(logFile, 'utf-8').split('\n').filter(l => l.trim());
165
+ const filtered = channel
166
+ ? lines.filter(l => l.toLowerCase().includes(channel.toLowerCase()))
167
+ : lines;
168
+
169
+ const last = filtered.slice(-20);
170
+ console.log('');
171
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
172
+ console.log(chalk.cyan.bold(`\n Kanal Logları${channel ? ` (${channel})` : ''}\n`));
173
+ last.forEach(l => console.log(chalk.gray(' ' + l)));
174
+ console.log('');
175
+ }
176
+
177
+ module.exports = channels;
@@ -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.16.5</div>
214
+ <div class="version-badge" id="version-badge">v2.17.2</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.16.5',
344
+ version: 'v2.17.2',
345
345
  bots: cfg.bots || [],
346
346
  telegramToken: cfg.telegramToken || null,
347
347
  whatsappConnected: cfg.whatsappConnected || false,
@@ -200,13 +200,10 @@ async function gitExplain() {
200
200
  }
201
201
 
202
202
  async function getDefaultBot() {
203
- const apiKey = getApiKey();
204
-
205
- if (!apiKey) {
206
- console.log(chalk.red('\n❌ Not logged in. Run "natureco login" first.\n'));
207
- process.exit(1);
208
- }
209
-
203
+ const { getConfig } = require('../utils/config');
204
+ const config = getConfig();
205
+ const apiKey = getApiKey() || config.providerApiKey || '';
206
+
210
207
  let botList;
211
208
  try {
212
209
  botList = await getBots(apiKey);
@@ -214,15 +211,15 @@ async function getDefaultBot() {
214
211
  console.log(chalk.red(`\n❌ Error: ${err.message}\n`));
215
212
  process.exit(1);
216
213
  }
217
-
214
+
218
215
  if (!botList || !botList.bots || botList.bots.length === 0) {
219
216
  console.log(chalk.gray('No bots found. Create one at https://developers.natureco.me\n'));
220
217
  process.exit(1);
221
218
  }
222
-
223
- // Use first bot as default
224
- const bot = botList.bots[0];
225
-
219
+
220
+ // Config'deki botName ile eşleştir, yoksa ilk botu kullan
221
+ const bot = botList.bots.find(b => b.name === config.botName) || botList.bots[0];
222
+
226
223
  return { apiKey, bot };
227
224
  }
228
225
 
@@ -72,11 +72,22 @@ function help() {
72
72
 
73
73
  // ── Diğer ────────────────────────────────────────────────────
74
74
  console.log(chalk.cyan.bold('\n Diğer\n'));
75
- printCmd('natureco sessions list', 'Geçmiş oturumları listele');
76
- printCmd('natureco tasks list', 'Arka plan görevlerini listele');
77
- printCmd('natureco config list', 'Tüm ayarları göster');
78
- printCmd('natureco config set <k> <v>', 'Ayar değiştir');
79
- printCmd('natureco init', 'Proje klasörü oluştur (.natureco/)');
75
+ printCmd('natureco channels [action]', 'Kanal yönetimi (list|status|remove|logs)');
76
+ printCmd('natureco models [action]', 'Model yönetimi (list|set|scan|aliases)');
77
+ printCmd('natureco memory [action]', 'Hafıza yönetimi (status|list|search|show|clear)');
78
+ printCmd('natureco agents [action]', 'Agent yönetimi (list|set|info)');
79
+ printCmd('natureco plugins [action]', 'Plugin yönetimi (list|install|enable|disable)');
80
+ printCmd('natureco pairing [action]', 'Cihaz eşleştirme (list|approve|reject)');
81
+ printCmd('natureco logs', 'Gateway loglarını göster (--follow ile canlı)');
82
+ printCmd('natureco status', 'Genel sistem durumu');
83
+ printCmd('natureco security audit', 'Güvenlik denetimi (--fix ile otomatik düzelt)');
84
+ printCmd('natureco reset', 'Config sıfırla (--scope config|memory|sessions|full)');
85
+ printCmd('natureco uninstall', 'CLI verilerini kaldır (--all ile tam temizlik)');
86
+ printCmd('natureco sessions list', 'Geçmiş oturumları listele');
87
+ printCmd('natureco tasks list', 'Arka plan görevlerini listele');
88
+ printCmd('natureco config list', 'Tüm ayarları göster');
89
+ printCmd('natureco config set <k> <v>', 'Ayar değiştir');
90
+ printCmd('natureco init', 'Proje klasörü oluştur (.natureco/)');
80
91
 
81
92
  // ── Chat içi komutlar ────────────────────────────────────────
82
93
  console.log(chalk.cyan.bold('\n Chat İçi Komutlar\n'));
@@ -0,0 +1,99 @@
1
+ const chalk = require('chalk');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const os = require('os');
5
+
6
+ const LOG_FILE = path.join(os.homedir(), '.natureco', 'gateway.log');
7
+
8
+ async function logs(args) {
9
+ const follow = args.includes('--follow') || args.includes('-f');
10
+ const json = args.includes('--json');
11
+ const plain = args.includes('--plain');
12
+ const limitIdx = args.indexOf('--limit');
13
+ const limit = limitIdx !== -1 && args[limitIdx + 1]
14
+ ? parseInt(args[limitIdx + 1]) || 50
15
+ : (args.find(a => a.startsWith('--limit='))
16
+ ? parseInt(args.find(a => a.startsWith('--limit=')).split('=')[1]) || 50
17
+ : 50);
18
+
19
+ if (!fs.existsSync(LOG_FILE)) {
20
+ if (!json) console.log(chalk.gray('\n Log dosyası bulunamadı: ' + LOG_FILE + '\n'));
21
+ else console.log(JSON.stringify({ error: 'Log file not found' }));
22
+ return;
23
+ }
24
+
25
+ const printLines = (lines) => {
26
+ const last = lines.slice(-limit);
27
+ if (json) {
28
+ console.log(JSON.stringify({ lines: last }));
29
+ return;
30
+ }
31
+ if (!plain) {
32
+ console.log('');
33
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
34
+ console.log(chalk.cyan.bold(`\n Gateway Logları (son ${limit})\n`));
35
+ }
36
+ last.forEach(line => {
37
+ if (!line.trim()) return;
38
+ if (plain) {
39
+ console.log(line);
40
+ return;
41
+ }
42
+ // Renklendirme
43
+ if (line.includes('[error]') || line.includes('ERROR') || line.includes('❌')) {
44
+ console.log(chalk.red(' ' + line));
45
+ } else if (line.includes('[warn]') || line.includes('WARN') || line.includes('⚠')) {
46
+ console.log(chalk.yellow(' ' + line));
47
+ } else if (line.includes('[whatsapp]') || line.includes('[telegram]') || line.includes('[discord]')) {
48
+ console.log(chalk.cyan(' ' + line));
49
+ } else {
50
+ console.log(chalk.gray(' ' + line));
51
+ }
52
+ });
53
+ if (!plain) console.log('');
54
+ };
55
+
56
+ const content = fs.readFileSync(LOG_FILE, 'utf-8');
57
+ const lines = content.split('\n').filter(l => l.trim());
58
+ printLines(lines);
59
+
60
+ if (follow) {
61
+ if (!plain) console.log(chalk.gray(' Canlı takip modunda... (Ctrl+C ile çık)\n'));
62
+ let lastSize = fs.statSync(LOG_FILE).size;
63
+
64
+ const watcher = setInterval(() => {
65
+ try {
66
+ const stat = fs.statSync(LOG_FILE);
67
+ if (stat.size > lastSize) {
68
+ const fd = fs.openSync(LOG_FILE, 'r');
69
+ const buf = Buffer.alloc(stat.size - lastSize);
70
+ fs.readSync(fd, buf, 0, buf.length, lastSize);
71
+ fs.closeSync(fd);
72
+ const newLines = buf.toString('utf-8').split('\n').filter(l => l.trim());
73
+ newLines.forEach(line => {
74
+ if (!line.trim()) return;
75
+ if (plain) { console.log(line); return; }
76
+ if (line.includes('[error]') || line.includes('ERROR')) {
77
+ console.log(chalk.red(' ' + line));
78
+ } else if (line.includes('[warn]') || line.includes('WARN')) {
79
+ console.log(chalk.yellow(' ' + line));
80
+ } else if (line.includes('[whatsapp]') || line.includes('[telegram]')) {
81
+ console.log(chalk.cyan(' ' + line));
82
+ } else {
83
+ console.log(chalk.gray(' ' + line));
84
+ }
85
+ });
86
+ lastSize = stat.size;
87
+ }
88
+ } catch {}
89
+ }, 500);
90
+
91
+ process.on('SIGINT', () => {
92
+ clearInterval(watcher);
93
+ console.log(chalk.gray('\n Takip durduruldu.\n'));
94
+ process.exit(0);
95
+ });
96
+ }
97
+ }
98
+
99
+ module.exports = logs;