natureco-cli 2.23.28 → 2.23.30

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 (96) hide show
  1. package/README.md +94 -11
  2. package/bin/natureco.js +470 -10
  3. package/package.json +10 -6
  4. package/src/commands/admin-rpc.js +219 -0
  5. package/src/commands/agent.js +89 -0
  6. package/src/commands/approvals.js +53 -0
  7. package/src/commands/backup.js +124 -0
  8. package/src/commands/bonjour.js +167 -0
  9. package/src/commands/capability.js +64 -0
  10. package/src/commands/channels.js +94 -4
  11. package/src/commands/chat.js +11 -25
  12. package/src/commands/clickclack.js +130 -0
  13. package/src/commands/commitments.js +32 -0
  14. package/src/commands/completion.js +76 -0
  15. package/src/commands/config.js +111 -68
  16. package/src/commands/configure.js +93 -0
  17. package/src/commands/crestodian.js +92 -0
  18. package/src/commands/daemon.js +60 -0
  19. package/src/commands/device-pair.js +248 -0
  20. package/src/commands/devices.js +110 -0
  21. package/src/commands/directory.js +47 -0
  22. package/src/commands/dns.js +58 -0
  23. package/src/commands/docs.js +43 -0
  24. package/src/commands/doctor.js +121 -16
  25. package/src/commands/exec-policy.js +71 -0
  26. package/src/commands/gateway-server.js +1175 -30
  27. package/src/commands/gateway.js +11 -20
  28. package/src/commands/health.js +18 -0
  29. package/src/commands/help.js +6 -0
  30. package/src/commands/imessage.js +169 -0
  31. package/src/commands/infer.js +73 -0
  32. package/src/commands/irc.js +119 -0
  33. package/src/commands/mattermost.js +164 -0
  34. package/src/commands/memory-cmd.js +134 -1
  35. package/src/commands/message.js +30 -4
  36. package/src/commands/migrate.js +213 -2
  37. package/src/commands/models.js +584 -216
  38. package/src/commands/node.js +98 -0
  39. package/src/commands/nodes.js +106 -0
  40. package/src/commands/oc-path.js +200 -0
  41. package/src/commands/onboard.js +70 -0
  42. package/src/commands/open-prose.js +67 -0
  43. package/src/commands/plugins.js +415 -172
  44. package/src/commands/policy.js +176 -0
  45. package/src/commands/proxy.js +155 -0
  46. package/src/commands/qr.js +28 -0
  47. package/src/commands/sandbox.js +125 -0
  48. package/src/commands/secrets.js +118 -0
  49. package/src/commands/security.js +149 -1
  50. package/src/commands/setup.js +114 -10
  51. package/src/commands/signal.js +495 -0
  52. package/src/commands/skills.js +20 -29
  53. package/src/commands/sms.js +168 -0
  54. package/src/commands/system.js +53 -0
  55. package/src/commands/tasks.js +328 -79
  56. package/src/commands/terminal.js +21 -0
  57. package/src/commands/thread-ownership.js +157 -0
  58. package/src/commands/transcripts.js +72 -0
  59. package/src/commands/voice.js +82 -0
  60. package/src/commands/vydra.js +98 -0
  61. package/src/commands/webhooks.js +79 -0
  62. package/src/commands/whatsapp.js +7 -21
  63. package/src/commands/workboard.js +207 -0
  64. package/src/tools/audio_understanding.js +154 -0
  65. package/src/tools/bash.js +63 -29
  66. package/src/tools/browser.js +112 -0
  67. package/src/tools/canvas.js +104 -0
  68. package/src/tools/document_extract.js +84 -0
  69. package/src/tools/duckduckgo.js +54 -0
  70. package/src/tools/exa_search.js +66 -0
  71. package/src/tools/firecrawl.js +104 -0
  72. package/src/tools/image_generation.js +99 -0
  73. package/src/tools/llm_task.js +118 -0
  74. package/src/tools/media_understanding.js +128 -0
  75. package/src/tools/music_generation.js +113 -0
  76. package/src/tools/parallel_search.js +77 -0
  77. package/src/tools/phone_control.js +80 -0
  78. package/src/tools/phone_control_enhanced.js +184 -0
  79. package/src/tools/searxng.js +61 -0
  80. package/src/tools/speech_to_text.js +135 -0
  81. package/src/tools/text_to_speech.js +105 -0
  82. package/src/tools/thread_ownership.js +88 -0
  83. package/src/tools/video_generation.js +72 -0
  84. package/src/tools/web_readability.js +104 -0
  85. package/src/utils/api.js +3 -20
  86. package/src/utils/approvals.js +297 -0
  87. package/src/utils/background.js +223 -66
  88. package/src/utils/baileys.js +21 -0
  89. package/src/utils/config.js +141 -10
  90. package/src/utils/errors.js +148 -0
  91. package/src/utils/inquirer-wrapper.js +1 -2
  92. package/src/utils/memory.js +200 -0
  93. package/src/utils/path-utils.js +13 -13
  94. package/src/utils/plugin-registry.js +238 -0
  95. package/src/utils/secrets.js +177 -0
  96. package/src/utils/skills.js +10 -23
@@ -0,0 +1,168 @@
1
+ const chalk = require('chalk');
2
+ const inquirer = require('../utils/inquirer-wrapper');
3
+ const { getConfig, saveConfig } = require('../utils/config');
4
+
5
+ async function sms(action) {
6
+ if (!action || action === 'connect') return connectSms();
7
+ if (action === 'disconnect') return disconnectSms();
8
+ if (action === 'status') return statusSms();
9
+ if (action === 'probe') return probeSms();
10
+ console.log(chalk.red('\n❌ Unknown action\n'));
11
+ console.log(chalk.gray('Available actions: connect, disconnect, status, probe\n'));
12
+ process.exit(1);
13
+ }
14
+
15
+ async function connectSms() {
16
+ const config = getConfig();
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
+ }
21
+ console.log(chalk.yellow('\n⏳ SMS (Twilio) bağlantısı hazırlanıyor...\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
+
33
+ const answers = await inquirer.prompt([
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 },
46
+ ]);
47
+
48
+ const botId = `sms_${Date.now()}`;
49
+ config.smsAccountSid = answers.accountSid.trim();
50
+ config.smsAuthToken = answers.authToken.trim();
51
+ config.smsFromNumber = answers.fromNumber.trim();
52
+ config.smsMessagingServiceSid = answers.messagingServiceSid.trim() || '';
53
+ config.smsPublicWebhookUrl = answers.webhookUrl.trim() || '';
54
+ config.smsDmPolicy = answers.dmPolicy;
55
+ config.smsEnableWebhook = answers.enableWebhook;
56
+ config.smsBotId = botId;
57
+ saveConfig(config);
58
+
59
+ console.log(chalk.green('\n✅ SMS (Twilio) bağlantısı kaydedildi!\n'));
60
+ console.log(chalk.cyan('Bot ID:'), chalk.white(botId));
61
+ console.log(chalk.cyan('Account SID:'), chalk.white(answers.accountSid.slice(0, 20) + '...'));
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'));
74
+ }
75
+
76
+ async function disconnectSms() {
77
+ const config = getConfig();
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
+ }
89
+ delete config.smsAccountSid; delete config.smsAuthToken; delete config.smsFromNumber;
90
+ delete config.smsMessagingServiceSid; delete config.smsPublicWebhookUrl;
91
+ delete config.smsDmPolicy; delete config.smsEnableWebhook; delete config.smsBotId;
92
+ saveConfig(config);
93
+ console.log(chalk.green('\n✅ SMS disconnected\n'));
94
+ }
95
+
96
+ function statusSms() {
97
+ const config = getConfig();
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
+ }
103
+ console.log(chalk.green('\n✅ SMS (Twilio) connected\n'));
104
+ console.log(chalk.cyan('Bot ID:'), chalk.white(config.smsBotId));
105
+ console.log(chalk.cyan('Account SID:'), chalk.white((config.smsAccountSid || '').slice(0, 20) + '...'));
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ışı'));
109
+ console.log(chalk.gray('\nDisconnect with: natureco sms disconnect\n'));
110
+ }
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
+
168
+ module.exports = sms;
@@ -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;
@@ -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,21 @@
1
+ const chalk = require('chalk');
2
+ const { execSync } = require('child_process');
3
+
4
+ function terminal(args) {
5
+ console.log(chalk.cyan('\n 🖥️ Terminal UI\n'));
6
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
7
+ console.log(chalk.gray(' Open a terminal UI connected to the Gateway.\n'));
8
+ console.log(chalk.gray(' Starting chat interface...\n'));
9
+
10
+ try {
11
+ execSync('node "' + __dirname + '\\chat.js"', {
12
+ stdio: 'inherit',
13
+ cwd: require('path').join(__dirname, '..', '..'),
14
+ timeout: 5000
15
+ });
16
+ } catch {
17
+ console.log(chalk.cyan(' Use:') + chalk.white(' natureco chat\n'));
18
+ }
19
+ }
20
+
21
+ module.exports = terminal;