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,18 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const os = require('os');
|
|
3
|
+
|
|
4
|
+
function health(args) {
|
|
5
|
+
console.log(chalk.cyan('\n 🏥 System Health\n'));
|
|
6
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
7
|
+
console.log(` ${chalk.white('Status:')} ${chalk.green('Healthy')}`);
|
|
8
|
+
console.log(` ${chalk.white('Node:')} ${process.version}`);
|
|
9
|
+
console.log(` ${chalk.white('Platform:')} ${process.platform} ${os.release()}`);
|
|
10
|
+
console.log(` ${chalk.white('Uptime:')} ${Math.floor(process.uptime())}s`);
|
|
11
|
+
console.log(` ${chalk.white('Memory:')} ${Math.round(process.memoryUsage().heapUsed / 1024 / 1024)}MB / ${Math.round(process.memoryUsage().heapTotal / 1024 / 1024)}MB`);
|
|
12
|
+
console.log(` ${chalk.white('CPU:')} ${os.cpus()[0]?.model || 'unknown'}`);
|
|
13
|
+
console.log(` ${chalk.white('Load:')} ${os.loadavg()[0].toFixed(2)}`);
|
|
14
|
+
console.log(` ${chalk.white('Host:')} ${os.hostname()}`);
|
|
15
|
+
console.log();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = health;
|
package/src/commands/imessage.js
CHANGED
|
@@ -1,55 +1,169 @@
|
|
|
1
1
|
const chalk = require('chalk');
|
|
2
2
|
const inquirer = require('../utils/inquirer-wrapper');
|
|
3
3
|
const { getConfig, saveConfig } = require('../utils/config');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const { execSync } = require('child_process');
|
|
4
6
|
|
|
5
7
|
async function imessage(action) {
|
|
6
8
|
if (!action || action === 'connect') return connectImessage();
|
|
7
9
|
if (action === 'disconnect') return disconnectImessage();
|
|
8
10
|
if (action === 'status') return statusImessage();
|
|
11
|
+
if (action === 'probe') return probeImessage();
|
|
9
12
|
console.log(chalk.red('\n❌ Unknown action\n'));
|
|
10
|
-
console.log(chalk.gray('Available actions: connect, disconnect, status\n'));
|
|
13
|
+
console.log(chalk.gray('Available actions: connect, disconnect, status, probe\n'));
|
|
11
14
|
process.exit(1);
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
async function connectImessage() {
|
|
15
18
|
const config = getConfig();
|
|
16
|
-
if (!config.providerUrl) {
|
|
19
|
+
if (!config.providerUrl) {
|
|
20
|
+
console.log(chalk.red('\n❌ Setup yapılmamış. Önce "natureco setup" çalıştırın.\n'));
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (process.platform !== 'darwin') {
|
|
25
|
+
console.log(chalk.red('\n❌ iMessage sadece macOS\'te çalışır.\n'));
|
|
26
|
+
console.log(chalk.gray('Mevcut platform:'), chalk.white(process.platform));
|
|
27
|
+
console.log(chalk.gray('Diğer platformlar için SMS (Twilio) kullanılabilir.\n'));
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
|
|
17
31
|
console.log(chalk.yellow('\n⏳ iMessage bağlantısı hazırlanıyor...\n'));
|
|
18
|
-
console.log(chalk.gray('
|
|
19
|
-
|
|
32
|
+
console.log(chalk.gray('Gereken: imsg bridge — https://github.com/mbilker/imsg\n'));
|
|
33
|
+
|
|
34
|
+
const defaults = {
|
|
35
|
+
cliPath: config.imessageCliPath || '',
|
|
36
|
+
service: config.imessageService || 'auto',
|
|
37
|
+
dbPath: config.imessageDbPath || '~/Library/Messages/chat.db',
|
|
38
|
+
dmPolicy: config.imessageDmPolicy || 'pairing',
|
|
39
|
+
};
|
|
40
|
+
|
|
20
41
|
const answers = await inquirer.prompt([
|
|
21
|
-
{ type: 'input', name: 'cliPath', message: 'imsg CLI yolu (
|
|
22
|
-
{ type: '
|
|
42
|
+
{ type: 'input', name: 'cliPath', message: 'imsg CLI yolu (boş = PATH):', default: defaults.cliPath },
|
|
43
|
+
{ type: 'input', name: 'dbPath', message: 'iMessage veritabanı yolu:', default: defaults.dbPath },
|
|
44
|
+
{ type: 'list', name: 'service', message: 'Servis:', default: defaults.service, choices: [
|
|
45
|
+
{ name: 'Auto-detect (önerilen)', value: 'auto' },
|
|
46
|
+
{ name: 'iMessage', value: 'imessage' },
|
|
47
|
+
{ name: 'SMS', value: 'sms' },
|
|
48
|
+
]},
|
|
49
|
+
{ type: 'list', name: 'dmPolicy', message: 'DM politikası:', default: defaults.dmPolicy, choices: [
|
|
50
|
+
{ name: 'Pairing (önerilen)', value: 'pairing' },
|
|
51
|
+
{ name: 'Allowlist', value: 'allowlist' },
|
|
52
|
+
{ name: 'Open', value: 'open' },
|
|
53
|
+
{ name: 'Disabled', value: 'disabled' },
|
|
54
|
+
]},
|
|
23
55
|
]);
|
|
56
|
+
|
|
24
57
|
const botId = `imessage_${Date.now()}`;
|
|
25
58
|
config.imessageCliPath = answers.cliPath.trim() || '';
|
|
59
|
+
config.imessageDbPath = answers.dbPath.trim() || '~/Library/Messages/chat.db';
|
|
60
|
+
config.imessageService = answers.service;
|
|
26
61
|
config.imessageDmPolicy = answers.dmPolicy;
|
|
27
62
|
config.imessageBotId = botId;
|
|
28
63
|
saveConfig(config);
|
|
64
|
+
|
|
29
65
|
console.log(chalk.green('\n✅ iMessage bağlantısı kaydedildi!\n'));
|
|
30
66
|
console.log(chalk.cyan('Bot ID:'), chalk.white(botId));
|
|
31
67
|
if (config.imessageCliPath) console.log(chalk.cyan('CLI Yolu:'), chalk.white(config.imessageCliPath));
|
|
32
|
-
console.log(chalk.
|
|
33
|
-
console.log(chalk.gray('
|
|
68
|
+
console.log(chalk.cyan('Servis:'), chalk.white(answers.service));
|
|
69
|
+
console.log(chalk.gray('\nGateway ile başlatmak için: natureco gateway start\n'));
|
|
34
70
|
}
|
|
35
71
|
|
|
36
72
|
async function disconnectImessage() {
|
|
37
73
|
const config = getConfig();
|
|
38
|
-
if (!config.imessageBotId) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
74
|
+
if (!config.imessageBotId) {
|
|
75
|
+
console.log(chalk.gray('\n⚠️ No iMessage connection found\n'));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const { confirm } = await inquirer.prompt([
|
|
79
|
+
{ type: 'confirm', name: 'confirm', message: 'iMessage bağlantısını kaldırmak istediğinize emin misiniz?', default: false }
|
|
80
|
+
]);
|
|
81
|
+
if (!confirm) {
|
|
82
|
+
console.log(chalk.gray('\nCancelled\n'));
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
delete config.imessageCliPath; delete config.imessageDbPath; delete config.imessageService;
|
|
86
|
+
delete config.imessageDmPolicy; delete config.imessageBotId;
|
|
42
87
|
saveConfig(config);
|
|
43
88
|
console.log(chalk.green('\n✅ iMessage disconnected\n'));
|
|
44
89
|
}
|
|
45
90
|
|
|
46
|
-
function statusImessage() {
|
|
91
|
+
async function statusImessage() {
|
|
47
92
|
const config = getConfig();
|
|
48
|
-
if (!config.imessageBotId) {
|
|
93
|
+
if (!config.imessageBotId) {
|
|
94
|
+
console.log(chalk.gray('\n⚠️ iMessage not connected\n'));
|
|
95
|
+
console.log(chalk.gray('Connect with: natureco imessage connect\n'));
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
49
98
|
console.log(chalk.green('\n✅ iMessage connected\n'));
|
|
50
99
|
console.log(chalk.cyan('Bot ID:'), chalk.white(config.imessageBotId));
|
|
51
100
|
if (config.imessageCliPath) console.log(chalk.cyan('CLI Yolu:'), chalk.white(config.imessageCliPath));
|
|
101
|
+
console.log(chalk.cyan('Servis:'), chalk.white(config.imessageService || 'auto'));
|
|
102
|
+
|
|
103
|
+
if (process.platform === 'darwin') {
|
|
104
|
+
const imsgPath = findImsgBinary(config);
|
|
105
|
+
console.log(chalk.cyan('imsg binary:'), chalk.white(imsgPath || 'Bulunamadı'));
|
|
106
|
+
if (config.imessageDbPath) console.log(chalk.cyan('DB Yolu:'), chalk.white(config.imessageDbPath));
|
|
107
|
+
} else {
|
|
108
|
+
console.log(chalk.yellow('\n⚠️ iMessage sadece macOS\'te çalışır'));
|
|
109
|
+
}
|
|
110
|
+
|
|
52
111
|
console.log(chalk.gray('\nDisconnect with: natureco imessage disconnect\n'));
|
|
53
112
|
}
|
|
54
113
|
|
|
114
|
+
async function probeImessage() {
|
|
115
|
+
const config = getConfig();
|
|
116
|
+
if (!config.imessageBotId) {
|
|
117
|
+
console.log(chalk.red('\n❌ iMessage bağlantısı yapılmamış\n'));
|
|
118
|
+
console.log(chalk.gray('Önce: natureco imessage connect\n'));
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (process.platform !== 'darwin') {
|
|
123
|
+
console.log(chalk.red('\n❌ iMessage sadece macOS\'te kullanılabilir.\n'));
|
|
124
|
+
process.exit(1);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
console.log(chalk.yellow('\n⏳ iMessage problanıyor...\n'));
|
|
128
|
+
|
|
129
|
+
const imsgPath = findImsgBinary(config);
|
|
130
|
+
if (!imsgPath) {
|
|
131
|
+
console.log(chalk.red('✗ imsg binary bulunamadı\n'));
|
|
132
|
+
console.log(chalk.gray('Kurulum: brew install mbilker/imsg/imsg'));
|
|
133
|
+
console.log(chalk.gray('Veya: https://github.com/mbilker/imsg\n'));
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
|
136
|
+
console.log(chalk.green(`✓ imsg found: ${imsgPath}`));
|
|
137
|
+
|
|
138
|
+
// Check DB
|
|
139
|
+
const dbPath = (config.imessageDbPath || '~/Library/Messages/chat.db').replace(/^~/, require('os').homedir());
|
|
140
|
+
if (fs.existsSync(dbPath)) {
|
|
141
|
+
console.log(chalk.green(`✓ iMessage DB: ${dbPath}`));
|
|
142
|
+
} else {
|
|
143
|
+
console.log(chalk.yellow(`⚠️ iMessage DB bulunamadı: ${dbPath}`));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Try to send a test message (dry run)
|
|
147
|
+
try {
|
|
148
|
+
const result = execSync(`"${imsgPath}" --help 2>&1`, { encoding: 'utf-8', timeout: 5000 });
|
|
149
|
+
console.log(chalk.gray(`\nimsg version: ${result.split('\n')[0]}`));
|
|
150
|
+
} catch {
|
|
151
|
+
console.log(chalk.yellow('⚠️ imsg çalıştırılamadı'));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
console.log('');
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function findImsgBinary(config) {
|
|
158
|
+
if (config.imessageCliPath && fs.existsSync(config.imessageCliPath)) {
|
|
159
|
+
return config.imessageCliPath;
|
|
160
|
+
}
|
|
161
|
+
try {
|
|
162
|
+
const which = execSync('which imsg 2>/dev/null || echo ""', { encoding: 'utf-8', timeout: 5000 });
|
|
163
|
+
const p = which.trim();
|
|
164
|
+
if (p && fs.existsSync(p)) return p;
|
|
165
|
+
} catch {}
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
|
|
55
169
|
module.exports = imessage;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const { getConfig } = require('../utils/config');
|
|
3
|
+
|
|
4
|
+
function infer(args) {
|
|
5
|
+
const [action, ...params] = args || [];
|
|
6
|
+
|
|
7
|
+
if (!action || action === 'models') return inferModels();
|
|
8
|
+
if (action === 'media') return inferMedia();
|
|
9
|
+
if (action === 'capabilities') return inferCapabilities();
|
|
10
|
+
|
|
11
|
+
console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
|
|
12
|
+
console.log(chalk.gray(' Kullanım: natureco infer [models|media|capabilities]\n'));
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function inferModels() {
|
|
17
|
+
const config = getConfig();
|
|
18
|
+
console.log(chalk.cyan('\n 🔍 Inferring models...\n'));
|
|
19
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
20
|
+
|
|
21
|
+
const providers = ['openai', 'anthropic', 'groq', 'deepseek', 'xai'];
|
|
22
|
+
for (const p of providers) {
|
|
23
|
+
const key = config[`${p}ApiKey`] || process.env[`${p.toUpperCase()}_API_KEY`];
|
|
24
|
+
const status = key ? chalk.green('API key found') : chalk.gray('not configured');
|
|
25
|
+
console.log(` ${chalk.white(p)}: ${status}`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
console.log(chalk.gray('\n For full model listing: ') + chalk.cyan('natureco models list\n'));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function inferMedia() {
|
|
32
|
+
const config = getConfig();
|
|
33
|
+
console.log(chalk.cyan('\n 🔍 Inferring media capabilities...\n'));
|
|
34
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
35
|
+
|
|
36
|
+
const checks = [
|
|
37
|
+
{ name: 'Image Generation', key: 'openaiApiKey', provider: 'OpenAI / FAL / Together' },
|
|
38
|
+
{ name: 'Video Generation', key: 'runwayApiKey', provider: 'Runway / DeepInfra' },
|
|
39
|
+
{ name: 'Music Generation', key: 'sunoApiKey', provider: 'Suno / Udio / ElevenLabs' },
|
|
40
|
+
{ name: 'Speech-to-Text', key: 'openaiApiKey', provider: 'OpenAI Whisper / Deepgram' },
|
|
41
|
+
{ name: 'Text-to-Speech', key: 'elevenlabsApiKey', provider: 'ElevenLabs / OpenAI' },
|
|
42
|
+
{ name: 'Audio Understanding', key: 'openaiApiKey', provider: 'OpenAI / Deepgram' }
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
for (const c of checks) {
|
|
46
|
+
const key = config[c.key] || process.env[c.key.replace(/([a-z])([A-Z])/g, '$1_$2').toUpperCase()];
|
|
47
|
+
const status = key ? chalk.green('available') : chalk.gray('not configured');
|
|
48
|
+
console.log(` ${chalk.white(c.name)}: ${status} ${chalk.gray(`(${c.provider})`)}`);
|
|
49
|
+
}
|
|
50
|
+
console.log();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function inferCapabilities() {
|
|
54
|
+
const config = getConfig();
|
|
55
|
+
console.log(chalk.cyan('\n 🔍 Provider capabilities...\n'));
|
|
56
|
+
|
|
57
|
+
const cap = [
|
|
58
|
+
{ name: 'Chat', needs: ['openaiApiKey', 'anthropicApiKey'] },
|
|
59
|
+
{ name: 'Vision', needs: ['openaiApiKey', 'anthropicApiKey'] },
|
|
60
|
+
{ name: 'Embeddings', needs: ['openaiApiKey'] },
|
|
61
|
+
{ name: 'Web Search', needs: ['tavilyApiKey'] },
|
|
62
|
+
{ name: 'Image Gen', needs: ['openaiApiKey', 'falApiKey'] },
|
|
63
|
+
{ name: 'TTS', needs: ['elevenlabsApiKey', 'openaiApiKey'] }
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
for (const c of cap) {
|
|
67
|
+
const ok = c.needs.some(k => config[k] || process.env[k.replace(/([a-z])([A-Z])/g, '$1_$2').toUpperCase()]);
|
|
68
|
+
console.log(` ${ok ? chalk.green('●') : chalk.gray('○')} ${chalk.white(c.name)}`);
|
|
69
|
+
}
|
|
70
|
+
console.log();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
module.exports = infer;
|
package/src/commands/irc.js
CHANGED
|
@@ -13,29 +13,60 @@ async function irc(action) {
|
|
|
13
13
|
|
|
14
14
|
async function connectIrc() {
|
|
15
15
|
const config = getConfig();
|
|
16
|
-
if (!config.providerUrl) {
|
|
16
|
+
if (!config.providerUrl) {
|
|
17
|
+
console.log(chalk.red('\n❌ Setup yapılmamış. Önce "natureco setup" çalıştırın.\n'));
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
17
20
|
console.log(chalk.yellow('\n⏳ IRC bağlantısı hazırlanıyor...\n'));
|
|
21
|
+
|
|
22
|
+
const defaults = {
|
|
23
|
+
host: config.ircHost || '',
|
|
24
|
+
port: config.ircPort || 6697,
|
|
25
|
+
tls: config.ircTls !== undefined ? config.ircTls : true,
|
|
26
|
+
nick: config.ircNick || '',
|
|
27
|
+
username: config.ircUsername || '',
|
|
28
|
+
realname: config.ircRealname || '',
|
|
29
|
+
password: config.ircPassword || '',
|
|
30
|
+
channels: config.ircChannels || [],
|
|
31
|
+
dmPolicy: config.ircDmPolicy || 'pairing',
|
|
32
|
+
nickservEnabled: config.ircNickservEnabled !== undefined ? config.ircNickservEnabled : true,
|
|
33
|
+
nickservPassword: config.ircNickservPassword || '',
|
|
34
|
+
};
|
|
35
|
+
|
|
18
36
|
const answers = await inquirer.prompt([
|
|
19
|
-
{ type: 'input', name: 'host', message: 'IRC sunucusu
|
|
20
|
-
{ type: 'input', name: 'port', message: 'Port:', default: '
|
|
21
|
-
{ type: 'confirm', name: 'tls', message: 'TLS kullanılsın mı?', default:
|
|
22
|
-
{ type: 'input', name: 'nick', message: 'Nick:', validate: v => v.trim() ? true : 'Gerekli' },
|
|
23
|
-
{ type: 'input', name: 'username', message: 'Kullanıcı adı (opsiyonel):' },
|
|
24
|
-
{ type: '
|
|
25
|
-
{ type: '
|
|
26
|
-
{ type: '
|
|
37
|
+
{ type: 'input', name: 'host', message: 'IRC sunucusu:', default: defaults.host, validate: v => v.trim() ? true : 'Gerekli' },
|
|
38
|
+
{ type: 'input', name: 'port', message: 'Port:', default: String(defaults.port), validate: v => { const n = parseInt(v); return n > 0 && n < 65536 ? true : '1-65535 arası' } },
|
|
39
|
+
{ type: 'confirm', name: 'tls', message: 'TLS kullanılsın mı?', default: defaults.tls },
|
|
40
|
+
{ type: 'input', name: 'nick', message: 'Nick:', default: defaults.nick, validate: v => v.trim() ? true : 'Gerekli' },
|
|
41
|
+
{ type: 'input', name: 'username', message: 'Kullanıcı adı (opsiyonel):', default: defaults.username || defaults.nick },
|
|
42
|
+
{ type: 'input', name: 'realname', message: 'Gerçek ad (opsiyonel):', default: defaults.realname || 'NatureCo' },
|
|
43
|
+
{ type: 'password', name: 'password', message: 'Sunucu parolası (opsiyonel):' },
|
|
44
|
+
{ type: 'input', name: 'channels', message: 'Kanallar (virgülle ayırın):', default: defaults.channels.join(',') },
|
|
45
|
+
{ type: 'confirm', name: 'nickservEnabled', message: 'NickServ kullanılsın mı?', default: defaults.nickservEnabled },
|
|
46
|
+
{ type: 'password', name: 'nickservPassword', message: 'NickServ parolası (opsiyonel):' },
|
|
47
|
+
{ type: 'list', name: 'dmPolicy', message: 'DM politikası:', default: defaults.dmPolicy, choices: [
|
|
48
|
+
{ name: 'Pairing (önerilen)', value: 'pairing' },
|
|
49
|
+
{ name: 'Allowlist', value: 'allowlist' },
|
|
50
|
+
{ name: 'Open', value: 'open' },
|
|
51
|
+
{ name: 'Disabled', value: 'disabled' },
|
|
52
|
+
]},
|
|
27
53
|
]);
|
|
54
|
+
|
|
28
55
|
const botId = `irc_${Date.now()}`;
|
|
29
56
|
config.ircHost = answers.host.trim();
|
|
30
|
-
config.ircPort = parseInt(answers.port)
|
|
57
|
+
config.ircPort = parseInt(answers.port);
|
|
31
58
|
config.ircTls = answers.tls;
|
|
32
59
|
config.ircNick = answers.nick.trim();
|
|
33
60
|
config.ircUsername = answers.username.trim() || answers.nick.trim();
|
|
61
|
+
config.ircRealname = answers.realname.trim() || 'NatureCo';
|
|
34
62
|
config.ircPassword = answers.password || '';
|
|
35
63
|
config.ircChannels = answers.channels ? answers.channels.split(',').map(c => c.trim()).filter(Boolean) : [];
|
|
64
|
+
config.ircNickservEnabled = answers.nickservEnabled;
|
|
65
|
+
config.ircNickservPassword = answers.nickservPassword || '';
|
|
36
66
|
config.ircDmPolicy = answers.dmPolicy;
|
|
37
67
|
config.ircBotId = botId;
|
|
38
68
|
saveConfig(config);
|
|
69
|
+
|
|
39
70
|
console.log(chalk.green('\n✅ IRC bağlantısı kaydedildi!\n'));
|
|
40
71
|
console.log(chalk.cyan('Bot ID:'), chalk.white(botId));
|
|
41
72
|
console.log(chalk.cyan('Sunucu:'), chalk.white(`${answers.host.trim()}:${answers.port}`));
|
|
@@ -46,11 +77,20 @@ async function connectIrc() {
|
|
|
46
77
|
|
|
47
78
|
async function disconnectIrc() {
|
|
48
79
|
const config = getConfig();
|
|
49
|
-
if (!config.ircBotId) {
|
|
50
|
-
|
|
51
|
-
|
|
80
|
+
if (!config.ircBotId) {
|
|
81
|
+
console.log(chalk.gray('\n⚠️ No IRC connection found\n'));
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const { confirm } = await inquirer.prompt([
|
|
85
|
+
{ type: 'confirm', name: 'confirm', message: 'IRC bağlantısını kaldırmak istediğinize emin misiniz?', default: false }
|
|
86
|
+
]);
|
|
87
|
+
if (!confirm) {
|
|
88
|
+
console.log(chalk.gray('\nCancelled\n'));
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
52
91
|
delete config.ircHost; delete config.ircPort; delete config.ircTls; delete config.ircNick;
|
|
53
|
-
delete config.ircUsername; delete config.
|
|
92
|
+
delete config.ircUsername; delete config.ircRealname; delete config.ircPassword;
|
|
93
|
+
delete config.ircChannels; delete config.ircNickservEnabled; delete config.ircNickservPassword;
|
|
54
94
|
delete config.ircDmPolicy; delete config.ircBotId;
|
|
55
95
|
saveConfig(config);
|
|
56
96
|
console.log(chalk.green('\n✅ IRC disconnected\n'));
|
|
@@ -58,12 +98,21 @@ async function disconnectIrc() {
|
|
|
58
98
|
|
|
59
99
|
function statusIrc() {
|
|
60
100
|
const config = getConfig();
|
|
61
|
-
if (!config.ircBotId) {
|
|
101
|
+
if (!config.ircBotId) {
|
|
102
|
+
console.log(chalk.gray('\n⚠️ IRC not connected\n'));
|
|
103
|
+
console.log(chalk.gray('Connect with: natureco irc connect\n'));
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
62
106
|
console.log(chalk.green('\n✅ IRC connected\n'));
|
|
63
107
|
console.log(chalk.cyan('Bot ID:'), chalk.white(config.ircBotId));
|
|
64
108
|
console.log(chalk.cyan('Sunucu:'), chalk.white(`${config.ircHost}:${config.ircPort}`));
|
|
109
|
+
console.log(chalk.cyan('TLS:'), chalk.white(config.ircTls ? 'Evet' : 'Hayır'));
|
|
65
110
|
console.log(chalk.cyan('Nick:'), chalk.white(config.ircNick));
|
|
111
|
+
console.log(chalk.cyan('Kullanıcı:'), chalk.white(config.ircUsername));
|
|
112
|
+
if (config.ircRealname) console.log(chalk.cyan('Realname:'), chalk.white(config.ircRealname));
|
|
66
113
|
if (config.ircChannels?.length) console.log(chalk.cyan('Kanallar:'), chalk.white(config.ircChannels.join(', ')));
|
|
114
|
+
console.log(chalk.cyan('NickServ:'), chalk.white(config.ircNickservEnabled ? 'Evet' : 'Hayır'));
|
|
115
|
+
console.log(chalk.cyan('DM Politikası:'), chalk.white(config.ircDmPolicy || 'pairing'));
|
|
67
116
|
console.log(chalk.gray('\nDisconnect with: natureco irc disconnect\n'));
|
|
68
117
|
}
|
|
69
118
|
|
|
@@ -6,57 +6,159 @@ async function mattermost(action) {
|
|
|
6
6
|
if (!action || action === 'connect') return connectMattermost();
|
|
7
7
|
if (action === 'disconnect') return disconnectMattermost();
|
|
8
8
|
if (action === 'status') return statusMattermost();
|
|
9
|
+
if (action === 'probe') return probeMattermost();
|
|
9
10
|
console.log(chalk.red('\n❌ Unknown action\n'));
|
|
10
|
-
console.log(chalk.gray('Available actions: connect, disconnect, status\n'));
|
|
11
|
+
console.log(chalk.gray('Available actions: connect, disconnect, status, probe\n'));
|
|
11
12
|
process.exit(1);
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
async function connectMattermost() {
|
|
15
16
|
const config = getConfig();
|
|
16
|
-
if (!config.providerUrl) {
|
|
17
|
+
if (!config.providerUrl) {
|
|
18
|
+
console.log(chalk.red('\n❌ Setup yapılmamış. Önce "natureco setup" çalıştırın.\n'));
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
17
21
|
console.log(chalk.yellow('\n⏳ Mattermost bağlantısı hazırlanıyor...\n'));
|
|
18
22
|
console.log(chalk.gray('Mattermost bot token almak için:'));
|
|
19
23
|
console.log(chalk.gray('1. Mattermost > System Console > Bot Accounts'));
|
|
20
24
|
console.log(chalk.gray('2. Bot oluşturun veya mevcut botu kullanın'));
|
|
21
25
|
console.log(chalk.gray('3. Access Token oluşturun\n'));
|
|
26
|
+
|
|
27
|
+
const defaults = {
|
|
28
|
+
baseUrl: config.mattermostBaseUrl || '',
|
|
29
|
+
token: config.mattermostToken || '',
|
|
30
|
+
dmPolicy: config.mattermostDmPolicy || 'pairing',
|
|
31
|
+
};
|
|
32
|
+
|
|
22
33
|
const answers = await inquirer.prompt([
|
|
23
|
-
{ type: 'input', name: 'baseUrl', message: 'Mattermost sunucu URL
|
|
24
|
-
{ type: 'input', name: 'token', message: 'Bot token:', validate: v => v.trim() ? true : 'Gerekli' },
|
|
25
|
-
{ type: '
|
|
34
|
+
{ type: 'input', name: 'baseUrl', message: 'Mattermost sunucu URL:', default: defaults.baseUrl, validate: v => v.trim() ? true : 'Gerekli' },
|
|
35
|
+
{ type: 'input', name: 'token', message: 'Bot token:', default: defaults.token ? defaults.token.slice(0, 10) + '...' : '', validate: v => v.trim() ? true : 'Gerekli' },
|
|
36
|
+
{ type: 'confirm', name: 'enableSlash', message: 'Slash komutları kaydedilsin mi?', default: config.mattermostSlashEnabled !== false },
|
|
37
|
+
{ type: 'list', name: 'dmPolicy', message: 'DM politikası:', default: defaults.dmPolicy, choices: [
|
|
38
|
+
{ name: 'Pairing (önerilen)', value: 'pairing' },
|
|
39
|
+
{ name: 'Allowlist', value: 'allowlist' },
|
|
40
|
+
{ name: 'Open', value: 'open' },
|
|
41
|
+
{ name: 'Disabled', value: 'disabled' },
|
|
42
|
+
]},
|
|
26
43
|
]);
|
|
44
|
+
|
|
27
45
|
const botId = `mattermost_${Date.now()}`;
|
|
28
|
-
config.mattermostBaseUrl = answers.baseUrl.trim().replace(
|
|
46
|
+
config.mattermostBaseUrl = answers.baseUrl.trim().replace(/\/+$/, '');
|
|
29
47
|
config.mattermostToken = answers.token.trim();
|
|
48
|
+
config.mattermostSlashEnabled = answers.enableSlash;
|
|
30
49
|
config.mattermostDmPolicy = answers.dmPolicy;
|
|
31
50
|
config.mattermostBotId = botId;
|
|
32
51
|
saveConfig(config);
|
|
52
|
+
|
|
33
53
|
console.log(chalk.green('\n✅ Mattermost bağlantısı kaydedildi!\n'));
|
|
34
54
|
console.log(chalk.cyan('Bot ID:'), chalk.white(botId));
|
|
35
55
|
console.log(chalk.cyan('Sunucu:'), chalk.white(config.mattermostBaseUrl));
|
|
36
|
-
console.log(chalk.cyan('Token:'), chalk.white(answers.token.slice(0, 20) + '...'));
|
|
56
|
+
console.log(chalk.cyan('Token:'), chalk.white((answers.token || '').slice(0, 20) + '...'));
|
|
37
57
|
console.log(chalk.gray('\nGateway ile başlatmak için: natureco gateway start\n'));
|
|
38
58
|
}
|
|
39
59
|
|
|
40
60
|
async function disconnectMattermost() {
|
|
41
61
|
const config = getConfig();
|
|
42
|
-
if (!config.mattermostBotId) {
|
|
43
|
-
|
|
44
|
-
|
|
62
|
+
if (!config.mattermostBotId) {
|
|
63
|
+
console.log(chalk.gray('\n⚠️ No Mattermost connection found\n'));
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const { confirm } = await inquirer.prompt([
|
|
67
|
+
{ type: 'confirm', name: 'confirm', message: 'Mattermost bağlantısını kaldırmak istediğinize emin misiniz?', default: false }
|
|
68
|
+
]);
|
|
69
|
+
if (!confirm) {
|
|
70
|
+
console.log(chalk.gray('\nCancelled\n'));
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
45
73
|
delete config.mattermostBaseUrl; delete config.mattermostToken;
|
|
46
|
-
delete config.
|
|
74
|
+
delete config.mattermostSlashEnabled; delete config.mattermostDmPolicy;
|
|
75
|
+
delete config.mattermostBotId;
|
|
47
76
|
saveConfig(config);
|
|
48
77
|
console.log(chalk.green('\n✅ Mattermost disconnected\n'));
|
|
49
78
|
}
|
|
50
79
|
|
|
51
80
|
function statusMattermost() {
|
|
52
81
|
const config = getConfig();
|
|
53
|
-
if (!config.mattermostBotId) {
|
|
82
|
+
if (!config.mattermostBotId) {
|
|
83
|
+
console.log(chalk.gray('\n⚠️ Mattermost not connected\n'));
|
|
84
|
+
console.log(chalk.gray('Connect with: natureco mattermost connect\n'));
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
54
87
|
console.log(chalk.green('\n✅ Mattermost connected\n'));
|
|
55
88
|
console.log(chalk.cyan('Bot ID:'), chalk.white(config.mattermostBotId));
|
|
56
89
|
console.log(chalk.cyan('Sunucu:'), chalk.white(config.mattermostBaseUrl));
|
|
57
90
|
console.log(chalk.cyan('Token:'), chalk.white((config.mattermostToken || '').slice(0, 20) + '...'));
|
|
91
|
+
console.log(chalk.cyan('Slash Komutları:'), chalk.white(config.mattermostSlashEnabled !== false ? 'Aktif' : 'Devre Dışı'));
|
|
58
92
|
console.log(chalk.cyan('DM Politikası:'), chalk.white(config.mattermostDmPolicy || 'pairing'));
|
|
93
|
+
|
|
94
|
+
// Optionally probe
|
|
95
|
+
if (config.mattermostBaseUrl && config.mattermostToken) {
|
|
96
|
+
console.log(chalk.gray('\nProbe için: natureco mattermost probe\n'));
|
|
97
|
+
}
|
|
59
98
|
console.log(chalk.gray('\nDisconnect with: natureco mattermost disconnect\n'));
|
|
60
99
|
}
|
|
61
100
|
|
|
101
|
+
async function probeMattermost() {
|
|
102
|
+
const config = getConfig();
|
|
103
|
+
if (!config.mattermostBaseUrl || !config.mattermostToken) {
|
|
104
|
+
console.log(chalk.red('\n❌ Mattermost bağlantısı yapılmamış\n'));
|
|
105
|
+
console.log(chalk.gray('Önce: natureco mattermost connect\n'));
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const baseUrl = config.mattermostBaseUrl.replace(/\/+$/, '');
|
|
110
|
+
const token = config.mattermostToken;
|
|
111
|
+
|
|
112
|
+
console.log(chalk.yellow(`\n⏳ Problanıyor: ${baseUrl}\n`));
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
const res = await fetch(`${baseUrl}/api/v4/users/me`, {
|
|
116
|
+
headers: { 'Authorization': `Bearer ${token}` },
|
|
117
|
+
signal: AbortSignal.timeout(10000),
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
if (!res.ok) {
|
|
121
|
+
console.log(chalk.red(`✗ API Hatası: HTTP ${res.status}`));
|
|
122
|
+
if (res.status === 401) console.log(chalk.gray(' Token geçersiz. Yeni bir bot token alın.'));
|
|
123
|
+
if (res.status === 403) console.log(chalk.gray(' Botun yetkisi yetersiz.'));
|
|
124
|
+
process.exit(1);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const me = await res.json();
|
|
128
|
+
console.log(chalk.green('✓ API Bağlantısı Başarılı\n'));
|
|
129
|
+
console.log(chalk.cyan('Bot Kullanıcı ID:'), chalk.white(me.id));
|
|
130
|
+
console.log(chalk.cyan('Kullanıcı Adı:'), chalk.white(me.username));
|
|
131
|
+
console.log(chalk.cyan('E-posta:'), chalk.white(me.email));
|
|
132
|
+
console.log(chalk.cyan('Rol:'), chalk.white(me.roles));
|
|
133
|
+
|
|
134
|
+
// Check WebSocket
|
|
135
|
+
const wsUrl = baseUrl.replace(/^http/, 'ws') + '/api/v4/websocket';
|
|
136
|
+
console.log(chalk.gray(`\nWebSocket: ${wsUrl}`));
|
|
137
|
+
|
|
138
|
+
// Check slash commands
|
|
139
|
+
try {
|
|
140
|
+
const teamsRes = await fetch(`${baseUrl}/api/v4/users/me/teams`, {
|
|
141
|
+
headers: { 'Authorization': `Bearer ${token}` },
|
|
142
|
+
signal: AbortSignal.timeout(5000),
|
|
143
|
+
});
|
|
144
|
+
if (teamsRes.ok) {
|
|
145
|
+
const teams = await teamsRes.json();
|
|
146
|
+
console.log(chalk.gray(`\nTakımlar (${teams.length}):`));
|
|
147
|
+
for (const team of teams.slice(0, 5)) {
|
|
148
|
+
console.log(chalk.gray(` - ${team.display_name} (${team.name})`));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
} catch {}
|
|
152
|
+
|
|
153
|
+
console.log('');
|
|
154
|
+
|
|
155
|
+
} catch (err) {
|
|
156
|
+
console.log(chalk.red(`\n✗ Probe hatası: ${err.message}\n`));
|
|
157
|
+
if (err.message.includes('ENOTFOUND') || err.message.includes('ECONNREFUSED')) {
|
|
158
|
+
console.log(chalk.gray('Sunucuya erişilemiyor. URL\'yi kontrol edin.\n'));
|
|
159
|
+
}
|
|
160
|
+
process.exit(1);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
62
164
|
module.exports = mattermost;
|