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
@@ -3,6 +3,7 @@ const os = require('os');
3
3
  const fs = require('fs');
4
4
  const readline = require('readline');
5
5
  const inquirer = require('../utils/inquirer-wrapper');
6
+ const TB = require('../utils/token-budget');
6
7
  const chalk = require('chalk');
7
8
  const { getApiKey, getConfig } = require('../utils/config');
8
9
  const { getBots, sendMessage, _sendMessage } = require('../utils/api');
@@ -14,7 +15,7 @@ const { getCommands, getCommandContent } = require('../utils/commands');
14
15
  const { runHooks } = require('../utils/hooks');
15
16
  const { createSession, loadSession, getLatestSession, addMessageToSession, loadLastSession, listSessions, saveSession } = require('../utils/sessions');
16
17
  const { NatureCoError, ApiError, handleError } = require('../utils/errors');
17
- const { getToolDefinitions, getSessionStats, resetSessionStats } = require('../utils/tool-runner');
18
+ const { getSessionStats, resetSessionStats } = require('../utils/tool-runner');
18
19
 
19
20
  // ── ASCII Logo ────────────────────────────────────────────────────────────────
20
21
  const ASCII_LOGO = [
@@ -133,10 +134,7 @@ async function chat(botName, options = {}) {
133
134
  if (memoryPrompt) systemPrompt += '\n\n' + memoryPrompt;
134
135
  }
135
136
 
136
- const estimatedTokens = Math.ceil(systemPrompt.length / 4);
137
- if (estimatedTokens > 3000) {
138
- systemPrompt = systemPrompt.slice(0, 12000);
139
- }
137
+ systemPrompt = TB.trimSystemPrompt(systemPrompt);
140
138
 
141
139
  // ── Session ─────────────────────────────────────────────────────────────────
142
140
  let session;
@@ -189,7 +187,7 @@ async function chat(botName, options = {}) {
189
187
 
190
188
  // ── Önceki session mesajları ─────────────────────────────────────────────────
191
189
  if (options.resume && session.messages?.length) {
192
- const last = session.messages.slice(-5);
190
+ const last = session.messages.slice(-(TB.load().conversationInContext));
193
191
  last.forEach(msg => {
194
192
  console.log(chalk.white('You ') + msg.user);
195
193
  console.log(chalk.cyan(`${displayBotName} `) + msg.bot);
@@ -334,8 +332,7 @@ async function chat(botName, options = {}) {
334
332
  startLoading();
335
333
 
336
334
  try {
337
- const toolDefinitions = getToolDefinitions();
338
- let response = await _sendMessage(apiKey ?? config.providerApiKey, bot.id, userMessage, conversationId, systemPrompt, toolDefinitions, options);
335
+ let response = await _sendMessage(apiKey ?? config.providerApiKey, bot.id, userMessage, conversationId, systemPrompt, { ...options, noTools: true });
339
336
  stopLoading();
340
337
 
341
338
  if (response?.conversation_id) conversationId = response.conversation_id;
@@ -0,0 +1,19 @@
1
+ const chalk = require('chalk');
2
+
3
+ function clawbot(args) {
4
+ const [action, ...params] = args || [];
5
+
6
+ if (action === 'qr') {
7
+ const qr = require('../commands/qr');
8
+ return qr(['--format', 'clawbot', ...params]);
9
+ }
10
+
11
+ console.log(chalk.cyan('\n 🤖 ClawBot\n'));
12
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
13
+ console.log(chalk.gray(' Legacy namespace for ClawBot operations.\n'));
14
+ console.log(` ${chalk.white('Subcommands:')}`);
15
+ console.log(` ${chalk.cyan('qr')} ${chalk.gray('Show QR pairing code for ClawBot')}`);
16
+ console.log();
17
+ }
18
+
19
+ module.exports = clawbot;
@@ -0,0 +1,130 @@
1
+ const chalk = require('chalk');
2
+ const { getConfig, saveConfig } = require('../utils/config');
3
+ const http = require('http');
4
+
5
+ function beep() {
6
+ try {
7
+ process.stdout.write('\x07');
8
+ } catch {}
9
+ }
10
+
11
+ function speak(text) {
12
+ try {
13
+ const { execSync } = require('child_process');
14
+ const escaped = text.replace(/"/g, '\\"');
15
+ if (process.platform === 'darwin') execSync(`say "${escaped}"`, { stdio: 'ignore' });
16
+ else if (process.platform === 'win32') {
17
+ const powershell = `(New-Object -ComObject SAPI.SpVoice).Speak("${escaped}")`;
18
+ execSync(`powershell -Command "${powershell}"`, { stdio: 'ignore' });
19
+ }
20
+ } catch {}
21
+ }
22
+
23
+ async function clickclack(args) {
24
+ const [action, ...params] = args || [];
25
+
26
+ if (!action || action === 'status') return statusClickclack();
27
+ if (action === 'test') return testClickclack();
28
+ if (action === 'enable') return enableClickclack();
29
+ if (action === 'disable') return disableClickclack();
30
+ if (action === 'listen') {
31
+ const port = params[0] || 3888;
32
+ return listenWebhook(parseInt(port, 10));
33
+ }
34
+ if (action === 'notify') return sendNotification(params.join(' '));
35
+
36
+ console.log(chalk.red(`\n ❌ Unknown command: ${action}\n`));
37
+ console.log(chalk.gray(' Usage: natureco clickclack [status|test|enable|disable|listen|notify]\n'));
38
+ process.exit(1);
39
+ }
40
+
41
+ function statusClickclack() {
42
+ const config = getConfig();
43
+ const cc = config.clickclack || {};
44
+ console.log(chalk.cyan('\n 🔔 ClickClack Status\n'));
45
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
46
+ console.log(` ${chalk.white('Enabled:')} ${cc.enabled !== false ? chalk.green('Yes') : chalk.red('No')}`);
47
+ console.log(` ${chalk.white('Beep on msg:')} ${cc.beepOnMessage !== false ? chalk.green('Yes') : chalk.red('No')}`);
48
+ console.log(` ${chalk.white('Speak on msg:')} ${cc.speakOnMessage ? chalk.green('Yes') : chalk.gray('No')}`);
49
+ console.log(` ${chalk.white('Webhook port:')} ${chalk.cyan(cc.webhookPort || 3888)}`);
50
+ console.log(chalk.gray('\n Commands:'));
51
+ console.log(chalk.cyan(' natureco clickclack test') + chalk.gray(' Test beep/speak'));
52
+ console.log(chalk.cyan(' natureco clickclack enable') + chalk.gray(' Enable notifications'));
53
+ console.log(chalk.cyan(' natureco clickclack disable') + chalk.gray(' Disable notifications'));
54
+ console.log(chalk.cyan(' natureco clickclack listen') + chalk.gray(' Listen for webhook'));
55
+ console.log(chalk.cyan(' natureco clickclack notify') + chalk.gray(' Send notification'));
56
+ console.log();
57
+ }
58
+
59
+ function testClickclack() {
60
+ console.log(chalk.cyan('\n Testing ClickClack...\n'));
61
+ beep();
62
+ console.log(chalk.gray(' Beep sent'));
63
+ speak('ClickClack notification test');
64
+ console.log(chalk.gray(' Speech sent'));
65
+ console.log(chalk.green('\n ✅ Test complete\n'));
66
+ }
67
+
68
+ function enableClickclack() {
69
+ const config = getConfig();
70
+ if (!config.clickclack) config.clickclack = {};
71
+ config.clickclack.enabled = true;
72
+ saveConfig(config);
73
+ console.log(chalk.green('\n ✅ ClickClack enabled\n'));
74
+ }
75
+
76
+ function disableClickclack() {
77
+ const config = getConfig();
78
+ if (!config.clickclack) config.clickclack = {};
79
+ config.clickclack.enabled = false;
80
+ saveConfig(config);
81
+ console.log(chalk.gray('\n 🔕 ClickClack disabled\n'));
82
+ }
83
+
84
+ function sendNotification(message) {
85
+ if (!message) {
86
+ console.log(chalk.red('\n ❌ Message required\n'));
87
+ console.log(chalk.cyan(' natureco clickclack notify "Your message here"\n'));
88
+ process.exit(1);
89
+ }
90
+ beep();
91
+ if (message.length < 100) speak(message);
92
+ console.log(chalk.green(` 🔔 ${message}\n`));
93
+ }
94
+
95
+ function listenWebhook(port) {
96
+ const server = http.createServer((req, res) => {
97
+ if (req.method === 'POST') {
98
+ let body = '';
99
+ req.on('data', chunk => { body += chunk; });
100
+ req.on('end', () => {
101
+ try {
102
+ const data = JSON.parse(body);
103
+ const message = data.message || data.text || data.notification || JSON.stringify(data);
104
+ beep();
105
+ if (message.length < 100) speak(message);
106
+ console.log(chalk.green(`\n 🔔 ${new Date().toISOString()} — ${message}\n`));
107
+ } catch {
108
+ beep();
109
+ console.log(chalk.green(`\n 🔔 ${new Date().toISOString()} — ${body}\n`));
110
+ }
111
+ res.writeHead(200, { 'Content-Type': 'application/json' });
112
+ res.end(JSON.stringify({ ok: true }));
113
+ });
114
+ } else {
115
+ res.writeHead(200, { 'Content-Type': 'text/plain' });
116
+ res.end('ClickClack webhook listener');
117
+ }
118
+ });
119
+
120
+ server.listen(port, () => {
121
+ console.log(chalk.cyan(`\n 🔔 ClickClack listening on port ${port}\n`));
122
+ console.log(chalk.gray(' Send POST requests to:'));
123
+ console.log(chalk.white(` http://localhost:${port}/`));
124
+ console.log(chalk.gray(' With JSON body:'));
125
+ console.log(chalk.white(' { "message": "Hello from NatureCo" }'));
126
+ console.log(chalk.gray('\n Press Ctrl+C to stop\n'));
127
+ });
128
+ }
129
+
130
+ module.exports = clickclack;
@@ -4,6 +4,7 @@ const fs = require('fs');
4
4
  const readline = require('readline');
5
5
  const { execSync } = require('child_process');
6
6
  const inquirer = require('../utils/inquirer-wrapper');
7
+ const TB = require('../utils/token-budget');
7
8
  const chalk = require('chalk');
8
9
  const { getApiKey, getConfig } = require('../utils/config');
9
10
  const { getBots, getProviderConfig, startMcpServers, sendMessageOpenAICompatible, streamProviderCompletion } = require('../utils/api');
@@ -376,14 +377,14 @@ ${indexPrompt}`;
376
377
  // ── Proje hafızası ────────────────────────────────────────────────────────
377
378
  const projectMemory = loadProjectMemory(workDir);
378
379
  if (projectMemory) {
379
- systemPrompt += `\n\n## Proje Geçmişi (.natureco/project.md)\n${projectMemory.slice(0, 2000)}`;
380
+ systemPrompt += `\n\n## Proje Geçmişi (.natureco/project.md)\n${TB.trimProjectMemory(projectMemory)}`;
380
381
  }
381
382
 
382
383
  // Hedef dosya varsa context'e ekle
383
384
  if (targetFile) {
384
385
  try {
385
386
  const content = fs.readFileSync(path.resolve(targetFile), 'utf-8');
386
- systemPrompt += `\n\n## Odak Dosyası: ${targetFile}\n\`\`\`\n${content.slice(0, 2000)}\n\`\`\``;
387
+ systemPrompt += `\n\n## Odak Dosyası: ${targetFile}\n\`\`\`\n${TB.trimFileContent(content)}\n\`\`\``;
387
388
  } catch {
388
389
  console.log(chalk.yellow(` ⚠️ ${targetFile} okunamadı\n`));
389
390
  }
@@ -0,0 +1,148 @@
1
+ const chalk = require('chalk');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const os = require('os');
5
+
6
+ const COMMITMENTS_FILE = path.join(os.homedir(), '.natureco', 'commitments.json');
7
+
8
+ function load() {
9
+ if (!fs.existsSync(COMMITMENTS_FILE)) return [];
10
+ try { return JSON.parse(fs.readFileSync(COMMITMENTS_FILE, 'utf-8')); }
11
+ catch { return []; }
12
+ }
13
+
14
+ function save(items) {
15
+ const dir = path.dirname(COMMITMENTS_FILE);
16
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
17
+ fs.writeFileSync(COMMITMENTS_FILE, JSON.stringify(items, null, 2), 'utf-8');
18
+ }
19
+
20
+ function genId() {
21
+ return Date.now().toString(36) + Math.random().toString(36).slice(2, 6);
22
+ }
23
+
24
+ function commitments(args) {
25
+ const [action, ...params] = args || [];
26
+
27
+ if (!action || action === 'list') return listC();
28
+ if (action === 'add') return addC(params.join(' '));
29
+ if (action === 'check' || action === 'done') return checkC(params[0]);
30
+ if (action === 'resolve') return resolveC(params[0]);
31
+ if (action === 'pending') return pendingC();
32
+ if (action === 'summary') return summaryC();
33
+ if (action === 'delete') return deleteC(params[0]);
34
+
35
+ console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
36
+ console.log(chalk.gray(' Kullanım: natureco commitments [list|add|check|resolve|pending|summary|delete]\n'));
37
+ process.exit(1);
38
+ }
39
+
40
+ function listC() {
41
+ const items = load();
42
+ console.log(chalk.cyan('\n 📋 Commitments\n'));
43
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
44
+ if (items.length === 0) {
45
+ console.log(chalk.gray(' Henüz commitment yok.\n'));
46
+ return;
47
+ }
48
+ for (const c of items) {
49
+ const icon = c.status === 'resolved' ? '✅' : c.status === 'checked' ? '☑️ ' : '⬜';
50
+ console.log(` ${icon} ${chalk[c.status === 'resolved' ? 'gray' : 'white'](c.text)}`);
51
+ console.log(chalk.gray(` [${c.id}] ${c.createdAt.slice(0, 10)}`));
52
+ }
53
+ console.log();
54
+ }
55
+
56
+ function addC(text) {
57
+ if (!text) {
58
+ console.log(chalk.red('\n ❌ Commitment text gerekli\n'));
59
+ process.exit(1);
60
+ }
61
+ const items = load();
62
+ const c = { id: genId(), text, status: 'pending', createdAt: new Date().toISOString(), resolvedAt: null };
63
+ items.push(c);
64
+ save(items);
65
+ console.log(chalk.green(`\n ✅ Commitment eklendi: ${c.id}\n`));
66
+ console.log(` ${chalk.white(c.text)}`);
67
+ console.log();
68
+ }
69
+
70
+ function checkC(id) {
71
+ if (!id) {
72
+ console.log(chalk.red('\n ❌ Commitment ID gerekli\n'));
73
+ process.exit(1);
74
+ }
75
+ const items = load();
76
+ const c = items.find(x => x.id === id);
77
+ if (!c) { console.log(chalk.red(`\n ❌ Commitment bulunamadı: ${id}\n`)); process.exit(1); }
78
+ if (c.status === 'resolved') { console.log(chalk.yellow(`\n ⚠️ "${c.text}" zaten çözülmüş\n`)); return; }
79
+ c.status = 'checked';
80
+ save(items);
81
+ console.log(chalk.green(`\n ☑️ "${c.text}" tamamlandı olarak işaretlendi\n`));
82
+ }
83
+
84
+ function resolveC(id) {
85
+ if (!id) {
86
+ const items = load();
87
+ const pending = items.filter(x => x.status !== 'resolved');
88
+ if (pending.length === 0) { console.log(chalk.gray('\n Çözülecek commitment yok\n')); return; }
89
+ for (const c of pending) {
90
+ c.status = 'resolved';
91
+ c.resolvedAt = new Date().toISOString();
92
+ }
93
+ save(items);
94
+ console.log(chalk.green(`\n ✅ ${pending.length} commitment çözüldü\n`));
95
+ return;
96
+ }
97
+ const items = load();
98
+ const c = items.find(x => x.id === id);
99
+ if (!c) { console.log(chalk.red(`\n ❌ Commitment bulunamadı: ${id}\n`)); process.exit(1); }
100
+ c.status = 'resolved';
101
+ c.resolvedAt = new Date().toISOString();
102
+ save(items);
103
+ console.log(chalk.green(`\n ✅ "${c.text}" çözüldü\n`));
104
+ }
105
+
106
+ function pendingC() {
107
+ const items = load().filter(c => c.status !== 'resolved');
108
+ console.log(chalk.cyan('\n ⏳ Bekleyen Commitments\n'));
109
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
110
+ if (items.length === 0) {
111
+ console.log(chalk.gray(' Bekleyen commitment yok.\n'));
112
+ return;
113
+ }
114
+ for (const c of items) {
115
+ console.log(` ${chalk.white(c.text)}`);
116
+ console.log(chalk.gray(` [${c.id}] ${c.createdAt.slice(0, 10)}\n`));
117
+ }
118
+ }
119
+
120
+ function summaryC() {
121
+ const items = load();
122
+ const total = items.length;
123
+ const resolved = items.filter(c => c.status === 'resolved').length;
124
+ const checked = items.filter(c => c.status === 'checked').length;
125
+ const pending = total - resolved - checked;
126
+ console.log(chalk.cyan('\n 📊 Commitments Summary\n'));
127
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
128
+ console.log(` ${chalk.white('Toplam:')} ${total}`);
129
+ console.log(` ${chalk.green('Çözülen:')} ${resolved}`);
130
+ console.log(` ${chalk.yellow('Kontrol:')} ${checked}`);
131
+ console.log(` ${chalk.cyan('Kalan:')} ${pending}`);
132
+ console.log();
133
+ }
134
+
135
+ function deleteC(id) {
136
+ if (!id) {
137
+ console.log(chalk.red('\n ❌ Commitment ID gerekli\n'));
138
+ process.exit(1);
139
+ }
140
+ let items = load();
141
+ const idx = items.findIndex(x => x.id === id);
142
+ if (idx === -1) { console.log(chalk.red(`\n ❌ Commitment bulunamadı: ${id}\n`)); process.exit(1); }
143
+ const removed = items.splice(idx, 1)[0];
144
+ save(items);
145
+ console.log(chalk.gray(`\n 🗑️ "${removed.text}" silindi\n`));
146
+ }
147
+
148
+ module.exports = commitments;
@@ -0,0 +1,84 @@
1
+ const chalk = require('chalk');
2
+
3
+ function getCommands() {
4
+ return [
5
+ 'agent', 'agents', 'approvals', 'ask', 'backup', 'bonjour', 'bots',
6
+ 'capability', 'channels', 'chat', 'clickclack', 'code', 'commands',
7
+ 'commitments', 'completion', 'config', 'configure', 'crestodian', 'cron',
8
+ 'daemon', 'dashboard', 'device-pair', 'devices', 'directory', 'discord',
9
+ 'dns', 'doctor', 'docs', 'exec-policy', 'gateway', 'git', 'health', 'help',
10
+ 'hooks', 'imessage', 'infer', 'init', 'irc', 'login', 'logs', 'logout',
11
+ 'mattermost', 'mcp', 'memory', 'message', 'migrate', 'models', 'node',
12
+ 'nodes', 'oc-path', 'onboard', 'open-prose', 'pairing', 'plugins', 'policy',
13
+ 'proxy', 'qr', 'reset', 'run', 'sandbox', 'secrets', 'security', 'sessions',
14
+ 'setup', 'signal', 'skills', 'slack', 'sms', 'status', 'system', 'tasks',
15
+ 'telegram', 'terminal', 'thread-ownership', 'transcripts', 'ultrareview',
16
+ 'uninstall', 'update', 'voice', 'vydra', 'webhooks', 'whatsapp', 'workboard',
17
+ ];
18
+ }
19
+
20
+ function completion(params) {
21
+ try {
22
+ const [shell] = params || [];
23
+
24
+ if (!shell || shell === 'bash') return printBash();
25
+ if (shell === 'zsh') return printZsh();
26
+ if (shell === 'fish') return printFish();
27
+ if (shell === 'install') return printInstall();
28
+
29
+ console.log(chalk.red(`\n Unknown shell: ${shell}\n`));
30
+ console.log(chalk.gray(' Usage: natureco completion [bash|zsh|fish|install]\n'));
31
+ } catch (err) {
32
+ console.log(chalk.red(`\n Completion error: ${err.message}\n`));
33
+ }
34
+ }
35
+
36
+ function printBash() {
37
+ const cmds = getCommands().join(' ');
38
+ console.log(`# natureco bash completion
39
+ _natureco() {
40
+ local cur prev opts
41
+ COMPREPLY=()
42
+ cur="\${COMP_WORDS[COMP_CWORD]}"
43
+ opts="${cmds}"
44
+ COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
45
+ return 0
46
+ }
47
+ complete -F _natureco natureco`);
48
+ }
49
+
50
+ function printZsh() {
51
+ console.log(`#compdef natureco
52
+ _natureco() {
53
+ local -a commands
54
+ commands=(
55
+ ${getCommands().map(c => `"${c}:${c}"`).join(' ')}
56
+ )
57
+ _describe 'command' commands
58
+ }
59
+ _natureco "$@"`);
60
+ }
61
+
62
+ function printFish() {
63
+ const cmds = getCommands().join(' ');
64
+ console.log(`complete -c natureco -f -a "${cmds}"`);
65
+ }
66
+
67
+ function printInstall() {
68
+ console.log(chalk.cyan('\n Shell Completion Installation\n'));
69
+ console.log(chalk.white(' Bash:'));
70
+ console.log(chalk.gray(' natureco completion bash >> ~/.bashrc'));
71
+ console.log(chalk.gray(' source ~/.bashrc'));
72
+ console.log('');
73
+ console.log(chalk.white(' Zsh:'));
74
+ console.log(chalk.gray(' mkdir -p ~/.zsh/completion'));
75
+ console.log(chalk.gray(' natureco completion zsh > ~/.zsh/completion/_natureco'));
76
+ console.log(chalk.gray(' echo "fpath=(~/.zsh/completion \$fpath)" >> ~/.zshrc'));
77
+ console.log(chalk.gray(' echo "autoload -Uz compinit && compinit" >> ~/.zshrc'));
78
+ console.log('');
79
+ console.log(chalk.white(' Fish:'));
80
+ console.log(chalk.gray(' natureco completion fish > ~/.config/fish/completions/natureco.fish'));
81
+ console.log('');
82
+ }
83
+
84
+ module.exports = completion;