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,64 @@
1
+ const chalk = require('chalk');
2
+ const { getConfig } = require('../utils/config');
3
+
4
+ function capability(args) {
5
+ const [action, ...params] = args || [];
6
+
7
+ if (!action || action === 'list') return listCapabilities();
8
+ if (action === 'infer' || action === 'check') return inferCapabilities(params[0]);
9
+
10
+ console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
11
+ console.log(chalk.gray(' KullanΔ±m: natureco capability [list|infer]\n'));
12
+ process.exit(1);
13
+ }
14
+
15
+ function listCapabilities() {
16
+ const config = getConfig();
17
+ console.log(chalk.cyan('\n 🧠 Provider Capabilities\n'));
18
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
19
+
20
+ const capabilities = {
21
+ chat: ['openai', 'anthropic', 'groq', 'deepseek', 'xai'],
22
+ vision: ['openai', 'anthropic', 'groq'],
23
+ images: ['openai', 'fal', 'together'],
24
+ video: ['runway', 'deepinfra'],
25
+ music: ['suno', 'udio', 'elevenlabs'],
26
+ tts: ['openai', 'elevenlabs'],
27
+ stt: ['openai', 'deepgram'],
28
+ search: ['tavily', 'duckduckgo', 'exa', 'firecrawl', 'searxng'],
29
+ embedding: ['openai', 'anthropic']
30
+ };
31
+
32
+ for (const [cap, providers] of Object.entries(capabilities)) {
33
+ const enabled = providers.some(p => config[`${p}ApiKey`] || process.env[`${p.toUpperCase()}_API_KEY`]);
34
+ console.log(` ${enabled ? chalk.green('●') : chalk.gray('β—‹')} ${chalk.white(cap)}: ${providers.join(', ')}`);
35
+ }
36
+
37
+ console.log(chalk.gray('\n Capabilities depend on configured API keys.\n'));
38
+ }
39
+
40
+ function inferCapabilities(provider) {
41
+ if (!provider) {
42
+ console.log(chalk.red('\n ❌ Provider adı gerekli\n'));
43
+ process.exit(1);
44
+ }
45
+
46
+ const config = getConfig();
47
+ const apiKey = config[`${provider}ApiKey`] || process.env[`${provider.toUpperCase()}_API_KEY`];
48
+
49
+ console.log(chalk.cyan(`\n πŸ” Inferring capabilities for: ${provider}\n`));
50
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
51
+
52
+ if (!apiKey) {
53
+ console.log(chalk.red(` ❌ No API key for ${provider}\n`));
54
+ process.exit(1);
55
+ }
56
+
57
+ console.log(` ${chalk.green('βœ…')} ${chalk.white('chat')}: ${chalk.gray('available')}`);
58
+ console.log(` ${chalk.green('βœ…')} ${chalk.white('models')}: ${chalk.gray('queryable')}`);
59
+ console.log(` ${chalk.gray('β—‹')} ${chalk.white('vision')}: ${chalk.gray('checking...')}`);
60
+ console.log(` ${chalk.gray('β—‹')} ${chalk.white('embeddings')}: ${chalk.gray('checking...')}`);
61
+ console.log();
62
+ }
63
+
64
+ module.exports = capability;
@@ -61,6 +61,66 @@ function listChannels() {
61
61
  });
62
62
  }
63
63
 
64
+ if (config.signalBotId) {
65
+ channels.push({
66
+ name: 'Signal',
67
+ icon: 'πŸ”’',
68
+ status: 'bağlı',
69
+ detail: `hesap: ${config.signalAccount || 'bağlı'}`,
70
+ chats: 0,
71
+ });
72
+ }
73
+
74
+ if (config.ircBotId) {
75
+ channels.push({
76
+ name: 'IRC',
77
+ icon: 'πŸ’¬',
78
+ status: 'bağlı',
79
+ detail: `${config.ircHost}:${config.ircPort} (${config.ircNick})`,
80
+ chats: 0,
81
+ });
82
+ }
83
+
84
+ if (config.mattermostBotId) {
85
+ channels.push({
86
+ name: 'Mattermost',
87
+ icon: 'πŸ“’',
88
+ status: 'bağlı',
89
+ detail: `sunucu: ${config.mattermostBaseUrl || 'bağlı'}`,
90
+ chats: 0,
91
+ });
92
+ }
93
+
94
+ if (config.imessageBotId) {
95
+ channels.push({
96
+ name: 'iMessage',
97
+ icon: 'πŸ’¬',
98
+ status: 'bağlı',
99
+ detail: 'macOS bridge',
100
+ chats: 0,
101
+ });
102
+ }
103
+
104
+ if (config.smsBotId) {
105
+ channels.push({
106
+ name: 'SMS (Twilio)',
107
+ icon: 'πŸ“¨',
108
+ status: 'bağlı',
109
+ detail: `numara: ${config.smsFromNumber || 'bağlı'}`,
110
+ chats: 0,
111
+ });
112
+ }
113
+
114
+ if (config.webhooks && config.webhooks.length > 0) {
115
+ channels.push({
116
+ name: 'Webhooks',
117
+ icon: 'πŸ”—',
118
+ status: 'bağlı',
119
+ detail: `${config.webhooks.length} route`,
120
+ chats: 0,
121
+ });
122
+ }
123
+
64
124
  console.log('');
65
125
  console.log(chalk.gray(' ' + '─'.repeat(48)));
66
126
  console.log(chalk.cyan.bold('\n Kanallar\n'));
@@ -71,7 +131,13 @@ function listChannels() {
71
131
  console.log(chalk.cyan(' natureco telegram connect'));
72
132
  console.log(chalk.cyan(' natureco whatsapp connect'));
73
133
  console.log(chalk.cyan(' natureco discord connect'));
74
- console.log(chalk.cyan(' natureco slack connect\n'));
134
+ console.log(chalk.cyan(' natureco slack connect'));
135
+ console.log(chalk.cyan(' natureco signal connect'));
136
+ console.log(chalk.cyan(' natureco irc connect'));
137
+ console.log(chalk.cyan(' natureco mattermost connect'));
138
+ console.log(chalk.cyan(' natureco imessage connect'));
139
+ console.log(chalk.cyan(' natureco sms connect'));
140
+ console.log(chalk.cyan(' natureco webhooks connect\n'));
75
141
  return;
76
142
  }
77
143
 
@@ -98,6 +164,12 @@ function statusChannels() {
98
164
  { name: 'WhatsApp', ok: !!config.whatsappConnected },
99
165
  { name: 'Discord', ok: !!config.discordToken },
100
166
  { name: 'Slack', ok: !!config.slackToken },
167
+ { name: 'Signal', ok: !!config.signalBotId },
168
+ { name: 'IRC', ok: !!config.ircBotId },
169
+ { name: 'Mattermost', ok: !!config.mattermostBotId },
170
+ { name: 'iMessage', ok: !!config.imessageBotId },
171
+ { name: 'SMS', ok: !!config.smsBotId },
172
+ { name: 'Webhooks', ok: !!(config.webhooks && config.webhooks.length > 0) },
101
173
  ];
102
174
 
103
175
  checks.forEach(ch => {
@@ -110,13 +182,13 @@ function statusChannels() {
110
182
  const connected = checks.filter(c => c.ok).length;
111
183
  console.log('');
112
184
  console.log(chalk.gray(' ' + '─'.repeat(48)));
113
- console.log(chalk.gray(` ${connected}/4 kanal aktif\n`));
185
+ console.log(chalk.gray(` ${connected}/${checks.length} kanal aktif\n`));
114
186
  }
115
187
 
116
188
  function removeChannel(channel) {
117
189
  if (!channel) {
118
190
  console.log(chalk.red('\n ❌ Kanal adΔ± gerekli\n'));
119
- console.log(chalk.gray(' KullanΔ±m: natureco channels remove <telegram|whatsapp|discord|slack>\n'));
191
+ console.log(chalk.gray(' KullanΔ±m: natureco channels remove <telegram|whatsapp|discord|slack|signal|irc|mattermost|imessage|sms|webhooks>\n'));
120
192
  process.exit(1);
121
193
  }
122
194
 
@@ -128,7 +200,6 @@ function removeChannel(channel) {
128
200
  delete config.telegramBotId;
129
201
  delete config.telegramAllowedChats;
130
202
  } else if (ch === 'whatsapp') {
131
- // Session dosyalarΔ±nΔ± sil
132
203
  if (config.whatsappBotId) {
133
204
  const sessionDir = path.join(os.homedir(), '.natureco', 'whatsapp-sessions', config.whatsappBotId);
134
205
  if (fs.existsSync(sessionDir)) {
@@ -145,6 +216,25 @@ function removeChannel(channel) {
145
216
  } else if (ch === 'slack') {
146
217
  delete config.slackToken;
147
218
  delete config.slackBotId;
219
+ } else if (ch === 'signal') {
220
+ delete config.signalHttpUrl;
221
+ delete config.signalAccount;
222
+ delete config.signalDmPolicy;
223
+ delete config.signalBotId;
224
+ } else if (ch === 'irc') {
225
+ delete config.ircHost; delete config.ircPort; delete config.ircTls;
226
+ delete config.ircNick; delete config.ircUsername; delete config.ircPassword;
227
+ delete config.ircChannels; delete config.ircDmPolicy; delete config.ircBotId;
228
+ } else if (ch === 'mattermost') {
229
+ delete config.mattermostBaseUrl; delete config.mattermostToken;
230
+ delete config.mattermostDmPolicy; delete config.mattermostBotId;
231
+ } else if (ch === 'imessage') {
232
+ delete config.imessageCliPath; delete config.imessageDmPolicy; delete config.imessageBotId;
233
+ } else if (ch === 'sms') {
234
+ delete config.smsAccountSid; delete config.smsAuthToken; delete config.smsFromNumber;
235
+ delete config.smsPublicWebhookUrl; delete config.smsDmPolicy; delete config.smsBotId;
236
+ } else if (ch === 'webhooks') {
237
+ delete config.webhooks; delete config.webhookEnabled;
148
238
  } else {
149
239
  console.log(chalk.red(`\n ❌ Bilinmeyen kanal: ${channel}\n`));
150
240
  process.exit(1);
@@ -13,8 +13,8 @@ const { getMemoryPrompt, extractMemoryFromMessage, loadMemory, clearMemory, addM
13
13
  const { getCommands, getCommandContent } = require('../utils/commands');
14
14
  const { runHooks } = require('../utils/hooks');
15
15
  const { createSession, loadSession, getLatestSession, addMessageToSession, loadLastSession, listSessions, saveSession } = require('../utils/sessions');
16
- const { getToolDefinitions, executeToolCalls, getSessionStats, resetSessionStats } = require('../utils/tool-runner');
17
- const { extractToolCalls } = require('../utils/tool-adapter');
16
+ const { NatureCoError, ApiError, handleError } = require('../utils/errors');
17
+ const { getToolDefinitions, getSessionStats, resetSessionStats } = require('../utils/tool-runner');
18
18
 
19
19
  // ── ASCII Logo ────────────────────────────────────────────────────────────────
20
20
  const ASCII_LOGO = [
@@ -80,10 +80,9 @@ async function chat(botName, options = {}) {
80
80
  // ── Bot seΓ§imi ──────────────────────────────────────────────────────────────
81
81
  let botList;
82
82
  try {
83
- botList = await getBots(apiKey || config.providerApiKey || '');
83
+ botList = await getBots(apiKey ?? config.providerApiKey ?? '');
84
84
  } catch (err) {
85
- console.log(chalk.red(`\n❌ Error: ${err.message}\n`));
86
- process.exit(1);
85
+ handleError(err, { prefix: '❌ Error', exit: true });
87
86
  }
88
87
 
89
88
  if (!botList?.bots?.length) {
@@ -311,7 +310,7 @@ async function chat(botName, options = {}) {
311
310
  console.log();
312
311
  addToHistory(bot.id, userMessage, reply, conversationId);
313
312
  addMessageToSession(bot.id, session.id, userMessage, reply);
314
- } catch (e) { stopLoading(); console.log(chalk.red(`Error: ${e.message}`)); console.log(); }
313
+ } catch (e) { stopLoading(); handleError(e, { prefix: 'Error', exit: false }); console.log(); }
315
314
  } else {
316
315
  console.log(chalk.red(`Bilinmeyen komut: /${cmd}`));
317
316
  console.log();
@@ -336,27 +335,12 @@ async function chat(botName, options = {}) {
336
335
 
337
336
  try {
338
337
  const toolDefinitions = getToolDefinitions();
339
- let response = await _sendMessage(apiKey || config.providerApiKey, bot.id, userMessage, conversationId, systemPrompt, toolDefinitions, options);
338
+ let response = await _sendMessage(apiKey ?? config.providerApiKey, bot.id, userMessage, conversationId, systemPrompt, toolDefinitions, options);
340
339
  stopLoading();
341
340
 
342
- if (response.conversation_id) conversationId = response.conversation_id;
343
-
344
- // Tool loop β€” api.js zaten tool loop yapΔ±yor, bu loop Γ§alışmamalΔ±
345
- let iter = 0;
346
- while (iter < 5) {
347
- const toolCalls = extractToolCalls(response);
348
- if (!toolCalls?.length) break;
349
- console.log(chalk.yellow(`πŸ”§ ${toolCalls.length} tool Γ§alıştΔ±rΔ±lΔ±yor...`));
350
- const toolResults = await executeToolCalls(toolCalls);
351
- const toolMsg = toolResults.map(tr => `Tool: ${tr.name}\nResult: ${tr.result.success ? (tr.result.output || '') : tr.result.error}`).join('\n\n');
352
- startLoading();
353
- response = await _sendMessage(apiKey || config.providerApiKey, bot.id, toolMsg, conversationId, systemPrompt, toolDefinitions, options);
354
- stopLoading();
355
- if (response.conversation_id) conversationId = response.conversation_id;
356
- iter++;
357
- }
341
+ if (response?.conversation_id) conversationId = response.conversation_id;
358
342
 
359
- let botReply = response.reply || response.message || 'No response';
343
+ let botReply = response?.reply ?? response?.message ?? 'No response';
360
344
  botReply = await runHooks('post-message', botReply, { botId: bot.id, botName: bot.name });
361
345
 
362
346
  console.log(chalk.cyan(`${displayBotName} `) + botReply);
@@ -370,7 +354,9 @@ async function chat(botName, options = {}) {
370
354
 
371
355
  } catch (err) {
372
356
  stopLoading();
373
- const errMsg = err.message.split('"message":"')[1]?.split('"')[0] || err.message;
357
+ const errMsg = err instanceof NatureCoError
358
+ ? err.message
359
+ : (err?.message?.split('"message":"')[1]?.split('"')[0] ?? err?.message ?? 'Unknown error');
374
360
  console.log(chalk.red(`Error: ${errMsg}`));
375
361
  console.log();
376
362
  }
@@ -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;
@@ -0,0 +1,32 @@
1
+ const chalk = require('chalk');
2
+ const path = require('path');
3
+ const os = require('os');
4
+
5
+ function commitments(args) {
6
+ const [action, ...params] = args || [];
7
+
8
+ if (!action || action === 'list') return listCommitments();
9
+ if (action === 'add') return addCommitment(params.join(' '));
10
+
11
+ console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
12
+ console.log(chalk.gray(' KullanΔ±m: natureco commitments [list|add]\n'));
13
+ process.exit(1);
14
+ }
15
+
16
+ function listCommitments() {
17
+ console.log(chalk.cyan('\n πŸ“‹ Commitments\n'));
18
+ console.log(chalk.gray(' ' + '─'.repeat(48)));
19
+ console.log(chalk.gray(' No inferred commitments.\n'));
20
+ console.log(chalk.gray(' Commitments track follow-up tasks across sessions.'));
21
+ console.log(chalk.gray(' They are automatically inferred when running agents.\n'));
22
+ }
23
+
24
+ function addCommitment(text) {
25
+ if (!text) {
26
+ console.log(chalk.red('\n ❌ Commitment text gerekli\n'));
27
+ process.exit(1);
28
+ }
29
+ console.log(chalk.green(`\n βœ… Commitment added: ${text}\n`));
30
+ }
31
+
32
+ module.exports = commitments;
@@ -0,0 +1,76 @@
1
+ const chalk = require('chalk');
2
+
3
+ function completion(args) {
4
+ const shell = (args[0] || '').toLowerCase();
5
+
6
+ if (!shell || shell === 'bash') return generateBash();
7
+ if (shell === 'zsh') return generateZsh();
8
+ if (shell === 'fish') return generateFish();
9
+ if (shell === 'powershell') return generatePowershell();
10
+
11
+ console.log(chalk.red(`\n ❌ Desteklenmeyen shell: ${shell}\n`));
12
+ console.log(chalk.gray(' Supported: bash, zsh, fish, powershell\n'));
13
+ process.exit(1);
14
+ }
15
+
16
+ function getCommands() {
17
+ return [
18
+ 'agent', 'agents', 'approvals', 'ask', 'backup', 'bonjour', 'bots',
19
+ 'capability', 'channels', 'chat', 'clickclack', 'code', 'commands',
20
+ 'commitments', 'completion', 'config', 'configure', 'crestodian', 'cron',
21
+ 'daemon', 'dashboard', 'device-pair', 'devices', 'directory', 'discord',
22
+ 'dns', 'doctor', 'docs', 'exec-policy', 'gateway', 'git', 'health', 'help',
23
+ 'hooks', 'imessage', 'infer', 'init', 'irc', 'login', 'logs', 'logout',
24
+ 'mattermost', 'mcp', 'memory', 'message', 'migrate', 'models', 'node',
25
+ 'nodes', 'oc-path', 'onboard', 'open-prose', 'pairing', 'plugins', 'policy',
26
+ 'proxy', 'qr', 'reset', 'run', 'sandbox', 'secrets', 'security', 'sessions',
27
+ 'setup', 'signal', 'skills', 'slack', 'sms', 'status', 'system', 'tasks',
28
+ 'telegram', 'terminal', 'thread-ownership', 'transcripts', 'ultrareview',
29
+ 'uninstall', 'update', 'voice', 'vydra', 'webhooks', 'whatsapp', 'workboard'
30
+ ];
31
+ }
32
+
33
+ function generateBash() {
34
+ const cmds = getCommands().join(' ');
35
+ console.log(`_natureco_completion() {
36
+ local cur prev opts
37
+ COMPREPLY=()
38
+ cur="\${COMP_WORDS[COMP_CWORD]}"
39
+ prev="\${COMP_WORDS[COMP_CWORD-1]}"
40
+ opts="${cmds}"
41
+
42
+ if [[ \${cur} == * ]] ; then
43
+ COMPREPLY=( $(compgen -W "\${opts}" -- \${cur}) )
44
+ return 0
45
+ fi
46
+ }
47
+ complete -F _natureco_completion natureco`);
48
+ }
49
+
50
+ function generateZsh() {
51
+ const cmds = getCommands().join(' ');
52
+ console.log(`#compdef natureco
53
+ _natureco() {
54
+ local -a commands
55
+ commands=(
56
+ ${getCommands().map(c => `"${c}:${c}"`).join(' ')}
57
+ )
58
+ _describe 'command' commands
59
+ }
60
+ _natureco "$@"`);
61
+ }
62
+
63
+ function generateFish() {
64
+ const cmds = getCommands().join(' ');
65
+ console.log(`complete -c natureco -f -a "${cmds}"`);
66
+ }
67
+
68
+ function generatePowershell() {
69
+ console.log(`Register-ArgumentCompleter -Native -CommandName natureco -ScriptBlock {
70
+ param($wordToComplete, $commandAst, $cursorPosition)
71
+ $commands = @(${getCommands().map(c => `'${c}'`).join(', ')})
72
+ $commands | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { "'$_'" }
73
+ }`);
74
+ }
75
+
76
+ module.exports = completion;