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
@@ -6,59 +6,163 @@ async function sms(action) {
6
6
  if (!action || action === 'connect') return connectSms();
7
7
  if (action === 'disconnect') return disconnectSms();
8
8
  if (action === 'status') return statusSms();
9
+ if (action === 'probe') return probeSms();
9
10
  console.log(chalk.red('\n❌ Unknown action\n'));
10
- console.log(chalk.gray('Available actions: connect, disconnect, status\n'));
11
+ console.log(chalk.gray('Available actions: connect, disconnect, status, probe\n'));
11
12
  process.exit(1);
12
13
  }
13
14
 
14
15
  async function connectSms() {
15
16
  const config = getConfig();
16
- if (!config.providerUrl) { console.log(chalk.red('\n❌ Setup yapılmamış. Önce "natureco setup" çalıştırın.\n')); process.exit(1); }
17
+ if (!config.providerUrl) {
18
+ console.log(chalk.red('\n❌ Setup yapılmamış. Önce "natureco setup" çalıştırın.\n'));
19
+ process.exit(1);
20
+ }
17
21
  console.log(chalk.yellow('\n⏳ SMS (Twilio) bağlantısı hazırlanıyor...\n'));
18
- console.log(chalk.gray('Twilio hesabı gereklidir: https://twilio.com'));
19
- console.log(chalk.gray('Account SID ve Auth Token\'ı Twilio Console\'dan alın.\n'));
22
+ console.log(chalk.gray('Twilio hesabı gereklidir: https://twilio.com\n'));
23
+
24
+ const defaults = {
25
+ accountSid: config.smsAccountSid || '',
26
+ authToken: config.smsAuthToken || '',
27
+ fromNumber: config.smsFromNumber || '',
28
+ webhookUrl: config.smsPublicWebhookUrl || '',
29
+ dmPolicy: config.smsDmPolicy || 'allowlist',
30
+ messagingServiceSid: config.smsMessagingServiceSid || '',
31
+ };
32
+
20
33
  const answers = await inquirer.prompt([
21
- { type: 'input', name: 'accountSid', message: 'Twilio Account SID:', validate: v => v.trim() ? true : 'Gerekli' },
22
- { type: 'password', name: 'authToken', message: 'Twilio Auth Token:', validate: v => v.trim() ? true : 'Gerekli' },
23
- { type: 'input', name: 'fromNumber', message: 'Twilio telefon numarası (E.164, örn: +15551234567):', validate: v => v.trim() ? true : 'Gerekli' },
24
- { type: 'input', name: 'publicWebhookUrl', message: 'Webhook URL\'si (opsiyonel, ngrok vb.):' },
25
- { type: 'list', name: 'dmPolicy', message: 'DM politikası:', choices: [{ name: 'Allowlist (önerilen)', value: 'allowlist' }, { name: 'Pairing', value: 'pairing' }, { name: 'Open', value: 'open' }, { name: 'Disabled', value: 'disabled' }], default: 'allowlist' },
34
+ { type: 'input', name: 'accountSid', message: 'Twilio Account SID:', default: defaults.accountSid ? defaults.accountSid.slice(0, 10) + '...' : '', validate: v => v.trim() ? true : 'Gerekli' },
35
+ { type: 'password', name: 'authToken', message: 'Twilio Auth Token:' },
36
+ { type: 'input', name: 'fromNumber', message: 'Gönderen numara (E.164, +15551234567):', default: defaults.fromNumber, validate: v => v.trim() || defaults.messagingServiceSid ? true : 'Numara veya Messaging Service SID gerekli' },
37
+ { type: 'input', name: 'messagingServiceSid', message: 'Messaging Service SID (opsiyonel):', default: defaults.messagingServiceSid },
38
+ { type: 'input', name: 'webhookUrl', message: 'Genel webhook URL (ngrok vb., opsiyonel):', default: defaults.webhookUrl },
39
+ { type: 'list', name: 'dmPolicy', message: 'DM politikası:', default: defaults.dmPolicy, choices: [
40
+ { name: 'Allowlist (önerilen) — spam koruması', value: 'allowlist' },
41
+ { name: 'Pairing — eşleşme kodu ile', value: 'pairing' },
42
+ { name: 'Open — herkese açık', value: 'open' },
43
+ { name: 'Disabled — devre dışı', value: 'disabled' },
44
+ ]},
45
+ { type: 'confirm', name: 'enableWebhook', message: 'Gelen SMS webhook\'u etkinleştirilsin mi?', default: config.smsEnableWebhook !== false },
26
46
  ]);
47
+
27
48
  const botId = `sms_${Date.now()}`;
28
49
  config.smsAccountSid = answers.accountSid.trim();
29
50
  config.smsAuthToken = answers.authToken.trim();
30
51
  config.smsFromNumber = answers.fromNumber.trim();
31
- config.smsPublicWebhookUrl = answers.publicWebhookUrl.trim() || '';
52
+ config.smsMessagingServiceSid = answers.messagingServiceSid.trim() || '';
53
+ config.smsPublicWebhookUrl = answers.webhookUrl.trim() || '';
32
54
  config.smsDmPolicy = answers.dmPolicy;
55
+ config.smsEnableWebhook = answers.enableWebhook;
33
56
  config.smsBotId = botId;
34
57
  saveConfig(config);
58
+
35
59
  console.log(chalk.green('\n✅ SMS (Twilio) bağlantısı kaydedildi!\n'));
36
60
  console.log(chalk.cyan('Bot ID:'), chalk.white(botId));
37
61
  console.log(chalk.cyan('Account SID:'), chalk.white(answers.accountSid.slice(0, 20) + '...'));
38
- console.log(chalk.cyan('Numara:'), chalk.white(answers.fromNumber.trim()));
39
- console.log(chalk.gray('\nNot: SMS webhook\'u için Twilio Console\'da Webhook URL\'si ayarlayın.'));
40
- console.log(chalk.gray('Gateway ile başlatmak için: natureco gateway start\n'));
62
+ console.log(chalk.cyan('Numara:'), chalk.white(answers.fromNumber || '(Messaging Service)'));
63
+ console.log(chalk.cyan('DM Politikası:'), chalk.white(answers.dmPolicy));
64
+
65
+ if (answers.enableWebhook) {
66
+ console.log(chalk.gray('\nTwilio Console\'da webhook URL\'si ayarlayın:'));
67
+ if (answers.webhookUrl) {
68
+ console.log(chalk.cyan(` ${answers.webhookUrl}/webhooks/sms`));
69
+ } else {
70
+ console.log(chalk.gray(' (önce bir genel URL ayarlayın)'));
71
+ }
72
+ }
73
+ console.log(chalk.gray('\nGateway ile başlatmak için: natureco gateway start\n'));
41
74
  }
42
75
 
43
76
  async function disconnectSms() {
44
77
  const config = getConfig();
45
- if (!config.smsBotId) { console.log(chalk.gray('\n⚠️ No SMS connection found\n')); return; }
46
- const { confirm } = await inquirer.prompt([{ type: 'confirm', name: 'confirm', message: 'SMS bağlantısını kaldırmak istediğinize emin misiniz?', default: false }]);
47
- if (!confirm) { console.log(chalk.gray('\nCancelled\n')); return; }
78
+ if (!config.smsBotId) {
79
+ console.log(chalk.gray('\n⚠️ No SMS connection found\n'));
80
+ return;
81
+ }
82
+ const { confirm } = await inquirer.prompt([
83
+ { type: 'confirm', name: 'confirm', message: 'SMS bağlantısını kaldırmak istediğinize emin misiniz?', default: false }
84
+ ]);
85
+ if (!confirm) {
86
+ console.log(chalk.gray('\nCancelled\n'));
87
+ return;
88
+ }
48
89
  delete config.smsAccountSid; delete config.smsAuthToken; delete config.smsFromNumber;
49
- delete config.smsPublicWebhookUrl; delete config.smsDmPolicy; delete config.smsBotId;
90
+ delete config.smsMessagingServiceSid; delete config.smsPublicWebhookUrl;
91
+ delete config.smsDmPolicy; delete config.smsEnableWebhook; delete config.smsBotId;
50
92
  saveConfig(config);
51
93
  console.log(chalk.green('\n✅ SMS disconnected\n'));
52
94
  }
53
95
 
54
96
  function statusSms() {
55
97
  const config = getConfig();
56
- if (!config.smsBotId) { console.log(chalk.gray('\n⚠️ SMS not connected\n')); console.log(chalk.gray('Connect with: natureco sms connect\n')); return; }
98
+ if (!config.smsBotId) {
99
+ console.log(chalk.gray('\n⚠️ SMS not connected\n'));
100
+ console.log(chalk.gray('Connect with: natureco sms connect\n'));
101
+ return;
102
+ }
57
103
  console.log(chalk.green('\n✅ SMS (Twilio) connected\n'));
58
104
  console.log(chalk.cyan('Bot ID:'), chalk.white(config.smsBotId));
59
105
  console.log(chalk.cyan('Account SID:'), chalk.white((config.smsAccountSid || '').slice(0, 20) + '...'));
60
- console.log(chalk.cyan('Numara:'), chalk.white(config.smsFromNumber));
106
+ console.log(chalk.cyan('Numara:'), chalk.white(config.smsFromNumber || '(Messaging Service)'));
107
+ console.log(chalk.cyan('DM Politikası:'), chalk.white(config.smsDmPolicy || 'allowlist'));
108
+ console.log(chalk.cyan('Webhook:'), chalk.white(config.smsEnableWebhook !== false ? 'Aktif' : 'Devre Dışı'));
61
109
  console.log(chalk.gray('\nDisconnect with: natureco sms disconnect\n'));
62
110
  }
63
111
 
112
+ async function probeSms() {
113
+ const config = getConfig();
114
+ if (!config.smsAccountSid || !config.smsAuthToken) {
115
+ console.log(chalk.red('\n❌ SMS bağlantısı yapılmamış\n'));
116
+ console.log(chalk.gray('Önce: natureco sms connect\n'));
117
+ process.exit(1);
118
+ }
119
+
120
+ const base64Auth = Buffer.from(`${config.smsAccountSid}:${config.smsAuthToken}`).toString('base64');
121
+ console.log(chalk.yellow('\n⏳ Twilio problanıyor...\n'));
122
+
123
+ try {
124
+ const res = await fetch('https://api.twilio.com/2010-04-01/Accounts/' + config.smsAccountSid + '.json', {
125
+ headers: { 'Authorization': `Basic ${base64Auth}` },
126
+ signal: AbortSignal.timeout(10000),
127
+ });
128
+
129
+ if (!res.ok) {
130
+ console.log(chalk.red(`✗ Twilio API Hatası: HTTP ${res.status}\n`));
131
+ if (res.status === 401) console.log(chalk.gray(' Account SID veya Auth Token hatalı.\n'));
132
+ process.exit(1);
133
+ }
134
+
135
+ const account = await res.json();
136
+ console.log(chalk.green('✓ Twilio API Bağlantısı Başarılı\n'));
137
+ console.log(chalk.cyan('Hesap Adı:'), chalk.white(account.friendly_name));
138
+ console.log(chalk.cyan('Status:'), chalk.white(account.status));
139
+ console.log(chalk.cyan('Type:'), chalk.white(account.type));
140
+
141
+ // Check balance
142
+ if (account.subresource_uris?.balance) {
143
+ try {
144
+ const balRes = await fetch('https://api.twilio.com' + account.subresource_uris.balance, {
145
+ headers: { 'Authorization': `Basic ${base64Auth}` },
146
+ signal: AbortSignal.timeout(5000),
147
+ });
148
+ if (balRes.ok) {
149
+ const balance = await balRes.json();
150
+ console.log(chalk.cyan('Bakiye:'), chalk.white(`${balance.balance} ${balance.currency}`));
151
+ }
152
+ } catch {}
153
+ }
154
+
155
+ // Check phone number
156
+ if (config.smsFromNumber) {
157
+ console.log(chalk.gray(`\nGönderen numara: ${config.smsFromNumber}`));
158
+ }
159
+
160
+ console.log('');
161
+
162
+ } catch (err) {
163
+ console.log(chalk.red(`\n✗ Probe hatası: ${err.message}\n`));
164
+ process.exit(1);
165
+ }
166
+ }
167
+
64
168
  module.exports = sms;
@@ -1,127 +1,101 @@
1
- const chalk = require('chalk');
2
- const fs = require('fs');
3
- const path = require('path');
4
- const os = require('os');
5
- const { getConfig } = require('../utils/config');
6
- const { getSkills } = require('../utils/skills');
7
-
8
- async function status() {
9
- const config = getConfig();
10
- const version = require('../../package.json').version;
11
- const w = process.stdout.columns || 120;
12
- const line = chalk.gray('─'.repeat(w));
13
-
14
- // ── Header ────────────────────────────────────────────────────────────────
15
- console.log('');
16
- console.log(line);
17
- const title = chalk.bold.cyan(' NatureCo CLI') + chalk.gray(' — Durum Raporu');
18
- const ver = chalk.gray(`v${version} `);
19
- const pad = w - 16 - version.length - 3;
20
- console.log(title + ' '.repeat(Math.max(1, pad)) + ver);
21
- console.log(line);
22
-
23
- // ── Provider & Bot ────────────────────────────────────────────────────────
24
- const providerHost = config.providerUrl
25
- ? config.providerUrl.replace('https://', '').split('/')[0]
26
- : null;
27
- const model = config.providerModel
28
- ? config.providerModel.split('/').pop().split('-').slice(0, 3).join('-')
29
- : 'bilinmiyor';
30
-
31
- console.log('');
32
- row('Provider ', providerHost ? chalk.white(providerHost) : chalk.yellow('yapılandırılmamış'),
33
- 'Bot ', config.botName ? chalk.cyan(config.botName) : chalk.gray(''), w);
34
- row('Model ', chalk.white(model),
35
- 'Kullanıcı', config.userName ? chalk.white(config.userName) : chalk.gray('—'), w);
36
-
37
- // ── Servisler ─────────────────────────────────────────────────────────────
38
- const pidFile = path.join(os.homedir(), '.natureco', 'gateway.pid');
39
- const dashPid = path.join(os.homedir(), '.natureco', 'dashboard.pid');
40
- const gatewayRunning = fs.existsSync(pidFile);
41
- const dashRunning = fs.existsSync(dashPid);
42
-
43
- row('Gateway ', gatewayRunning ? chalk.green('● çalışıyor') : chalk.gray('○ durdurulmuş'),
44
- 'Dashboard', dashRunning ? chalk.green('● localhost:3848') : chalk.gray('○ durdurulmuş'), w);
45
-
46
- // ── Entegrasyonlar ────────────────────────────────────────────────────────
47
- const tg = config.telegramToken ? chalk.green('● bağlı') : chalk.gray(' ');
48
- const wa = config.whatsappConnected ? chalk.green('● bağlı') : chalk.gray('○ —');
49
- const dc = config.discordToken ? chalk.green('● bağlı') : chalk.gray('○ —');
50
- const sl = config.slackToken ? chalk.green('● bağlı') : chalk.gray('○ —');
51
-
52
- console.log('');
53
- console.log(chalk.gray(' ' + '─'.repeat(w - 2)));
54
- console.log(chalk.gray(' Entegrasyonlar'));
55
- console.log('');
56
- row('Telegram ', tg, 'Discord ', dc, w);
57
- row('WhatsApp ', wa, 'Slack ', sl, w);
58
-
59
- // ── Kaynaklar ─────────────────────────────────────────────────────────────
60
- const skills = getSkills();
61
- const memDir = path.join(os.homedir(), '.natureco', 'memory');
62
- const memFiles = fs.existsSync(memDir)
63
- ? fs.readdirSync(memDir).filter(f => f.endsWith('.json')).length : 0;
64
- const sessDir = path.join(os.homedir(), '.natureco', 'sessions');
65
- let sessCount = 0;
66
- if (fs.existsSync(sessDir)) {
67
- sessCount = fs.readdirSync(sessDir).filter(f => f.endsWith('.json')).length;
68
- }
69
-
70
- console.log('');
71
- console.log(chalk.gray(' ' + '─'.repeat(w - 2)));
72
- console.log(chalk.gray(' Kaynaklar'));
73
- console.log('');
74
- row('Skills ', chalk.white(`${skills.length} yüklü`),
75
- 'Hafıza ', chalk.white(`${memFiles} bot`), w);
76
- row('Sessions ', chalk.white(`${sessCount} kayıtlı`),
77
- 'Versiyon ', chalk.white(`v${version}`), w);
78
-
79
- // ── Son Loglar ────────────────────────────────────────────────────────────
80
- const logFile = path.join(os.homedir(), '.natureco', 'gateway.log');
81
- if (fs.existsSync(logFile)) {
82
- const lines = fs.readFileSync(logFile, 'utf-8').split('\n').filter(l => l.trim());
83
- const last = lines.slice(-3);
84
- if (last.length > 0) {
85
- console.log('');
86
- console.log(chalk.gray(' ' + '─'.repeat(w - 2)));
87
- console.log(chalk.gray(' Son Aktivite'));
88
- console.log('');
89
- last.forEach(l => {
90
- const trimmed = l.slice(0, w - 4);
91
- console.log(chalk.gray(' ') + chalk.gray(trimmed));
92
- });
93
- }
94
- }
95
-
96
- // ── Footer ────────────────────────────────────────────────────────────────
97
- console.log('');
98
- console.log(line);
99
- console.log(
100
- chalk.gray(' natureco doctor') +
101
- chalk.gray(' · ') +
102
- chalk.gray('natureco chat') +
103
- chalk.gray(' · ') +
104
- chalk.gray('natureco code') +
105
- chalk.gray(' · ') +
106
- chalk.gray('natureco channels status')
107
- );
108
- console.log(line);
109
- console.log('');
110
- }
111
-
112
- // ── İki kolon satır yardımcısı ─────────────────────────────────────────────
113
- function row(label1, val1, label2, val2, w) {
114
- const col = Math.floor(w / 2);
115
- const left = chalk.gray(' ' + label1) + val1;
116
- const right = chalk.gray(label2) + val2;
117
- // ANSI kodlarını sayma — sabit padding kullan
118
- const leftPlain = (' ' + label1).length + stripAnsi(String(val1)).length;
119
- const pad = Math.max(1, col - leftPlain);
120
- console.log(left + ' '.repeat(pad) + right);
121
- }
122
-
123
- function stripAnsi(str) {
124
- return str.replace(/\x1B\[[0-9;]*m/g, '');
125
- }
126
-
127
- module.exports = status;
1
+ const chalk = require('chalk');
2
+ const F = require('../utils/format');
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const os = require('os');
6
+
7
+ function tryRequire(mod) {
8
+ try { return require(mod); }
9
+ catch { return null; }
10
+ }
11
+
12
+ function status(args) {
13
+ const [action, ...params] = args || [];
14
+
15
+ if (!action || action === 'run') return cmdRun();
16
+ if (action === 'simple') return cmdSimple();
17
+ if (action === 'usage') return cmdUsage();
18
+
19
+ F.error(`Unknown status action: ${action}`);
20
+ F.meta('Usage: natureco status <action>');
21
+ F.meta('Actions: run, simple, usage');
22
+ process.exit(1);
23
+ }
24
+
25
+ function cmdRun() {
26
+ let version = '—';
27
+ try { version = require('../../package.json').version; } catch {}
28
+
29
+ const config = tryRequire('../utils/config');
30
+ const cfg = config ? config.getConfig() : {};
31
+
32
+ F.header('System Status');
33
+ F.kv('Version', version);
34
+ F.kv('Platform', `${process.platform} ${os.release()}`);
35
+
36
+ const pidFile = path.join(os.homedir(), '.natureco', 'gateway.pid');
37
+ const gatewayRunning = fs.existsSync(pidFile);
38
+ F.dot(gatewayRunning, 'Gateway');
39
+
40
+ if (cfg.providerUrl) {
41
+ F.kv('Provider', cfg.providerUrl);
42
+ }
43
+ if (cfg.botName) {
44
+ F.kv('Bot', cfg.botName);
45
+ }
46
+
47
+ const nodesFile = path.join(os.homedir(), '.natureco', 'nodes.json');
48
+ let nodeCount = 0;
49
+ if (fs.existsSync(nodesFile)) {
50
+ try { nodeCount = Object.keys(JSON.parse(fs.readFileSync(nodesFile, 'utf8'))).length; } catch {}
51
+ }
52
+ F.kv('Nodes', String(nodeCount));
53
+
54
+ const channels = cfg.channels || cfg.telegramToken || cfg.whatsappConnected || cfg.discordToken || cfg.slackToken;
55
+ const channelCount = [cfg.telegramToken, cfg.whatsappConnected, cfg.discordToken, cfg.slackToken].filter(Boolean).length;
56
+ F.kv('Channels', String(channelCount));
57
+ F.divider();
58
+ }
59
+
60
+ function cmdSimple() {
61
+ let version = '';
62
+ try { version = require('../../package.json').version; } catch {}
63
+
64
+ const config = tryRequire('../utils/config');
65
+ const cfg = config ? config.getConfig() : {};
66
+ const pidFile = path.join(os.homedir(), '.natureco', 'gateway.pid');
67
+ const gatewayRunning = fs.existsSync(pidFile);
68
+
69
+ F.dot(gatewayRunning, 'Gateway');
70
+
71
+ const parts = [chalk.gray(`v${version}`)];
72
+ if (cfg.providerUrl) {
73
+ const host = cfg.providerUrl.replace('https://', '').split('/')[0];
74
+ parts.push(chalk.white(host));
75
+ }
76
+
77
+ console.log(chalk.cyan.bold(' NatureCo ') + parts.join(chalk.gray(' · ')));
78
+ }
79
+
80
+ function cmdUsage() {
81
+ const config = tryRequire('../utils/config');
82
+ const cfg = config ? config.getConfig() : {};
83
+
84
+ F.header('Provider Usage');
85
+
86
+ if (cfg.providerUrl) {
87
+ const rows = [
88
+ ['Provider', cfg.providerUrl],
89
+ ['Model', cfg.providerModel || '—'],
90
+ ];
91
+ const usage = cfg.usage || {};
92
+ rows.push(['Tokens', String(usage.totalTokens || '—')]);
93
+ rows.push(['Requests', String(usage.totalRequests || '—')]);
94
+ rows.push(['Session', String(usage.sessionTokens || '—')]);
95
+ F.table(['Key', 'Value'], rows);
96
+ } else {
97
+ F.info('No provider configured.');
98
+ }
99
+ }
100
+
101
+ module.exports = status;
@@ -0,0 +1,53 @@
1
+ const chalk = require('chalk');
2
+ const os = require('os');
3
+
4
+ function system(args) {
5
+ const [action, ...params] = args || [];
6
+
7
+ if (!action || action === 'status') return systemStatus();
8
+ if (action === 'events' || action === 'heartbeat') return systemHeartbeat();
9
+ if (action === 'presence') return systemPresence();
10
+
11
+ console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
12
+ console.log(chalk.gray(' Kullanım: natureco system [status|events|presence]\n'));
13
+ process.exit(1);
14
+ }
15
+
16
+ function systemStatus() {
17
+ const mem = process.memoryUsage();
18
+ const uptime = process.uptime();
19
+ const days = Math.floor(uptime / 86400);
20
+ const hours = Math.floor((uptime % 86400) / 3600);
21
+ const mins = Math.floor((uptime % 3600) / 60);
22
+
23
+ console.log(chalk.cyan('\n 💻 System\n'));
24
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
25
+ console.log(` ${chalk.white('Host:')} ${os.hostname()}`);
26
+ console.log(` ${chalk.white('Platform:')} ${process.platform} ${os.release()}`);
27
+ console.log(` ${chalk.white('Uptime:')} ${days}d ${hours}h ${mins}m`);
28
+ console.log(` ${chalk.white('Node:')} ${process.version}`);
29
+ console.log(` ${chalk.white('Memory:')} ${Math.round(mem.heapUsed / 1024 / 1024)}MB / ${Math.round(mem.heapTotal / 1024 / 1024)}MB`);
30
+ console.log(` ${chalk.white('CPU:')} ${os.cpus()[0]?.model || 'unknown'}`);
31
+ console.log(` ${chalk.white('Load:')} ${os.loadavg().map(l => l.toFixed(2)).join(', ')}`);
32
+ console.log(` ${chalk.white('PID:')} ${process.pid}`);
33
+ console.log();
34
+ }
35
+
36
+ function systemHeartbeat() {
37
+ console.log(chalk.cyan(`\n 💓 Heartbeat: ${new Date().toISOString()}\n`));
38
+ console.log(chalk.gray(` PID: ${process.pid}`));
39
+ console.log(chalk.gray(` Memory: ${Math.round(process.memoryUsage().heapUsed / 1024 / 1024)}MB`));
40
+ console.log(chalk.gray(` Status: ${chalk.green('alive')}\n`));
41
+ }
42
+
43
+ function systemPresence() {
44
+ console.log(chalk.cyan('\n 🟢 Presence\n'));
45
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
46
+ console.log(` ${chalk.white('Status:')} ${chalk.green('online')}`);
47
+ console.log(` ${chalk.white('Since:')} ${new Date(Date.now() - process.uptime() * 1000).toISOString()}`);
48
+ console.log(` ${chalk.white('Host:')} ${os.hostname()}`);
49
+ console.log(` ${chalk.white('Version:')} NatureCo CLI`);
50
+ console.log();
51
+ }
52
+
53
+ module.exports = system;