natureco-cli 2.23.30 → 2.23.32

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 (69) hide show
  1. package/bin/natureco.js +178 -167
  2. package/package.json +1 -1
  3. package/src/commands/acp.js +39 -0
  4. package/src/commands/admin-rpc.js +83 -0
  5. package/src/commands/agent.js +214 -23
  6. package/src/commands/agents.js +114 -30
  7. package/src/commands/approvals.js +172 -11
  8. package/src/commands/ask.js +1 -1
  9. package/src/commands/browser.js +815 -0
  10. package/src/commands/capability.js +195 -22
  11. package/src/commands/channels.js +422 -267
  12. package/src/commands/chat.js +5 -8
  13. package/src/commands/clawbot.js +19 -0
  14. package/src/commands/code.js +3 -2
  15. package/src/commands/commitments.js +125 -9
  16. package/src/commands/completion.js +40 -32
  17. package/src/commands/config.js +228 -30
  18. package/src/commands/configure.js +84 -67
  19. package/src/commands/cron.js +239 -19
  20. package/src/commands/daemon.js +34 -4
  21. package/src/commands/dashboard.js +47 -374
  22. package/src/commands/devices.js +53 -26
  23. package/src/commands/directory.js +146 -14
  24. package/src/commands/dns.js +148 -10
  25. package/src/commands/docs.js +119 -26
  26. package/src/commands/doctor.js +143 -492
  27. package/src/commands/exec-policy.js +57 -48
  28. package/src/commands/gateway.js +492 -249
  29. package/src/commands/health.js +141 -11
  30. package/src/commands/help.js +24 -25
  31. package/src/commands/hooks.js +141 -87
  32. package/src/commands/infer.js +1442 -41
  33. package/src/commands/logs.js +122 -99
  34. package/src/commands/mcp.js +121 -309
  35. package/src/commands/memory.js +128 -0
  36. package/src/commands/message.js +720 -140
  37. package/src/commands/models.js +39 -1
  38. package/src/commands/node.js +77 -77
  39. package/src/commands/nodes.js +278 -22
  40. package/src/commands/onboard.js +115 -56
  41. package/src/commands/pairing.js +108 -107
  42. package/src/commands/path.js +206 -0
  43. package/src/commands/plugins.js +35 -1
  44. package/src/commands/proxy.js +159 -8
  45. package/src/commands/qr.js +55 -13
  46. package/src/commands/reset.js +101 -94
  47. package/src/commands/secrets.js +104 -21
  48. package/src/commands/sessions.js +110 -51
  49. package/src/commands/setup.js +229 -649
  50. package/src/commands/skills.js +67 -1
  51. package/src/commands/status.js +101 -127
  52. package/src/commands/tasks.js +208 -100
  53. package/src/commands/terminal.js +130 -12
  54. package/src/commands/transcripts.js +24 -1
  55. package/src/commands/tui.js +41 -0
  56. package/src/commands/uninstall.js +73 -92
  57. package/src/commands/update.js +146 -91
  58. package/src/commands/web-fetch.js +34 -0
  59. package/src/commands/webhooks.js +58 -66
  60. package/src/commands/wiki.js +783 -0
  61. package/src/utils/agents-md.js +85 -0
  62. package/src/utils/api.js +40 -41
  63. package/src/utils/format.js +144 -0
  64. package/src/utils/headless.js +2 -1
  65. package/src/utils/parallel-tools.js +106 -0
  66. package/src/utils/sub-agent.js +148 -0
  67. package/src/utils/token-budget.js +304 -0
  68. package/src/utils/tool-runner.js +7 -5
  69. package/src/utils/web-fetch.js +107 -0
@@ -1,9 +1,11 @@
1
1
  const chalk = require('chalk');
2
+ const F = require('../utils/format');
2
3
  const fs = require('fs');
3
4
  const path = require('path');
4
5
  const os = require('os');
5
6
 
6
7
  const CRONS_FILE = path.join(os.homedir(), '.natureco', 'crons.json');
8
+ const CRONS_RUNS_FILE = path.join(os.homedir(), '.natureco', 'cron-runs.json');
7
9
 
8
10
  /**
9
11
  * Normalize WhatsApp number from JID format to clean phone number
@@ -36,12 +38,18 @@ function saveCrons(crons) {
36
38
  }
37
39
 
38
40
  async function cron(action, options) {
39
- if (!action || !['add', 'list', 'remove'].includes(action)) {
41
+ if (!action || !['add', 'list', 'remove', 'get', 'edit', 'enable', 'disable', 'runs', 'run'].includes(action)) {
40
42
  console.log(chalk.red('\n❌ Geçersiz aksiyon\n'));
41
43
  console.log(chalk.gray('Kullanım:'));
42
44
  console.log(chalk.cyan(' natureco cron add --name <name> --schedule <cron> --action <channel> --target <target> --prompt <prompt>'));
43
45
  console.log(chalk.cyan(' natureco cron list'));
46
+ console.log(chalk.cyan(' natureco cron get <name>'));
47
+ console.log(chalk.cyan(' natureco cron edit <name> [--name <name>] [--schedule <cron>] [--action <channel>] [--target <target>] [--prompt <prompt>]'));
44
48
  console.log(chalk.cyan(' natureco cron remove --name <name>'));
49
+ console.log(chalk.cyan(' natureco cron enable <name>'));
50
+ console.log(chalk.cyan(' natureco cron disable <name>'));
51
+ console.log(chalk.cyan(' natureco cron runs <name>'));
52
+ console.log(chalk.cyan(' natureco cron run <name>'));
45
53
  console.log(chalk.gray('\nÖrnek:'));
46
54
  console.log(chalk.cyan(' natureco cron add --name "bitcoin-fiyat" --schedule "0 9 * * *" --action "whatsapp" --target "+905422842631" --prompt "Bugünkü Bitcoin fiyatını öğren ve kısaca bildir"\n'));
47
55
  process.exit(1);
@@ -53,6 +61,18 @@ async function cron(action, options) {
53
61
  listCrons();
54
62
  } else if (action === 'remove') {
55
63
  removeCron(options);
64
+ } else if (action === 'get') {
65
+ getCron(options);
66
+ } else if (action === 'edit') {
67
+ editCron(options);
68
+ } else if (action === 'enable') {
69
+ enableCron(options);
70
+ } else if (action === 'disable') {
71
+ disableCron(options);
72
+ } else if (action === 'runs') {
73
+ showRuns(options);
74
+ } else if (action === 'run') {
75
+ runCron(options);
56
76
  }
57
77
  }
58
78
 
@@ -120,42 +140,42 @@ function listCrons() {
120
140
  const crons = loadCrons();
121
141
 
122
142
  if (crons.length === 0) {
123
- console.log(chalk.gray('\n⚪ Kayıtlı cron yok\n'));
143
+ F.header('Cron Jobs');
144
+ F.meta('Kayıtlı cron yok');
124
145
  return;
125
146
  }
126
147
 
127
- // Load config for fallback targets
128
148
  const { getConfig } = require('../utils/config');
129
149
  const config = getConfig();
130
150
  const defaultWhatsappTarget = normalizeWhatsAppNumber(config.whatsappPhone) || 'N/A';
131
151
  const defaultTelegramTarget = (config.telegramAllowedChats && config.telegramAllowedChats[0]) || 'N/A';
132
152
 
133
- console.log(chalk.green(`\n📅 Kayıtlı Cron'lar (${crons.length})\n`));
134
-
135
- crons.forEach((c, i) => {
136
- // Use target from cron or fallback to config
153
+ const runs = loadRuns();
154
+ const rows = crons.map(c => {
137
155
  let target = c.target;
138
156
  if (!target || target === 'undefined') {
139
157
  target = c.action === 'telegram' ? defaultTelegramTarget : defaultWhatsappTarget;
140
158
  } else if (c.action === 'whatsapp') {
141
- // Normalize WhatsApp JID format
142
159
  target = normalizeWhatsAppNumber(target);
143
160
  }
144
-
145
- console.log(chalk.cyan(`${i + 1}. ${c.name}`));
146
- console.log(chalk.gray(` Zamanlama: ${c.schedule}`));
147
- console.log(chalk.gray(` Kanal: ${c.action} → ${target}`));
148
- console.log(chalk.gray(` Prompt: ${c.prompt.substring(0, 60)}${c.prompt.length > 60 ? '...' : ''}`));
149
- console.log(chalk.gray(` Durum: ${c.enabled ? 'Aktif' : 'Pasif'}`));
150
- console.log('');
161
+ const cronRuns = runs.filter(r => r.name === c.name);
162
+ const lastRun = cronRuns.sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp))[0];
163
+ return [
164
+ c.name,
165
+ c.schedule,
166
+ c.enabled ? 'Aktif' : 'Pasif',
167
+ lastRun ? lastRun.timestamp.slice(0, 10) : ''
168
+ ];
151
169
  });
170
+ F.header('Cron Jobs');
171
+ F.table(['Name', 'Schedule', 'Status', 'LastRun'], rows);
152
172
  }
153
173
 
154
174
  function removeCron(options) {
155
175
  const { name } = options;
156
176
 
157
177
  if (!name) {
158
- console.log(chalk.red('\n❌ --name parametresi gerekli\n'));
178
+ F.error('--name parametresi gerekli');
159
179
  process.exit(1);
160
180
  }
161
181
 
@@ -163,15 +183,215 @@ function removeCron(options) {
163
183
  const index = crons.findIndex(c => c.name === name);
164
184
 
165
185
  if (index === -1) {
166
- console.log(chalk.red('\n❌ Bu isimde bir cron bulunamadı\n'));
186
+ F.error('Bu isimde bir cron bulunamadı');
167
187
  process.exit(1);
168
188
  }
169
189
 
170
190
  crons.splice(index, 1);
171
191
  saveCrons(crons);
172
192
 
173
- console.log(chalk.green('\n✅ Cron silindi!\n'));
174
- console.log(chalk.gray('Gateway çalışıyorsa yeniden başlatın: natureco gateway stop && natureco gateway start\n'));
193
+ F.success('Cron silindi!');
194
+ F.meta('Gateway çalışıyorsa yeniden başlatın: natureco gateway stop && natureco gateway start');
195
+ }
196
+
197
+ function getCron(options) {
198
+ const { name } = options;
199
+ if (!name) {
200
+ F.error('Cron adı gerekli. Kullanım: natureco cron get <name>');
201
+ process.exit(1);
202
+ }
203
+
204
+ const crons = loadCrons();
205
+ const cron = crons.find(c => c.name === name);
206
+ if (!cron) {
207
+ F.error('"' + name + '" isminde bir cron bulunamadı');
208
+ process.exit(1);
209
+ }
210
+
211
+ F.header('Cron: ' + cron.name);
212
+ F.kv('İsim', cron.name);
213
+ F.kv('Zamanlama', cron.schedule);
214
+ F.kv('Kanal', cron.action);
215
+ F.kv('Hedef', cron.target);
216
+ F.kv('Prompt', cron.prompt);
217
+ F.kv('Oluşturulma', cron.createdAt);
218
+ F.kv('Durum', cron.enabled ? 'Aktif' : 'Pasif');
219
+ }
220
+
221
+ function editCron(options) {
222
+ const { name, schedule, action, target, prompt } = options;
223
+ const newName = options['newName'];
224
+
225
+ if (!name) {
226
+ F.error('Cron adı gerekli. Kullanım: natureco cron edit <name> [--name <newName>] [--schedule <cron>] [--action <channel>] [--target <target>] [--prompt <prompt>]');
227
+ process.exit(1);
228
+ }
229
+
230
+ const crons = loadCrons();
231
+ const cron = crons.find(c => c.name === name);
232
+ if (!cron) {
233
+ F.error('"' + name + '" isminde bir cron bulunamadı');
234
+ process.exit(1);
235
+ }
236
+
237
+ if (newName) cron.name = newName;
238
+ if (schedule) {
239
+ try {
240
+ const nodeCron = require('node-cron');
241
+ if (!nodeCron.validate(schedule)) {
242
+ F.error('Geçersiz cron ifadesi');
243
+ process.exit(1);
244
+ }
245
+ } catch (err) {
246
+ F.error('node-cron yüklü değil');
247
+ process.exit(1);
248
+ }
249
+ cron.schedule = schedule;
250
+ }
251
+ if (action) {
252
+ if (!['whatsapp', 'telegram'].includes(action)) {
253
+ F.error('Geçersiz action. Sadece "whatsapp" veya "telegram" kullanılabilir');
254
+ process.exit(1);
255
+ }
256
+ cron.action = action;
257
+ }
258
+ if (target) cron.target = target;
259
+ if (prompt) cron.prompt = prompt;
260
+
261
+ saveCrons(crons);
262
+
263
+ F.success('Cron güncellendi!');
264
+ F.kv('İsim', cron.name);
265
+ F.kv('Zamanlama', cron.schedule);
266
+ F.kv('Kanal', cron.action);
267
+ F.kv('Hedef', cron.target);
268
+ F.kv('Prompt', cron.prompt);
269
+ F.meta('Gateway çalışıyorsa yeniden başlatın: natureco gateway stop && natureco gateway start');
270
+ }
271
+
272
+ function enableCron(options) {
273
+ const { name } = options;
274
+ if (!name) {
275
+ F.error('Cron adı gerekli. Kullanım: natureco cron enable <name>');
276
+ process.exit(1);
277
+ }
278
+
279
+ const crons = loadCrons();
280
+ const cron = crons.find(c => c.name === name);
281
+ if (!cron) {
282
+ F.error('"' + name + '" isminde bir cron bulunamadı');
283
+ process.exit(1);
284
+ }
285
+
286
+ if (cron.enabled) {
287
+ F.warning('"' + name + '" cron zaten aktif');
288
+ return;
289
+ }
290
+
291
+ cron.enabled = true;
292
+ saveCrons(crons);
293
+ F.dot(true, name);
294
+ F.success('"' + name + '" cron aktifleştirildi');
295
+ F.meta('Gateway çalışıyorsa yeniden başlatın: natureco gateway stop && natureco gateway start');
296
+ }
297
+
298
+ function disableCron(options) {
299
+ const { name } = options;
300
+ if (!name) {
301
+ F.error('Cron adı gerekli. Kullanım: natureco cron disable <name>');
302
+ process.exit(1);
303
+ }
304
+
305
+ const crons = loadCrons();
306
+ const cron = crons.find(c => c.name === name);
307
+ if (!cron) {
308
+ F.error('"' + name + '" isminde bir cron bulunamadı');
309
+ process.exit(1);
310
+ }
311
+
312
+ if (!cron.enabled) {
313
+ F.warning('"' + name + '" cron zaten pasif');
314
+ return;
315
+ }
316
+
317
+ cron.enabled = false;
318
+ saveCrons(crons);
319
+ F.dot(false, name);
320
+ F.success('"' + name + '" cron pasifleştirildi');
321
+ F.meta('Gateway çalışıyorsa yeniden başlatın: natureco gateway stop && natureco gateway start');
322
+ }
323
+
324
+ function loadRuns() {
325
+ try {
326
+ if (!fs.existsSync(CRONS_RUNS_FILE)) {
327
+ return [];
328
+ }
329
+ return JSON.parse(fs.readFileSync(CRONS_RUNS_FILE, 'utf-8'));
330
+ } catch {
331
+ return [];
332
+ }
333
+ }
334
+
335
+ function showRuns(options) {
336
+ const { name } = options;
337
+ if (!name) {
338
+ F.error('Cron adı gerekli. Kullanım: natureco cron runs <name>');
339
+ process.exit(1);
340
+ }
341
+
342
+ const runs = loadRuns().filter(r => r.name === name);
343
+
344
+ F.header('Cron Runs: ' + name);
345
+
346
+ if (runs.length === 0) {
347
+ F.meta('"' + name + '" için kayıtlı çalışma geçmişi yok');
348
+ return;
349
+ }
350
+
351
+ const rows = runs.map(r => [
352
+ r.timestamp,
353
+ r.status,
354
+ r.output ? r.output.substring(0, 60) : '—'
355
+ ]);
356
+ F.table(['Time', 'Status', 'Output'], rows);
357
+ }
358
+
359
+ function runCron(options) {
360
+ const { name } = options;
361
+ if (!name) {
362
+ F.error('Cron adı gerekli. Kullanım: natureco cron run <name>');
363
+ process.exit(1);
364
+ }
365
+
366
+ const crons = loadCrons();
367
+ const cron = crons.find(c => c.name === name);
368
+ if (!cron) {
369
+ F.error('"' + name + '" isminde bir cron bulunamadı');
370
+ process.exit(1);
371
+ }
372
+
373
+ const timestamp = new Date().toISOString();
374
+
375
+ F.info('"' + name + '" cron manuel olarak çalıştırılıyor...');
376
+ F.kv('Zamanlama', cron.schedule);
377
+ F.kv('Kanal', cron.action);
378
+ F.kv('Hedef', cron.target);
379
+ F.kv('Prompt', cron.prompt);
380
+ F.success('Cron tetiklendi (mock)');
381
+
382
+ // Log the run
383
+ const runs = loadRuns();
384
+ runs.push({
385
+ name,
386
+ timestamp,
387
+ status: 'success',
388
+ output: `Mock run of ${name} (${cron.action} → ${cron.target})`
389
+ });
390
+ const dir = path.dirname(CRONS_RUNS_FILE);
391
+ if (!fs.existsSync(dir)) {
392
+ fs.mkdirSync(dir, { recursive: true });
393
+ }
394
+ fs.writeFileSync(CRONS_RUNS_FILE, JSON.stringify(runs, null, 2), 'utf-8');
175
395
  }
176
396
 
177
397
  module.exports = cron;
@@ -1,6 +1,8 @@
1
1
  const chalk = require('chalk');
2
2
  const { execSync, spawn } = require('child_process');
3
3
  const path = require('path');
4
+ const fs = require('fs');
5
+ const os = require('os');
4
6
 
5
7
  const GATEWAY_SCRIPT = path.join(__dirname, 'gateway-server.js');
6
8
 
@@ -11,18 +13,38 @@ function daemon(args) {
11
13
  if (action === 'start') return startDaemon();
12
14
  if (action === 'stop') return stopDaemon();
13
15
  if (action === 'restart') return restartDaemon();
16
+ if (action === 'install') return installDaemon();
17
+ if (action === 'uninstall') return uninstallDaemon();
14
18
 
15
19
  console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
16
- console.log(chalk.gray(' Kullanım: natureco daemon [status|start|stop|restart]\n'));
20
+ console.log(chalk.gray(' Kullanım: natureco daemon [status|start|stop|restart|install|uninstall]\n'));
17
21
  process.exit(1);
18
22
  }
19
23
 
20
24
  function statusDaemon() {
25
+ const pidFile = path.join(os.homedir(), '.natureco', 'daemon.pid');
26
+ let running = false;
27
+ let pid = null;
28
+
29
+ if (fs.existsSync(pidFile)) {
30
+ try {
31
+ pid = parseInt(fs.readFileSync(pidFile, 'utf8').trim(), 10);
32
+ process.kill(pid, 0);
33
+ running = true;
34
+ } catch {
35
+ running = false;
36
+ }
37
+ }
38
+
21
39
  console.log(chalk.cyan('\n ⚙️ Gateway Daemon\n'));
22
40
  console.log(chalk.gray(' ' + '─'.repeat(48)));
23
- console.log(` ${chalk.white('Status:')} ${chalk.green('running')}`);
24
- console.log(` ${chalk.white('PID:')} ${process.pid}`);
25
- console.log(` ${chalk.white('Uptime:')} ${Math.floor(process.uptime())}s`);
41
+ if (running) {
42
+ console.log(` ${chalk.white('Status:')} ${chalk.green('running')}`);
43
+ console.log(` ${chalk.white('PID:')} ${pid}`);
44
+ } else {
45
+ console.log(` ${chalk.white('Status:')} ${chalk.yellow('not running')}`);
46
+ console.log(` ${chalk.white('PID:')} ${chalk.gray('N/A')}`);
47
+ }
26
48
  console.log(chalk.gray('\n Manage with:') + chalk.cyan(' natureco gateway start|stop|status'));
27
49
  console.log();
28
50
  }
@@ -57,4 +79,12 @@ function restartDaemon() {
57
79
  setTimeout(() => startDaemon(), 1000);
58
80
  }
59
81
 
82
+ function installDaemon() {
83
+ console.log(chalk.yellow('\n daemon install would register as a system service\n'));
84
+ }
85
+
86
+ function uninstallDaemon() {
87
+ console.log(chalk.yellow('\n daemon uninstall would remove system service registration\n'));
88
+ }
89
+
60
90
  module.exports = daemon;