natureco-cli 2.23.27 → 2.23.29

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.
@@ -1,79 +1,328 @@
1
- const chalk = require('chalk');
2
- const { loadBackgroundTasks, getBackgroundTask } = require('../utils/background');
3
-
4
- async function tasks(action, ...args) {
5
- if (!action || action === 'list') {
6
- return listTasks();
7
- }
8
-
9
- if (action === 'show') {
10
- const id = args[0];
11
- if (!id) {
12
- console.log(chalk.red('\n❌ Task ID required\n'));
13
- console.log(chalk.gray('Usage: natureco tasks show <id>\n'));
14
- process.exit(1);
15
- }
16
- return showTask(id);
17
- }
18
-
19
- console.log(chalk.red(`\n❌ Unknown action: ${action}\n`));
20
- console.log(chalk.gray('Available actions: list, show\n'));
21
- process.exit(1);
22
- }
23
-
24
- function listTasks() {
25
- const tasks = loadBackgroundTasks();
26
-
27
- if (tasks.length === 0) {
28
- console.log(chalk.gray('\nNo background tasks found.\n'));
29
- console.log(chalk.gray('Create one by pressing Ctrl+B in chat.\n'));
30
- return;
31
- }
32
-
33
- console.log(chalk.yellow('\nBackground Tasks:\n'));
34
-
35
- tasks.forEach(task => {
36
- const statusColor = task.status === 'completed' ? chalk.green : task.status === 'failed' ? chalk.red : chalk.yellow;
37
- const status = statusColor(task.status);
38
-
39
- console.log(` ${chalk.cyan(task.id)} ${status}`);
40
- console.log(chalk.white(` ${task.message.slice(0, 60)}...`));
41
- console.log(chalk.gray(` Bot: ${task.botName} | Created: ${new Date(task.createdAt).toLocaleString()}`));
42
- console.log('');
43
- });
44
- }
45
-
46
- function showTask(id) {
47
- const task = getBackgroundTask(id);
48
-
49
- if (!task) {
50
- console.log(chalk.red(`\n❌ Task not found: ${id}\n`));
51
- process.exit(1);
52
- }
53
-
54
- console.log(chalk.yellow(`\nTask: ${task.id}\n`));
55
- console.log(chalk.gray(`Status: ${task.status}`));
56
- console.log(chalk.gray(`Bot: ${task.botName}`));
57
- console.log(chalk.gray(`Created: ${new Date(task.createdAt).toLocaleString()}`));
58
-
59
- if (task.completedAt) {
60
- console.log(chalk.gray(`Completed: ${new Date(task.completedAt).toLocaleString()}`));
61
- }
62
-
63
- console.log(chalk.cyan('\nMessage:'));
64
- console.log(chalk.white(task.message));
65
-
66
- if (task.result) {
67
- console.log(chalk.cyan('\nResult:'));
68
- console.log(chalk.white(task.result));
69
- }
70
-
71
- if (task.error) {
72
- console.log(chalk.red('\nError:'));
73
- console.log(chalk.white(task.error));
74
- }
75
-
76
- console.log('');
77
- }
78
-
79
- module.exports = tasks;
1
+ const chalk = require('chalk');
2
+ const { listTasks, getTask, cancelTask, auditTasks, maintenanceTasks, getTaskSummary, TASK_STATUSES, RUNTIME_TYPES } = require('../utils/background');
3
+
4
+ function parseFlags(args) {
5
+ return {
6
+ json: args.includes('--json') || args.includes('-j'),
7
+ apply: args.includes('--apply'),
8
+ runtime: extractFlag(args, '--runtime'),
9
+ status: extractFlag(args, '--status'),
10
+ limit: parseInt(extractFlag(args, '--limit') || '50', 10),
11
+ severity: extractFlag(args, '--severity'),
12
+ };
13
+ }
14
+
15
+ function extractFlag(params, name) {
16
+ const idx = params.indexOf(name);
17
+ return idx >= 0 && idx + 1 < params.length ? params[idx + 1] : null;
18
+ }
19
+
20
+ const STATUS_ICONS = {
21
+ queued: '⏳',
22
+ running: '🔄',
23
+ succeeded: '✅',
24
+ failed: '❌',
25
+ timed_out: '⏰',
26
+ cancelled: '🚫',
27
+ lost: '👻',
28
+ };
29
+
30
+ const STATUS_COLORS = {
31
+ queued: chalk.yellow,
32
+ running: chalk.cyan,
33
+ succeeded: chalk.green,
34
+ failed: chalk.red,
35
+ timed_out: chalk.red,
36
+ cancelled: chalk.gray,
37
+ lost: chalk.magenta,
38
+ };
39
+
40
+ async function tasks(args) {
41
+ const [action, ...params] = (args || []);
42
+ const opts = parseFlags(params);
43
+
44
+ if (!action || action === 'list') return listTasksHandler(opts);
45
+ if (action === 'show') return showTaskHandler(params[0], opts);
46
+ if (action === 'cancel') return cancelTaskHandler(params[0]);
47
+ if (action === 'audit') return auditHandler(opts);
48
+ if (action === 'maintenance') return maintenanceHandler(opts);
49
+ if (action === 'flow' && params[0]) {
50
+ const flowAction = params[0];
51
+ const flowParams = params.slice(1);
52
+ if (flowAction === 'list') return flowListHandler(parseFlags(flowParams));
53
+ if (flowAction === 'show') return flowShowHandler(flowParams[0], parseFlags(flowParams));
54
+ if (flowAction === 'cancel') return flowCancelHandler(flowParams[0]);
55
+ }
56
+ if (action === 'summary' || action === 'status') return summaryHandler(opts);
57
+
58
+ console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
59
+ console.log(chalk.gray(' Kullanım: natureco tasks [list|show|cancel|audit|maintenance|flow|summary]\n'));
60
+ process.exit(1);
61
+ }
62
+
63
+ function listTasksHandler(opts) {
64
+ const tasks = listTasks({ runtime: opts.runtime, status: opts.status, limit: opts.limit });
65
+
66
+ if (opts.json) {
67
+ console.log(JSON.stringify({ tasks, total: tasks.length, filters: { runtime: opts.runtime, status: opts.status } }, null, 2));
68
+ return;
69
+ }
70
+
71
+ console.log('');
72
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
73
+ console.log(chalk.cyan.bold('\n Background Tasks\n'));
74
+
75
+ if (tasks.length === 0) {
76
+ console.log(chalk.gray(' Hiç task bulunamadı.\n'));
77
+ if (opts.runtime) console.log(chalk.gray(` Filtre: runtime=${opts.runtime}`));
78
+ if (opts.status) console.log(chalk.gray(` Filtre: status=${opts.status}`));
79
+ console.log('');
80
+ return;
81
+ }
82
+
83
+ tasks.forEach(t => {
84
+ const icon = STATUS_ICONS[t.status] || '❓';
85
+ const color = STATUS_COLORS[t.status] || chalk.white;
86
+ const runtimeIcon = t.runtime === 'cron' ? '⏰' : t.runtime === 'subagent' ? '🧑‍💻' : t.runtime === 'acp' ? '🔄' : '💻';
87
+ const age = getAgeString(t.createdAt);
88
+ console.log(` ${icon} ${chalk.white(t.id.slice(0, 12))} ${color(t.status)} ${runtimeIcon}${t.runtime}`);
89
+ if (t.message) {
90
+ const msg = t.message.length > 50 ? t.message.slice(0, 50) + '...' : t.message;
91
+ console.log(chalk.gray(` ${msg}`));
92
+ }
93
+ console.log(chalk.gray(` ${age} | notify: ${t.notifyPolicy || 'done_only'}`));
94
+ console.log('');
95
+ });
96
+
97
+ const summary = getTaskSummary();
98
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
99
+ console.log(chalk.gray(` Toplam: ${tasks.length} (gösterilen) | Aktif: ${summary.active} | Hata: ${summary.failures}`));
100
+ console.log(chalk.gray(' Filtre: ') + chalk.cyan('--runtime <type> --status <status>'));
101
+ console.log(chalk.gray(" JSON: ") + chalk.cyan('natureco tasks list --json\n'));
102
+ }
103
+
104
+ function showTaskHandler(id, opts) {
105
+ if (!id) {
106
+ console.log(chalk.red('\n ❌ Task ID gerekli\n'));
107
+ console.log(chalk.gray(' Kullanım: natureco tasks show <id>\n'));
108
+ process.exit(1);
109
+ }
110
+
111
+ const task = getTask(id);
112
+ if (!task) {
113
+ console.log(chalk.red(`\n ❌ Task bulunamadı: ${id}\n`));
114
+ process.exit(1);
115
+ }
116
+
117
+ if (opts.json) {
118
+ console.log(JSON.stringify(task, null, 2));
119
+ return;
120
+ }
121
+
122
+ const color = STATUS_COLORS[task.status] || chalk.white;
123
+ const icon = STATUS_ICONS[task.status] || '❓';
124
+
125
+ console.log('');
126
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
127
+ console.log(`\n ${icon} ${chalk.white('Task:')} ${chalk.cyan(task.id)}`);
128
+ console.log(` ${chalk.gray('Durum :')} ${color(task.status)}`);
129
+ console.log(` ${chalk.gray('Runtime :')} ${chalk.white(task.runtime)}`);
130
+ console.log(` ${chalk.gray('Bot :')} ${chalk.white(task.botName)}`);
131
+ if (task.message) console.log(` ${chalk.gray('Mesaj :')} ${chalk.white(task.message)}`);
132
+ console.log(` ${chalk.gray('Oluşturma:')} ${chalk.white(formatTime(task.createdAt))}`);
133
+ if (task.startedAt) console.log(` ${chalk.gray('Başlangıç:')} ${chalk.white(formatTime(task.startedAt))}`);
134
+ if (task.endedAt) console.log(` ${chalk.gray('Bitiş :')} ${chalk.white(formatTime(task.endedAt))}`);
135
+ if (task.notifyPolicy) console.log(` ${chalk.gray('Bildirim :')} ${chalk.white(task.notifyPolicy)}`);
136
+ if (task.childSessionKey) console.log(` ${chalk.gray('Çocuk :')} ${chalk.gray(task.childSessionKey)}`);
137
+ if (task.runId) console.log(` ${chalk.gray('Run ID :')} ${chalk.gray(task.runId)}`);
138
+
139
+ if (task.result) {
140
+ console.log(`\n ${chalk.cyan('Sonuç:')}`);
141
+ console.log(` ${chalk.white(task.result)}`);
142
+ }
143
+ if (task.error) {
144
+ console.log(`\n ${chalk.red('Hata:')}`);
145
+ console.log(` ${chalk.white(task.error)}`);
146
+ }
147
+ if (task.cleanupAfter) {
148
+ console.log(`\n ${chalk.gray(`Temizlik: ${formatTime(task.cleanupAfter)}`)}`);
149
+ }
150
+ if (task.metadata && Object.keys(task.metadata).length > 0) {
151
+ console.log(`\n ${chalk.gray('Metadata:')}`);
152
+ Object.entries(task.metadata).forEach(([k, v]) => console.log(` ${k}: ${v}`));
153
+ }
154
+ console.log('');
155
+ }
156
+
157
+ function cancelTaskHandler(id) {
158
+ if (!id) {
159
+ console.log(chalk.red('\n ❌ Task ID gerekli\n'));
160
+ console.log(chalk.gray(' Kullanım: natureco tasks cancel <id>\n'));
161
+ process.exit(1);
162
+ }
163
+
164
+ const result = cancelTask(id);
165
+ if (!result) {
166
+ console.log(chalk.red(`\n ❌ Task bulunamadı: ${id}\n`));
167
+ process.exit(1);
168
+ }
169
+
170
+ if (result.status === 'cancelled') {
171
+ console.log(chalk.green(`\n ✓ Task iptal edildi: ${id}\n`));
172
+ } else {
173
+ console.log(chalk.yellow(`\n ⚠ Task zaten terminal durumda: ${result.status}\n`));
174
+ }
175
+ }
176
+
177
+ function auditHandler(opts) {
178
+ const findings = auditTasks();
179
+
180
+ if (opts.json) {
181
+ console.log(JSON.stringify({ findings, total: findings.length }, null, 2));
182
+ return;
183
+ }
184
+
185
+ console.log('');
186
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
187
+ console.log(chalk.cyan.bold('\n Task Denetimi\n'));
188
+
189
+ if (findings.length === 0) {
190
+ console.log(chalk.green(' ✓ Sorun bulunamadı.\n'));
191
+ return;
192
+ }
193
+
194
+ let filtered = findings;
195
+ if (opts.severity) {
196
+ filtered = findings.filter(f => f.severity === opts.severity);
197
+ }
198
+
199
+ const errors = filtered.filter(f => f.severity === 'error');
200
+ const warnings = filtered.filter(f => f.severity === 'warn');
201
+
202
+ if (errors.length > 0) {
203
+ console.log(chalk.red(`\n ${errors.length} HATA\n`));
204
+ errors.forEach(f => {
205
+ console.log(` ${chalk.red('✗')} ${chalk.white(f.id.slice(0, 12))} ${chalk.red(f.code)}`);
206
+ console.log(chalk.gray(` ${f.message}`));
207
+ });
208
+ }
209
+
210
+ if (warnings.length > 0) {
211
+ console.log(chalk.yellow(`\n ${warnings.length} UYARI\n`));
212
+ warnings.forEach(f => {
213
+ console.log(` ${chalk.yellow('⚠')} ${chalk.white(f.id.slice(0, 12))} ${chalk.yellow(f.code)}`);
214
+ console.log(chalk.gray(` ${f.message}`));
215
+ });
216
+ }
217
+
218
+ console.log(chalk.gray(`\n Toplam: ${filtered.length} bulgu`));
219
+ console.log(chalk.gray(` Bakım: natureco tasks maintenance --apply\n`));
220
+ }
221
+
222
+ function maintenanceHandler(opts) {
223
+ console.log(chalk.cyan('\n Task Bakımı\n'));
224
+
225
+ const dryRun = !opts.apply;
226
+ const result = maintenanceTasks(dryRun);
227
+
228
+ if (dryRun) {
229
+ console.log(chalk.gray(' Kuru çalışma (--apply ile uygula)\n'));
230
+ }
231
+
232
+ console.log(chalk.gray(` Temizlenen : ${result.pruned}`));
233
+ console.log(chalk.gray(` Düzeltilen : ${result.reconciled}`));
234
+ console.log(chalk.gray(` Etiketlenen : ${result.cleaned}`));
235
+ console.log(chalk.gray(` Kalan task : ${result.remaining}`));
236
+
237
+ if (result.pruned > 0 || result.reconciled > 0 || result.cleaned > 0) {
238
+ if (dryRun) {
239
+ console.log(chalk.gray(`\n Uygulamak için: natureco tasks maintenance --apply`));
240
+ } else {
241
+ console.log(chalk.green(`\n ✓ Bakım uygulandı.\n`));
242
+ }
243
+ } else {
244
+ console.log(chalk.green(`\n ✓ Bakım gerekmiyor.\n`));
245
+ }
246
+ console.log('');
247
+ }
248
+
249
+ function flowListHandler(opts) {
250
+ const tasks = listTasks({ runtime: 'acp', limit: opts.limit || 50 });
251
+
252
+ if (opts.json) {
253
+ console.log(JSON.stringify({ flows: tasks, total: tasks.length }, null, 2));
254
+ return;
255
+ }
256
+
257
+ console.log('');
258
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
259
+ console.log(chalk.cyan.bold('\n Task Flow\n'));
260
+
261
+ if (tasks.length === 0) {
262
+ console.log(chalk.gray(' Task Flow kaydı yok.\n'));
263
+ return;
264
+ }
265
+
266
+ tasks.forEach(t => {
267
+ const icon = STATUS_ICONS[t.status] || '❓';
268
+ const color = STATUS_COLORS[t.status] || chalk.white;
269
+ console.log(` ${icon} ${chalk.white(t.id.slice(0, 12))} ${color(t.status)}`);
270
+ if (t.message) console.log(chalk.gray(` ${t.message.slice(0, 60)}`));
271
+ });
272
+ console.log(chalk.gray(`\n Toplam: ${tasks.length} flow\n`));
273
+ }
274
+
275
+ function flowShowHandler(id, opts) {
276
+ if (!id) {
277
+ console.log(chalk.red('\n ❌ Flow ID gerekli\n'));
278
+ process.exit(1);
279
+ }
280
+ return showTaskHandler(id, opts);
281
+ }
282
+
283
+ function flowCancelHandler(id) {
284
+ if (!id) {
285
+ console.log(chalk.red('\n ❌ Flow ID gerekli\n'));
286
+ process.exit(1);
287
+ }
288
+ return cancelTaskHandler(id);
289
+ }
290
+
291
+ function summaryHandler(opts) {
292
+ const summary = getTaskSummary();
293
+
294
+ if (opts.json) {
295
+ console.log(JSON.stringify(summary, null, 2));
296
+ return;
297
+ }
298
+
299
+ console.log('');
300
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
301
+ console.log(chalk.cyan.bold('\n Task Özeti\n'));
302
+ console.log(chalk.gray(' Aktif : ') + (summary.active > 0 ? chalk.yellow(summary.active) : chalk.green('0')));
303
+ console.log(chalk.gray(' Hatalı : ') + (summary.failures > 0 ? chalk.red(summary.failures) : chalk.green('0')));
304
+ console.log(chalk.gray(' Toplam : ') + chalk.white(summary.total));
305
+ console.log(chalk.gray('\n Runtime Dağılımı'));
306
+ Object.entries(summary.byRuntime).forEach(([rt, count]) => {
307
+ if (count > 0) console.log(chalk.gray(` ${rt.padEnd(10)}: ${count}`));
308
+ });
309
+ console.log('');
310
+ }
311
+
312
+ function getAgeString(dateStr) {
313
+ const ms = Date.now() - new Date(dateStr).getTime();
314
+ const sec = Math.floor(ms / 1000);
315
+ if (sec < 60) return `${sec}s önce`;
316
+ const min = Math.floor(sec / 60);
317
+ if (min < 60) return `${min}dk önce`;
318
+ const hr = Math.floor(min / 60);
319
+ if (hr < 24) return `${hr}sa önce`;
320
+ const days = Math.floor(hr / 24);
321
+ return `${days}g önce`;
322
+ }
323
+
324
+ function formatTime(dateStr) {
325
+ return new Date(dateStr).toLocaleString('tr-TR');
326
+ }
327
+
328
+ module.exports = tasks;
@@ -0,0 +1,79 @@
1
+ const chalk = require('chalk');
2
+ const inquirer = require('../utils/inquirer-wrapper');
3
+ const { getConfig, saveConfig } = require('../utils/config');
4
+
5
+ async function webhooks(action) {
6
+ if (!action || action === 'connect') return connectWebhook();
7
+ if (action === 'disconnect') return disconnectWebhook();
8
+ if (action === 'status') return statusWebhooks();
9
+ if (action === 'list') return listWebhooks();
10
+ console.log(chalk.red('\n❌ Unknown action\n'));
11
+ console.log(chalk.gray('Available actions: connect, disconnect, status, list\n'));
12
+ process.exit(1);
13
+ }
14
+
15
+ async function connectWebhook() {
16
+ const config = getConfig();
17
+ if (!config.providerUrl) { console.log(chalk.red('\n❌ Setup yapılmamış. Önce "natureco setup" çalıştırın.\n')); process.exit(1); }
18
+ console.log(chalk.yellow('\n⏳ Webhook bağlantısı hazırlanıyor...\n'));
19
+ console.log(chalk.gray('Gelen webhook\'lar NatureCo\'nun gateway\'ine yönlendirilir.\n'));
20
+ const answers = await inquirer.prompt([
21
+ { type: 'input', name: 'name', message: 'Webhook adı:', validate: v => v.trim() ? true : 'Gerekli' },
22
+ { type: 'input', name: 'path', message: 'Webhook yolu (örn: /my-webhook):', validate: v => v.startsWith('/') ? true : 'Yol / ile başlamalı' },
23
+ { type: 'input', name: 'secret', message: 'Webhook secret (opsiyonel):' },
24
+ ]);
25
+ const webhooks = config.webhooks || [];
26
+ const entry = {
27
+ id: `webhook_${Date.now()}`,
28
+ name: answers.name.trim(),
29
+ path: answers.path.trim(),
30
+ secret: answers.secret.trim() || '',
31
+ createdAt: new Date().toISOString(),
32
+ };
33
+ webhooks.push(entry);
34
+ config.webhooks = webhooks;
35
+ config.webhookEnabled = true;
36
+ saveConfig(config);
37
+ console.log(chalk.green('\n✅ Webhook eklendi!\n'));
38
+ console.log(chalk.cyan('ID:'), chalk.white(entry.id));
39
+ console.log(chalk.cyan('İsim:'), chalk.white(entry.name));
40
+ console.log(chalk.cyan('Yol:'), chalk.white(entry.path));
41
+ console.log(chalk.gray('\nGateway ile başlatmak için: natureco gateway start\n'));
42
+ }
43
+
44
+ async function disconnectWebhook() {
45
+ const config = getConfig();
46
+ const webhooks = config.webhooks || [];
47
+ if (webhooks.length === 0) { console.log(chalk.gray('\n⚠️ No webhooks configured\n')); return; }
48
+ const { confirm } = await inquirer.prompt([{ type: 'confirm', name: 'confirm', message: 'Tüm webhook\'ları kaldırmak istediğinize emin misiniz?', default: false }]);
49
+ if (!confirm) { console.log(chalk.gray('\nCancelled\n')); return; }
50
+ delete config.webhooks;
51
+ delete config.webhookEnabled;
52
+ saveConfig(config);
53
+ console.log(chalk.green('\n✅ All webhooks removed\n'));
54
+ }
55
+
56
+ function listWebhooks() {
57
+ const config = getConfig();
58
+ const webhooks = config.webhooks || [];
59
+ if (webhooks.length === 0) { console.log(chalk.gray('\n⚠️ No webhooks configured\n')); return; }
60
+ console.log(chalk.green(`\n✅ ${webhooks.length} webhook(s) configured\n`));
61
+ webhooks.forEach(w => {
62
+ console.log(chalk.cyan(' ID:'), chalk.white(w.id));
63
+ console.log(chalk.cyan(' İsim:'), chalk.white(w.name));
64
+ console.log(chalk.cyan(' Yol:'), chalk.white(w.path));
65
+ if (w.secret) console.log(chalk.cyan(' Secret:'), chalk.gray('✓ ayarlı'));
66
+ console.log('');
67
+ });
68
+ }
69
+
70
+ function statusWebhooks() {
71
+ const config = getConfig();
72
+ const webhooks = config.webhooks || [];
73
+ if (webhooks.length === 0) { console.log(chalk.gray('\n⚠️ No webhooks configured\n')); console.log(chalk.gray('Add with: natureco webhooks connect\n')); return; }
74
+ console.log(chalk.green(`\n✅ Webhooks active (${webhooks.length} route(s))\n`));
75
+ webhooks.forEach(w => console.log(chalk.white(` ${w.path} → ${w.name}`)));
76
+ console.log(chalk.gray('\nDisconnect with: natureco webhooks disconnect\n'));
77
+ }
78
+
79
+ module.exports = webhooks;
@@ -7,25 +7,11 @@ const os = require('os');
7
7
  const pino = require('pino');
8
8
  const { getApiKey, getConfig, saveConfig } = require('../utils/config');
9
9
  const { getBots, sendMessage } = require('../utils/api');
10
+ const { loadBaileys } = require('../utils/baileys');
11
+ const { NatureCoError, ChannelError, handleError } = require('../utils/errors');
10
12
 
11
- // Baileys imports
12
- let makeWASocket, useMultiFileAuthState, DisconnectReason, fetchLatestBaileysVersion, Browsers;
13
-
14
- // Logger
15
13
  const logger = pino({ level: 'silent' });
16
14
 
17
- // Lazy load Baileys (only when needed)
18
- function loadBaileys() {
19
- if (!makeWASocket) {
20
- const baileys = require('@whiskeysockets/baileys');
21
- makeWASocket = baileys.default;
22
- useMultiFileAuthState = baileys.useMultiFileAuthState;
23
- DisconnectReason = baileys.DisconnectReason;
24
- fetchLatestBaileysVersion = baileys.fetchLatestBaileysVersion;
25
- Browsers = baileys.Browsers;
26
- }
27
- }
28
-
29
15
  // WhatsApp session directory
30
16
  const WHATSAPP_SESSION_DIR = path.join(os.homedir(), '.natureco', 'whatsapp-sessions');
31
17
 
@@ -73,9 +59,6 @@ async function connectWhatsApp() {
73
59
  console.log(chalk.cyan('\n📱 WhatsApp bağlantısı başlatılıyor...'));
74
60
  console.log(chalk.gray('Telefonunuzda WhatsApp\'ı açın ve QR kodu taratın.\n'));
75
61
 
76
- // Load Baileys
77
- loadBaileys();
78
-
79
62
  // Create session directory
80
63
  const sessionDir = path.join(WHATSAPP_SESSION_DIR, botId);
81
64
  if (!fs.existsSync(sessionDir)) {
@@ -88,6 +71,8 @@ async function connectWhatsApp() {
88
71
 
89
72
  async function startWhatsAppConnection(sessionDir, botId, selectedBot, config) {
90
73
  try {
74
+ const { makeWASocket, useMultiFileAuthState, DisconnectReason, fetchLatestBaileysVersion, Browsers } = loadBaileys();
75
+
91
76
  // Create auth state
92
77
  const { state, saveCreds } = await useMultiFileAuthState(sessionDir);
93
78
 
@@ -197,8 +182,9 @@ async function startWhatsAppConnection(sessionDir, botId, selectedBot, config) {
197
182
  });
198
183
 
199
184
  } catch (err) {
200
- console.log(chalk.red(`\n❌ Connection failed: ${err.message}\n`));
201
- if (err.message.includes('Cannot find module')) {
185
+ const msg = err instanceof NatureCoError ? err.message : err?.message ?? 'Unknown error';
186
+ console.log(chalk.red(`\n❌ Connection failed: ${msg}\n`));
187
+ if (err?.message?.includes('Cannot find module')) {
202
188
  console.log(chalk.yellow('⚠️ Baileys paketi yüklü değil. Yükleniyor...\n'));
203
189
  console.log(chalk.gray('Lütfen şu komutu çalıştırın:\n'));
204
190
  console.log(chalk.cyan('npm install -g @whiskeysockets/baileys pino\n'));
package/src/tools/bash.js CHANGED
@@ -1,5 +1,7 @@
1
1
  const { execSync } = require('child_process');
2
2
  const os = require('os');
3
+ const chalk = require('chalk');
4
+ const { isDangerousCommand, checkCommand, isSafeCommand } = require('../utils/approvals');
3
5
 
4
6
  module.exports = {
5
7
  name: 'bash',
@@ -17,43 +19,75 @@ module.exports = {
17
19
 
18
20
  async execute(params) {
19
21
  try {
20
- // Security: Block dangerous commands
21
- const DANGEROUS_COMMANDS = ['kill', 'rm -rf', 'sudo rm', 'pkill', 'killall', 'shutdown', 'reboot', 'format'];
22
- const isDangerous = DANGEROUS_COMMANDS.some(cmd => params.command.includes(cmd));
23
-
24
- if (isDangerous) {
22
+ if (!params.command || !params.command.trim()) {
23
+ return { success: false, error: 'No command provided' };
24
+ }
25
+
26
+ const command = params.command;
27
+
28
+ // Skip approval checks for safe commands
29
+ if (isSafeCommand(command)) {
30
+ return runCommand(command);
31
+ }
32
+
33
+ // Check command against approvals policy
34
+ const approval = await checkCommand(command, { agentId: 'default' });
35
+
36
+ if (!approval.allowed) {
37
+ if (approval.reason === 'denied-by-policy') {
38
+ return {
39
+ success: false,
40
+ error: 'Command execution is denied by security policy. Use "natureco security allowlist add" to allow specific commands.',
41
+ };
42
+ }
43
+ if (approval.reason === 'not-in-allowlist') {
44
+ return {
45
+ success: false,
46
+ error: 'Command is not in the allowlist. Use "natureco security allowlist add" to add it, or set a less restrictive policy.',
47
+ };
48
+ }
49
+ return { success: false, error: `Command rejected: ${approval.reason}` };
50
+ }
51
+
52
+ // Check for dangerous commands that weren't already user-approved
53
+ if (isDangerousCommand(command)) {
54
+ console.log(chalk.yellow('\n ⚠️ Potentially dangerous command'));
55
+ console.log(chalk.gray(' ') + command);
56
+ console.log('');
25
57
  return {
26
58
  success: false,
27
- error: 'Bu komut güvenlik nedeniyle engellendi. Kullanıcıdan onay alınması gerekiyor.'
59
+ error: 'Dangerous command blocked. Run manually after review.',
28
60
  };
29
61
  }
30
-
31
- // Replace /home with actual home directory (Unix only)
32
- // Handles: /home, /home/Documents, /home/anything
33
- let command = params.command;
34
- if (process.platform !== 'win32') {
35
- command = command.replace(/\/home(\/[^\s]*)?/g, (match, subpath) => {
36
- return os.homedir() + (subpath || '');
37
- });
38
- }
39
-
40
- const output = execSync(command, {
41
- encoding: 'utf-8',
42
- maxBuffer: 10 * 1024 * 1024, // 10MB
43
- timeout: 30000, // 30 seconds
44
- shell: true // Use shell for command execution
45
- });
46
-
47
- return {
48
- success: true,
49
- output: output.trim()
50
- };
62
+
63
+ return runCommand(approval.editedCommand || command);
51
64
  } catch (error) {
52
65
  return {
53
66
  success: false,
54
- error: error.message,
55
- stderr: error.stderr?.toString() || ''
67
+ error: error?.message ?? 'Unknown error',
68
+ stderr: error?.stderr?.toString() ?? '',
56
69
  };
57
70
  }
58
71
  }
59
72
  };
73
+
74
+ function runCommand(command) {
75
+ let cmd = command;
76
+ if (process.platform !== 'win32') {
77
+ cmd = cmd.replace(/\/home(\/[^\s]*)?/g, (match, subpath) => {
78
+ return os.homedir() + (subpath || '');
79
+ });
80
+ }
81
+
82
+ const output = execSync(cmd, {
83
+ encoding: 'utf-8',
84
+ maxBuffer: 10 * 1024 * 1024,
85
+ timeout: 30000,
86
+ shell: true,
87
+ });
88
+
89
+ return {
90
+ success: true,
91
+ output: output.trim(),
92
+ };
93
+ }