natureco-cli 2.19.1 → 2.20.0
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 +232 -358
- package/package.json +1 -1
- package/src/commands/code.js +197 -39
- package/src/commands/memory-cmd.js +28 -13
- package/src/commands/sessions.js +126 -62
- package/src/commands/status.js +86 -43
package/src/commands/sessions.js
CHANGED
|
@@ -1,119 +1,183 @@
|
|
|
1
1
|
const chalk = require('chalk');
|
|
2
2
|
const { listSessions, loadSession } = require('../utils/sessions');
|
|
3
|
-
const { getApiKey } = require('../utils/config');
|
|
3
|
+
const { getApiKey, getConfig } = require('../utils/config');
|
|
4
4
|
const { getBots } = require('../utils/api');
|
|
5
5
|
|
|
6
6
|
async function sessions(action, ...args) {
|
|
7
|
-
if (!action || action === 'list')
|
|
8
|
-
return listSessionsCommand();
|
|
9
|
-
}
|
|
10
|
-
|
|
7
|
+
if (!action || action === 'list') return listSessionsCommand();
|
|
11
8
|
if (action === 'show') {
|
|
12
9
|
const sessionId = args[0];
|
|
13
10
|
if (!sessionId) {
|
|
14
|
-
console.log(chalk.red('\n❌ Session ID
|
|
15
|
-
console.log(chalk.gray('
|
|
11
|
+
console.log(chalk.red('\n ❌ Session ID gerekli\n'));
|
|
12
|
+
console.log(chalk.gray(' Kullanım: natureco sessions show <id>\n'));
|
|
16
13
|
process.exit(1);
|
|
17
14
|
}
|
|
18
15
|
return showSession(sessionId);
|
|
19
16
|
}
|
|
20
|
-
|
|
21
|
-
console.log(chalk.
|
|
22
|
-
console.log(chalk.gray('Available actions: list, show\n'));
|
|
17
|
+
console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
|
|
18
|
+
console.log(chalk.gray(' Kullanım: natureco sessions [list|show]\n'));
|
|
23
19
|
process.exit(1);
|
|
24
20
|
}
|
|
25
21
|
|
|
26
22
|
async function listSessionsCommand() {
|
|
27
23
|
const apiKey = getApiKey();
|
|
28
|
-
|
|
24
|
+
const w = process.stdout.columns || 120;
|
|
25
|
+
const line = chalk.gray('─'.repeat(w));
|
|
26
|
+
|
|
29
27
|
if (!apiKey) {
|
|
30
|
-
console.log(chalk.red('\n❌
|
|
28
|
+
console.log(chalk.red('\n ❌ Giriş yapılmamış. natureco login\n'));
|
|
31
29
|
process.exit(1);
|
|
32
30
|
}
|
|
33
|
-
|
|
31
|
+
|
|
34
32
|
let botList;
|
|
35
33
|
try {
|
|
36
34
|
botList = await getBots(apiKey);
|
|
37
35
|
} catch (err) {
|
|
38
|
-
console.log(chalk.red(`\n❌
|
|
36
|
+
console.log(chalk.red(`\n ❌ Hata: ${err.message}\n`));
|
|
39
37
|
process.exit(1);
|
|
40
38
|
}
|
|
41
|
-
|
|
42
|
-
if (!botList
|
|
43
|
-
console.log(chalk.gray('
|
|
39
|
+
|
|
40
|
+
if (!botList?.bots?.length) {
|
|
41
|
+
console.log(chalk.gray('\n Bot bulunamadı.\n'));
|
|
44
42
|
return;
|
|
45
43
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
let foundAny = false;
|
|
50
|
-
|
|
44
|
+
|
|
45
|
+
// Tüm session'ları topla
|
|
46
|
+
const allSessions = [];
|
|
51
47
|
botList.bots.forEach(bot => {
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
console.log(` ${chalk.white(session.id)} - ${chalk.gray(date)} - ${chalk.gray(messageCount + ' messages')}`);
|
|
48
|
+
const list = listSessions(bot.id);
|
|
49
|
+
list.forEach(s => {
|
|
50
|
+
allSessions.push({
|
|
51
|
+
...s,
|
|
52
|
+
botName: bot.name,
|
|
53
|
+
messageCount: (s.messages || []).length,
|
|
54
|
+
lastMessage: s.messages?.slice(-1)[0]?.user || '',
|
|
60
55
|
});
|
|
61
|
-
|
|
62
|
-
}
|
|
56
|
+
});
|
|
63
57
|
});
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
58
|
+
|
|
59
|
+
// 0 mesajlıları filtrele
|
|
60
|
+
const active = allSessions.filter(s => s.messageCount > 0);
|
|
61
|
+
|
|
62
|
+
console.log('');
|
|
63
|
+
console.log(line);
|
|
64
|
+
const title = chalk.bold.cyan(' Oturumlar');
|
|
65
|
+
const count = chalk.gray(`${active.length} aktif `);
|
|
66
|
+
const pad = w - 12 - String(active.length).length - 8;
|
|
67
|
+
console.log(title + ' '.repeat(Math.max(1, pad)) + count);
|
|
68
|
+
console.log(line);
|
|
69
|
+
|
|
70
|
+
if (active.length === 0) {
|
|
71
|
+
console.log(chalk.gray('\n Henüz oturum yok.\n'));
|
|
72
|
+
console.log(line);
|
|
73
|
+
return;
|
|
67
74
|
}
|
|
75
|
+
|
|
76
|
+
// Grupla
|
|
77
|
+
const now = Date.now();
|
|
78
|
+
const todayStr = new Date().toDateString();
|
|
79
|
+
const groups = { 'Bugün': [], 'Bu Hafta': [], 'Daha Önce': [] };
|
|
80
|
+
|
|
81
|
+
active.forEach(s => {
|
|
82
|
+
const d = new Date(s.createdAt);
|
|
83
|
+
if (d.toDateString() === todayStr) groups['Bugün'].push(s);
|
|
84
|
+
else if (now - d < 7 * 24 * 60 * 60 * 1000) groups['Bu Hafta'].push(s);
|
|
85
|
+
else groups['Daha Önce'].push(s);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Kolon genişlikleri
|
|
89
|
+
const dateW = 17;
|
|
90
|
+
const botW = 14;
|
|
91
|
+
const previewW = Math.max(20, w - dateW - botW - 18 - 10);
|
|
92
|
+
|
|
93
|
+
Object.entries(groups).forEach(([label, items]) => {
|
|
94
|
+
if (!items.length) return;
|
|
95
|
+
|
|
96
|
+
console.log('');
|
|
97
|
+
console.log(chalk.yellow(` ${label}`));
|
|
98
|
+
console.log(chalk.gray(' ' +
|
|
99
|
+
'Tarih/Saat'.padEnd(dateW) +
|
|
100
|
+
'Bot'.padEnd(botW) +
|
|
101
|
+
'Son Mesaj'.padEnd(previewW) +
|
|
102
|
+
'Mesaj'.padStart(6) +
|
|
103
|
+
' ID'
|
|
104
|
+
));
|
|
105
|
+
console.log(chalk.gray(' ' + '·'.repeat(w - 4)));
|
|
106
|
+
|
|
107
|
+
items.forEach(s => {
|
|
108
|
+
const d = new Date(s.createdAt);
|
|
109
|
+
const time = d.toLocaleString('tr-TR', {
|
|
110
|
+
day: '2-digit', month: '2-digit',
|
|
111
|
+
hour: '2-digit', minute: '2-digit',
|
|
112
|
+
});
|
|
113
|
+
const bot = (s.botName || '—').slice(0, botW - 2).padEnd(botW);
|
|
114
|
+
const preview = (s.lastMessage || '—').slice(0, previewW - 2).padEnd(previewW);
|
|
115
|
+
const msgs = String(s.messageCount).padStart(5);
|
|
116
|
+
const id = chalk.gray(s.id.slice(-8));
|
|
117
|
+
|
|
118
|
+
console.log(
|
|
119
|
+
chalk.gray(' ' + time.padEnd(dateW)) +
|
|
120
|
+
chalk.cyan(bot) +
|
|
121
|
+
chalk.white(preview) +
|
|
122
|
+
chalk.gray(msgs) +
|
|
123
|
+
' ' + id
|
|
124
|
+
);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
console.log('');
|
|
129
|
+
console.log(line);
|
|
130
|
+
console.log(chalk.gray(` ${active.length} aktif oturum · natureco sessions show <id>`));
|
|
131
|
+
console.log(line);
|
|
132
|
+
console.log('');
|
|
68
133
|
}
|
|
69
134
|
|
|
70
135
|
async function showSession(sessionId) {
|
|
71
136
|
const apiKey = getApiKey();
|
|
72
|
-
|
|
137
|
+
const w = process.stdout.columns || 120;
|
|
138
|
+
const line = chalk.gray('─'.repeat(w));
|
|
139
|
+
|
|
73
140
|
if (!apiKey) {
|
|
74
|
-
console.log(chalk.red('\n❌
|
|
141
|
+
console.log(chalk.red('\n ❌ Giriş yapılmamış. natureco login\n'));
|
|
75
142
|
process.exit(1);
|
|
76
143
|
}
|
|
77
|
-
|
|
144
|
+
|
|
78
145
|
let botList;
|
|
79
146
|
try {
|
|
80
147
|
botList = await getBots(apiKey);
|
|
81
148
|
} catch (err) {
|
|
82
|
-
console.log(chalk.red(`\n❌
|
|
149
|
+
console.log(chalk.red(`\n ❌ Hata: ${err.message}\n`));
|
|
83
150
|
process.exit(1);
|
|
84
151
|
}
|
|
85
|
-
|
|
86
|
-
if (!botList || !botList.bots || botList.bots.length === 0) {
|
|
87
|
-
console.log(chalk.gray('No bots found.\n'));
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Find session across all bots
|
|
152
|
+
|
|
92
153
|
let session = null;
|
|
93
154
|
let botName = null;
|
|
94
|
-
|
|
95
|
-
for (const bot of botList.bots) {
|
|
155
|
+
for (const bot of (botList?.bots || [])) {
|
|
96
156
|
session = loadSession(bot.id, sessionId);
|
|
97
|
-
if (session) {
|
|
98
|
-
botName = bot.name;
|
|
99
|
-
break;
|
|
100
|
-
}
|
|
157
|
+
if (session) { botName = bot.name; break; }
|
|
101
158
|
}
|
|
102
|
-
|
|
159
|
+
|
|
103
160
|
if (!session) {
|
|
104
|
-
console.log(chalk.red(`\n❌
|
|
161
|
+
console.log(chalk.red(`\n ❌ Oturum bulunamadı: ${sessionId}\n`));
|
|
105
162
|
process.exit(1);
|
|
106
163
|
}
|
|
107
|
-
|
|
108
|
-
console.log(
|
|
109
|
-
console.log(
|
|
110
|
-
console.log(chalk.
|
|
111
|
-
console.log(chalk.gray(`
|
|
112
|
-
|
|
164
|
+
|
|
165
|
+
console.log('');
|
|
166
|
+
console.log(line);
|
|
167
|
+
console.log(chalk.bold.cyan(` Oturum: ${session.id.slice(-8)}`));
|
|
168
|
+
console.log(chalk.gray(` Bot: ${botName} · ${new Date(session.createdAt).toLocaleString('tr-TR')} · ${session.messages.length} mesaj`));
|
|
169
|
+
console.log(line);
|
|
170
|
+
console.log('');
|
|
171
|
+
|
|
113
172
|
session.messages.forEach((msg, i) => {
|
|
114
|
-
|
|
115
|
-
console.log(chalk.
|
|
173
|
+
const num = chalk.gray(` ${String(i + 1).padStart(2)}.`);
|
|
174
|
+
console.log(num + ' ' + chalk.white('You ') + msg.user);
|
|
175
|
+
console.log(' ' + chalk.cyan('Bot ') + msg.bot);
|
|
176
|
+
console.log('');
|
|
116
177
|
});
|
|
178
|
+
|
|
179
|
+
console.log(line);
|
|
180
|
+
console.log('');
|
|
117
181
|
}
|
|
118
182
|
|
|
119
183
|
module.exports = sessions;
|
package/src/commands/status.js
CHANGED
|
@@ -8,77 +8,120 @@ const { getSkills } = require('../utils/skills');
|
|
|
8
8
|
async function status() {
|
|
9
9
|
const config = getConfig();
|
|
10
10
|
const version = require('../../package.json').version;
|
|
11
|
+
const w = process.stdout.columns || 120;
|
|
12
|
+
const line = chalk.gray('─'.repeat(w));
|
|
11
13
|
|
|
14
|
+
// ── Header ────────────────────────────────────────────────────────────────
|
|
12
15
|
console.log('');
|
|
13
|
-
console.log(
|
|
14
|
-
|
|
16
|
+
console.log(line);
|
|
17
|
+
const title = chalk.bold.cyan(' NatureCo CLI') + chalk.gray(' — Durum Raporu');
|
|
18
|
+
const ver = chalk.gray(`v${version} `);
|
|
19
|
+
const pad = w - 16 - version.length - 3;
|
|
20
|
+
console.log(title + ' '.repeat(Math.max(1, pad)) + ver);
|
|
21
|
+
console.log(line);
|
|
15
22
|
|
|
16
|
-
// Provider
|
|
23
|
+
// ── Provider & Bot ────────────────────────────────────────────────────────
|
|
17
24
|
const providerHost = config.providerUrl
|
|
18
25
|
? config.providerUrl.replace('https://', '').split('/')[0]
|
|
19
26
|
: null;
|
|
27
|
+
const model = config.providerModel
|
|
28
|
+
? config.providerModel.split('/').pop().split('-').slice(0, 3).join('-')
|
|
29
|
+
: 'bilinmiyor';
|
|
20
30
|
|
|
21
|
-
console.log(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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));
|
|
31
|
+
console.log('');
|
|
32
|
+
row('Provider ', providerHost ? chalk.white(providerHost) : chalk.yellow('yapılandırılmamış'),
|
|
33
|
+
'Bot ', config.botName ? chalk.cyan(config.botName) : chalk.gray('—'), w);
|
|
34
|
+
row('Model ', chalk.white(model),
|
|
35
|
+
'Kullanıcı', config.userName ? chalk.white(config.userName) : chalk.gray('—'), w);
|
|
30
36
|
|
|
31
|
-
//
|
|
37
|
+
// ── Servisler ─────────────────────────────────────────────────────────────
|
|
32
38
|
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
39
|
const dashPid = path.join(os.homedir(), '.natureco', 'dashboard.pid');
|
|
40
|
+
const gatewayRunning = fs.existsSync(pidFile);
|
|
38
41
|
const dashRunning = fs.existsSync(dashPid);
|
|
39
|
-
console.log(chalk.gray(' Dashboard : ') + (dashRunning ? chalk.green('çalışıyor (localhost:3848)') : chalk.gray('durdurulmuş')));
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
|
|
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')));
|
|
43
|
+
row('Gateway ', gatewayRunning ? chalk.green('● çalışıyor') : chalk.gray('○ durdurulmuş'),
|
|
44
|
+
'Dashboard', dashRunning ? chalk.green('● localhost:3848') : chalk.gray('○ durdurulmuş'), w);
|
|
48
45
|
|
|
49
|
-
//
|
|
50
|
-
const
|
|
51
|
-
|
|
46
|
+
// ── Entegrasyonlar ────────────────────────────────────────────────────────
|
|
47
|
+
const tg = config.telegramToken ? chalk.green('● bağlı') : chalk.gray('○ —');
|
|
48
|
+
const wa = config.whatsappConnected ? chalk.green('● bağlı') : chalk.gray('○ —');
|
|
49
|
+
const dc = config.discordToken ? chalk.green('● bağlı') : chalk.gray('○ —');
|
|
50
|
+
const sl = config.slackToken ? chalk.green('● bağlı') : chalk.gray('○ —');
|
|
52
51
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
console.log(
|
|
52
|
+
console.log('');
|
|
53
|
+
console.log(chalk.gray(' ' + '─'.repeat(w - 2)));
|
|
54
|
+
console.log(chalk.gray(' Entegrasyonlar'));
|
|
55
|
+
console.log('');
|
|
56
|
+
row('Telegram ', tg, 'Discord ', dc, w);
|
|
57
|
+
row('WhatsApp ', wa, 'Slack ', sl, w);
|
|
57
58
|
|
|
58
|
-
//
|
|
59
|
+
// ── Kaynaklar ─────────────────────────────────────────────────────────────
|
|
60
|
+
const skills = getSkills();
|
|
61
|
+
const memDir = path.join(os.homedir(), '.natureco', 'memory');
|
|
62
|
+
const memFiles = fs.existsSync(memDir)
|
|
63
|
+
? fs.readdirSync(memDir).filter(f => f.endsWith('.json')).length : 0;
|
|
59
64
|
const sessDir = path.join(os.homedir(), '.natureco', 'sessions');
|
|
65
|
+
let sessCount = 0;
|
|
60
66
|
if (fs.existsSync(sessDir)) {
|
|
61
|
-
|
|
62
|
-
if (sessions.length > 0) {
|
|
63
|
-
console.log(chalk.gray(' Sessions : ') + chalk.white(`${sessions.length} kayıtlı`));
|
|
64
|
-
}
|
|
67
|
+
sessCount = fs.readdirSync(sessDir).filter(f => f.endsWith('.json')).length;
|
|
65
68
|
}
|
|
66
69
|
|
|
67
|
-
|
|
70
|
+
console.log('');
|
|
71
|
+
console.log(chalk.gray(' ' + '─'.repeat(w - 2)));
|
|
72
|
+
console.log(chalk.gray(' Kaynaklar'));
|
|
73
|
+
console.log('');
|
|
74
|
+
row('Skills ', chalk.white(`${skills.length} yüklü`),
|
|
75
|
+
'Hafıza ', chalk.white(`${memFiles} bot`), w);
|
|
76
|
+
row('Sessions ', chalk.white(`${sessCount} kayıtlı`),
|
|
77
|
+
'Versiyon ', chalk.white(`v${version}`), w);
|
|
78
|
+
|
|
79
|
+
// ── Son Loglar ────────────────────────────────────────────────────────────
|
|
68
80
|
const logFile = path.join(os.homedir(), '.natureco', 'gateway.log');
|
|
69
81
|
if (fs.existsSync(logFile)) {
|
|
70
82
|
const lines = fs.readFileSync(logFile, 'utf-8').split('\n').filter(l => l.trim());
|
|
71
83
|
const last = lines.slice(-3);
|
|
72
84
|
if (last.length > 0) {
|
|
73
|
-
console.log(
|
|
74
|
-
|
|
85
|
+
console.log('');
|
|
86
|
+
console.log(chalk.gray(' ' + '─'.repeat(w - 2)));
|
|
87
|
+
console.log(chalk.gray(' Son Aktivite'));
|
|
88
|
+
console.log('');
|
|
89
|
+
last.forEach(l => {
|
|
90
|
+
const trimmed = l.slice(0, w - 4);
|
|
91
|
+
console.log(chalk.gray(' ') + chalk.gray(trimmed));
|
|
92
|
+
});
|
|
75
93
|
}
|
|
76
94
|
}
|
|
77
95
|
|
|
96
|
+
// ── Footer ────────────────────────────────────────────────────────────────
|
|
78
97
|
console.log('');
|
|
79
|
-
console.log(
|
|
80
|
-
console.log(
|
|
81
|
-
|
|
98
|
+
console.log(line);
|
|
99
|
+
console.log(
|
|
100
|
+
chalk.gray(' natureco doctor') +
|
|
101
|
+
chalk.gray(' · ') +
|
|
102
|
+
chalk.gray('natureco chat') +
|
|
103
|
+
chalk.gray(' · ') +
|
|
104
|
+
chalk.gray('natureco code') +
|
|
105
|
+
chalk.gray(' · ') +
|
|
106
|
+
chalk.gray('natureco channels status')
|
|
107
|
+
);
|
|
108
|
+
console.log(line);
|
|
109
|
+
console.log('');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// ── İki kolon satır yardımcısı ─────────────────────────────────────────────
|
|
113
|
+
function row(label1, val1, label2, val2, w) {
|
|
114
|
+
const col = Math.floor(w / 2);
|
|
115
|
+
const left = chalk.gray(' ' + label1) + val1;
|
|
116
|
+
const right = chalk.gray(label2) + val2;
|
|
117
|
+
// ANSI kodlarını sayma — sabit padding kullan
|
|
118
|
+
const leftPlain = (' ' + label1).length + stripAnsi(String(val1)).length;
|
|
119
|
+
const pad = Math.max(1, col - leftPlain);
|
|
120
|
+
console.log(left + ' '.repeat(pad) + right);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function stripAnsi(str) {
|
|
124
|
+
return str.replace(/\x1B\[[0-9;]*m/g, '');
|
|
82
125
|
}
|
|
83
126
|
|
|
84
127
|
module.exports = status;
|