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.
- package/README.md +94 -11
- package/bin/natureco.js +470 -10
- package/package.json +10 -6
- package/src/commands/admin-rpc.js +219 -0
- package/src/commands/agent.js +89 -0
- package/src/commands/approvals.js +53 -0
- package/src/commands/backup.js +124 -0
- package/src/commands/bonjour.js +167 -0
- package/src/commands/capability.js +64 -0
- package/src/commands/channels.js +94 -4
- package/src/commands/chat.js +11 -25
- package/src/commands/clickclack.js +130 -0
- package/src/commands/commitments.js +32 -0
- package/src/commands/completion.js +76 -0
- package/src/commands/config.js +111 -68
- package/src/commands/configure.js +93 -0
- package/src/commands/crestodian.js +92 -0
- package/src/commands/daemon.js +60 -0
- package/src/commands/device-pair.js +248 -0
- package/src/commands/devices.js +110 -0
- package/src/commands/directory.js +47 -0
- package/src/commands/dns.js +58 -0
- package/src/commands/docs.js +43 -0
- package/src/commands/doctor.js +121 -16
- package/src/commands/exec-policy.js +71 -0
- package/src/commands/gateway-server.js +1175 -30
- package/src/commands/gateway.js +11 -20
- package/src/commands/health.js +18 -0
- package/src/commands/help.js +6 -0
- package/src/commands/imessage.js +169 -0
- package/src/commands/infer.js +73 -0
- package/src/commands/irc.js +119 -0
- package/src/commands/mattermost.js +164 -0
- package/src/commands/memory-cmd.js +134 -1
- package/src/commands/message.js +30 -4
- package/src/commands/migrate.js +213 -2
- package/src/commands/models.js +584 -216
- package/src/commands/node.js +98 -0
- package/src/commands/nodes.js +106 -0
- package/src/commands/oc-path.js +200 -0
- package/src/commands/onboard.js +70 -0
- package/src/commands/open-prose.js +67 -0
- package/src/commands/plugins.js +415 -172
- package/src/commands/policy.js +176 -0
- package/src/commands/proxy.js +155 -0
- package/src/commands/qr.js +28 -0
- package/src/commands/sandbox.js +125 -0
- package/src/commands/secrets.js +118 -0
- package/src/commands/security.js +149 -1
- package/src/commands/setup.js +114 -10
- package/src/commands/signal.js +495 -0
- package/src/commands/skills.js +20 -29
- package/src/commands/sms.js +168 -0
- package/src/commands/system.js +53 -0
- package/src/commands/tasks.js +328 -79
- package/src/commands/terminal.js +21 -0
- package/src/commands/thread-ownership.js +157 -0
- package/src/commands/transcripts.js +72 -0
- package/src/commands/voice.js +82 -0
- package/src/commands/vydra.js +98 -0
- package/src/commands/webhooks.js +79 -0
- package/src/commands/whatsapp.js +7 -21
- package/src/commands/workboard.js +207 -0
- package/src/tools/audio_understanding.js +154 -0
- package/src/tools/bash.js +63 -29
- package/src/tools/browser.js +112 -0
- package/src/tools/canvas.js +104 -0
- package/src/tools/document_extract.js +84 -0
- package/src/tools/duckduckgo.js +54 -0
- package/src/tools/exa_search.js +66 -0
- package/src/tools/firecrawl.js +104 -0
- package/src/tools/image_generation.js +99 -0
- package/src/tools/llm_task.js +118 -0
- package/src/tools/media_understanding.js +128 -0
- package/src/tools/music_generation.js +113 -0
- package/src/tools/parallel_search.js +77 -0
- package/src/tools/phone_control.js +80 -0
- package/src/tools/phone_control_enhanced.js +184 -0
- package/src/tools/searxng.js +61 -0
- package/src/tools/speech_to_text.js +135 -0
- package/src/tools/text_to_speech.js +105 -0
- package/src/tools/thread_ownership.js +88 -0
- package/src/tools/video_generation.js +72 -0
- package/src/tools/web_readability.js +104 -0
- package/src/utils/api.js +3 -20
- package/src/utils/approvals.js +297 -0
- package/src/utils/background.js +223 -66
- package/src/utils/baileys.js +21 -0
- package/src/utils/config.js +141 -10
- package/src/utils/errors.js +148 -0
- package/src/utils/inquirer-wrapper.js +1 -2
- package/src/utils/memory.js +200 -0
- package/src/utils/path-utils.js +13 -13
- package/src/utils/plugin-registry.js +238 -0
- package/src/utils/secrets.js +177 -0
- 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;
|
package/src/commands/channels.js
CHANGED
|
@@ -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
|
|
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}
|
|
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);
|
package/src/commands/chat.js
CHANGED
|
@@ -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 {
|
|
17
|
-
const {
|
|
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
|
|
83
|
+
botList = await getBots(apiKey ?? config.providerApiKey ?? '');
|
|
84
84
|
} catch (err) {
|
|
85
|
-
|
|
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();
|
|
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
|
|
338
|
+
let response = await _sendMessage(apiKey ?? config.providerApiKey, bot.id, userMessage, conversationId, systemPrompt, toolDefinitions, options);
|
|
340
339
|
stopLoading();
|
|
341
340
|
|
|
342
|
-
if (response
|
|
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
|
|
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
|
|
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;
|