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,157 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const { getConfig, saveConfig } = require('../utils/config');
|
|
3
|
+
|
|
4
|
+
const MENTION_TTL_MS = 300 * 1000;
|
|
5
|
+
|
|
6
|
+
function threadOwnership(args) {
|
|
7
|
+
const [action, ...params] = args || [];
|
|
8
|
+
|
|
9
|
+
if (!action || action === 'status') return statusOwnership();
|
|
10
|
+
if (action === 'list') return listOwnership();
|
|
11
|
+
if (action === 'assign') return assignOwnership(params[0], params[1], params[2]);
|
|
12
|
+
if (action === 'release') return releaseOwnership(params[0], params[1]);
|
|
13
|
+
if (action === 'check') return checkOwnership(params[0], params[1], params[2]);
|
|
14
|
+
if (action === 'agent') return setDefaultAgent(params[0]);
|
|
15
|
+
|
|
16
|
+
console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
|
|
17
|
+
console.log(chalk.gray(' Kullanım: natureco thread-ownership [status|list|assign|release|check|agent]\n'));
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function statusOwnership() {
|
|
22
|
+
const config = getConfig();
|
|
23
|
+
const to = config.threadOwnership || {};
|
|
24
|
+
const agents = to.agents || { default: config.agentName || 'default' };
|
|
25
|
+
|
|
26
|
+
const totalAssigned = Object.keys(to).filter(k => k !== 'agents').length;
|
|
27
|
+
|
|
28
|
+
console.log(chalk.cyan('\n 🧵 Thread Ownership\n'));
|
|
29
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
30
|
+
console.log(` ${chalk.white('Default Agent:')} ${chalk.cyan(agents.default || 'default')}`);
|
|
31
|
+
console.log(` ${chalk.white('Assigned:')} ${chalk.cyan(totalAssigned)} threads`);
|
|
32
|
+
console.log(` ${chalk.white('Slack Forwarder:')} ${chalk.gray(to.forwarderUrl || process.env.SLACK_FORWARDER_URL || 'not configured')}`);
|
|
33
|
+
console.log(` ${chalk.white('Config Path:')} ${chalk.gray('~/.natureco/config.json → threadOwnership')}`);
|
|
34
|
+
console.log(chalk.gray('\n Commands:'));
|
|
35
|
+
console.log(chalk.cyan(' list') + chalk.gray(' List assignments'));
|
|
36
|
+
console.log(chalk.cyan(' assign <thread> <agent> [channel]') + chalk.gray(' Assign thread'));
|
|
37
|
+
console.log(chalk.cyan(' release <thread> [channel]') + chalk.gray(' Release thread'));
|
|
38
|
+
console.log(chalk.cyan(' check <thread> <channel> <agent>') + chalk.gray(' Check if agent can claim'));
|
|
39
|
+
console.log(chalk.cyan(' agent <name>') + chalk.gray(' Set default agent'));
|
|
40
|
+
console.log();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function listOwnership() {
|
|
44
|
+
const config = getConfig();
|
|
45
|
+
const to = config.threadOwnership || {};
|
|
46
|
+
const entries = Object.entries(to).filter(([k]) => k !== 'agents' && k !== 'forwarderUrl');
|
|
47
|
+
|
|
48
|
+
console.log(chalk.cyan(`\n 🧵 Thread Assignments (${entries.length})\n`));
|
|
49
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
50
|
+
|
|
51
|
+
if (entries.length === 0) {
|
|
52
|
+
console.log(chalk.gray(' Atanmış thread yok.\n'));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
for (const [threadId, data] of entries) {
|
|
57
|
+
const agent = typeof data === 'string' ? data : data.agent || 'unknown';
|
|
58
|
+
const channel = typeof data === 'string' ? '-' : data.channel || '-';
|
|
59
|
+
const ts = typeof data === 'string' ? '-' : data.since ? new Date(data.since).toLocaleString() : '-';
|
|
60
|
+
console.log(` ${chalk.cyan(threadId.substring(0, 30))}`);
|
|
61
|
+
console.log(` ${chalk.gray('Agent:')} ${chalk.white(agent)}`);
|
|
62
|
+
console.log(` ${chalk.gray('Channel:')} ${chalk.white(channel)}`);
|
|
63
|
+
if (ts !== '-') console.log(` ${chalk.gray('Since:')} ${chalk.gray(ts)}`);
|
|
64
|
+
}
|
|
65
|
+
console.log();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function assignOwnership(threadId, agentName, channel) {
|
|
69
|
+
if (!threadId || !agentName) {
|
|
70
|
+
console.log(chalk.red('\n ❌ threadId ve agentName gerekli\n'));
|
|
71
|
+
console.log(chalk.cyan(' natureco thread-ownership assign C012345 "agent-bob" slack\n'));
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const config = getConfig();
|
|
76
|
+
if (!config.threadOwnership) config.threadOwnership = {};
|
|
77
|
+
config.threadOwnership[threadId] = { agent: agentName, channel: channel || 'slack', since: new Date().toISOString() };
|
|
78
|
+
saveConfig(config);
|
|
79
|
+
|
|
80
|
+
console.log(chalk.green(`\n ✅ Thread ${threadId} → ${agentName}${channel ? ` (${channel})` : ''}\n`));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function releaseOwnership(threadId, channel) {
|
|
84
|
+
if (!threadId) {
|
|
85
|
+
console.log(chalk.red('\n ❌ threadId gerekli\n'));
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const config = getConfig();
|
|
90
|
+
if (!config.threadOwnership) config.threadOwnership = {};
|
|
91
|
+
|
|
92
|
+
if (channel) {
|
|
93
|
+
const found = Object.entries(config.threadOwnership).find(([k, v]) =>
|
|
94
|
+
k === threadId && (typeof v === 'string' ? true : v.channel === channel)
|
|
95
|
+
);
|
|
96
|
+
if (found) delete config.threadOwnership[found[0]];
|
|
97
|
+
} else {
|
|
98
|
+
delete config.threadOwnership[threadId];
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
saveConfig(config);
|
|
102
|
+
console.log(chalk.gray(`\n 🔓 Thread ${threadId} serbest bırakıldı\n`));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function checkOwnership(threadId, channel, agentName) {
|
|
106
|
+
if (!threadId || !channel || !agentName) {
|
|
107
|
+
console.log(chalk.red('\n ❌ threadId, channel ve agentName gerekli\n'));
|
|
108
|
+
console.log(chalk.cyan(' natureco thread-ownership check C012345 slack agent-bob\n'));
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const config = getConfig();
|
|
113
|
+
const to = config.threadOwnership || {};
|
|
114
|
+
const entry = Object.entries(to).find(([k, v]) => {
|
|
115
|
+
if (k !== threadId) return false;
|
|
116
|
+
if (typeof v === 'string') return true;
|
|
117
|
+
return v.channel === channel || !v.channel;
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
if (!entry) {
|
|
121
|
+
console.log(chalk.green(`\n ✅ Thread ${threadId} sahipsiz — ${agentName} alabilir\n`));
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const [, data] = entry;
|
|
126
|
+
const owner = typeof data === 'string' ? data : data.agent;
|
|
127
|
+
const since = typeof data === 'string' ? '-' : data.since ? new Date(data.since).toLocaleString() : '-';
|
|
128
|
+
|
|
129
|
+
if (owner === agentName) {
|
|
130
|
+
console.log(chalk.green(`\n ✅ Thread ${threadId} zaten ${agentName}'e ait\n`));
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const expired = data.since ? (Date.now() - new Date(data.since).getTime() > MENTION_TTL_MS) : false;
|
|
135
|
+
if (expired) {
|
|
136
|
+
console.log(chalk.yellow(`\n ⚠️ Thread ${threadId} süresi dolmuş (${owner}), ${agentName} alabilir\n`));
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
console.log(chalk.red(`\n ❌ Thread ${threadId} ${owner}'e ait (since: ${since}) — ${agentName} alamaz\n`));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function setDefaultAgent(name) {
|
|
144
|
+
if (!name) {
|
|
145
|
+
console.log(chalk.red('\n ❌ Agent adı gerekli\n'));
|
|
146
|
+
process.exit(1);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const config = getConfig();
|
|
150
|
+
if (!config.threadOwnership) config.threadOwnership = {};
|
|
151
|
+
if (!config.threadOwnership.agents) config.threadOwnership.agents = {};
|
|
152
|
+
config.threadOwnership.agents.default = name;
|
|
153
|
+
saveConfig(config);
|
|
154
|
+
console.log(chalk.green(`\n ✅ Default agent set to: ${name}\n`));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
module.exports = threadOwnership;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
|
|
6
|
+
function transcripts(args) {
|
|
7
|
+
const [action, ...params] = args || [];
|
|
8
|
+
|
|
9
|
+
if (!action || action === 'list') return listTranscripts();
|
|
10
|
+
if (action === 'show') return showTranscript(params[0]);
|
|
11
|
+
|
|
12
|
+
console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
|
|
13
|
+
console.log(chalk.gray(' Kullanım: natureco transcripts [list|show]\n'));
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function listTranscripts() {
|
|
18
|
+
const sessionsDir = path.join(os.homedir(), '.natureco', 'sessions');
|
|
19
|
+
console.log(chalk.cyan('\n 📜 Transcripts\n'));
|
|
20
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
21
|
+
|
|
22
|
+
if (!fs.existsSync(sessionsDir)) {
|
|
23
|
+
console.log(chalk.gray(' No transcripts found.\n'));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const files = fs.readdirSync(sessionsDir).filter(f => f.endsWith('.json'));
|
|
28
|
+
if (files.length === 0) {
|
|
29
|
+
console.log(chalk.gray(' No transcripts found.\n'));
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
for (const f of files.sort().reverse().slice(0, 20)) {
|
|
34
|
+
const stat = fs.statSync(path.join(sessionsDir, f));
|
|
35
|
+
const size = (stat.size / 1024).toFixed(1);
|
|
36
|
+
const date = stat.birthtime.toLocaleString();
|
|
37
|
+
const preview = f.replace('.json', '').substring(0, 40);
|
|
38
|
+
console.log(` ${chalk.cyan('●')} ${chalk.white(preview)} ${chalk.gray(`(${size} KB, ${date})`)}`);
|
|
39
|
+
}
|
|
40
|
+
console.log();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function showTranscript(id) {
|
|
44
|
+
if (!id) {
|
|
45
|
+
console.log(chalk.red('\n ❌ Transcript ID gerekli\n'));
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const sessionsDir = path.join(os.homedir(), '.natureco', 'sessions');
|
|
50
|
+
const file = path.join(sessionsDir, `${id}.json`);
|
|
51
|
+
|
|
52
|
+
if (!fs.existsSync(file)) {
|
|
53
|
+
const alt = path.join(sessionsDir, id);
|
|
54
|
+
if (!fs.existsSync(alt)) {
|
|
55
|
+
console.log(chalk.red(`\n ❌ Transcript bulunamadı: ${id}\n`));
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
const content = fs.readFileSync(alt, 'utf8');
|
|
59
|
+
console.log(chalk.gray(`\n ${alt}\n`));
|
|
60
|
+
console.log(content.substring(0, 5000));
|
|
61
|
+
if (content.length > 5000) console.log(chalk.gray('\n ... (truncated)\n'));
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const content = fs.readFileSync(file, 'utf8');
|
|
66
|
+
console.log(chalk.gray(`\n ${file}\n`));
|
|
67
|
+
const parsed = JSON.parse(content);
|
|
68
|
+
console.log(JSON.stringify(parsed, null, 2).substring(0, 5000));
|
|
69
|
+
console.log();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
module.exports = transcripts;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const { getConfig, saveConfig } = require('../utils/config');
|
|
3
|
+
|
|
4
|
+
const PROVIDER_LABELS = {
|
|
5
|
+
openai: 'OpenAI',
|
|
6
|
+
elevenlabs: 'ElevenLabs',
|
|
7
|
+
microsoft: 'Microsoft (Azure)',
|
|
8
|
+
deepgram: 'Deepgram',
|
|
9
|
+
google: 'Google Cloud'
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
function mask(str, keep = 6) {
|
|
13
|
+
if (!str) return '(unset)';
|
|
14
|
+
return str.length <= keep ? '***' : `${str.slice(0, keep)}…`;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async function voice(args) {
|
|
18
|
+
const [action, ...params] = args || [];
|
|
19
|
+
|
|
20
|
+
if (!action || action === 'status') return statusVoice();
|
|
21
|
+
if (action === 'providers') return listProviders();
|
|
22
|
+
if (action === 'set') return setVoiceProvider(params);
|
|
23
|
+
|
|
24
|
+
console.log(chalk.red(`\n ❌ Unknown command: ${action}\n`));
|
|
25
|
+
console.log(chalk.gray(' Usage: natureco voice [status|providers|set]\n'));
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function statusVoice() {
|
|
30
|
+
const config = getConfig();
|
|
31
|
+
const ttsConfig = config.tts || {};
|
|
32
|
+
const provider = ttsConfig.provider || 'openai';
|
|
33
|
+
const voiceId = ttsConfig.voiceId;
|
|
34
|
+
const apiKey = ttsConfig.apiKey || config[`${provider}ApiKey`] || process.env[`${provider.toUpperCase()}_API_KEY`];
|
|
35
|
+
|
|
36
|
+
console.log(chalk.cyan('\n 🎤 Voice Status\n'));
|
|
37
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
38
|
+
console.log(` ${chalk.white('Provider:')} ${chalk.cyan(provider)}`);
|
|
39
|
+
console.log(` ${chalk.white('Voice ID:')} ${chalk.cyan(voiceId || '(default)')}`);
|
|
40
|
+
console.log(` ${chalk.white('API Key:')} ${chalk.gray(mask(apiKey))}`);
|
|
41
|
+
console.log(chalk.gray('\n Commands:'));
|
|
42
|
+
console.log(chalk.cyan(' natureco voice providers') + chalk.gray(' List available providers'));
|
|
43
|
+
console.log(chalk.cyan(' natureco voice set <provider> [voiceId]') + chalk.gray(' Set voice provider'));
|
|
44
|
+
console.log();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function listProviders() {
|
|
48
|
+
console.log(chalk.cyan('\n 🎤 Voice Providers\n'));
|
|
49
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
50
|
+
|
|
51
|
+
for (const [id, label] of Object.entries(PROVIDER_LABELS)) {
|
|
52
|
+
console.log(` ${chalk.white(label)} ${chalk.gray(`(${id})`)}`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
console.log(chalk.gray('\n Set provider:'));
|
|
56
|
+
console.log(chalk.cyan(' natureco voice set openai'));
|
|
57
|
+
console.log(chalk.cyan(' natureco voice set elevenlabs [voiceId]'));
|
|
58
|
+
console.log();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function setVoiceProvider(args) {
|
|
62
|
+
const provider = args[0];
|
|
63
|
+
const voiceId = args.slice(1).join(' ') || '';
|
|
64
|
+
|
|
65
|
+
if (!provider || !PROVIDER_LABELS[provider]) {
|
|
66
|
+
console.log(chalk.red(`\n ❌ Unknown provider: ${provider}\n`));
|
|
67
|
+
console.log(chalk.gray(' Available: ' + Object.keys(PROVIDER_LABELS).join(', ')));
|
|
68
|
+
console.log();
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const config = getConfig();
|
|
73
|
+
if (!config.tts) config.tts = {};
|
|
74
|
+
config.tts.provider = provider;
|
|
75
|
+
if (voiceId) config.tts.voiceId = voiceId;
|
|
76
|
+
else delete config.tts.voiceId;
|
|
77
|
+
saveConfig(config);
|
|
78
|
+
|
|
79
|
+
console.log(chalk.green(`\n ✅ Voice provider set to ${PROVIDER_LABELS[provider]}${voiceId ? ` (voice: ${voiceId})` : ''}\n`));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
module.exports = voice;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const { getConfig, saveConfig } = require('../utils/config');
|
|
3
|
+
|
|
4
|
+
const VYDRA_ENDPOINTS = {
|
|
5
|
+
'vydra-image': {
|
|
6
|
+
name: 'Vydra Image Generation',
|
|
7
|
+
endpoint: 'https://api.vydra.ai/v1/images/generations',
|
|
8
|
+
docs: 'https://docs.vydra.ai/image-generation'
|
|
9
|
+
},
|
|
10
|
+
'vydra-video': {
|
|
11
|
+
name: 'Vydra Video Generation',
|
|
12
|
+
endpoint: 'https://api.vydra.ai/v1/video/generations',
|
|
13
|
+
docs: 'https://docs.vydra.ai/video-generation'
|
|
14
|
+
},
|
|
15
|
+
'vydra-music': {
|
|
16
|
+
name: 'Vydra Music Generation',
|
|
17
|
+
endpoint: 'https://api.vydra.ai/v1/music/generations',
|
|
18
|
+
docs: 'https://docs.vydra.ai/music-generation'
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
function vydra(args) {
|
|
23
|
+
const [action, ...params] = args || [];
|
|
24
|
+
|
|
25
|
+
if (!action || action === 'status') return statusVydra();
|
|
26
|
+
if (action === 'configure') return configureVydra(params[0], params[1]);
|
|
27
|
+
if (action === 'test') return testVydra();
|
|
28
|
+
|
|
29
|
+
console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
|
|
30
|
+
console.log(chalk.gray(' Kullanım: natureco vydra [status|configure|test]\n'));
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function statusVydra() {
|
|
35
|
+
const config = getConfig();
|
|
36
|
+
const apiKey = config.vydraApiKey || process.env.VYDRA_API_KEY;
|
|
37
|
+
|
|
38
|
+
console.log(chalk.cyan('\n 🎬 Vydra Media Provider\n'));
|
|
39
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
40
|
+
console.log(` ${chalk.white('API Key:')} ${apiKey ? chalk.green('Configured') : chalk.red('Not set')}`);
|
|
41
|
+
console.log(chalk.gray('\n Available endpoints:\n'));
|
|
42
|
+
|
|
43
|
+
for (const [id, ep] of Object.entries(VYDRA_ENDPOINTS)) {
|
|
44
|
+
const configured = apiKey ? chalk.green('✅') : chalk.gray('⏸️');
|
|
45
|
+
console.log(` ${configured} ${chalk.white(ep.name)}`);
|
|
46
|
+
console.log(` ${chalk.gray(ep.endpoint)}`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
console.log(chalk.gray('\n Commands:'));
|
|
50
|
+
console.log(chalk.cyan(' configure <key>') + chalk.gray(' Set Vydra API key'));
|
|
51
|
+
console.log(chalk.cyan(' test') + chalk.gray(' Test API connection'));
|
|
52
|
+
console.log();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function configureVydra(key) {
|
|
56
|
+
if (!key) {
|
|
57
|
+
console.log(chalk.red('\n ❌ API key gerekli\n'));
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const config = getConfig();
|
|
62
|
+
config.vydraApiKey = key;
|
|
63
|
+
saveConfig(config);
|
|
64
|
+
console.log(chalk.green('\n ✅ Vydra API key saved\n'));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function testVydra() {
|
|
68
|
+
const config = getConfig();
|
|
69
|
+
const apiKey = config.vydraApiKey || process.env.VYDRA_API_KEY;
|
|
70
|
+
|
|
71
|
+
if (!apiKey) {
|
|
72
|
+
console.log(chalk.red('\n ❌ Vydra API key gerekli\n'));
|
|
73
|
+
console.log(chalk.cyan(' natureco vydra configure <your-api-key>\n'));
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
console.log(chalk.cyan('\n Testing Vydra API connection...\n'));
|
|
78
|
+
|
|
79
|
+
for (const [id, ep] of Object.entries(VYDRA_ENDPOINTS)) {
|
|
80
|
+
try {
|
|
81
|
+
const response = await fetch(ep.endpoint, {
|
|
82
|
+
method: 'HEAD',
|
|
83
|
+
headers: { 'Authorization': `Bearer ${apiKey}` }
|
|
84
|
+
});
|
|
85
|
+
console.log(` ${response.ok ? chalk.green('✅') : chalk.red('❌')} ${chalk.white(ep.name)} ${chalk.gray(`(${response.status})`)}`);
|
|
86
|
+
} catch (err) {
|
|
87
|
+
console.log(` ${chalk.red('❌')} ${chalk.white(ep.name)} ${chalk.gray(`(${err.message})`)}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
console.log(chalk.gray('\n Vydra API endpoints are available as providers for:'));
|
|
92
|
+
console.log(chalk.cyan(' image_generation') + chalk.gray(' tool (provider: vydra)'));
|
|
93
|
+
console.log(chalk.cyan(' video_generation') + chalk.gray(' tool (provider: vydra)'));
|
|
94
|
+
console.log(chalk.cyan(' music_generation') + chalk.gray(' tool (provider: vydra)'));
|
|
95
|
+
console.log();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
module.exports = vydra;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const inquirer = require('../utils/inquirer-wrapper');
|
|
3
|
+
const { getConfig, saveConfig } = require('../utils/config');
|
|
4
|
+
|
|
5
|
+
async function webhooks(action) {
|
|
6
|
+
if (!action || action === 'connect') return connectWebhook();
|
|
7
|
+
if (action === 'disconnect') return disconnectWebhook();
|
|
8
|
+
if (action === 'status') return statusWebhooks();
|
|
9
|
+
if (action === 'list') return listWebhooks();
|
|
10
|
+
console.log(chalk.red('\n❌ Unknown action\n'));
|
|
11
|
+
console.log(chalk.gray('Available actions: connect, disconnect, status, list\n'));
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async function connectWebhook() {
|
|
16
|
+
const config = getConfig();
|
|
17
|
+
if (!config.providerUrl) { console.log(chalk.red('\n❌ Setup yapılmamış. Önce "natureco setup" çalıştırın.\n')); process.exit(1); }
|
|
18
|
+
console.log(chalk.yellow('\n⏳ Webhook bağlantısı hazırlanıyor...\n'));
|
|
19
|
+
console.log(chalk.gray('Gelen webhook\'lar NatureCo\'nun gateway\'ine yönlendirilir.\n'));
|
|
20
|
+
const answers = await inquirer.prompt([
|
|
21
|
+
{ type: 'input', name: 'name', message: 'Webhook adı:', validate: v => v.trim() ? true : 'Gerekli' },
|
|
22
|
+
{ type: 'input', name: 'path', message: 'Webhook yolu (örn: /my-webhook):', validate: v => v.startsWith('/') ? true : 'Yol / ile başlamalı' },
|
|
23
|
+
{ type: 'input', name: 'secret', message: 'Webhook secret (opsiyonel):' },
|
|
24
|
+
]);
|
|
25
|
+
const webhooks = config.webhooks || [];
|
|
26
|
+
const entry = {
|
|
27
|
+
id: `webhook_${Date.now()}`,
|
|
28
|
+
name: answers.name.trim(),
|
|
29
|
+
path: answers.path.trim(),
|
|
30
|
+
secret: answers.secret.trim() || '',
|
|
31
|
+
createdAt: new Date().toISOString(),
|
|
32
|
+
};
|
|
33
|
+
webhooks.push(entry);
|
|
34
|
+
config.webhooks = webhooks;
|
|
35
|
+
config.webhookEnabled = true;
|
|
36
|
+
saveConfig(config);
|
|
37
|
+
console.log(chalk.green('\n✅ Webhook eklendi!\n'));
|
|
38
|
+
console.log(chalk.cyan('ID:'), chalk.white(entry.id));
|
|
39
|
+
console.log(chalk.cyan('İsim:'), chalk.white(entry.name));
|
|
40
|
+
console.log(chalk.cyan('Yol:'), chalk.white(entry.path));
|
|
41
|
+
console.log(chalk.gray('\nGateway ile başlatmak için: natureco gateway start\n'));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function disconnectWebhook() {
|
|
45
|
+
const config = getConfig();
|
|
46
|
+
const webhooks = config.webhooks || [];
|
|
47
|
+
if (webhooks.length === 0) { console.log(chalk.gray('\n⚠️ No webhooks configured\n')); return; }
|
|
48
|
+
const { confirm } = await inquirer.prompt([{ type: 'confirm', name: 'confirm', message: 'Tüm webhook\'ları kaldırmak istediğinize emin misiniz?', default: false }]);
|
|
49
|
+
if (!confirm) { console.log(chalk.gray('\nCancelled\n')); return; }
|
|
50
|
+
delete config.webhooks;
|
|
51
|
+
delete config.webhookEnabled;
|
|
52
|
+
saveConfig(config);
|
|
53
|
+
console.log(chalk.green('\n✅ All webhooks removed\n'));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function listWebhooks() {
|
|
57
|
+
const config = getConfig();
|
|
58
|
+
const webhooks = config.webhooks || [];
|
|
59
|
+
if (webhooks.length === 0) { console.log(chalk.gray('\n⚠️ No webhooks configured\n')); return; }
|
|
60
|
+
console.log(chalk.green(`\n✅ ${webhooks.length} webhook(s) configured\n`));
|
|
61
|
+
webhooks.forEach(w => {
|
|
62
|
+
console.log(chalk.cyan(' ID:'), chalk.white(w.id));
|
|
63
|
+
console.log(chalk.cyan(' İsim:'), chalk.white(w.name));
|
|
64
|
+
console.log(chalk.cyan(' Yol:'), chalk.white(w.path));
|
|
65
|
+
if (w.secret) console.log(chalk.cyan(' Secret:'), chalk.gray('✓ ayarlı'));
|
|
66
|
+
console.log('');
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function statusWebhooks() {
|
|
71
|
+
const config = getConfig();
|
|
72
|
+
const webhooks = config.webhooks || [];
|
|
73
|
+
if (webhooks.length === 0) { console.log(chalk.gray('\n⚠️ No webhooks configured\n')); console.log(chalk.gray('Add with: natureco webhooks connect\n')); return; }
|
|
74
|
+
console.log(chalk.green(`\n✅ Webhooks active (${webhooks.length} route(s))\n`));
|
|
75
|
+
webhooks.forEach(w => console.log(chalk.white(` ${w.path} → ${w.name}`)));
|
|
76
|
+
console.log(chalk.gray('\nDisconnect with: natureco webhooks disconnect\n'));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
module.exports = webhooks;
|
package/src/commands/whatsapp.js
CHANGED
|
@@ -7,25 +7,11 @@ const os = require('os');
|
|
|
7
7
|
const pino = require('pino');
|
|
8
8
|
const { getApiKey, getConfig, saveConfig } = require('../utils/config');
|
|
9
9
|
const { getBots, sendMessage } = require('../utils/api');
|
|
10
|
+
const { loadBaileys } = require('../utils/baileys');
|
|
11
|
+
const { NatureCoError, ChannelError, handleError } = require('../utils/errors');
|
|
10
12
|
|
|
11
|
-
// Baileys imports
|
|
12
|
-
let makeWASocket, useMultiFileAuthState, DisconnectReason, fetchLatestBaileysVersion, Browsers;
|
|
13
|
-
|
|
14
|
-
// Logger
|
|
15
13
|
const logger = pino({ level: 'silent' });
|
|
16
14
|
|
|
17
|
-
// Lazy load Baileys (only when needed)
|
|
18
|
-
function loadBaileys() {
|
|
19
|
-
if (!makeWASocket) {
|
|
20
|
-
const baileys = require('@whiskeysockets/baileys');
|
|
21
|
-
makeWASocket = baileys.default;
|
|
22
|
-
useMultiFileAuthState = baileys.useMultiFileAuthState;
|
|
23
|
-
DisconnectReason = baileys.DisconnectReason;
|
|
24
|
-
fetchLatestBaileysVersion = baileys.fetchLatestBaileysVersion;
|
|
25
|
-
Browsers = baileys.Browsers;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
15
|
// WhatsApp session directory
|
|
30
16
|
const WHATSAPP_SESSION_DIR = path.join(os.homedir(), '.natureco', 'whatsapp-sessions');
|
|
31
17
|
|
|
@@ -73,9 +59,6 @@ async function connectWhatsApp() {
|
|
|
73
59
|
console.log(chalk.cyan('\n📱 WhatsApp bağlantısı başlatılıyor...'));
|
|
74
60
|
console.log(chalk.gray('Telefonunuzda WhatsApp\'ı açın ve QR kodu taratın.\n'));
|
|
75
61
|
|
|
76
|
-
// Load Baileys
|
|
77
|
-
loadBaileys();
|
|
78
|
-
|
|
79
62
|
// Create session directory
|
|
80
63
|
const sessionDir = path.join(WHATSAPP_SESSION_DIR, botId);
|
|
81
64
|
if (!fs.existsSync(sessionDir)) {
|
|
@@ -88,6 +71,8 @@ async function connectWhatsApp() {
|
|
|
88
71
|
|
|
89
72
|
async function startWhatsAppConnection(sessionDir, botId, selectedBot, config) {
|
|
90
73
|
try {
|
|
74
|
+
const { makeWASocket, useMultiFileAuthState, DisconnectReason, fetchLatestBaileysVersion, Browsers } = loadBaileys();
|
|
75
|
+
|
|
91
76
|
// Create auth state
|
|
92
77
|
const { state, saveCreds } = await useMultiFileAuthState(sessionDir);
|
|
93
78
|
|
|
@@ -197,8 +182,9 @@ async function startWhatsAppConnection(sessionDir, botId, selectedBot, config) {
|
|
|
197
182
|
});
|
|
198
183
|
|
|
199
184
|
} catch (err) {
|
|
200
|
-
|
|
201
|
-
|
|
185
|
+
const msg = err instanceof NatureCoError ? err.message : err?.message ?? 'Unknown error';
|
|
186
|
+
console.log(chalk.red(`\n❌ Connection failed: ${msg}\n`));
|
|
187
|
+
if (err?.message?.includes('Cannot find module')) {
|
|
202
188
|
console.log(chalk.yellow('⚠️ Baileys paketi yüklü değil. Yükleniyor...\n'));
|
|
203
189
|
console.log(chalk.gray('Lütfen şu komutu çalıştırın:\n'));
|
|
204
190
|
console.log(chalk.cyan('npm install -g @whiskeysockets/baileys pino\n'));
|