natureco-cli 2.23.27 → 2.23.29
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 +68 -6
- package/package.json +10 -6
- package/src/commands/channels.js +94 -4
- package/src/commands/chat.js +11 -25
- package/src/commands/code.js +12 -11
- package/src/commands/config.js +111 -68
- package/src/commands/doctor.js +121 -16
- package/src/commands/gateway-server.js +35 -21
- package/src/commands/gateway.js +11 -20
- package/src/commands/help.js +6 -0
- package/src/commands/imessage.js +55 -0
- package/src/commands/irc.js +70 -0
- package/src/commands/mattermost.js +62 -0
- package/src/commands/message.js +24 -4
- package/src/commands/models.js +584 -216
- package/src/commands/plugins.js +415 -172
- package/src/commands/security.js +149 -1
- package/src/commands/setup.js +1 -3
- package/src/commands/signal.js +66 -0
- package/src/commands/skills.js +20 -29
- package/src/commands/sms.js +64 -0
- package/src/commands/tasks.js +328 -79
- package/src/commands/webhooks.js +79 -0
- package/src/commands/whatsapp.js +7 -21
- package/src/tools/bash.js +63 -29
- package/src/utils/api.js +3 -20
- package/src/utils/approvals.js +297 -0
- package/src/utils/background.js +223 -66
- package/src/utils/baileys.js +21 -0
- package/src/utils/config.js +141 -10
- package/src/utils/errors.js +148 -0
- package/src/utils/inquirer-wrapper.js +1 -2
- package/src/utils/path-utils.js +13 -13
- package/src/utils/plugin-registry.js +238 -0
- package/src/utils/secrets.js +177 -0
- package/src/utils/skills.js +10 -23
package/bin/natureco.js
CHANGED
|
@@ -13,6 +13,12 @@ const init = require('../src/commands/init');
|
|
|
13
13
|
const config = require('../src/commands/config');
|
|
14
14
|
const ask = require('../src/commands/ask');
|
|
15
15
|
const run = require('../src/commands/run');
|
|
16
|
+
const signal = require('../src/commands/signal');
|
|
17
|
+
const irc = require('../src/commands/irc');
|
|
18
|
+
const mattermost = require('../src/commands/mattermost');
|
|
19
|
+
const imessage = require('../src/commands/imessage');
|
|
20
|
+
const sms = require('../src/commands/sms');
|
|
21
|
+
const webhooks = require('../src/commands/webhooks');
|
|
16
22
|
|
|
17
23
|
const program = new Command();
|
|
18
24
|
|
|
@@ -42,6 +48,12 @@ ${chalk.yellow('🔌 Entegrasyonlar')}
|
|
|
42
48
|
${chalk.cyan('whatsapp')} WhatsApp bağlantısı
|
|
43
49
|
${chalk.cyan('discord')} Discord bağlantısı
|
|
44
50
|
${chalk.cyan('slack')} Slack bağlantısı
|
|
51
|
+
${chalk.cyan('signal')} Signal bağlantısı
|
|
52
|
+
${chalk.cyan('irc')} IRC bağlantısı
|
|
53
|
+
${chalk.cyan('mattermost')} Mattermost bağlantısı
|
|
54
|
+
${chalk.cyan('imessage')} iMessage bağlantısı
|
|
55
|
+
${chalk.cyan('sms')} SMS (Twilio) bağlantısı
|
|
56
|
+
${chalk.cyan('webhooks')} Webhook yönetimi
|
|
45
57
|
${chalk.cyan('gateway')} WebSocket gateway
|
|
46
58
|
|
|
47
59
|
${chalk.yellow('🛠️ Geliştirici Araçları')}
|
|
@@ -123,7 +135,7 @@ program
|
|
|
123
135
|
|
|
124
136
|
program
|
|
125
137
|
.command('config <action> [key] [value...]')
|
|
126
|
-
.description('Manage configuration (get|set|list)')
|
|
138
|
+
.description('Manage configuration (get|set|list|backups|restore)')
|
|
127
139
|
.action((action, key, value) => config([action, key, ...(value || [])]));
|
|
128
140
|
|
|
129
141
|
program
|
|
@@ -232,10 +244,10 @@ program
|
|
|
232
244
|
|
|
233
245
|
program
|
|
234
246
|
.command('tasks [action] [params...]')
|
|
235
|
-
.description('Manage background tasks (list|show)')
|
|
247
|
+
.description('Manage background tasks (list|show|cancel|audit|maintenance|flow|summary)')
|
|
236
248
|
.action((action, params) => {
|
|
237
249
|
const tasksCmd = require('../src/commands/tasks');
|
|
238
|
-
tasksCmd(action, ...(params || []));
|
|
250
|
+
tasksCmd([action, ...(params || [])]);
|
|
239
251
|
});
|
|
240
252
|
|
|
241
253
|
program
|
|
@@ -286,6 +298,54 @@ program
|
|
|
286
298
|
telegramCmd(action, chatId);
|
|
287
299
|
});
|
|
288
300
|
|
|
301
|
+
program
|
|
302
|
+
.command('signal <action>')
|
|
303
|
+
.description('Signal integration (connect|disconnect|status)')
|
|
304
|
+
.action((action) => {
|
|
305
|
+
const signalCmd = require('../src/commands/signal');
|
|
306
|
+
signalCmd(action);
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
program
|
|
310
|
+
.command('irc <action>')
|
|
311
|
+
.description('IRC integration (connect|disconnect|status)')
|
|
312
|
+
.action((action) => {
|
|
313
|
+
const ircCmd = require('../src/commands/irc');
|
|
314
|
+
ircCmd(action);
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
program
|
|
318
|
+
.command('mattermost <action>')
|
|
319
|
+
.description('Mattermost integration (connect|disconnect|status)')
|
|
320
|
+
.action((action) => {
|
|
321
|
+
const mattermostCmd = require('../src/commands/mattermost');
|
|
322
|
+
mattermostCmd(action);
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
program
|
|
326
|
+
.command('imessage <action>')
|
|
327
|
+
.description('iMessage integration (connect|disconnect|status)')
|
|
328
|
+
.action((action) => {
|
|
329
|
+
const imessageCmd = require('../src/commands/imessage');
|
|
330
|
+
imessageCmd(action);
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
program
|
|
334
|
+
.command('sms <action>')
|
|
335
|
+
.description('SMS/Twilio integration (connect|disconnect|status)')
|
|
336
|
+
.action((action) => {
|
|
337
|
+
const smsCmd = require('../src/commands/sms');
|
|
338
|
+
smsCmd(action);
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
program
|
|
342
|
+
.command('webhooks <action>')
|
|
343
|
+
.description('Webhook management (connect|disconnect|status|list)')
|
|
344
|
+
.action((action) => {
|
|
345
|
+
const webhooksCmd = require('../src/commands/webhooks');
|
|
346
|
+
webhooksCmd(action);
|
|
347
|
+
});
|
|
348
|
+
|
|
289
349
|
program
|
|
290
350
|
.command('message <action>')
|
|
291
351
|
.description('Send messages directly (send)')
|
|
@@ -332,10 +392,12 @@ program
|
|
|
332
392
|
|
|
333
393
|
program
|
|
334
394
|
.command('models [action] [params...]')
|
|
335
|
-
.description('Manage AI models (list|set|scan|aliases)')
|
|
395
|
+
.description('Manage AI models (list|set|scan|aliases|fallbacks)')
|
|
396
|
+
.allowUnknownOption()
|
|
336
397
|
.action((action, params) => {
|
|
337
398
|
const modelsCmd = require('../src/commands/models');
|
|
338
|
-
|
|
399
|
+
const allArgs = process.argv.slice(process.argv.indexOf('models') + 1);
|
|
400
|
+
modelsCmd(allArgs);
|
|
339
401
|
});
|
|
340
402
|
|
|
341
403
|
program
|
|
@@ -396,7 +458,7 @@ program
|
|
|
396
458
|
|
|
397
459
|
program
|
|
398
460
|
.command('plugins [action] [params...]')
|
|
399
|
-
.description('Manage plugins (list|install|enable|disable|info|doctor)')
|
|
461
|
+
.description('Manage plugins (list|install|uninstall|enable|disable|info|update|search|doctor|registry)')
|
|
400
462
|
.action((action, params) => {
|
|
401
463
|
const pluginsCmd = require('../src/commands/plugins');
|
|
402
464
|
pluginsCmd([action, ...(params || [])]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "natureco-cli",
|
|
3
|
-
"version": "2.23.
|
|
3
|
+
"version": "2.23.29",
|
|
4
4
|
"description": "NatureCo AI Bot Terminal Interface",
|
|
5
5
|
"bin": {
|
|
6
6
|
"natureco": "bin/natureco.js"
|
|
@@ -11,7 +11,10 @@
|
|
|
11
11
|
"skills/"
|
|
12
12
|
],
|
|
13
13
|
"scripts": {
|
|
14
|
-
"test": "node bin/natureco.js help"
|
|
14
|
+
"test": "node bin/natureco.js help",
|
|
15
|
+
"test:unit": "vitest run",
|
|
16
|
+
"test:watch": "vitest watch",
|
|
17
|
+
"test:coverage": "vitest run --coverage"
|
|
15
18
|
},
|
|
16
19
|
"keywords": [
|
|
17
20
|
"natureco",
|
|
@@ -27,17 +30,18 @@
|
|
|
27
30
|
"@whiskeysockets/baileys": "^7.0.0-rc10",
|
|
28
31
|
"chalk": "^4.1.2",
|
|
29
32
|
"commander": "^11.1.0",
|
|
30
|
-
"
|
|
33
|
+
"json5": "^2.2.3",
|
|
31
34
|
"node-cron": "^4.2.1",
|
|
32
35
|
"node-telegram-bot-api": "^0.67.0",
|
|
33
|
-
"ora": "^9.4.0",
|
|
34
36
|
"pino": "^8.21.0",
|
|
35
37
|
"qrcode-terminal": "^0.12.0",
|
|
36
38
|
"semver": "^7.8.1",
|
|
37
39
|
"ws": "^8.20.0"
|
|
38
40
|
},
|
|
39
41
|
"engines": {
|
|
40
|
-
"node": ">=
|
|
42
|
+
"node": ">=18.0.0"
|
|
41
43
|
},
|
|
42
|
-
"
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"vitest": "^4.1.9"
|
|
46
|
+
}
|
|
43
47
|
}
|
package/src/commands/channels.js
CHANGED
|
@@ -61,6 +61,66 @@ function listChannels() {
|
|
|
61
61
|
});
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
if (config.signalBotId) {
|
|
65
|
+
channels.push({
|
|
66
|
+
name: 'Signal',
|
|
67
|
+
icon: '🔒',
|
|
68
|
+
status: 'bağlı',
|
|
69
|
+
detail: `hesap: ${config.signalAccount || 'bağlı'}`,
|
|
70
|
+
chats: 0,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (config.ircBotId) {
|
|
75
|
+
channels.push({
|
|
76
|
+
name: 'IRC',
|
|
77
|
+
icon: '💬',
|
|
78
|
+
status: 'bağlı',
|
|
79
|
+
detail: `${config.ircHost}:${config.ircPort} (${config.ircNick})`,
|
|
80
|
+
chats: 0,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (config.mattermostBotId) {
|
|
85
|
+
channels.push({
|
|
86
|
+
name: 'Mattermost',
|
|
87
|
+
icon: '📢',
|
|
88
|
+
status: 'bağlı',
|
|
89
|
+
detail: `sunucu: ${config.mattermostBaseUrl || 'bağlı'}`,
|
|
90
|
+
chats: 0,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (config.imessageBotId) {
|
|
95
|
+
channels.push({
|
|
96
|
+
name: 'iMessage',
|
|
97
|
+
icon: '💬',
|
|
98
|
+
status: 'bağlı',
|
|
99
|
+
detail: 'macOS bridge',
|
|
100
|
+
chats: 0,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (config.smsBotId) {
|
|
105
|
+
channels.push({
|
|
106
|
+
name: 'SMS (Twilio)',
|
|
107
|
+
icon: '📨',
|
|
108
|
+
status: 'bağlı',
|
|
109
|
+
detail: `numara: ${config.smsFromNumber || 'bağlı'}`,
|
|
110
|
+
chats: 0,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (config.webhooks && config.webhooks.length > 0) {
|
|
115
|
+
channels.push({
|
|
116
|
+
name: 'Webhooks',
|
|
117
|
+
icon: '🔗',
|
|
118
|
+
status: 'bağlı',
|
|
119
|
+
detail: `${config.webhooks.length} route`,
|
|
120
|
+
chats: 0,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
64
124
|
console.log('');
|
|
65
125
|
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
66
126
|
console.log(chalk.cyan.bold('\n Kanallar\n'));
|
|
@@ -71,7 +131,13 @@ function listChannels() {
|
|
|
71
131
|
console.log(chalk.cyan(' natureco telegram connect'));
|
|
72
132
|
console.log(chalk.cyan(' natureco whatsapp connect'));
|
|
73
133
|
console.log(chalk.cyan(' natureco discord connect'));
|
|
74
|
-
console.log(chalk.cyan(' natureco slack connect
|
|
134
|
+
console.log(chalk.cyan(' natureco slack connect'));
|
|
135
|
+
console.log(chalk.cyan(' natureco signal connect'));
|
|
136
|
+
console.log(chalk.cyan(' natureco irc connect'));
|
|
137
|
+
console.log(chalk.cyan(' natureco mattermost connect'));
|
|
138
|
+
console.log(chalk.cyan(' natureco imessage connect'));
|
|
139
|
+
console.log(chalk.cyan(' natureco sms connect'));
|
|
140
|
+
console.log(chalk.cyan(' natureco webhooks connect\n'));
|
|
75
141
|
return;
|
|
76
142
|
}
|
|
77
143
|
|
|
@@ -98,6 +164,12 @@ function statusChannels() {
|
|
|
98
164
|
{ name: 'WhatsApp', ok: !!config.whatsappConnected },
|
|
99
165
|
{ name: 'Discord', ok: !!config.discordToken },
|
|
100
166
|
{ name: 'Slack', ok: !!config.slackToken },
|
|
167
|
+
{ name: 'Signal', ok: !!config.signalBotId },
|
|
168
|
+
{ name: 'IRC', ok: !!config.ircBotId },
|
|
169
|
+
{ name: 'Mattermost', ok: !!config.mattermostBotId },
|
|
170
|
+
{ name: 'iMessage', ok: !!config.imessageBotId },
|
|
171
|
+
{ name: 'SMS', ok: !!config.smsBotId },
|
|
172
|
+
{ name: 'Webhooks', ok: !!(config.webhooks && config.webhooks.length > 0) },
|
|
101
173
|
];
|
|
102
174
|
|
|
103
175
|
checks.forEach(ch => {
|
|
@@ -110,13 +182,13 @@ function statusChannels() {
|
|
|
110
182
|
const connected = checks.filter(c => c.ok).length;
|
|
111
183
|
console.log('');
|
|
112
184
|
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
113
|
-
console.log(chalk.gray(` ${connected}
|
|
185
|
+
console.log(chalk.gray(` ${connected}/${checks.length} kanal aktif\n`));
|
|
114
186
|
}
|
|
115
187
|
|
|
116
188
|
function removeChannel(channel) {
|
|
117
189
|
if (!channel) {
|
|
118
190
|
console.log(chalk.red('\n ❌ Kanal adı gerekli\n'));
|
|
119
|
-
console.log(chalk.gray(' Kullanım: natureco channels remove <telegram|whatsapp|discord|slack>\n'));
|
|
191
|
+
console.log(chalk.gray(' Kullanım: natureco channels remove <telegram|whatsapp|discord|slack|signal|irc|mattermost|imessage|sms|webhooks>\n'));
|
|
120
192
|
process.exit(1);
|
|
121
193
|
}
|
|
122
194
|
|
|
@@ -128,7 +200,6 @@ function removeChannel(channel) {
|
|
|
128
200
|
delete config.telegramBotId;
|
|
129
201
|
delete config.telegramAllowedChats;
|
|
130
202
|
} else if (ch === 'whatsapp') {
|
|
131
|
-
// Session dosyalarını sil
|
|
132
203
|
if (config.whatsappBotId) {
|
|
133
204
|
const sessionDir = path.join(os.homedir(), '.natureco', 'whatsapp-sessions', config.whatsappBotId);
|
|
134
205
|
if (fs.existsSync(sessionDir)) {
|
|
@@ -145,6 +216,25 @@ function removeChannel(channel) {
|
|
|
145
216
|
} else if (ch === 'slack') {
|
|
146
217
|
delete config.slackToken;
|
|
147
218
|
delete config.slackBotId;
|
|
219
|
+
} else if (ch === 'signal') {
|
|
220
|
+
delete config.signalHttpUrl;
|
|
221
|
+
delete config.signalAccount;
|
|
222
|
+
delete config.signalDmPolicy;
|
|
223
|
+
delete config.signalBotId;
|
|
224
|
+
} else if (ch === 'irc') {
|
|
225
|
+
delete config.ircHost; delete config.ircPort; delete config.ircTls;
|
|
226
|
+
delete config.ircNick; delete config.ircUsername; delete config.ircPassword;
|
|
227
|
+
delete config.ircChannels; delete config.ircDmPolicy; delete config.ircBotId;
|
|
228
|
+
} else if (ch === 'mattermost') {
|
|
229
|
+
delete config.mattermostBaseUrl; delete config.mattermostToken;
|
|
230
|
+
delete config.mattermostDmPolicy; delete config.mattermostBotId;
|
|
231
|
+
} else if (ch === 'imessage') {
|
|
232
|
+
delete config.imessageCliPath; delete config.imessageDmPolicy; delete config.imessageBotId;
|
|
233
|
+
} else if (ch === 'sms') {
|
|
234
|
+
delete config.smsAccountSid; delete config.smsAuthToken; delete config.smsFromNumber;
|
|
235
|
+
delete config.smsPublicWebhookUrl; delete config.smsDmPolicy; delete config.smsBotId;
|
|
236
|
+
} else if (ch === 'webhooks') {
|
|
237
|
+
delete config.webhooks; delete config.webhookEnabled;
|
|
148
238
|
} else {
|
|
149
239
|
console.log(chalk.red(`\n ❌ Bilinmeyen kanal: ${channel}\n`));
|
|
150
240
|
process.exit(1);
|
package/src/commands/chat.js
CHANGED
|
@@ -13,8 +13,8 @@ const { getMemoryPrompt, extractMemoryFromMessage, loadMemory, clearMemory, addM
|
|
|
13
13
|
const { getCommands, getCommandContent } = require('../utils/commands');
|
|
14
14
|
const { runHooks } = require('../utils/hooks');
|
|
15
15
|
const { createSession, loadSession, getLatestSession, addMessageToSession, loadLastSession, listSessions, saveSession } = require('../utils/sessions');
|
|
16
|
-
const {
|
|
17
|
-
const {
|
|
16
|
+
const { NatureCoError, ApiError, handleError } = require('../utils/errors');
|
|
17
|
+
const { getToolDefinitions, getSessionStats, resetSessionStats } = require('../utils/tool-runner');
|
|
18
18
|
|
|
19
19
|
// ── ASCII Logo ────────────────────────────────────────────────────────────────
|
|
20
20
|
const ASCII_LOGO = [
|
|
@@ -80,10 +80,9 @@ async function chat(botName, options = {}) {
|
|
|
80
80
|
// ── Bot seçimi ──────────────────────────────────────────────────────────────
|
|
81
81
|
let botList;
|
|
82
82
|
try {
|
|
83
|
-
botList = await getBots(apiKey
|
|
83
|
+
botList = await getBots(apiKey ?? config.providerApiKey ?? '');
|
|
84
84
|
} catch (err) {
|
|
85
|
-
|
|
86
|
-
process.exit(1);
|
|
85
|
+
handleError(err, { prefix: '❌ Error', exit: true });
|
|
87
86
|
}
|
|
88
87
|
|
|
89
88
|
if (!botList?.bots?.length) {
|
|
@@ -311,7 +310,7 @@ async function chat(botName, options = {}) {
|
|
|
311
310
|
console.log();
|
|
312
311
|
addToHistory(bot.id, userMessage, reply, conversationId);
|
|
313
312
|
addMessageToSession(bot.id, session.id, userMessage, reply);
|
|
314
|
-
} catch (e) { stopLoading();
|
|
313
|
+
} catch (e) { stopLoading(); handleError(e, { prefix: 'Error', exit: false }); console.log(); }
|
|
315
314
|
} else {
|
|
316
315
|
console.log(chalk.red(`Bilinmeyen komut: /${cmd}`));
|
|
317
316
|
console.log();
|
|
@@ -336,27 +335,12 @@ async function chat(botName, options = {}) {
|
|
|
336
335
|
|
|
337
336
|
try {
|
|
338
337
|
const toolDefinitions = getToolDefinitions();
|
|
339
|
-
let response = await _sendMessage(apiKey
|
|
338
|
+
let response = await _sendMessage(apiKey ?? config.providerApiKey, bot.id, userMessage, conversationId, systemPrompt, toolDefinitions, options);
|
|
340
339
|
stopLoading();
|
|
341
340
|
|
|
342
|
-
if (response
|
|
343
|
-
|
|
344
|
-
// Tool loop — api.js zaten tool loop yapıyor, bu loop çalışmamalı
|
|
345
|
-
let iter = 0;
|
|
346
|
-
while (iter < 5) {
|
|
347
|
-
const toolCalls = extractToolCalls(response);
|
|
348
|
-
if (!toolCalls?.length) break;
|
|
349
|
-
console.log(chalk.yellow(`🔧 ${toolCalls.length} tool çalıştırılıyor...`));
|
|
350
|
-
const toolResults = await executeToolCalls(toolCalls);
|
|
351
|
-
const toolMsg = toolResults.map(tr => `Tool: ${tr.name}\nResult: ${tr.result.success ? (tr.result.output || '') : tr.result.error}`).join('\n\n');
|
|
352
|
-
startLoading();
|
|
353
|
-
response = await _sendMessage(apiKey || config.providerApiKey, bot.id, toolMsg, conversationId, systemPrompt, toolDefinitions, options);
|
|
354
|
-
stopLoading();
|
|
355
|
-
if (response.conversation_id) conversationId = response.conversation_id;
|
|
356
|
-
iter++;
|
|
357
|
-
}
|
|
341
|
+
if (response?.conversation_id) conversationId = response.conversation_id;
|
|
358
342
|
|
|
359
|
-
let botReply = response
|
|
343
|
+
let botReply = response?.reply ?? response?.message ?? 'No response';
|
|
360
344
|
botReply = await runHooks('post-message', botReply, { botId: bot.id, botName: bot.name });
|
|
361
345
|
|
|
362
346
|
console.log(chalk.cyan(`${displayBotName} `) + botReply);
|
|
@@ -370,7 +354,9 @@ async function chat(botName, options = {}) {
|
|
|
370
354
|
|
|
371
355
|
} catch (err) {
|
|
372
356
|
stopLoading();
|
|
373
|
-
const errMsg = err
|
|
357
|
+
const errMsg = err instanceof NatureCoError
|
|
358
|
+
? err.message
|
|
359
|
+
: (err?.message?.split('"message":"')[1]?.split('"')[0] ?? err?.message ?? 'Unknown error');
|
|
374
360
|
console.log(chalk.red(`Error: ${errMsg}`));
|
|
375
361
|
console.log();
|
|
376
362
|
}
|
package/src/commands/code.js
CHANGED
|
@@ -13,6 +13,18 @@ const { createSession, addMessageToSession } = require('../utils/sessions');
|
|
|
13
13
|
const { addToHistory } = require('../utils/history');
|
|
14
14
|
const { getToolDefinitions, executeTool } = require('../utils/tool-runner');
|
|
15
15
|
|
|
16
|
+
let rl = null;
|
|
17
|
+
|
|
18
|
+
async function confirmAction(message) {
|
|
19
|
+
return new Promise(resolve => {
|
|
20
|
+
rl.question(chalk.yellow(`⚠ ${message}\n[? Devam edilsin mi? (Y/n) `), answer => {
|
|
21
|
+
const confirmed = !answer || answer.toLowerCase() === 'y';
|
|
22
|
+
console.log(chalk.gray(` ✓ Devam edilsin mi? ${confirmed ? 'Yes' : 'No'}`));
|
|
23
|
+
resolve(confirmed);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
16
28
|
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
17
29
|
const sep = () => chalk.gray('─'.repeat(process.stdout.columns || 120));
|
|
18
30
|
|
|
@@ -670,17 +682,6 @@ ${indexPrompt}`;
|
|
|
670
682
|
}
|
|
671
683
|
|
|
672
684
|
// ── Input loop — readline herhangi bir sebepten kapanırsa yeniden oluştur ───
|
|
673
|
-
let rl;
|
|
674
|
-
|
|
675
|
-
async function confirmAction(message) {
|
|
676
|
-
return new Promise(resolve => {
|
|
677
|
-
rl.question(chalk.yellow(`⚠ ${message}\n[? Devam edilsin mi? (Y/n) `), answer => {
|
|
678
|
-
const confirmed = !answer || answer.toLowerCase() === 'y';
|
|
679
|
-
console.log(chalk.gray(` ✓ Devam edilsin mi? ${confirmed ? 'Yes' : 'No'}`));
|
|
680
|
-
resolve(confirmed);
|
|
681
|
-
});
|
|
682
|
-
});
|
|
683
|
-
}
|
|
684
685
|
|
|
685
686
|
function createRl() {
|
|
686
687
|
if (rl) {
|
package/src/commands/config.js
CHANGED
|
@@ -1,68 +1,111 @@
|
|
|
1
|
-
const chalk = require('chalk');
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
console.log(
|
|
16
|
-
console.log(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
console.log(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
let parsedValue = value;
|
|
53
|
-
try {
|
|
54
|
-
parsedValue = JSON.parse(value);
|
|
55
|
-
} catch {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { getConfig, setConfigValue, getAllConfig, listBackups, restoreConfig, CONFIG_BACKUP_DIR } = require('../utils/config');
|
|
4
|
+
|
|
5
|
+
function config(args) {
|
|
6
|
+
const [action, key, ...valueParts] = args;
|
|
7
|
+
|
|
8
|
+
if (!action) {
|
|
9
|
+
console.log(chalk.red('\n❌ Kullanım: natureco config <get|set|list|backups|restore> [key] [value]\n'));
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (action === 'list') {
|
|
14
|
+
const cfg = getAllConfig();
|
|
15
|
+
console.log(chalk.green.bold('\n╭─ Config ─╮\n'));
|
|
16
|
+
console.log(JSON.stringify(cfg, null, 2));
|
|
17
|
+
console.log('');
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (action === 'get') {
|
|
22
|
+
if (!key) {
|
|
23
|
+
console.log(chalk.red('\n❌ Key belirtilmedi.\n'));
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
const cfg = getConfig();
|
|
27
|
+
const keys = key.split('.');
|
|
28
|
+
let value = cfg;
|
|
29
|
+
for (const k of keys) {
|
|
30
|
+
value = value?.[k];
|
|
31
|
+
}
|
|
32
|
+
if (value === undefined) {
|
|
33
|
+
console.log(chalk.gray(`\n${key}: (tanımlı değil)\n`));
|
|
34
|
+
} else {
|
|
35
|
+
console.log(chalk.cyan(`\n${key}:`), chalk.white(JSON.stringify(value, null, 2)));
|
|
36
|
+
console.log('');
|
|
37
|
+
}
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (action === 'set') {
|
|
42
|
+
if (!key) {
|
|
43
|
+
console.log(chalk.red('\n❌ Key belirtilmedi.\n'));
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
if (valueParts.length === 0) {
|
|
47
|
+
console.log(chalk.red('\n❌ Value belirtilmedi.\n'));
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
const value = valueParts.join(' ');
|
|
51
|
+
|
|
52
|
+
let parsedValue = value;
|
|
53
|
+
try {
|
|
54
|
+
parsedValue = JSON.parse(value);
|
|
55
|
+
} catch {}
|
|
56
|
+
|
|
57
|
+
setConfigValue(key, parsedValue);
|
|
58
|
+
console.log(chalk.green(`\n✅ ${key} = ${JSON.stringify(parsedValue)}\n`));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (action === 'backups' || action === 'backup') {
|
|
63
|
+
const backups = listBackups();
|
|
64
|
+
console.log(chalk.cyan.bold('\n Config Yedekleri\n'));
|
|
65
|
+
if (backups.length === 0) {
|
|
66
|
+
console.log(chalk.gray(' Henüz yedek alınmamış.\n'));
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
backups.forEach((f, i) => {
|
|
70
|
+
const ts = f.replace(/^config-|\.json$/g, '').replace(/T/, ' ').replace(/-/g, ':').replace(/:[^:]*$/, '');
|
|
71
|
+
console.log(chalk.white(` ${i + 1}. ${ts}`));
|
|
72
|
+
console.log(chalk.gray(` ${path.join(CONFIG_BACKUP_DIR, f)}`));
|
|
73
|
+
});
|
|
74
|
+
console.log(chalk.gray(`\n Geri yüklemek için: natureco config restore <dosya-adı>`));
|
|
75
|
+
console.log(chalk.gray(` Örnek: natureco config restore ${backups[0] || 'config-....json'}\n`));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (action === 'restore') {
|
|
80
|
+
const backupId = key;
|
|
81
|
+
if (!backupId) {
|
|
82
|
+
const backups = listBackups();
|
|
83
|
+
if (backups.length === 0) {
|
|
84
|
+
console.log(chalk.red('\n❌ Geri yüklenecek yedek bulunamadı.\n'));
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
console.log(chalk.cyan.bold('\n Geri Yükleme\n'));
|
|
88
|
+
console.log(chalk.gray(' En son yedek: ') + chalk.white(backups[0]));
|
|
89
|
+
console.log('');
|
|
90
|
+
console.log(chalk.gray(' Kullanım: ') + chalk.cyan(`natureco config restore ${backups[0]}`));
|
|
91
|
+
console.log(chalk.gray(' Yedekleri listelemek için: ') + chalk.cyan('natureco config backups\n'));
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
try {
|
|
96
|
+
const result = restoreConfig(backupId);
|
|
97
|
+
console.log(chalk.green(`\n✅ Config geri yüklendi: ${result.timestamp}\n`));
|
|
98
|
+
console.log(chalk.gray(` Kaynak: ${result.path}\n`));
|
|
99
|
+
} catch (err) {
|
|
100
|
+
console.log(chalk.red(`\n❌ Geri yükleme başarısız: ${err.message}\n`));
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
console.log(chalk.red(`\n❌ Geçersiz action: ${action}\n`));
|
|
107
|
+
console.log(chalk.gray(' Kullanım: natureco config <get|set|list|backups|restore> [key] [value]\n'));
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
module.exports = config;
|