natureco-cli 2.16.5 → 2.17.2
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/bin/natureco.js +99 -0
- package/package.json +1 -1
- package/src/commands/agents.js +141 -0
- package/src/commands/bots.js +17 -16
- package/src/commands/channels.js +177 -0
- package/src/commands/dashboard.js +2 -2
- package/src/commands/git.js +9 -12
- package/src/commands/help.js +16 -5
- package/src/commands/logs.js +99 -0
- package/src/commands/memory-cmd.js +190 -0
- package/src/commands/models.js +216 -0
- package/src/commands/pairing.js +107 -0
- package/src/commands/plugins.js +172 -0
- package/src/commands/reset.js +94 -0
- package/src/commands/security.js +142 -0
- package/src/commands/skills.js +15 -19
- package/src/commands/status.js +84 -0
- package/src/commands/ultrareview.js +15 -4
- package/src/commands/uninstall.js +92 -0
- package/src/utils/config.js +25 -9
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const inquirer = require('inquirer');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const os = require('os');
|
|
6
|
+
const { CONFIG_DIR, CONFIG_FILE } = require('../utils/config');
|
|
7
|
+
|
|
8
|
+
async function reset(args) {
|
|
9
|
+
const scope = args?.find(a => a.startsWith('--scope='))?.split('=')[1]
|
|
10
|
+
|| (args?.includes('--scope') ? args[args.indexOf('--scope') + 1] : null)
|
|
11
|
+
|| 'config';
|
|
12
|
+
const yes = args?.includes('--yes') || args?.includes('-y');
|
|
13
|
+
|
|
14
|
+
console.log('');
|
|
15
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
16
|
+
console.log(chalk.yellow.bold('\n NatureCo CLI — Sıfırlama\n'));
|
|
17
|
+
|
|
18
|
+
const scopeDescriptions = {
|
|
19
|
+
config: 'Sadece config dosyasını sıfırla (~/.natureco/config.json)',
|
|
20
|
+
memory: 'Tüm hafıza dosyalarını sil (~/.natureco/memory/)',
|
|
21
|
+
sessions: 'Tüm session dosyalarını sil (~/.natureco/sessions/)',
|
|
22
|
+
full: 'Her şeyi sil (~/.natureco/ klasörü tamamen)',
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
console.log(chalk.gray(` Kapsam: `) + chalk.white(scope));
|
|
26
|
+
console.log(chalk.gray(` İşlem: `) + chalk.yellow(scopeDescriptions[scope] || scopeDescriptions.config));
|
|
27
|
+
console.log('');
|
|
28
|
+
|
|
29
|
+
if (!yes) {
|
|
30
|
+
const { confirm } = await inquirer.prompt([{
|
|
31
|
+
type: 'confirm',
|
|
32
|
+
name: 'confirm',
|
|
33
|
+
message: ' Devam etmek istediğinizden emin misiniz?',
|
|
34
|
+
default: false,
|
|
35
|
+
}]);
|
|
36
|
+
if (!confirm) {
|
|
37
|
+
console.log(chalk.gray('\n İptal edildi.\n'));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (scope === 'config' || scope === 'full') {
|
|
43
|
+
if (fs.existsSync(CONFIG_FILE)) {
|
|
44
|
+
fs.unlinkSync(CONFIG_FILE);
|
|
45
|
+
console.log(chalk.green(' ✓ Config dosyası silindi'));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (scope === 'memory' || scope === 'full') {
|
|
50
|
+
const memDir = path.join(CONFIG_DIR, 'memory');
|
|
51
|
+
if (fs.existsSync(memDir)) {
|
|
52
|
+
fs.rmSync(memDir, { recursive: true, force: true });
|
|
53
|
+
console.log(chalk.green(' ✓ Hafıza dosyaları silindi'));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (scope === 'sessions' || scope === 'full') {
|
|
58
|
+
const sessDir = path.join(CONFIG_DIR, 'sessions');
|
|
59
|
+
if (fs.existsSync(sessDir)) {
|
|
60
|
+
fs.rmSync(sessDir, { recursive: true, force: true });
|
|
61
|
+
console.log(chalk.green(' ✓ Session dosyaları silindi'));
|
|
62
|
+
}
|
|
63
|
+
const convDir = path.join(CONFIG_DIR, 'conversations');
|
|
64
|
+
if (fs.existsSync(convDir)) {
|
|
65
|
+
fs.rmSync(convDir, { recursive: true, force: true });
|
|
66
|
+
console.log(chalk.green(' ✓ Konuşma geçmişi silindi'));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (scope === 'full') {
|
|
71
|
+
// WhatsApp sessions
|
|
72
|
+
const waDir = path.join(CONFIG_DIR, 'whatsapp-sessions');
|
|
73
|
+
if (fs.existsSync(waDir)) {
|
|
74
|
+
fs.rmSync(waDir, { recursive: true, force: true });
|
|
75
|
+
console.log(chalk.green(' ✓ WhatsApp session\'ları silindi'));
|
|
76
|
+
}
|
|
77
|
+
// Skills
|
|
78
|
+
const skillsDir = path.join(CONFIG_DIR, 'skills');
|
|
79
|
+
if (fs.existsSync(skillsDir)) {
|
|
80
|
+
fs.rmSync(skillsDir, { recursive: true, force: true });
|
|
81
|
+
console.log(chalk.green(' ✓ Skill\'ler silindi'));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
console.log('');
|
|
86
|
+
console.log(chalk.green(' ✓ Sıfırlama tamamlandı!'));
|
|
87
|
+
if (scope === 'config' || scope === 'full') {
|
|
88
|
+
console.log(chalk.gray('\n Yeniden kurulum için: ') + chalk.cyan('natureco setup\n'));
|
|
89
|
+
} else {
|
|
90
|
+
console.log('');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
module.exports = reset;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
const { getConfig, CONFIG_FILE, CONFIG_DIR } = require('../utils/config');
|
|
6
|
+
|
|
7
|
+
async function security(args) {
|
|
8
|
+
const [action, ...params] = (args || []);
|
|
9
|
+
|
|
10
|
+
if (!action || action === 'audit') return audit(args);
|
|
11
|
+
|
|
12
|
+
console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
|
|
13
|
+
console.log(chalk.gray(' Kullanım: natureco security [audit]\n'));
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async function audit(args) {
|
|
18
|
+
const fix = args.includes('--fix');
|
|
19
|
+
const json = args.includes('--json');
|
|
20
|
+
|
|
21
|
+
const issues = [];
|
|
22
|
+
const warnings = [];
|
|
23
|
+
const ok = [];
|
|
24
|
+
|
|
25
|
+
// 1. Config dosyası izinleri
|
|
26
|
+
if (fs.existsSync(CONFIG_FILE)) {
|
|
27
|
+
try {
|
|
28
|
+
const stat = fs.statSync(CONFIG_FILE);
|
|
29
|
+
const mode = (stat.mode & 0o777).toString(8);
|
|
30
|
+
if (process.platform !== 'win32' && mode !== '600' && mode !== '644') {
|
|
31
|
+
issues.push({
|
|
32
|
+
id: 'config-permissions',
|
|
33
|
+
msg: `Config dosyası izinleri geniş: ${mode} (önerilen: 600)`,
|
|
34
|
+
fix: () => fs.chmodSync(CONFIG_FILE, 0o600),
|
|
35
|
+
});
|
|
36
|
+
} else {
|
|
37
|
+
ok.push('Config dosyası izinleri');
|
|
38
|
+
}
|
|
39
|
+
} catch {}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 2. API key formatı
|
|
43
|
+
const config = getConfig();
|
|
44
|
+
if (config.providerApiKey) {
|
|
45
|
+
if (config.providerApiKey.length < 10) {
|
|
46
|
+
issues.push({ id: 'weak-api-key', msg: 'API key çok kısa görünüyor' });
|
|
47
|
+
} else {
|
|
48
|
+
ok.push('API key formatı');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 3. Debug mode
|
|
53
|
+
if (config.debug === true) {
|
|
54
|
+
warnings.push({ id: 'debug-mode', msg: 'Debug modu açık — API key\'ler loglara yazılabilir' });
|
|
55
|
+
} else {
|
|
56
|
+
ok.push('Debug modu kapalı');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// 4. WhatsApp session dosyaları
|
|
60
|
+
const waDir = path.join(CONFIG_DIR, 'whatsapp-sessions');
|
|
61
|
+
if (fs.existsSync(waDir)) {
|
|
62
|
+
const sessions = fs.readdirSync(waDir);
|
|
63
|
+
if (sessions.length > 3) {
|
|
64
|
+
warnings.push({ id: 'old-wa-sessions', msg: `${sessions.length} WhatsApp session var — eskiler temizlenebilir` });
|
|
65
|
+
} else {
|
|
66
|
+
ok.push('WhatsApp session sayısı');
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// 5. Gateway log boyutu
|
|
71
|
+
const logFile = path.join(CONFIG_DIR, 'gateway.log');
|
|
72
|
+
if (fs.existsSync(logFile)) {
|
|
73
|
+
const stat = fs.statSync(logFile);
|
|
74
|
+
const sizeMB = stat.size / (1024 * 1024);
|
|
75
|
+
if (sizeMB > 50) {
|
|
76
|
+
warnings.push({ id: 'large-log', msg: `Gateway log dosyası büyük: ${sizeMB.toFixed(1)}MB` });
|
|
77
|
+
} else {
|
|
78
|
+
ok.push('Gateway log boyutu');
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// 6. Eski conversation dosyaları
|
|
83
|
+
const convDir = path.join(CONFIG_DIR, 'conversations');
|
|
84
|
+
if (fs.existsSync(convDir)) {
|
|
85
|
+
const convFiles = fs.readdirSync(convDir).filter(f => f.endsWith('.json'));
|
|
86
|
+
if (convFiles.length > 20) {
|
|
87
|
+
warnings.push({ id: 'old-conversations', msg: `${convFiles.length} konuşma dosyası var — eskiler temizlenebilir` });
|
|
88
|
+
} else {
|
|
89
|
+
ok.push('Konuşma dosyası sayısı');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (json) {
|
|
94
|
+
console.log(JSON.stringify({ ok, warnings: warnings.map(w => w.msg), issues: issues.map(i => i.msg) }, null, 2));
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
console.log('');
|
|
99
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
100
|
+
console.log(chalk.cyan.bold('\n Güvenlik Denetimi\n'));
|
|
101
|
+
|
|
102
|
+
ok.forEach(msg => console.log(chalk.green(' ✓ ') + chalk.gray(msg)));
|
|
103
|
+
|
|
104
|
+
if (warnings.length > 0) {
|
|
105
|
+
console.log('');
|
|
106
|
+
warnings.forEach(w => console.log(chalk.yellow(' ⚠ ') + chalk.yellow(w.msg)));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (issues.length > 0) {
|
|
110
|
+
console.log('');
|
|
111
|
+
issues.forEach(i => console.log(chalk.red(' ❌ ') + chalk.red(i.msg)));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
console.log('');
|
|
115
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
116
|
+
|
|
117
|
+
if (issues.length === 0 && warnings.length === 0) {
|
|
118
|
+
console.log(chalk.green(' ✓ Güvenlik sorunu bulunamadı\n'));
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
console.log(chalk.gray(` ${ok.length} geçti · ${warnings.length} uyarı · ${issues.length} sorun`));
|
|
123
|
+
|
|
124
|
+
if (fix && issues.length > 0) {
|
|
125
|
+
console.log('');
|
|
126
|
+
issues.forEach(i => {
|
|
127
|
+
if (i.fix) {
|
|
128
|
+
try {
|
|
129
|
+
i.fix();
|
|
130
|
+
console.log(chalk.green(` ✓ Düzeltildi: ${i.id}`));
|
|
131
|
+
} catch (e) {
|
|
132
|
+
console.log(chalk.red(` ❌ Düzeltilemedi: ${i.id} — ${e.message}`));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
} else if (issues.length > 0) {
|
|
137
|
+
console.log(chalk.gray('\n Otomatik düzeltmek için: ') + chalk.cyan('natureco security audit --fix'));
|
|
138
|
+
}
|
|
139
|
+
console.log('');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
module.exports = security;
|
package/src/commands/skills.js
CHANGED
|
@@ -68,37 +68,33 @@ async function skills(args) {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
async function listSkills() {
|
|
71
|
-
console.log(chalk.green.bold('\n╭─ Yüklü Skill\'ler ─╮\n'));
|
|
72
|
-
|
|
73
71
|
const allSkills = getSkills();
|
|
74
72
|
|
|
73
|
+
console.log(chalk.gray('\n ' + '─'.repeat(48)));
|
|
74
|
+
console.log(chalk.cyan.bold('\n Yüklü Skill\'ler\n'));
|
|
75
|
+
|
|
75
76
|
if (allSkills.length === 0) {
|
|
76
|
-
console.log(chalk.gray('Hiç skill yüklü değil.\n'));
|
|
77
|
-
console.log(chalk.
|
|
77
|
+
console.log(chalk.gray(' Hiç skill yüklü değil.\n'));
|
|
78
|
+
console.log(chalk.gray(' Yüklemek için: ') + chalk.cyan('natureco skills install <slug>'));
|
|
79
|
+
console.log(chalk.gray(' Gözatmak için: ') + chalk.cyan('natureco skills browse\n'));
|
|
78
80
|
return;
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
allSkills.forEach((skill, index) => {
|
|
82
|
-
const sourceLabel = skill.source === 'builtin' ? chalk.blue('[
|
|
83
|
-
skill.source === 'user' ? chalk.cyan('[
|
|
84
|
-
chalk.magenta('[
|
|
85
|
-
|
|
86
|
-
console.log(chalk.
|
|
87
|
-
console.log(chalk.gray(` ${skill.description}`));
|
|
88
|
-
|
|
84
|
+
const sourceLabel = skill.source === 'builtin' ? chalk.blue('[yerleşik]') :
|
|
85
|
+
skill.source === 'user' ? chalk.cyan('[kişisel]') :
|
|
86
|
+
chalk.magenta('[proje]');
|
|
87
|
+
console.log(chalk.white(` ${index + 1}. ${skill.name} `) + sourceLabel);
|
|
88
|
+
console.log(chalk.gray(` ${skill.description}`));
|
|
89
89
|
if (skill.metadata?.requires?.bins) {
|
|
90
|
-
console.log(chalk.gray(`
|
|
90
|
+
console.log(chalk.gray(` Gerekli: ${skill.metadata.requires.bins.join(', ')}`));
|
|
91
91
|
}
|
|
92
|
-
|
|
93
|
-
if (skill.metadata?.os) {
|
|
94
|
-
console.log(chalk.gray(` Platform: ${skill.metadata.os.join(', ')}`));
|
|
95
|
-
}
|
|
96
|
-
|
|
97
92
|
console.log('');
|
|
98
93
|
});
|
|
99
94
|
|
|
100
|
-
console.log(chalk.
|
|
101
|
-
console.log(chalk.gray(`Toplam: ${allSkills.length} skill
|
|
95
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
96
|
+
console.log(chalk.gray(` Toplam: ${allSkills.length} skill`));
|
|
97
|
+
console.log(chalk.gray(' Kaldırmak için: ') + chalk.cyan('natureco skills remove <slug>\n'));
|
|
102
98
|
}
|
|
103
99
|
|
|
104
100
|
async function installSkillCommand(slug) {
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
const { getConfig } = require('../utils/config');
|
|
6
|
+
const { getSkills } = require('../utils/skills');
|
|
7
|
+
|
|
8
|
+
async function status() {
|
|
9
|
+
const config = getConfig();
|
|
10
|
+
const version = require('../../package.json').version;
|
|
11
|
+
|
|
12
|
+
console.log('');
|
|
13
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
14
|
+
console.log(chalk.cyan.bold('\n NatureCo CLI — Durum\n'));
|
|
15
|
+
|
|
16
|
+
// Provider
|
|
17
|
+
const providerHost = config.providerUrl
|
|
18
|
+
? config.providerUrl.replace('https://', '').split('/')[0]
|
|
19
|
+
: null;
|
|
20
|
+
|
|
21
|
+
console.log(chalk.gray(' Versiyon : ') + chalk.white(`v${version}`));
|
|
22
|
+
if (providerHost) {
|
|
23
|
+
console.log(chalk.gray(' Provider : ') + chalk.white(providerHost));
|
|
24
|
+
console.log(chalk.gray(' Model : ') + chalk.white(config.providerModel || 'bilinmiyor'));
|
|
25
|
+
} else {
|
|
26
|
+
console.log(chalk.gray(' Provider : ') + chalk.yellow('yapılandırılmamış'));
|
|
27
|
+
}
|
|
28
|
+
if (config.botName) console.log(chalk.gray(' Bot : ') + chalk.cyan(config.botName));
|
|
29
|
+
if (config.userName) console.log(chalk.gray(' Kullanıcı : ') + chalk.white(config.userName));
|
|
30
|
+
|
|
31
|
+
// Gateway durumu
|
|
32
|
+
const pidFile = path.join(os.homedir(), '.natureco', 'gateway.pid');
|
|
33
|
+
const gatewayRunning = fs.existsSync(pidFile);
|
|
34
|
+
console.log(chalk.gray(' Gateway : ') + (gatewayRunning ? chalk.green('çalışıyor') : chalk.gray('durdurulmuş')));
|
|
35
|
+
|
|
36
|
+
// Dashboard
|
|
37
|
+
const dashPid = path.join(os.homedir(), '.natureco', 'dashboard.pid');
|
|
38
|
+
const dashRunning = fs.existsSync(dashPid);
|
|
39
|
+
console.log(chalk.gray(' Dashboard : ') + (dashRunning ? chalk.green('çalışıyor (localhost:3848)') : chalk.gray('durdurulmuş')));
|
|
40
|
+
|
|
41
|
+
// Kanallar
|
|
42
|
+
const channels = [];
|
|
43
|
+
if (config.telegramToken) channels.push('Telegram');
|
|
44
|
+
if (config.whatsappConnected) channels.push('WhatsApp');
|
|
45
|
+
if (config.discordToken) channels.push('Discord');
|
|
46
|
+
if (config.slackToken) channels.push('Slack');
|
|
47
|
+
console.log(chalk.gray(' Kanallar : ') + (channels.length > 0 ? chalk.white(channels.join(', ')) : chalk.gray('yok')));
|
|
48
|
+
|
|
49
|
+
// Skills
|
|
50
|
+
const skills = getSkills();
|
|
51
|
+
console.log(chalk.gray(' Skills : ') + chalk.white(`${skills.length} yüklü`));
|
|
52
|
+
|
|
53
|
+
// Memory
|
|
54
|
+
const memDir = path.join(os.homedir(), '.natureco', 'memory');
|
|
55
|
+
const memFiles = fs.existsSync(memDir) ? fs.readdirSync(memDir).filter(f => f.endsWith('.json')).length : 0;
|
|
56
|
+
console.log(chalk.gray(' Hafıza : ') + chalk.white(`${memFiles} bot`));
|
|
57
|
+
|
|
58
|
+
// Son session
|
|
59
|
+
const sessDir = path.join(os.homedir(), '.natureco', 'sessions');
|
|
60
|
+
if (fs.existsSync(sessDir)) {
|
|
61
|
+
const sessions = fs.readdirSync(sessDir).filter(f => f.endsWith('.json'));
|
|
62
|
+
if (sessions.length > 0) {
|
|
63
|
+
console.log(chalk.gray(' Sessions : ') + chalk.white(`${sessions.length} kayıtlı`));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Son loglar
|
|
68
|
+
const logFile = path.join(os.homedir(), '.natureco', 'gateway.log');
|
|
69
|
+
if (fs.existsSync(logFile)) {
|
|
70
|
+
const lines = fs.readFileSync(logFile, 'utf-8').split('\n').filter(l => l.trim());
|
|
71
|
+
const last = lines.slice(-3);
|
|
72
|
+
if (last.length > 0) {
|
|
73
|
+
console.log(chalk.gray('\n Son Loglar:\n'));
|
|
74
|
+
last.forEach(l => console.log(chalk.gray(' ' + l)));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
console.log('');
|
|
79
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
80
|
+
console.log(chalk.gray(' Detaylı kontrol: ') + chalk.cyan('natureco doctor'));
|
|
81
|
+
console.log(chalk.gray(' Kanal durumu : ') + chalk.cyan('natureco channels status\n'));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
module.exports = status;
|
|
@@ -16,13 +16,24 @@ async function ultrareview(filePath) {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
const config = getConfig();
|
|
19
|
-
const defaultBotId = config.defaultBotId;
|
|
19
|
+
const defaultBotId = config.defaultBotId || config.botName || 'universal-provider';
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
// getBots ile gerçek bot ID'yi al
|
|
22
|
+
const apiKey = getApiKey();
|
|
23
|
+
if (!apiKey && !config.providerApiKey) {
|
|
24
|
+
console.log(chalk.red('\n❌ Not logged in. Run "natureco login" first.\n'));
|
|
23
25
|
process.exit(1);
|
|
24
26
|
}
|
|
25
27
|
|
|
28
|
+
let botId = defaultBotId;
|
|
29
|
+
try {
|
|
30
|
+
const botList = await getBots(apiKey || config.providerApiKey);
|
|
31
|
+
if (botList?.bots?.length > 0) {
|
|
32
|
+
const matched = botList.bots.find(b => b.name === config.botName) || botList.bots[0];
|
|
33
|
+
botId = matched.id;
|
|
34
|
+
}
|
|
35
|
+
} catch { /* fallback to defaultBotId */ }
|
|
36
|
+
|
|
26
37
|
let code;
|
|
27
38
|
let filename;
|
|
28
39
|
|
|
@@ -99,7 +110,7 @@ ${code}
|
|
|
99
110
|
\`\`\``;
|
|
100
111
|
|
|
101
112
|
try {
|
|
102
|
-
const response = await sendMessage(apiKey,
|
|
113
|
+
const response = await sendMessage(apiKey || config.providerApiKey, botId, prompt, null, '');
|
|
103
114
|
const review = response.reply || response.message || 'No response';
|
|
104
115
|
|
|
105
116
|
console.log(chalk.green('\n📊 Ultra Review:\n'));
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const inquirer = require('inquirer');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const os = require('os');
|
|
6
|
+
const { CONFIG_DIR } = require('../utils/config');
|
|
7
|
+
|
|
8
|
+
async function uninstall(args) {
|
|
9
|
+
const all = args?.includes('--all');
|
|
10
|
+
const yes = args?.includes('--yes') || args?.includes('-y');
|
|
11
|
+
const dryRun = args?.includes('--dry-run');
|
|
12
|
+
|
|
13
|
+
console.log('');
|
|
14
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
15
|
+
console.log(chalk.red.bold('\n NatureCo CLI — Kaldırma\n'));
|
|
16
|
+
|
|
17
|
+
const actions = [];
|
|
18
|
+
|
|
19
|
+
// Gateway service PID
|
|
20
|
+
const pidFile = path.join(CONFIG_DIR, 'gateway.pid');
|
|
21
|
+
if (fs.existsSync(pidFile)) actions.push('Gateway durdurulacak');
|
|
22
|
+
|
|
23
|
+
// Config ve data
|
|
24
|
+
if (all) {
|
|
25
|
+
actions.push(`~/.natureco/ klasörü silinecek (config, hafıza, session'lar)`);
|
|
26
|
+
} else {
|
|
27
|
+
actions.push('Gateway ve dashboard durdurulacak');
|
|
28
|
+
actions.push('~/.natureco/gateway.pid ve dashboard.pid silinecek');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
actions.push('npm uninstall -g natureco-cli komutu gösterilecek');
|
|
32
|
+
|
|
33
|
+
if (dryRun) {
|
|
34
|
+
console.log(chalk.yellow(' Dry-run modu — hiçbir şey silinmeyecek\n'));
|
|
35
|
+
actions.forEach(a => console.log(chalk.gray(` • ${a}`)));
|
|
36
|
+
console.log('');
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
console.log(chalk.yellow(' Yapılacaklar:\n'));
|
|
41
|
+
actions.forEach(a => console.log(chalk.gray(` • ${a}`)));
|
|
42
|
+
console.log('');
|
|
43
|
+
|
|
44
|
+
if (!yes) {
|
|
45
|
+
const { confirm } = await inquirer.prompt([{
|
|
46
|
+
type: 'confirm',
|
|
47
|
+
name: 'confirm',
|
|
48
|
+
message: ' Devam etmek istediğinizden emin misiniz?',
|
|
49
|
+
default: false,
|
|
50
|
+
}]);
|
|
51
|
+
if (!confirm) {
|
|
52
|
+
console.log(chalk.gray('\n İptal edildi.\n'));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Gateway durdur
|
|
58
|
+
if (fs.existsSync(pidFile)) {
|
|
59
|
+
try {
|
|
60
|
+
const pid = parseInt(fs.readFileSync(pidFile, 'utf-8').trim());
|
|
61
|
+
if (pid) process.kill(pid, 'SIGTERM');
|
|
62
|
+
fs.unlinkSync(pidFile);
|
|
63
|
+
console.log(chalk.green(' ✓ Gateway durduruldu'));
|
|
64
|
+
} catch {}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Dashboard durdur
|
|
68
|
+
const dashPid = path.join(CONFIG_DIR, 'dashboard.pid');
|
|
69
|
+
if (fs.existsSync(dashPid)) {
|
|
70
|
+
try {
|
|
71
|
+
const pid = parseInt(fs.readFileSync(dashPid, 'utf-8').trim());
|
|
72
|
+
if (pid) process.kill(pid, 'SIGTERM');
|
|
73
|
+
fs.unlinkSync(dashPid);
|
|
74
|
+
console.log(chalk.green(' ✓ Dashboard durduruldu'));
|
|
75
|
+
} catch {}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// --all ise tüm veriyi sil
|
|
79
|
+
if (all && fs.existsSync(CONFIG_DIR)) {
|
|
80
|
+
fs.rmSync(CONFIG_DIR, { recursive: true, force: true });
|
|
81
|
+
console.log(chalk.green(' ✓ ~/.natureco/ silindi'));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
console.log('');
|
|
85
|
+
console.log(chalk.green(' ✓ Temizlik tamamlandı!'));
|
|
86
|
+
console.log('');
|
|
87
|
+
console.log(chalk.gray(' CLI\'yi tamamen kaldırmak için:'));
|
|
88
|
+
console.log(chalk.cyan(' npm uninstall -g natureco-cli'));
|
|
89
|
+
console.log('');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
module.exports = uninstall;
|
package/src/utils/config.js
CHANGED
|
@@ -5,23 +5,39 @@ const os = require('os');
|
|
|
5
5
|
const CONFIG_DIR = path.join(os.homedir(), '.natureco');
|
|
6
6
|
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
|
|
7
7
|
|
|
8
|
+
// --profile flag desteği: ~/.natureco-<profile>/
|
|
9
|
+
function getProfileDir() {
|
|
10
|
+
const profileArg = process.argv.find(a => a.startsWith('--profile='));
|
|
11
|
+
const profileIdx = process.argv.indexOf('--profile');
|
|
12
|
+
const profile = profileArg
|
|
13
|
+
? profileArg.split('=')[1]
|
|
14
|
+
: (profileIdx !== -1 ? process.argv[profileIdx + 1] : null);
|
|
15
|
+
if (profile && profile !== 'default') {
|
|
16
|
+
return path.join(os.homedir(), `.natureco-${profile}`);
|
|
17
|
+
}
|
|
18
|
+
return CONFIG_DIR;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const ACTIVE_CONFIG_DIR = getProfileDir();
|
|
22
|
+
const ACTIVE_CONFIG_FILE = path.join(ACTIVE_CONFIG_DIR, 'config.json');
|
|
23
|
+
|
|
8
24
|
function ensureConfigDir() {
|
|
9
|
-
if (!fs.existsSync(
|
|
10
|
-
fs.mkdirSync(
|
|
25
|
+
if (!fs.existsSync(ACTIVE_CONFIG_DIR)) {
|
|
26
|
+
fs.mkdirSync(ACTIVE_CONFIG_DIR, { recursive: true });
|
|
11
27
|
}
|
|
12
28
|
}
|
|
13
29
|
|
|
14
30
|
function saveConfig(data) {
|
|
15
31
|
ensureConfigDir();
|
|
16
|
-
fs.writeFileSync(
|
|
32
|
+
fs.writeFileSync(ACTIVE_CONFIG_FILE, JSON.stringify(data, null, 2), 'utf8');
|
|
17
33
|
}
|
|
18
34
|
|
|
19
35
|
function loadConfig() {
|
|
20
|
-
if (!fs.existsSync(
|
|
36
|
+
if (!fs.existsSync(ACTIVE_CONFIG_FILE)) {
|
|
21
37
|
return null;
|
|
22
38
|
}
|
|
23
39
|
try {
|
|
24
|
-
const content = fs.readFileSync(
|
|
40
|
+
const content = fs.readFileSync(ACTIVE_CONFIG_FILE, 'utf8');
|
|
25
41
|
return JSON.parse(content);
|
|
26
42
|
} catch (err) {
|
|
27
43
|
return null;
|
|
@@ -29,8 +45,8 @@ function loadConfig() {
|
|
|
29
45
|
}
|
|
30
46
|
|
|
31
47
|
function deleteConfig() {
|
|
32
|
-
if (fs.existsSync(
|
|
33
|
-
fs.unlinkSync(
|
|
48
|
+
if (fs.existsSync(ACTIVE_CONFIG_FILE)) {
|
|
49
|
+
fs.unlinkSync(ACTIVE_CONFIG_FILE);
|
|
34
50
|
}
|
|
35
51
|
}
|
|
36
52
|
|
|
@@ -76,6 +92,6 @@ module.exports = {
|
|
|
76
92
|
getConfig,
|
|
77
93
|
getAllConfig,
|
|
78
94
|
setConfigValue,
|
|
79
|
-
CONFIG_FILE,
|
|
80
|
-
CONFIG_DIR,
|
|
95
|
+
CONFIG_FILE: ACTIVE_CONFIG_FILE,
|
|
96
|
+
CONFIG_DIR: ACTIVE_CONFIG_DIR,
|
|
81
97
|
};
|