natureco-cli 2.23.29 → 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 +402 -4
- package/package.json +1 -1
- 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/clickclack.js +130 -0
- package/src/commands/commitments.js +32 -0
- package/src/commands/completion.js +76 -0
- 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/exec-policy.js +71 -0
- package/src/commands/gateway-server.js +1155 -24
- package/src/commands/health.js +18 -0
- package/src/commands/imessage.js +128 -14
- package/src/commands/infer.js +73 -0
- package/src/commands/irc.js +64 -15
- package/src/commands/mattermost.js +114 -12
- package/src/commands/memory-cmd.js +134 -1
- package/src/commands/message.js +9 -3
- package/src/commands/migrate.js +213 -2
- 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/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/setup.js +113 -7
- package/src/commands/signal.js +447 -18
- package/src/commands/sms.js +123 -19
- package/src/commands/system.js +53 -0
- 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/workboard.js +207 -0
- package/src/tools/audio_understanding.js +154 -0
- 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/memory.js +200 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const crypto = require('crypto');
|
|
3
|
+
|
|
4
|
+
function qr(args) {
|
|
5
|
+
const data = args.join(' ') || generatePairingData();
|
|
6
|
+
|
|
7
|
+
console.log(chalk.cyan('\n 📱 QR Pairing Code\n'));
|
|
8
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
9
|
+
|
|
10
|
+
const code = crypto.randomBytes(4).toString('hex').toUpperCase();
|
|
11
|
+
const expiresAt = new Date(Date.now() + 15 * 60 * 1000);
|
|
12
|
+
|
|
13
|
+
console.log(` ${chalk.white('Pairing Code:')} ${chalk.bold.yellow(code)}`);
|
|
14
|
+
console.log(` ${chalk.white('Expires:')} ${chalk.gray(expiresAt.toLocaleString())}`);
|
|
15
|
+
console.log();
|
|
16
|
+
console.log(chalk.gray(' To pair a device, run on the device:'));
|
|
17
|
+
console.log(chalk.cyan(' natureco device-pair verify ') + chalk.yellow(code));
|
|
18
|
+
console.log();
|
|
19
|
+
console.log(chalk.gray(' Or scan with the NatureCo mobile app.'));
|
|
20
|
+
console.log();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function generatePairingData() {
|
|
24
|
+
const id = crypto.randomBytes(8).toString('hex');
|
|
25
|
+
return JSON.stringify({ id, timestamp: Date.now() });
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
module.exports = qr;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const { execSync, spawn } = require('child_process');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const os = require('os');
|
|
6
|
+
|
|
7
|
+
const SANDBOX_DIR = path.join(os.tmpdir(), 'natureco-sandboxes');
|
|
8
|
+
|
|
9
|
+
function sandbox(args) {
|
|
10
|
+
const [action, ...params] = args || [];
|
|
11
|
+
|
|
12
|
+
if (!action || action === 'list') return listSandboxes();
|
|
13
|
+
if (action === 'create') return createSandbox(params[0]);
|
|
14
|
+
if (action === 'destroy') return destroySandbox(params[0]);
|
|
15
|
+
if (action === 'exec') return execSandbox(params[0], params.slice(1).join(' '));
|
|
16
|
+
|
|
17
|
+
console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
|
|
18
|
+
console.log(chalk.gray(' Kullanım: natureco sandbox [list|create|destroy|exec]\n'));
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function getDirSandboxes() {
|
|
23
|
+
if (!fs.existsSync(SANDBOX_DIR)) return [];
|
|
24
|
+
return fs.readdirSync(SANDBOX_DIR).filter(name => {
|
|
25
|
+
const stat = fs.statSync(path.join(SANDBOX_DIR, name));
|
|
26
|
+
return stat.isDirectory();
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function listSandboxes() {
|
|
31
|
+
console.log(chalk.cyan('\n 📦 Sandbox Containers\n'));
|
|
32
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
33
|
+
|
|
34
|
+
// Dir-based sandboxes
|
|
35
|
+
const dirSandboxes = getDirSandboxes();
|
|
36
|
+
if (dirSandboxes.length > 0) {
|
|
37
|
+
for (const name of dirSandboxes) {
|
|
38
|
+
const dir = path.join(SANDBOX_DIR, name);
|
|
39
|
+
const files = fs.readdirSync(dir).length;
|
|
40
|
+
const created = fs.statSync(dir).birthtime;
|
|
41
|
+
console.log(` ${chalk.green('●')} ${chalk.white(name)} ${chalk.gray(`(${files} file(s), ${created.toISOString().slice(0, 10)})`)}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Docker sandboxes
|
|
46
|
+
try {
|
|
47
|
+
const dockerOut = execSync('docker ps --filter "name=natureco-sandbox" --format "{{.ID}}\t{{.Image}}\t{{.Status}}\t{{.Names}}" 2>nul', { encoding: 'utf8', timeout: 5000, stdio: 'pipe' }).trim();
|
|
48
|
+
if (dockerOut) {
|
|
49
|
+
for (const line of dockerOut.split('\n')) {
|
|
50
|
+
const [id, image, status, name] = line.split('\t');
|
|
51
|
+
console.log(` ${chalk.blue('●')} ${chalk.white(name || id)} ${chalk.gray(`${image} — ${status}`)}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
} catch {}
|
|
55
|
+
|
|
56
|
+
if (dirSandboxes.length === 0) {
|
|
57
|
+
console.log(chalk.gray(' No sandboxes found.\n'));
|
|
58
|
+
console.log(chalk.gray(' Create one:') + chalk.cyan(' natureco sandbox create [name]\n'));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
console.log();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function createSandbox(name) {
|
|
65
|
+
const sandboxName = name || `sandbox-${Date.now()}`;
|
|
66
|
+
const dir = path.join(SANDBOX_DIR, sandboxName);
|
|
67
|
+
|
|
68
|
+
if (fs.existsSync(dir)) {
|
|
69
|
+
console.log(chalk.red(`\n ❌ Sandbox '${sandboxName}' already exists\n`));
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
74
|
+
fs.writeFileSync(path.join(dir, '.natureco-sandbox'), JSON.stringify({ created: new Date().toISOString(), name: sandboxName }));
|
|
75
|
+
|
|
76
|
+
console.log(chalk.green(`\n ✅ Sandbox created: ${sandboxName}\n`));
|
|
77
|
+
console.log(chalk.gray(` Directory: ${dir}\n`));
|
|
78
|
+
console.log(chalk.gray(' Usage:') + chalk.cyan(` natureco sandbox exec ${sandboxName} "node -e 'console.log(\\"hello\\")'"`) + '\n');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function destroySandbox(name) {
|
|
82
|
+
if (!name) {
|
|
83
|
+
console.log(chalk.red('\n ❌ Sandbox name gerekli\n'));
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const dir = path.join(SANDBOX_DIR, name);
|
|
88
|
+
if (fs.existsSync(dir)) {
|
|
89
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
90
|
+
console.log(chalk.gray(` 🗑️ Dir sandbox destroyed: ${name}\n`));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
execSync(`docker rm -f ${name} 2>nul`, { stdio: 'pipe', timeout: 10000 });
|
|
95
|
+
console.log(chalk.gray(` 🗑️ Docker sandbox destroyed: ${name}\n`));
|
|
96
|
+
} catch {}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function execSandbox(name, command) {
|
|
100
|
+
if (!name || !command) {
|
|
101
|
+
console.log(chalk.red('\n ❌ Sandbox name ve command gerekli\n'));
|
|
102
|
+
console.log(chalk.gray(' Kullanım: natureco sandbox exec <name> <command>\n'));
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const dir = path.join(SANDBOX_DIR, name);
|
|
107
|
+
if (!fs.existsSync(dir)) {
|
|
108
|
+
console.log(chalk.red(`\n ❌ Sandbox '${name}' not found\n`));
|
|
109
|
+
console.log(chalk.gray(' Create one:') + chalk.cyan(` natureco sandbox create ${name}`) + '\n');
|
|
110
|
+
process.exit(1);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
console.log(chalk.cyan(`\n 🏃 Executing in sandbox '${name}': ${command}\n`));
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
const result = execSync(command, { cwd: dir, encoding: 'utf8', timeout: 30000, stdio: 'inherit' });
|
|
117
|
+
return result;
|
|
118
|
+
} catch (err) {
|
|
119
|
+
if (err.status !== undefined) process.exit(err.status);
|
|
120
|
+
console.log(chalk.red(` ❌ ${err.message}\n`));
|
|
121
|
+
process.exit(1);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
module.exports = sandbox;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const { getConfig, saveConfig } = require('../utils/config');
|
|
3
|
+
|
|
4
|
+
function secrets(args) {
|
|
5
|
+
const [action, ...params] = args || [];
|
|
6
|
+
|
|
7
|
+
if (!action || action === 'list') return listSecrets();
|
|
8
|
+
if (action === 'set') return setSecret(params[0], params.slice(1).join(' '));
|
|
9
|
+
if (action === 'get') return getSecret(params[0]);
|
|
10
|
+
if (action === 'unset') return unsetSecret(params[0]);
|
|
11
|
+
if (action === 'audit') return auditSecrets();
|
|
12
|
+
|
|
13
|
+
console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
|
|
14
|
+
console.log(chalk.gray(' Kullanım: natureco secrets [list|set|get|unset|audit]\n'));
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function listSecrets() {
|
|
19
|
+
const config = getConfig();
|
|
20
|
+
const secretKeys = Object.keys(config).filter(k =>
|
|
21
|
+
k.toLowerCase().includes('key') || k.toLowerCase().includes('token') || k.toLowerCase().includes('secret')
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
console.log(chalk.cyan('\n 🔐 Secrets\n'));
|
|
25
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
26
|
+
|
|
27
|
+
if (secretKeys.length === 0) {
|
|
28
|
+
console.log(chalk.gray(' No secrets stored.\n'));
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
for (const key of secretKeys.sort()) {
|
|
33
|
+
const val = config[key];
|
|
34
|
+
const masked = val ? val.substring(0, 6) + '…' + val.slice(-4) : '(empty)';
|
|
35
|
+
console.log(` ${chalk.white(key)}: ${chalk.gray(masked)}`);
|
|
36
|
+
}
|
|
37
|
+
console.log();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function setSecret(key, value) {
|
|
41
|
+
if (!key || !value) {
|
|
42
|
+
console.log(chalk.red('\n ❌ key ve value gerekli\n'));
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const config = getConfig();
|
|
47
|
+
config[key] = value;
|
|
48
|
+
saveConfig(config);
|
|
49
|
+
console.log(chalk.green(`\n ✅ Secret set: ${key}\n`));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function getSecret(key) {
|
|
53
|
+
if (!key) {
|
|
54
|
+
console.log(chalk.red('\n ❌ key gerekli\n'));
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const config = getConfig();
|
|
59
|
+
const value = config[key];
|
|
60
|
+
|
|
61
|
+
if (!value) {
|
|
62
|
+
console.log(chalk.yellow(`\n ⚠️ Secret not found: ${key}\n`));
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
console.log(chalk.cyan(`\n ${key}: ${chalk.white(value)}\n`));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function unsetSecret(key) {
|
|
70
|
+
if (!key) {
|
|
71
|
+
console.log(chalk.red('\n ❌ key gerekli\n'));
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const config = getConfig();
|
|
76
|
+
delete config[key];
|
|
77
|
+
saveConfig(config);
|
|
78
|
+
console.log(chalk.gray(`\n 🗑️ Secret removed: ${key}\n`));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function auditSecrets() {
|
|
82
|
+
const config = getConfig();
|
|
83
|
+
const secrets = Object.keys(config).filter(k =>
|
|
84
|
+
k.toLowerCase().includes('key') || k.toLowerCase().includes('token') || k.toLowerCase().includes('secret')
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
const envKeys = ['OPENAI_API_KEY', 'ANTHROPIC_API_KEY', 'GROQ_API_KEY', 'TAVILY_API_KEY',
|
|
88
|
+
'ELEVENLABS_API_KEY', 'DEEPGRAM_API_KEY', 'FAL_KEY', 'TOGETHER_API_KEY',
|
|
89
|
+
'PUSHOVER_TOKEN', 'PUSHOVER_USER', 'NTFY_TOPIC', 'NTFY_SERVER',
|
|
90
|
+
'TWILIO_SID', 'TWILIO_TOKEN', 'TWILIO_FROM', 'SUNO_API_KEY', 'UDIO_API_KEY',
|
|
91
|
+
'VYDRA_API_KEY', 'SLACK_BOT_TOKEN', 'DISCORD_BOT_TOKEN', 'TELEGRAM_BOT_TOKEN',
|
|
92
|
+
'WHATSAPP_API_KEY'
|
|
93
|
+
];
|
|
94
|
+
|
|
95
|
+
console.log(chalk.cyan('\n 🔐 Secrets Audit\n'));
|
|
96
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
97
|
+
|
|
98
|
+
console.log(chalk.white('\n Config Secrets:'));
|
|
99
|
+
for (const key of secrets.sort()) {
|
|
100
|
+
const val = config[key];
|
|
101
|
+
const status = val ? chalk.green('set') : chalk.red('empty');
|
|
102
|
+
console.log(` ${chalk.gray('●')} ${key}: ${status}`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
console.log(chalk.white('\n Environment Variables:'));
|
|
106
|
+
let found = 0;
|
|
107
|
+
for (const envKey of envKeys) {
|
|
108
|
+
if (process.env[envKey]) {
|
|
109
|
+
console.log(` ${chalk.green('●')} ${envKey}: ${chalk.green('set')}`);
|
|
110
|
+
found++;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (found === 0) console.log(chalk.gray(' (none set in environment)'));
|
|
114
|
+
|
|
115
|
+
console.log(chalk.gray(`\n Total: ${secrets.length} config + ${found} env\n`));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
module.exports = secrets;
|
package/src/commands/setup.js
CHANGED
|
@@ -41,6 +41,12 @@ const LANG = {
|
|
|
41
41
|
WhatsApp: 'natureco whatsapp connect',
|
|
42
42
|
Discord: 'natureco discord connect',
|
|
43
43
|
Slack: 'natureco slack connect',
|
|
44
|
+
Signal: 'natureco signal connect',
|
|
45
|
+
IRC: 'natureco irc connect',
|
|
46
|
+
Mattermost:'natureco mattermost connect',
|
|
47
|
+
iMessage: 'natureco imessage connect',
|
|
48
|
+
SMS: 'natureco sms connect',
|
|
49
|
+
Webhooks: 'natureco webhooks connect',
|
|
44
50
|
},
|
|
45
51
|
// Adım 5
|
|
46
52
|
gatewayTitle: 'Gateway',
|
|
@@ -99,6 +105,12 @@ const LANG = {
|
|
|
99
105
|
WhatsApp: 'natureco whatsapp connect',
|
|
100
106
|
Discord: 'natureco discord connect',
|
|
101
107
|
Slack: 'natureco slack connect',
|
|
108
|
+
Signal: 'natureco signal connect',
|
|
109
|
+
IRC: 'natureco irc connect',
|
|
110
|
+
Mattermost:'natureco mattermost connect',
|
|
111
|
+
iMessage: 'natureco imessage connect',
|
|
112
|
+
SMS: 'natureco sms connect',
|
|
113
|
+
Webhooks: 'natureco webhooks connect',
|
|
102
114
|
},
|
|
103
115
|
// Step 5
|
|
104
116
|
gatewayTitle: 'Gateway',
|
|
@@ -360,6 +372,12 @@ async function setup() {
|
|
|
360
372
|
{ name: 'WhatsApp', value: 'WhatsApp' },
|
|
361
373
|
{ name: 'Discord', value: 'Discord' },
|
|
362
374
|
{ name: 'Slack', value: 'Slack' },
|
|
375
|
+
{ name: 'Signal', value: 'Signal' },
|
|
376
|
+
{ name: 'IRC', value: 'IRC' },
|
|
377
|
+
{ name: 'Mattermost', value: 'Mattermost' },
|
|
378
|
+
{ name: 'iMessage', value: 'iMessage' },
|
|
379
|
+
{ name: 'SMS (Twilio)', value: 'SMS' },
|
|
380
|
+
{ name: 'Webhooks', value: 'Webhooks' },
|
|
363
381
|
],
|
|
364
382
|
}]);
|
|
365
383
|
|
|
@@ -425,14 +443,86 @@ async function setup() {
|
|
|
425
443
|
printDone(L, 'Discord');
|
|
426
444
|
}
|
|
427
445
|
|
|
446
|
+
if (integrations.includes('Signal')) {
|
|
447
|
+
console.log('');
|
|
448
|
+
console.log(chalk.cyan(' Signal kurulumu (signal-cli REST API):'));
|
|
449
|
+
const { sigUrl, sigAccount } = await inquirer.prompt([
|
|
450
|
+
{ type: 'input', name: 'sigUrl', message: lang === 'tr' ? ' signal-cli REST API URL (örn: http://localhost:8080):' : ' signal-cli REST API URL (e.g. http://localhost:8080):', validate: v => v.trim() ? true : (lang === 'tr' ? 'Gerekli' : 'Required') },
|
|
451
|
+
{ type: 'input', name: 'sigAccount', message: lang === 'tr' ? ' Signal hesap numarası:' : ' Signal account number:', validate: v => v.trim() ? true : (lang === 'tr' ? 'Gerekli' : 'Required') },
|
|
452
|
+
]);
|
|
453
|
+
const sigBotId = `signal_${Date.now()}`;
|
|
454
|
+
integConfig.signalHttpUrl = sigUrl.trim();
|
|
455
|
+
integConfig.signalAccount = sigAccount.trim();
|
|
456
|
+
integConfig.signalBotId = sigBotId;
|
|
457
|
+
printDone(L, 'Signal');
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
if (integrations.includes('IRC')) {
|
|
461
|
+
console.log('');
|
|
462
|
+
console.log(chalk.cyan(' IRC kurulumu:'));
|
|
463
|
+
const { ircHost, ircPort, ircNick } = await inquirer.prompt([
|
|
464
|
+
{ type: 'input', name: 'ircHost', message: lang === 'tr' ? ' IRC sunucusu (örn: irc.libera.chat):' : ' IRC server (e.g. irc.libera.chat):', validate: v => v.trim() ? true : (lang === 'tr' ? 'Gerekli' : 'Required') },
|
|
465
|
+
{ type: 'input', name: 'ircPort', message: lang === 'tr' ? ' Port:' : ' Port:', default: '6697' },
|
|
466
|
+
{ type: 'input', name: 'ircNick', message: lang === 'tr' ? ' Nick:' : ' Nick:', validate: v => v.trim() ? true : (lang === 'tr' ? 'Gerekli' : 'Required') },
|
|
467
|
+
]);
|
|
468
|
+
integConfig.ircHost = ircHost.trim();
|
|
469
|
+
integConfig.ircPort = parseInt(ircPort) || 6697;
|
|
470
|
+
integConfig.ircNick = ircNick.trim();
|
|
471
|
+
integConfig.ircBotId = `irc_${Date.now()}`;
|
|
472
|
+
printDone(L, 'IRC');
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
if (integrations.includes('Mattermost')) {
|
|
476
|
+
console.log('');
|
|
477
|
+
console.log(chalk.cyan(' Mattermost kurulumu:'));
|
|
478
|
+
const { mmUrl, mmToken } = await inquirer.prompt([
|
|
479
|
+
{ type: 'input', name: 'mmUrl', message: lang === 'tr' ? ' Mattermost sunucu URL:' : ' Mattermost server URL:', validate: v => v.trim() ? true : (lang === 'tr' ? 'Gerekli' : 'Required') },
|
|
480
|
+
{ type: 'password', name: 'mmToken', message: lang === 'tr' ? ' Bot token:' : ' Bot token:', mask: '*', validate: v => v.trim() ? true : (lang === 'tr' ? 'Gerekli' : 'Required') },
|
|
481
|
+
]);
|
|
482
|
+
integConfig.mattermostBaseUrl = mmUrl.trim().replace(/\/$/, '');
|
|
483
|
+
integConfig.mattermostToken = mmToken.trim();
|
|
484
|
+
integConfig.mattermostBotId = `mattermost_${Date.now()}`;
|
|
485
|
+
printDone(L, 'Mattermost');
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
if (integrations.includes('iMessage')) {
|
|
489
|
+
console.log('');
|
|
490
|
+
console.log(chalk.cyan(lang === 'tr' ? ' iMessage (sadece macOS):' : ' iMessage (macOS only):'));
|
|
491
|
+
const { imCliPath } = await inquirer.prompt([{ type: 'input', name: 'imCliPath', message: lang === 'tr' ? ' imsg CLI yolu (opsiyonel):' : ' imsg CLI path (optional):' }]);
|
|
492
|
+
integConfig.imessageCliPath = imCliPath.trim() || '';
|
|
493
|
+
integConfig.imessageBotId = `imessage_${Date.now()}`;
|
|
494
|
+
printDone(L, 'iMessage');
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
if (integrations.includes('SMS')) {
|
|
498
|
+
console.log('');
|
|
499
|
+
console.log(chalk.cyan(' SMS (Twilio) kurulumu:'));
|
|
500
|
+
const { smsSid, smsToken, smsFrom } = await inquirer.prompt([
|
|
501
|
+
{ type: 'input', name: 'smsSid', message: ' Twilio Account SID:', validate: v => v.trim() ? true : 'Required' },
|
|
502
|
+
{ type: 'password', name: 'smsToken', message: ' Twilio Auth Token:', mask: '*', validate: v => v.trim() ? true : 'Required' },
|
|
503
|
+
{ type: 'input', name: 'smsFrom', message: ' Twilio telefon numarası (E.164):', validate: v => v.trim() ? true : 'Required' },
|
|
504
|
+
]);
|
|
505
|
+
integConfig.smsAccountSid = smsSid.trim();
|
|
506
|
+
integConfig.smsAuthToken = smsToken.trim();
|
|
507
|
+
integConfig.smsFromNumber = smsFrom.trim();
|
|
508
|
+
integConfig.smsBotId = `sms_${Date.now()}`;
|
|
509
|
+
printDone(L, 'SMS');
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
if (integrations.includes('Webhooks')) {
|
|
513
|
+
printDone(L, 'Webhooks');
|
|
514
|
+
console.log(chalk.gray(lang === 'tr'
|
|
515
|
+
? ' → Webhook eklemek için: natureco webhooks connect'
|
|
516
|
+
: ' → To add a webhook: natureco webhooks connect'));
|
|
517
|
+
}
|
|
518
|
+
|
|
428
519
|
if (integrations.length > 0) {
|
|
429
|
-
|
|
520
|
+
const subflowChannels = ['Telegram', 'WhatsApp', 'Discord', 'Signal', 'IRC', 'Mattermost', 'iMessage', 'SMS', 'Webhooks'];
|
|
521
|
+
const hasSubflow = subflowChannels.some(ch => integrations.includes(ch));
|
|
522
|
+
if (!hasSubflow) {
|
|
430
523
|
printDone(L, integrations.join(', '));
|
|
431
524
|
}
|
|
432
525
|
console.log('');
|
|
433
|
-
if (integrations.includes('Slack')) {
|
|
434
|
-
console.log(chalk.gray(` → natureco slack connect`));
|
|
435
|
-
}
|
|
436
526
|
} else {
|
|
437
527
|
printDone(L, L.integSkip);
|
|
438
528
|
}
|
|
@@ -460,9 +550,25 @@ async function setup() {
|
|
|
460
550
|
skills: existingConfig.skills || { enabled: true, list: [] },
|
|
461
551
|
mcpServers: existingConfig.mcpServers || {},
|
|
462
552
|
// Entegrasyon config'leri
|
|
463
|
-
...(integConfig.telegramToken
|
|
464
|
-
...(integConfig.telegramChatId
|
|
465
|
-
...(integConfig.discordToken
|
|
553
|
+
...(integConfig.telegramToken && { telegramToken: integConfig.telegramToken }),
|
|
554
|
+
...(integConfig.telegramChatId && { telegramChatId: integConfig.telegramChatId }),
|
|
555
|
+
...(integConfig.discordToken && { discordToken: integConfig.discordToken }),
|
|
556
|
+
...(integConfig.signalHttpUrl && { signalHttpUrl: integConfig.signalHttpUrl }),
|
|
557
|
+
...(integConfig.signalAccount && { signalAccount: integConfig.signalAccount }),
|
|
558
|
+
...(integConfig.signalBotId && { signalBotId: integConfig.signalBotId }),
|
|
559
|
+
...(integConfig.ircHost && { ircHost: integConfig.ircHost }),
|
|
560
|
+
...(integConfig.ircPort && { ircPort: integConfig.ircPort }),
|
|
561
|
+
...(integConfig.ircNick && { ircNick: integConfig.ircNick }),
|
|
562
|
+
...(integConfig.ircBotId && { ircBotId: integConfig.ircBotId }),
|
|
563
|
+
...(integConfig.mattermostBaseUrl && { mattermostBaseUrl: integConfig.mattermostBaseUrl }),
|
|
564
|
+
...(integConfig.mattermostToken && { mattermostToken: integConfig.mattermostToken }),
|
|
565
|
+
...(integConfig.mattermostBotId && { mattermostBotId: integConfig.mattermostBotId }),
|
|
566
|
+
...(integConfig.imessageCliPath && { imessageCliPath: integConfig.imessageCliPath }),
|
|
567
|
+
...(integConfig.imessageBotId && { imessageBotId: integConfig.imessageBotId }),
|
|
568
|
+
...(integConfig.smsAccountSid && { smsAccountSid: integConfig.smsAccountSid }),
|
|
569
|
+
...(integConfig.smsAuthToken && { smsAuthToken: integConfig.smsAuthToken }),
|
|
570
|
+
...(integConfig.smsFromNumber && { smsFromNumber: integConfig.smsFromNumber }),
|
|
571
|
+
...(integConfig.smsBotId && { smsBotId: integConfig.smsBotId }),
|
|
466
572
|
};
|
|
467
573
|
|
|
468
574
|
saveConfig(config);
|