natureco-cli 1.0.15 → 1.0.17
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/package.json +1 -1
- package/src/commands/dashboard.js +17 -6
- package/src/commands/doctor.js +71 -54
package/package.json
CHANGED
|
@@ -72,6 +72,8 @@ function startDashboard() {
|
|
|
72
72
|
apiKey: config.apiKey,
|
|
73
73
|
defaultBot: config.defaultBot,
|
|
74
74
|
defaultBotId: config.defaultBotId,
|
|
75
|
+
skills: config.skills || { enabled: true, list: [] },
|
|
76
|
+
mcpServers: config.mcpServers || {},
|
|
75
77
|
}));
|
|
76
78
|
} else {
|
|
77
79
|
res.writeHead(404);
|
|
@@ -602,16 +604,18 @@ function getHTML(config) {
|
|
|
602
604
|
document.getElementById('send-btn').disabled = true;
|
|
603
605
|
|
|
604
606
|
try {
|
|
605
|
-
const response = await fetch(
|
|
607
|
+
const response = await fetch('https://api.natureco.me/api/agent/chat', {
|
|
606
608
|
method: 'POST',
|
|
607
609
|
headers: {
|
|
608
610
|
'Authorization': 'Bearer ' + apiKey,
|
|
609
611
|
'Content-Type': 'application/json',
|
|
612
|
+
'X-User-ID': 'dashboard-user',
|
|
610
613
|
},
|
|
611
614
|
body: JSON.stringify({
|
|
612
|
-
|
|
615
|
+
agent_id: currentBotId,
|
|
613
616
|
message: message,
|
|
614
|
-
|
|
617
|
+
platform: 'dashboard',
|
|
618
|
+
user_id: 'dashboard-user',
|
|
615
619
|
}),
|
|
616
620
|
});
|
|
617
621
|
|
|
@@ -660,9 +664,16 @@ function getHTML(config) {
|
|
|
660
664
|
// Load skills count
|
|
661
665
|
try {
|
|
662
666
|
const config = await fetch('/config').then(r => r.json());
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
667
|
+
|
|
668
|
+
// Skills count
|
|
669
|
+
const skillsCount = config.skills && config.skills.list ? config.skills.list.length : 0;
|
|
670
|
+
document.getElementById('skills-count').textContent = 'Skills: ' + skillsCount;
|
|
671
|
+
|
|
672
|
+
// MCP count
|
|
673
|
+
const mcpCount = config.mcpServers ? Object.keys(config.mcpServers).length : 0;
|
|
674
|
+
document.getElementById('mcp-count').textContent = 'MCP: ' + mcpCount;
|
|
675
|
+
|
|
676
|
+
// Sessions count (placeholder)
|
|
666
677
|
document.getElementById('sessions-count').textContent = 'Sessions: 0';
|
|
667
678
|
} catch (err) {
|
|
668
679
|
console.error('Failed to load stats:', err);
|
package/src/commands/doctor.js
CHANGED
|
@@ -4,6 +4,7 @@ const path = require('path');
|
|
|
4
4
|
const net = require('net');
|
|
5
5
|
const { getConfig, saveConfig, CONFIG_FILE, CONFIG_DIR } = require('../utils/config');
|
|
6
6
|
const { getBots } = require('../utils/api');
|
|
7
|
+
const { getSkills } = require('../utils/skills');
|
|
7
8
|
|
|
8
9
|
async function doctor(options) {
|
|
9
10
|
const shouldFix = options && (options.includes('--fix') || options.includes('-f'));
|
|
@@ -13,14 +14,18 @@ async function doctor(options) {
|
|
|
13
14
|
const results = [];
|
|
14
15
|
let passed = 0;
|
|
15
16
|
let total = 0;
|
|
17
|
+
let criticalPassed = 0;
|
|
18
|
+
let criticalTotal = 0;
|
|
16
19
|
|
|
17
20
|
// 1. Node.js versiyon kontrolü
|
|
18
21
|
total++;
|
|
22
|
+
criticalTotal++;
|
|
19
23
|
const nodeVersion = process.version;
|
|
20
24
|
const nodeMajor = parseInt(nodeVersion.slice(1).split('.')[0]);
|
|
21
25
|
if (nodeMajor >= 18) {
|
|
22
26
|
console.log(chalk.green('✅ Node.js versiyonu:'), chalk.white(nodeVersion));
|
|
23
27
|
passed++;
|
|
28
|
+
criticalPassed++;
|
|
24
29
|
results.push({ status: 'ok', message: 'Node.js 18+' });
|
|
25
30
|
} else {
|
|
26
31
|
console.log(chalk.red('❌ Node.js versiyonu:'), chalk.white(nodeVersion), chalk.gray('(18+ gerekli)'));
|
|
@@ -29,6 +34,7 @@ async function doctor(options) {
|
|
|
29
34
|
|
|
30
35
|
// 2. Config dosyası kontrolü
|
|
31
36
|
total++;
|
|
37
|
+
criticalTotal++;
|
|
32
38
|
let config = null;
|
|
33
39
|
if (fs.existsSync(CONFIG_FILE)) {
|
|
34
40
|
try {
|
|
@@ -36,6 +42,7 @@ async function doctor(options) {
|
|
|
36
42
|
config = JSON.parse(data);
|
|
37
43
|
console.log(chalk.green('✅ Config dosyası:'), chalk.white(CONFIG_FILE));
|
|
38
44
|
passed++;
|
|
45
|
+
criticalPassed++;
|
|
39
46
|
results.push({ status: 'ok', message: 'Config dosyası geçerli' });
|
|
40
47
|
} catch (err) {
|
|
41
48
|
console.log(chalk.red('❌ Config dosyası:'), chalk.white('Bozuk JSON'));
|
|
@@ -65,6 +72,7 @@ async function doctor(options) {
|
|
|
65
72
|
|
|
66
73
|
// 3. API key kontrolü
|
|
67
74
|
total++;
|
|
75
|
+
criticalTotal++;
|
|
68
76
|
let apiKeyValid = false;
|
|
69
77
|
if (config && config.apiKey) {
|
|
70
78
|
try {
|
|
@@ -75,6 +83,7 @@ async function doctor(options) {
|
|
|
75
83
|
if (response.ok) {
|
|
76
84
|
console.log(chalk.green('✅ API key:'), chalk.white(config.apiKey.slice(0, 8) + '...'));
|
|
77
85
|
passed++;
|
|
86
|
+
criticalPassed++;
|
|
78
87
|
apiKeyValid = true;
|
|
79
88
|
results.push({ status: 'ok', message: 'API key geçerli' });
|
|
80
89
|
} else {
|
|
@@ -108,20 +117,21 @@ async function doctor(options) {
|
|
|
108
117
|
|
|
109
118
|
// 5. Skills kontrolü
|
|
110
119
|
total++;
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
120
|
+
try {
|
|
121
|
+
const skills = getSkills();
|
|
122
|
+
const skillCount = skills.length;
|
|
123
|
+
|
|
124
|
+
if (skillCount > 0) {
|
|
125
|
+
console.log(chalk.green('✅ Skills:'), chalk.white(`${skillCount} yüklü`));
|
|
126
|
+
passed++;
|
|
127
|
+
results.push({ status: 'ok', message: `${skillCount} skill yüklü` });
|
|
128
|
+
} else {
|
|
129
|
+
console.log(chalk.yellow('⚠️ Skills:'), chalk.white('Yüklü skill yok'));
|
|
130
|
+
results.push({ status: 'warning', message: 'Skill yok', fix: 'Yerleşik skill\'ler yüklenebilir' });
|
|
131
|
+
}
|
|
132
|
+
} catch (err) {
|
|
133
|
+
console.log(chalk.yellow('⚠️ Skills:'), chalk.white('Kontrol edilemedi'));
|
|
134
|
+
results.push({ status: 'warning', message: 'Skills kontrol edilemedi' });
|
|
125
135
|
}
|
|
126
136
|
|
|
127
137
|
// 6. MCP sunucuları kontrolü
|
|
@@ -138,70 +148,75 @@ async function doctor(options) {
|
|
|
138
148
|
|
|
139
149
|
// 7. Hafıza kontrolü
|
|
140
150
|
total++;
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
151
|
+
const memoryDir = path.join(CONFIG_DIR, 'memory');
|
|
152
|
+
let memoryActive = false;
|
|
153
|
+
|
|
154
|
+
if (fs.existsSync(memoryDir)) {
|
|
155
|
+
try {
|
|
156
|
+
const files = fs.readdirSync(memoryDir);
|
|
157
|
+
const memoryFiles = files.filter(f => f.endsWith('.json'));
|
|
158
|
+
if (memoryFiles.length > 0) {
|
|
159
|
+
memoryActive = true;
|
|
160
|
+
console.log(chalk.green('✅ Hafıza:'), chalk.white(`Aktif (${memoryFiles.length} dosya)`));
|
|
161
|
+
passed++;
|
|
162
|
+
results.push({ status: 'ok', message: `Hafıza aktif (${memoryFiles.length} dosya)` });
|
|
163
|
+
} else {
|
|
164
|
+
console.log(chalk.yellow('⚠️ Hafıza:'), chalk.white('Klasör var, dosya yok'));
|
|
165
|
+
results.push({ status: 'warning', message: 'Hafıza dosyası yok' });
|
|
166
|
+
}
|
|
167
|
+
} catch (err) {
|
|
168
|
+
console.log(chalk.yellow('⚠️ Hafıza:'), chalk.white('Kontrol edilemedi'));
|
|
169
|
+
results.push({ status: 'warning', message: 'Hafıza kontrol edilemedi' });
|
|
170
|
+
}
|
|
146
171
|
} else {
|
|
147
172
|
console.log(chalk.yellow('⚠️ Hafıza:'), chalk.white('Pasif'));
|
|
148
173
|
results.push({ status: 'warning', message: 'Hafıza pasif' });
|
|
149
174
|
}
|
|
150
175
|
|
|
151
|
-
// 8. Telegram kontrolü
|
|
152
|
-
total++;
|
|
176
|
+
// 8. Telegram kontrolü (opsiyonel)
|
|
153
177
|
if (config && config.telegramToken) {
|
|
154
178
|
console.log(chalk.green('✅ Telegram:'), chalk.white('Bağlı'));
|
|
155
|
-
|
|
156
|
-
results.push({ status: 'ok', message: 'Telegram bağlı' });
|
|
179
|
+
results.push({ status: 'ok', message: 'Telegram bağlı', optional: true });
|
|
157
180
|
} else {
|
|
158
181
|
console.log(chalk.gray('⚪ Telegram:'), chalk.white('Bağlı değil'));
|
|
159
|
-
results.push({ status: 'info', message: 'Telegram bağlı değil' });
|
|
182
|
+
results.push({ status: 'info', message: 'Telegram bağlı değil', optional: true });
|
|
160
183
|
}
|
|
161
184
|
|
|
162
|
-
// 9. Discord kontrolü
|
|
163
|
-
total++;
|
|
185
|
+
// 9. Discord kontrolü (opsiyonel)
|
|
164
186
|
if (config && config.discordToken) {
|
|
165
187
|
console.log(chalk.green('✅ Discord:'), chalk.white('Bağlı'));
|
|
166
|
-
|
|
167
|
-
results.push({ status: 'ok', message: 'Discord bağlı' });
|
|
188
|
+
results.push({ status: 'ok', message: 'Discord bağlı', optional: true });
|
|
168
189
|
} else {
|
|
169
190
|
console.log(chalk.gray('⚪ Discord:'), chalk.white('Bağlı değil'));
|
|
170
|
-
results.push({ status: 'info', message: 'Discord bağlı değil' });
|
|
191
|
+
results.push({ status: 'info', message: 'Discord bağlı değil', optional: true });
|
|
171
192
|
}
|
|
172
193
|
|
|
173
|
-
// 10. Slack kontrolü
|
|
174
|
-
total++;
|
|
194
|
+
// 10. Slack kontrolü (opsiyonel)
|
|
175
195
|
if (config && config.slackToken) {
|
|
176
196
|
console.log(chalk.green('✅ Slack:'), chalk.white('Bağlı'));
|
|
177
|
-
|
|
178
|
-
results.push({ status: 'ok', message: 'Slack bağlı' });
|
|
197
|
+
results.push({ status: 'ok', message: 'Slack bağlı', optional: true });
|
|
179
198
|
} else {
|
|
180
199
|
console.log(chalk.gray('⚪ Slack:'), chalk.white('Bağlı değil'));
|
|
181
|
-
results.push({ status: 'info', message: 'Slack bağlı değil' });
|
|
200
|
+
results.push({ status: 'info', message: 'Slack bağlı değil', optional: true });
|
|
182
201
|
}
|
|
183
202
|
|
|
184
|
-
// 11. WhatsApp kontrolü
|
|
185
|
-
total++;
|
|
203
|
+
// 11. WhatsApp kontrolü (opsiyonel)
|
|
186
204
|
if (config && config.whatsappConnected) {
|
|
187
205
|
console.log(chalk.green('✅ WhatsApp:'), chalk.white('Bağlı'));
|
|
188
|
-
|
|
189
|
-
results.push({ status: 'ok', message: 'WhatsApp bağlı' });
|
|
206
|
+
results.push({ status: 'ok', message: 'WhatsApp bağlı', optional: true });
|
|
190
207
|
} else {
|
|
191
208
|
console.log(chalk.gray('⚪ WhatsApp:'), chalk.white('Bağlı değil'));
|
|
192
|
-
results.push({ status: 'info', message: 'WhatsApp bağlı değil' });
|
|
209
|
+
results.push({ status: 'info', message: 'WhatsApp bağlı değil', optional: true });
|
|
193
210
|
}
|
|
194
211
|
|
|
195
|
-
// 12. Dashboard kontrolü
|
|
196
|
-
total++;
|
|
212
|
+
// 12. Dashboard kontrolü (opsiyonel)
|
|
197
213
|
const dashboardRunning = await checkPort(3848);
|
|
198
214
|
if (dashboardRunning) {
|
|
199
215
|
console.log(chalk.green('✅ Dashboard:'), chalk.white('Çalışıyor (port 3848)'));
|
|
200
|
-
|
|
201
|
-
results.push({ status: 'ok', message: 'Dashboard çalışıyor' });
|
|
216
|
+
results.push({ status: 'ok', message: 'Dashboard çalışıyor', optional: true });
|
|
202
217
|
} else {
|
|
203
218
|
console.log(chalk.gray('⚪ Dashboard:'), chalk.white('Çalışmıyor'));
|
|
204
|
-
results.push({ status: 'info', message: 'Dashboard çalışmıyor', fix: 'natureco dashboard start' });
|
|
219
|
+
results.push({ status: 'info', message: 'Dashboard çalışmıyor', fix: 'natureco dashboard start', optional: true });
|
|
205
220
|
|
|
206
221
|
if (shouldFix) {
|
|
207
222
|
console.log(chalk.yellow(' 🔧 Dashboard başlatılıyor...'));
|
|
@@ -209,20 +224,19 @@ async function doctor(options) {
|
|
|
209
224
|
}
|
|
210
225
|
}
|
|
211
226
|
|
|
212
|
-
// 13. Gateway kontrolü
|
|
213
|
-
total++;
|
|
227
|
+
// 13. Gateway kontrolü (opsiyonel)
|
|
214
228
|
const gatewayRunning = await checkPort(3847);
|
|
215
229
|
if (gatewayRunning) {
|
|
216
230
|
console.log(chalk.green('✅ Gateway:'), chalk.white('Çalışıyor (port 3847)'));
|
|
217
|
-
|
|
218
|
-
results.push({ status: 'ok', message: 'Gateway çalışıyor' });
|
|
231
|
+
results.push({ status: 'ok', message: 'Gateway çalışıyor', optional: true });
|
|
219
232
|
} else {
|
|
220
233
|
console.log(chalk.gray('⚪ Gateway:'), chalk.white('Çalışmıyor'));
|
|
221
|
-
results.push({ status: 'info', message: 'Gateway çalışmıyor', fix: 'natureco gateway start' });
|
|
234
|
+
results.push({ status: 'info', message: 'Gateway çalışmıyor', fix: 'natureco gateway start', optional: true });
|
|
222
235
|
}
|
|
223
236
|
|
|
224
237
|
// 14. Internet bağlantısı kontrolü
|
|
225
238
|
total++;
|
|
239
|
+
criticalTotal++;
|
|
226
240
|
try {
|
|
227
241
|
const response = await fetch('https://api.natureco.me/health', {
|
|
228
242
|
method: 'GET',
|
|
@@ -232,6 +246,7 @@ async function doctor(options) {
|
|
|
232
246
|
if (response.ok || response.status === 404) {
|
|
233
247
|
console.log(chalk.green('✅ Internet:'), chalk.white('api.natureco.me erişilebilir'));
|
|
234
248
|
passed++;
|
|
249
|
+
criticalPassed++;
|
|
235
250
|
results.push({ status: 'ok', message: 'API erişilebilir' });
|
|
236
251
|
} else {
|
|
237
252
|
console.log(chalk.yellow('⚠️ Internet:'), chalk.white('API yanıt vermiyor'));
|
|
@@ -281,23 +296,25 @@ async function doctor(options) {
|
|
|
281
296
|
// Özet
|
|
282
297
|
console.log(chalk.cyan('\n────────────────────────────────'));
|
|
283
298
|
|
|
284
|
-
|
|
299
|
+
// Kritik kontroller için durum
|
|
300
|
+
const criticalPercentage = criticalTotal > 0 ? Math.round((criticalPassed / criticalTotal) * 100) : 100;
|
|
285
301
|
let statusColor = chalk.green;
|
|
286
302
|
let statusText = 'Mükemmel';
|
|
287
303
|
|
|
288
|
-
if (
|
|
304
|
+
if (criticalPercentage < 75) {
|
|
289
305
|
statusColor = chalk.red;
|
|
290
306
|
statusText = 'Kritik';
|
|
291
|
-
} else if (
|
|
307
|
+
} else if (criticalPercentage < 100) {
|
|
292
308
|
statusColor = chalk.yellow;
|
|
293
309
|
statusText = 'Dikkat';
|
|
294
|
-
} else if (
|
|
310
|
+
} else if (passed < total) {
|
|
295
311
|
statusColor = chalk.cyan;
|
|
296
312
|
statusText = 'İyi';
|
|
297
313
|
}
|
|
298
314
|
|
|
299
315
|
console.log(statusColor.bold(`Sistem Durumu: ${statusText}`));
|
|
300
|
-
console.log(chalk.white(`${passed}/${total} kontrol geçti
|
|
316
|
+
console.log(chalk.white(`${passed}/${total} kontrol geçti`));
|
|
317
|
+
console.log(chalk.gray(`Kritik: ${criticalPassed}/${criticalTotal}`));
|
|
301
318
|
|
|
302
319
|
// Sorunlar
|
|
303
320
|
const errors = results.filter(r => r.status === 'error');
|