natureco-cli 5.57.0 → 5.59.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/package.json +1 -1
- package/src/commands/channels.js +11 -9
- package/src/commands/cron.js +75 -73
- package/src/commands/doctor.js +24 -22
- package/src/commands/gateway.js +25 -23
- package/src/commands/init.js +30 -28
- package/src/commands/plugins.js +69 -67
- package/src/commands/setup.js +42 -40
- package/src/commands/skills.js +76 -74
- package/src/commands/status.js +10 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "natureco-cli",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.59.0",
|
|
4
4
|
"description": "OpenClaw'dan daha güvenli, daha hızlı, daha ucuz AI agent CLI. Multi-agent, self-evolving skills, audit log, maliyet optimizasyonu ve NatureCo platform-native.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"natureco": "bin/natureco.js"
|
package/src/commands/channels.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
const chalk = require('chalk');
|
|
2
|
+
const { getLang: _gl } = require('../utils/i18n');
|
|
3
|
+
const L = (tr, en) => (_gl() === 'en' ? en : tr);
|
|
2
4
|
const tui = require('../utils/tui');
|
|
3
5
|
const F = require('../utils/format');
|
|
4
6
|
const { getConfig, saveConfig } = require('../utils/config');
|
|
@@ -297,9 +299,9 @@ function listChannels() {
|
|
|
297
299
|
F.header('Channels');
|
|
298
300
|
|
|
299
301
|
if (channels.length === 0) {
|
|
300
|
-
console.log('\n' + tui.styled(' 📡 Bağlı Kanal Yok', { color: tui.PALETTE.warning, bold: true }));
|
|
302
|
+
console.log('\n' + tui.styled(L(' 📡 Bağlı Kanal Yok', ' 📡 No Connected Channels'), { color: tui.PALETTE.warning, bold: true }));
|
|
301
303
|
console.log(tui.styled(' ' + '─'.repeat(56), { color: tui.PALETTE.border }));
|
|
302
|
-
console.log('\n ' + tui.C.muted('Bağlamak için:'));
|
|
304
|
+
console.log('\n ' + tui.C.muted(L('Bağlamak için:', 'To connect:')));
|
|
303
305
|
const connectCmds = ['telegram', 'whatsapp', 'discord', 'slack', 'signal', 'irc', 'mattermost', 'imessage', 'sms', 'webhooks'];
|
|
304
306
|
for (const c of connectCmds) {
|
|
305
307
|
console.log(' ' + tui.C.brand('natureco ' + c + ' connect'));
|
|
@@ -308,23 +310,23 @@ function listChannels() {
|
|
|
308
310
|
return;
|
|
309
311
|
}
|
|
310
312
|
|
|
311
|
-
console.log('\n' + tui.styled(' 📡 Bağlı Kanallar (' + channels.length + ')', { color: tui.PALETTE.primary, bold: true }));
|
|
313
|
+
console.log('\n' + tui.styled(L(' 📡 Bağlı Kanallar (', ' 📡 Connected Channels (') + channels.length + ')', { color: tui.PALETTE.primary, bold: true }));
|
|
312
314
|
console.log(tui.styled(' ' + '─'.repeat(56), { color: tui.PALETTE.border }));
|
|
313
315
|
console.log('\n' + tui.table(channels, [
|
|
314
316
|
{
|
|
315
|
-
key: 'name', label: 'Kanal', minWidth: 14,
|
|
317
|
+
key: 'name', label: L('Kanal', 'Channel'), minWidth: 14,
|
|
316
318
|
render: r => tui.styled(r.type + ' ' + r.name, { color: tui.PALETTE.primary, bold: true })
|
|
317
319
|
},
|
|
318
320
|
{
|
|
319
|
-
key: 'status', label: 'Durum', minWidth: 14,
|
|
321
|
+
key: 'status', label: L('Durum', 'Status'), minWidth: 14,
|
|
320
322
|
render: r => r.status === 'connected'
|
|
321
|
-
? tui.styled(' ✓ Bağlı ', { bg: tui.PALETTE.success, color: '#000', bold: true })
|
|
322
|
-
: tui.styled(' ✗ Kopuk ', { bg: tui.PALETTE.muted, color: '#000', bold: true })
|
|
323
|
+
? tui.styled(L(' ✓ Bağlı ', ' ✓ Linked '), { bg: tui.PALETTE.success, color: '#000', bold: true })
|
|
324
|
+
: tui.styled(L(' ✗ Kopuk ', ' ✗ Down '), { bg: tui.PALETTE.muted, color: '#000', bold: true })
|
|
323
325
|
},
|
|
324
|
-
{ key: 'detail', label: 'Detay', minWidth: 30, render: r => tui.C.muted(r.detail) },
|
|
326
|
+
{ key: 'detail', label: L('Detay', 'Detail'), minWidth: 30, render: r => tui.C.muted(r.detail) },
|
|
325
327
|
], { borderStyle: 'round', zebra: true }));
|
|
326
328
|
|
|
327
|
-
console.log('\n ' + tui.C.muted('Kaldırmak için: ') + tui.C.brand('natureco channels remove <kanal>'));
|
|
329
|
+
console.log('\n ' + tui.C.muted(L('Kaldırmak için: ', 'To remove: ')) + tui.C.brand(L('natureco channels remove <kanal>', 'natureco channels remove <channel>')));
|
|
328
330
|
console.log('');
|
|
329
331
|
}
|
|
330
332
|
|
package/src/commands/cron.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
const chalk = require('chalk');
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const { getLang: _gl } = require('../utils/i18n');
|
|
3
|
+
const L = (tr, en) => (_gl() === 'en' ? en : tr);
|
|
2
4
|
const tui = require('../utils/tui');
|
|
3
5
|
const F = require('../utils/format');
|
|
4
6
|
const fs = require('fs');
|
|
@@ -40,8 +42,8 @@ function saveCrons(crons) {
|
|
|
40
42
|
|
|
41
43
|
async function cron(action, options) {
|
|
42
44
|
if (!action || !['add', 'list', 'remove', 'get', 'edit', 'enable', 'disable', 'runs', 'run'].includes(action)) {
|
|
43
|
-
console.log(chalk.red('\n❌ Geçersiz aksiyon\n'));
|
|
44
|
-
console.log(chalk.gray('Kullanım:'));
|
|
45
|
+
console.log(chalk.red(L('\n❌ Geçersiz aksiyon\n', '\n❌ Invalid action\n')));
|
|
46
|
+
console.log(chalk.gray(L('Kullanım:', 'Usage:')));
|
|
45
47
|
console.log(chalk.cyan(' natureco cron add --name <name> --schedule <cron> --action <channel> --target <target> --prompt <prompt>'));
|
|
46
48
|
console.log(chalk.cyan(' natureco cron list'));
|
|
47
49
|
console.log(chalk.cyan(' natureco cron get <name>'));
|
|
@@ -51,8 +53,8 @@ async function cron(action, options) {
|
|
|
51
53
|
console.log(chalk.cyan(' natureco cron disable <name>'));
|
|
52
54
|
console.log(chalk.cyan(' natureco cron runs <name>'));
|
|
53
55
|
console.log(chalk.cyan(' natureco cron run <name>'));
|
|
54
|
-
console.log(chalk.gray('\nÖrnek:'));
|
|
55
|
-
console.log(chalk.cyan(' natureco cron add --name "bitcoin-fiyat" --schedule "0 9 * * *" --action "whatsapp" --target "+905422842631" --prompt "Bugünkü Bitcoin fiyatını öğren ve kısaca bildir"\n'));
|
|
56
|
+
console.log(chalk.gray(L('\nÖrnek:', '\nExample:')));
|
|
57
|
+
console.log(chalk.cyan(L(' natureco cron add --name "bitcoin-fiyat" --schedule "0 9 * * *" --action "whatsapp" --target "+905422842631" --prompt "Bugünkü Bitcoin fiyatını öğren ve kısaca bildir"\n', ' natureco cron add --name "bitcoin-price" --schedule "0 9 * * *" --action "whatsapp" --target "+905422842631" --prompt "Get today\'s Bitcoin price and report briefly"\n')));
|
|
56
58
|
process.exit(1);
|
|
57
59
|
}
|
|
58
60
|
|
|
@@ -81,13 +83,13 @@ async function addCron(options) {
|
|
|
81
83
|
const { name, schedule, action, target, prompt } = options;
|
|
82
84
|
|
|
83
85
|
if (!name || !schedule || !action || !target || !prompt) {
|
|
84
|
-
console.log(chalk.red('\n❌ Eksik parametre\n'));
|
|
85
|
-
console.log(chalk.gray('Gerekli parametreler: --name, --schedule, --action, --target, --prompt\n'));
|
|
86
|
+
console.log(chalk.red(L('\n❌ Eksik parametre\n', '\n❌ Missing parameter\n')));
|
|
87
|
+
console.log(chalk.gray(L('Gerekli parametreler: --name, --schedule, --action, --target, --prompt\n', 'Required parameters: --name, --schedule, --action, --target, --prompt\n')));
|
|
86
88
|
process.exit(1);
|
|
87
89
|
}
|
|
88
90
|
|
|
89
91
|
if (!['whatsapp', 'telegram'].includes(action)) {
|
|
90
|
-
console.log(chalk.red('\n❌ Geçersiz action. Sadece "whatsapp" veya "telegram" kullanılabilir\n'));
|
|
92
|
+
console.log(chalk.red(L('\n❌ Geçersiz action. Sadece "whatsapp" veya "telegram" kullanılabilir\n', '\n❌ Invalid action. Only "whatsapp" or "telegram" can be used\n')));
|
|
91
93
|
process.exit(1);
|
|
92
94
|
}
|
|
93
95
|
|
|
@@ -95,13 +97,13 @@ async function addCron(options) {
|
|
|
95
97
|
try {
|
|
96
98
|
const nodeCron = require('node-cron');
|
|
97
99
|
if (!nodeCron.validate(schedule)) {
|
|
98
|
-
console.log(chalk.red('\n❌ Geçersiz cron ifadesi\n'));
|
|
99
|
-
console.log(chalk.gray('Örnek: "0 9 * * *" (her gün saat 09:00)\n'));
|
|
100
|
+
console.log(chalk.red(L('\n❌ Geçersiz cron ifadesi\n', '\n❌ Invalid cron expression\n')));
|
|
101
|
+
console.log(chalk.gray(L('Örnek: "0 9 * * *" (her gün saat 09:00)\n', 'Example: "0 9 * * *" (every day at 09:00)\n')));
|
|
100
102
|
process.exit(1);
|
|
101
103
|
}
|
|
102
104
|
} catch (err) {
|
|
103
|
-
console.log(chalk.red('\n❌ node-cron yüklü değil\n'));
|
|
104
|
-
console.log(chalk.yellow('Yüklemek için:'), chalk.cyan('npm install -g node-cron\n'));
|
|
105
|
+
console.log(chalk.red(L('\n❌ node-cron yüklü değil\n', '\n❌ node-cron not installed\n')));
|
|
106
|
+
console.log(chalk.yellow(L('Yüklemek için:', 'To install:')), chalk.cyan('npm install -g node-cron\n'));
|
|
105
107
|
process.exit(1);
|
|
106
108
|
}
|
|
107
109
|
|
|
@@ -109,8 +111,8 @@ async function addCron(options) {
|
|
|
109
111
|
|
|
110
112
|
// Check if name already exists
|
|
111
113
|
if (crons.find(c => c.name === name)) {
|
|
112
|
-
console.log(chalk.red('\n❌ Bu isimde bir cron zaten var\n'));
|
|
113
|
-
console.log(chalk.yellow('Önce silin:'), chalk.cyan(`natureco cron remove --name "${name}"\n`));
|
|
114
|
+
console.log(chalk.red(L('\n❌ Bu isimde bir cron zaten var\n', '\n❌ A cron with this name already exists\n')));
|
|
115
|
+
console.log(chalk.yellow(L('Önce silin:', 'Delete it first:')), chalk.cyan(`natureco cron remove --name "${name}"\n`));
|
|
114
116
|
process.exit(1);
|
|
115
117
|
}
|
|
116
118
|
|
|
@@ -127,24 +129,24 @@ async function addCron(options) {
|
|
|
127
129
|
crons.push(newCron);
|
|
128
130
|
saveCrons(crons);
|
|
129
131
|
|
|
130
|
-
console.log(chalk.green('\n✅ Cron eklendi!\n'));
|
|
131
|
-
console.log(chalk.cyan('İsim:'), chalk.white(name));
|
|
132
|
-
console.log(chalk.cyan('Zamanlama:'), chalk.white(schedule));
|
|
133
|
-
console.log(chalk.cyan('Kanal:'), chalk.white(action));
|
|
134
|
-
console.log(chalk.cyan('Hedef:'), chalk.white(target));
|
|
132
|
+
console.log(chalk.green(L('\n✅ Cron eklendi!\n', '\n✅ Cron added!\n')));
|
|
133
|
+
console.log(chalk.cyan(L('İsim:', 'Name:')), chalk.white(name));
|
|
134
|
+
console.log(chalk.cyan(L('Zamanlama:', 'Schedule:')), chalk.white(schedule));
|
|
135
|
+
console.log(chalk.cyan(L('Kanal:', 'Channel:')), chalk.white(action));
|
|
136
|
+
console.log(chalk.cyan(L('Hedef:', 'Target:')), chalk.white(target));
|
|
135
137
|
console.log(chalk.cyan('Prompt:'), chalk.white(prompt));
|
|
136
|
-
console.log(chalk.gray('\nCron\'lar gateway başlatıldığında aktif olur.'));
|
|
137
|
-
console.log(chalk.gray('Gateway çalışıyorsa yeniden başlatın: natureco gateway stop && natureco gateway start\n'));
|
|
138
|
+
console.log(chalk.gray(L('\nCron\'lar gateway başlatıldığında aktif olur.', '\nCrons become active when the gateway starts.')));
|
|
139
|
+
console.log(chalk.gray(L('Gateway çalışıyorsa yeniden başlatın: natureco gateway stop && natureco gateway start\n', 'If the gateway is running, restart it: natureco gateway stop && natureco gateway start\n')));
|
|
138
140
|
}
|
|
139
141
|
|
|
140
142
|
function listCrons() {
|
|
141
143
|
const crons = loadCrons();
|
|
142
144
|
|
|
143
145
|
if (crons.length === 0) {
|
|
144
|
-
console.log('\n' + tui.styled(' ⏰ Zamanlanmış Görevler', { color: tui.PALETTE.primary, bold: true }));
|
|
146
|
+
console.log('\n' + tui.styled(L(' ⏰ Zamanlanmış Görevler', ' ⏰ Scheduled Tasks'), { color: tui.PALETTE.primary, bold: true }));
|
|
145
147
|
console.log(tui.styled(' ' + '─'.repeat(56), { color: tui.PALETTE.border }));
|
|
146
|
-
console.log('\n ' + tui.C.muted('Henüz cron tanımlı değil. Eklemek için:'));
|
|
147
|
-
console.log(' ' + tui.C.brand('natureco cron add --name "görev" --schedule "0 9 * * *" --action telegram --prompt "..."'));
|
|
148
|
+
console.log('\n ' + tui.C.muted(L('Henüz cron tanımlı değil. Eklemek için:', 'No crons defined yet. To add:')));
|
|
149
|
+
console.log(' ' + tui.C.brand(L('natureco cron add --name "görev" --schedule "0 9 * * *" --action telegram --prompt "..."', 'natureco cron add --name "task" --schedule "0 9 * * *" --action telegram --prompt "..."')));
|
|
148
150
|
console.log('');
|
|
149
151
|
return;
|
|
150
152
|
}
|
|
@@ -177,16 +179,16 @@ function listCrons() {
|
|
|
177
179
|
console.log(tui.styled(' ' + '─'.repeat(56), { color: tui.PALETTE.border }));
|
|
178
180
|
|
|
179
181
|
console.log('\n' + tui.table(rows, [
|
|
180
|
-
{ key: 'name', label: 'İsim', minWidth: 20, render: r => tui.styled(r.name, { color: tui.PALETTE.primary, bold: true }) },
|
|
181
|
-
{ key: 'schedule', label: 'Zamanlama', minWidth: 18, render: r => tui.C.muted(r.schedule) },
|
|
182
|
+
{ key: 'name', label: L('İsim', 'Name'), minWidth: 20, render: r => tui.styled(r.name, { color: tui.PALETTE.primary, bold: true }) },
|
|
183
|
+
{ key: 'schedule', label: L('Zamanlama', 'Schedule'), minWidth: 18, render: r => tui.C.muted(r.schedule) },
|
|
182
184
|
{
|
|
183
|
-
key: 'status', label: 'Durum', minWidth: 10,
|
|
185
|
+
key: 'status', label: L('Durum', 'Status'), minWidth: 10,
|
|
184
186
|
render: r => r.status
|
|
185
|
-
? tui.styled(' ✓ Aktif ', { bg: tui.PALETTE.success, color: '#000', bold: true })
|
|
186
|
-
: tui.styled(' ✗ Pasif ', { bg: tui.PALETTE.muted, color: '#000', bold: true }),
|
|
187
|
+
? tui.styled(L(' ✓ Aktif ', ' ✓ Active '), { bg: tui.PALETTE.success, color: '#000', bold: true })
|
|
188
|
+
: tui.styled(L(' ✗ Pasif ', ' ✗ Inactive '), { bg: tui.PALETTE.muted, color: '#000', bold: true }),
|
|
187
189
|
},
|
|
188
|
-
{ key: 'target', label: 'Hedef', minWidth: 18, render: r => tui.C.text(r.target) },
|
|
189
|
-
{ key: 'lastRun', label: 'Son Çalışma', minWidth: 18, render: r => tui.C.muted(r.lastRun) },
|
|
190
|
+
{ key: 'target', label: L('Hedef', 'Target'), minWidth: 18, render: r => tui.C.text(r.target) },
|
|
191
|
+
{ key: 'lastRun', label: L('Son Çalışma', 'Last Run'), minWidth: 18, render: r => tui.C.muted(r.lastRun) },
|
|
190
192
|
], { borderStyle: 'round', zebra: true }));
|
|
191
193
|
|
|
192
194
|
console.log('');
|
|
@@ -196,7 +198,7 @@ function removeCron(options) {
|
|
|
196
198
|
const { name } = options;
|
|
197
199
|
|
|
198
200
|
if (!name) {
|
|
199
|
-
F.error('--name parametresi gerekli');
|
|
201
|
+
F.error(L('--name parametresi gerekli', '--name parameter required'));
|
|
200
202
|
process.exit(1);
|
|
201
203
|
}
|
|
202
204
|
|
|
@@ -204,39 +206,39 @@ function removeCron(options) {
|
|
|
204
206
|
const index = crons.findIndex(c => c.name === name);
|
|
205
207
|
|
|
206
208
|
if (index === -1) {
|
|
207
|
-
F.error('Bu isimde bir cron bulunamadı');
|
|
209
|
+
F.error(L('Bu isimde bir cron bulunamadı', 'No cron found with this name'));
|
|
208
210
|
process.exit(1);
|
|
209
211
|
}
|
|
210
212
|
|
|
211
213
|
crons.splice(index, 1);
|
|
212
214
|
saveCrons(crons);
|
|
213
215
|
|
|
214
|
-
F.success('Cron silindi!');
|
|
215
|
-
F.meta('Gateway çalışıyorsa yeniden başlatın: natureco gateway stop && natureco gateway start');
|
|
216
|
+
F.success(L('Cron silindi!', 'Cron deleted!'));
|
|
217
|
+
F.meta(L('Gateway çalışıyorsa yeniden başlatın: natureco gateway stop && natureco gateway start', 'If the gateway is running, restart it: natureco gateway stop && natureco gateway start'));
|
|
216
218
|
}
|
|
217
219
|
|
|
218
220
|
function getCron(options) {
|
|
219
221
|
const { name } = options;
|
|
220
222
|
if (!name) {
|
|
221
|
-
F.error('Cron adı gerekli. Kullanım: natureco cron get <name>');
|
|
223
|
+
F.error(L('Cron adı gerekli. Kullanım: natureco cron get <name>', 'Cron name required. Usage: natureco cron get <name>'));
|
|
222
224
|
process.exit(1);
|
|
223
225
|
}
|
|
224
226
|
|
|
225
227
|
const crons = loadCrons();
|
|
226
228
|
const cron = crons.find(c => c.name === name);
|
|
227
229
|
if (!cron) {
|
|
228
|
-
F.error('"' + name + '" isminde bir cron bulunamadı');
|
|
230
|
+
F.error('"' + name + L('" isminde bir cron bulunamadı', '" — no cron found with this name'));
|
|
229
231
|
process.exit(1);
|
|
230
232
|
}
|
|
231
233
|
|
|
232
234
|
F.header('Cron: ' + cron.name);
|
|
233
|
-
F.kv('İsim', cron.name);
|
|
234
|
-
F.kv('Zamanlama', cron.schedule);
|
|
235
|
-
F.kv('Kanal', cron.action);
|
|
236
|
-
F.kv('Hedef', cron.target);
|
|
235
|
+
F.kv(L('İsim', 'Name'), cron.name);
|
|
236
|
+
F.kv(L('Zamanlama', 'Schedule'), cron.schedule);
|
|
237
|
+
F.kv(L('Kanal', 'Channel'), cron.action);
|
|
238
|
+
F.kv(L('Hedef', 'Target'), cron.target);
|
|
237
239
|
F.kv('Prompt', cron.prompt);
|
|
238
|
-
F.kv('Oluşturulma', cron.createdAt);
|
|
239
|
-
F.kv('Durum', cron.enabled ? 'Aktif' : 'Pasif');
|
|
240
|
+
F.kv(L('Oluşturulma', 'Created'), cron.createdAt);
|
|
241
|
+
F.kv(L('Durum', 'Status'), cron.enabled ? L('Aktif', 'Active') : L('Pasif', 'Inactive'));
|
|
240
242
|
}
|
|
241
243
|
|
|
242
244
|
function editCron(options) {
|
|
@@ -244,14 +246,14 @@ function editCron(options) {
|
|
|
244
246
|
const newName = options['newName'];
|
|
245
247
|
|
|
246
248
|
if (!name) {
|
|
247
|
-
F.error('Cron adı gerekli. Kullanım: natureco cron edit <name> [--name <newName>] [--schedule <cron>] [--action <channel>] [--target <target>] [--prompt <prompt>]');
|
|
249
|
+
F.error(L('Cron adı gerekli. Kullanım: natureco cron edit <name> [--name <newName>] [--schedule <cron>] [--action <channel>] [--target <target>] [--prompt <prompt>]', 'Cron name required. Usage: natureco cron edit <name> [--name <newName>] [--schedule <cron>] [--action <channel>] [--target <target>] [--prompt <prompt>]'));
|
|
248
250
|
process.exit(1);
|
|
249
251
|
}
|
|
250
252
|
|
|
251
253
|
const crons = loadCrons();
|
|
252
254
|
const cron = crons.find(c => c.name === name);
|
|
253
255
|
if (!cron) {
|
|
254
|
-
F.error('"' + name + '" isminde bir cron bulunamadı');
|
|
256
|
+
F.error('"' + name + L('" isminde bir cron bulunamadı', '" — no cron found with this name'));
|
|
255
257
|
process.exit(1);
|
|
256
258
|
}
|
|
257
259
|
|
|
@@ -260,18 +262,18 @@ function editCron(options) {
|
|
|
260
262
|
try {
|
|
261
263
|
const nodeCron = require('node-cron');
|
|
262
264
|
if (!nodeCron.validate(schedule)) {
|
|
263
|
-
F.error('Geçersiz cron ifadesi');
|
|
265
|
+
F.error(L('Geçersiz cron ifadesi', 'Invalid cron expression'));
|
|
264
266
|
process.exit(1);
|
|
265
267
|
}
|
|
266
268
|
} catch (err) {
|
|
267
|
-
F.error('node-cron yüklü değil');
|
|
269
|
+
F.error(L('node-cron yüklü değil', 'node-cron not installed'));
|
|
268
270
|
process.exit(1);
|
|
269
271
|
}
|
|
270
272
|
cron.schedule = schedule;
|
|
271
273
|
}
|
|
272
274
|
if (action) {
|
|
273
275
|
if (!['whatsapp', 'telegram'].includes(action)) {
|
|
274
|
-
F.error('Geçersiz action. Sadece "whatsapp" veya "telegram" kullanılabilir');
|
|
276
|
+
F.error(L('Geçersiz action. Sadece "whatsapp" veya "telegram" kullanılabilir', 'Invalid action. Only "whatsapp" or "telegram" can be used'));
|
|
275
277
|
process.exit(1);
|
|
276
278
|
}
|
|
277
279
|
cron.action = action;
|
|
@@ -281,65 +283,65 @@ function editCron(options) {
|
|
|
281
283
|
|
|
282
284
|
saveCrons(crons);
|
|
283
285
|
|
|
284
|
-
F.success('Cron güncellendi!');
|
|
285
|
-
F.kv('İsim', cron.name);
|
|
286
|
-
F.kv('Zamanlama', cron.schedule);
|
|
287
|
-
F.kv('Kanal', cron.action);
|
|
288
|
-
F.kv('Hedef', cron.target);
|
|
286
|
+
F.success(L('Cron güncellendi!', 'Cron updated!'));
|
|
287
|
+
F.kv(L('İsim', 'Name'), cron.name);
|
|
288
|
+
F.kv(L('Zamanlama', 'Schedule'), cron.schedule);
|
|
289
|
+
F.kv(L('Kanal', 'Channel'), cron.action);
|
|
290
|
+
F.kv(L('Hedef', 'Target'), cron.target);
|
|
289
291
|
F.kv('Prompt', cron.prompt);
|
|
290
|
-
F.meta('Gateway çalışıyorsa yeniden başlatın: natureco gateway stop && natureco gateway start');
|
|
292
|
+
F.meta(L('Gateway çalışıyorsa yeniden başlatın: natureco gateway stop && natureco gateway start', 'If the gateway is running, restart it: natureco gateway stop && natureco gateway start'));
|
|
291
293
|
}
|
|
292
294
|
|
|
293
295
|
function enableCron(options) {
|
|
294
296
|
const { name } = options;
|
|
295
297
|
if (!name) {
|
|
296
|
-
F.error('Cron adı gerekli. Kullanım: natureco cron enable <name>');
|
|
298
|
+
F.error(L('Cron adı gerekli. Kullanım: natureco cron enable <name>', 'Cron name required. Usage: natureco cron enable <name>'));
|
|
297
299
|
process.exit(1);
|
|
298
300
|
}
|
|
299
301
|
|
|
300
302
|
const crons = loadCrons();
|
|
301
303
|
const cron = crons.find(c => c.name === name);
|
|
302
304
|
if (!cron) {
|
|
303
|
-
F.error('"' + name + '" isminde bir cron bulunamadı');
|
|
305
|
+
F.error('"' + name + L('" isminde bir cron bulunamadı', '" — no cron found with this name'));
|
|
304
306
|
process.exit(1);
|
|
305
307
|
}
|
|
306
308
|
|
|
307
309
|
if (cron.enabled) {
|
|
308
|
-
F.warning('"' + name + '" cron zaten aktif');
|
|
310
|
+
F.warning('"' + name + L('" cron zaten aktif', '" cron already active'));
|
|
309
311
|
return;
|
|
310
312
|
}
|
|
311
313
|
|
|
312
314
|
cron.enabled = true;
|
|
313
315
|
saveCrons(crons);
|
|
314
316
|
F.dot(true, name);
|
|
315
|
-
F.success('"' + name + '" cron aktifleştirildi');
|
|
316
|
-
F.meta('Gateway çalışıyorsa yeniden başlatın: natureco gateway stop && natureco gateway start');
|
|
317
|
+
F.success('"' + name + L('" cron aktifleştirildi', '" cron enabled'));
|
|
318
|
+
F.meta(L('Gateway çalışıyorsa yeniden başlatın: natureco gateway stop && natureco gateway start', 'If the gateway is running, restart it: natureco gateway stop && natureco gateway start'));
|
|
317
319
|
}
|
|
318
320
|
|
|
319
321
|
function disableCron(options) {
|
|
320
322
|
const { name } = options;
|
|
321
323
|
if (!name) {
|
|
322
|
-
F.error('Cron adı gerekli. Kullanım: natureco cron disable <name>');
|
|
324
|
+
F.error(L('Cron adı gerekli. Kullanım: natureco cron disable <name>', 'Cron name required. Usage: natureco cron disable <name>'));
|
|
323
325
|
process.exit(1);
|
|
324
326
|
}
|
|
325
327
|
|
|
326
328
|
const crons = loadCrons();
|
|
327
329
|
const cron = crons.find(c => c.name === name);
|
|
328
330
|
if (!cron) {
|
|
329
|
-
F.error('"' + name + '" isminde bir cron bulunamadı');
|
|
331
|
+
F.error('"' + name + L('" isminde bir cron bulunamadı', '" — no cron found with this name'));
|
|
330
332
|
process.exit(1);
|
|
331
333
|
}
|
|
332
334
|
|
|
333
335
|
if (!cron.enabled) {
|
|
334
|
-
F.warning('"' + name + '" cron zaten pasif');
|
|
336
|
+
F.warning('"' + name + L('" cron zaten pasif', '" cron already inactive'));
|
|
335
337
|
return;
|
|
336
338
|
}
|
|
337
339
|
|
|
338
340
|
cron.enabled = false;
|
|
339
341
|
saveCrons(crons);
|
|
340
342
|
F.dot(false, name);
|
|
341
|
-
F.success('"' + name + '" cron pasifleştirildi');
|
|
342
|
-
F.meta('Gateway çalışıyorsa yeniden başlatın: natureco gateway stop && natureco gateway start');
|
|
343
|
+
F.success('"' + name + L('" cron pasifleştirildi', '" cron disabled'));
|
|
344
|
+
F.meta(L('Gateway çalışıyorsa yeniden başlatın: natureco gateway stop && natureco gateway start', 'If the gateway is running, restart it: natureco gateway stop && natureco gateway start'));
|
|
343
345
|
}
|
|
344
346
|
|
|
345
347
|
function loadRuns() {
|
|
@@ -356,7 +358,7 @@ function loadRuns() {
|
|
|
356
358
|
function showRuns(options) {
|
|
357
359
|
const { name } = options;
|
|
358
360
|
if (!name) {
|
|
359
|
-
F.error('Cron adı gerekli. Kullanım: natureco cron runs <name>');
|
|
361
|
+
F.error(L('Cron adı gerekli. Kullanım: natureco cron runs <name>', 'Cron name required. Usage: natureco cron runs <name>'));
|
|
360
362
|
process.exit(1);
|
|
361
363
|
}
|
|
362
364
|
|
|
@@ -365,7 +367,7 @@ function showRuns(options) {
|
|
|
365
367
|
F.header('Cron Runs: ' + name);
|
|
366
368
|
|
|
367
369
|
if (runs.length === 0) {
|
|
368
|
-
F.meta('"' + name + '" için kayıtlı çalışma geçmişi yok');
|
|
370
|
+
F.meta('"' + name + L('" için kayıtlı çalışma geçmişi yok', '" — no run history recorded'));
|
|
369
371
|
return;
|
|
370
372
|
}
|
|
371
373
|
|
|
@@ -380,25 +382,25 @@ function showRuns(options) {
|
|
|
380
382
|
function runCron(options) {
|
|
381
383
|
const { name } = options;
|
|
382
384
|
if (!name) {
|
|
383
|
-
F.error('Cron adı gerekli. Kullanım: natureco cron run <name>');
|
|
385
|
+
F.error(L('Cron adı gerekli. Kullanım: natureco cron run <name>', 'Cron name required. Usage: natureco cron run <name>'));
|
|
384
386
|
process.exit(1);
|
|
385
387
|
}
|
|
386
388
|
|
|
387
389
|
const crons = loadCrons();
|
|
388
390
|
const cron = crons.find(c => c.name === name);
|
|
389
391
|
if (!cron) {
|
|
390
|
-
F.error('"' + name + '" isminde bir cron bulunamadı');
|
|
392
|
+
F.error('"' + name + L('" isminde bir cron bulunamadı', '" — no cron found with this name'));
|
|
391
393
|
process.exit(1);
|
|
392
394
|
}
|
|
393
395
|
|
|
394
396
|
const timestamp = new Date().toISOString();
|
|
395
397
|
|
|
396
|
-
F.info('"' + name + '" cron manuel olarak çalıştırılıyor...');
|
|
397
|
-
F.kv('Zamanlama', cron.schedule);
|
|
398
|
-
F.kv('Kanal', cron.action);
|
|
399
|
-
F.kv('Hedef', cron.target);
|
|
398
|
+
F.info('"' + name + L('" cron manuel olarak çalıştırılıyor...', '" cron running manually...'));
|
|
399
|
+
F.kv(L('Zamanlama', 'Schedule'), cron.schedule);
|
|
400
|
+
F.kv(L('Kanal', 'Channel'), cron.action);
|
|
401
|
+
F.kv(L('Hedef', 'Target'), cron.target);
|
|
400
402
|
F.kv('Prompt', cron.prompt);
|
|
401
|
-
F.success('Cron tetiklendi (mock)');
|
|
403
|
+
F.success(L('Cron tetiklendi (mock)', 'Cron triggered (mock)'));
|
|
402
404
|
|
|
403
405
|
// Log the run
|
|
404
406
|
const runs = loadRuns();
|
package/src/commands/doctor.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
const chalk = require('chalk');
|
|
2
|
+
const { getLang: _gl } = require('../utils/i18n');
|
|
3
|
+
const L = (tr, en) => (_gl() === 'en' ? en : tr);
|
|
2
4
|
const F = require('../utils/format');
|
|
3
5
|
const tui = require('../utils/tui');
|
|
4
6
|
const fs = require('fs');
|
|
@@ -98,19 +100,19 @@ function cmdCheck(name) {
|
|
|
98
100
|
}
|
|
99
101
|
|
|
100
102
|
function cmdRun(opts = {}) {
|
|
101
|
-
F.header(opts.fix ? 'System Doctor · Otomatik Düzeltme (--fix)' : 'System Doctor · Tüm Sistem Kontrolleri', { icon: opts.fix ? '🔧' : '🩺' });
|
|
103
|
+
F.header(opts.fix ? L('System Doctor · Otomatik Düzeltme (--fix)', 'System Doctor · Auto-Fix (--fix)') : L('System Doctor · Tüm Sistem Kontrolleri', 'System Doctor · All System Checks'), { icon: opts.fix ? '🔧' : '🩺' });
|
|
102
104
|
|
|
103
105
|
// v5.43.2: --fix modunda önce düzeltilebilir sorunları onar, sonra kontrolleri çalıştır.
|
|
104
106
|
if (opts.fix) {
|
|
105
107
|
const { applied, failed } = applyFixes();
|
|
106
108
|
if (applied.length) {
|
|
107
|
-
console.log('\n' + tui.C.green(' 🔧 Düzeltildi:'));
|
|
109
|
+
console.log('\n' + tui.C.green(L(' 🔧 Düzeltildi:', ' 🔧 Fixed:')));
|
|
108
110
|
applied.forEach(a => console.log(' ' + tui.C.text('• ' + a)));
|
|
109
111
|
} else {
|
|
110
|
-
console.log('\n' + tui.C.muted(' 🔧 Düzeltilecek bir şey yok — sistem zaten düzgün.'));
|
|
112
|
+
console.log('\n' + tui.C.muted(L(' 🔧 Düzeltilecek bir şey yok — sistem zaten düzgün.', ' 🔧 Nothing to fix — system is already fine.')));
|
|
111
113
|
}
|
|
112
114
|
if (failed.length) {
|
|
113
|
-
console.log('\n' + tui.C.amber(' ⚠️ Otomatik düzeltilemedi:'));
|
|
115
|
+
console.log('\n' + tui.C.amber(L(' ⚠️ Otomatik düzeltilemedi:', ' ⚠️ Could not auto-fix:')));
|
|
114
116
|
failed.forEach(f => console.log(' ' + tui.C.muted('• ' + f)));
|
|
115
117
|
}
|
|
116
118
|
console.log('');
|
|
@@ -133,14 +135,14 @@ function cmdRun(opts = {}) {
|
|
|
133
135
|
|
|
134
136
|
// Yeni TUI tablo
|
|
135
137
|
console.log('\n' + tui.table(rows, [
|
|
136
|
-
{ key: 'check', label: 'Kontrol', minWidth: 28 },
|
|
138
|
+
{ key: 'check', label: L('Kontrol', 'Check'), minWidth: 28 },
|
|
137
139
|
{
|
|
138
|
-
key: 'status', label: 'Durum', minWidth: 9,
|
|
140
|
+
key: 'status', label: L('Durum', 'Status'), minWidth: 9,
|
|
139
141
|
render: r => r.status
|
|
140
142
|
? tui.styled(' ✓ PASS ', { bg: tui.PALETTE.success, color: '#000000', bold: true })
|
|
141
143
|
: tui.styled(' ✗ FAIL ', { bg: tui.PALETTE.danger, color: '#000000', bold: true }),
|
|
142
144
|
},
|
|
143
|
-
{ key: 'message', label: 'Mesaj', minWidth: 20 },
|
|
145
|
+
{ key: 'message', label: L('Mesaj', 'Message'), minWidth: 20 },
|
|
144
146
|
], { borderStyle: 'round', zebra: true }));
|
|
145
147
|
|
|
146
148
|
const total = passed + failed;
|
|
@@ -148,17 +150,17 @@ function cmdRun(opts = {}) {
|
|
|
148
150
|
|
|
149
151
|
// Özet kartı
|
|
150
152
|
console.log('\n' + tui.box(60, 5, {
|
|
151
|
-
title: 'Özet',
|
|
153
|
+
title: L('Özet', 'Summary'),
|
|
152
154
|
borderColor: failed > 0 ? tui.PALETTE.warning : tui.PALETTE.success,
|
|
153
155
|
}).split('\n').map((line, i) => {
|
|
154
|
-
if (i === 2) return line.replace(' '.repeat(58), ` ${tui.C.text(`${passed}/${total} kontrol geçti`)} · ${tui.C.muted(duration + 'ms')}`);
|
|
156
|
+
if (i === 2) return line.replace(' '.repeat(58), ` ${tui.C.text(`${passed}/${total} ${L('kontrol geçti', 'checks passed')}`)} · ${tui.C.muted(duration + 'ms')}`);
|
|
155
157
|
return line;
|
|
156
158
|
}).join('\n'));
|
|
157
159
|
|
|
158
160
|
if (failed > 0) {
|
|
159
|
-
console.log('\n' + tui.C.amber(' ⚠️ Bazı kontroller başarısız. Detay için: ') + tui.C.brand('natureco doctor check <name>'));
|
|
161
|
+
console.log('\n' + tui.C.amber(L(' ⚠️ Bazı kontroller başarısız. Detay için: ', ' ⚠️ Some checks failed. For details: ')) + tui.C.brand('natureco doctor check <name>'));
|
|
160
162
|
} else {
|
|
161
|
-
console.log('\n' + tui.C.green(' ✨ Tüm kontroller geçti! Sistem sağlıklı.'));
|
|
163
|
+
console.log('\n' + tui.C.green(L(' ✨ Tüm kontroller geçti! Sistem sağlıklı.', ' ✨ All checks passed! System healthy.')));
|
|
162
164
|
}
|
|
163
165
|
console.log('');
|
|
164
166
|
}
|
|
@@ -209,7 +211,7 @@ function runCheck(name) {
|
|
|
209
211
|
}
|
|
210
212
|
return {
|
|
211
213
|
pass: freeGB > 0.5,
|
|
212
|
-
message: freeGB > 0.5 ? `${freeGB.toFixed(1)} GB free` :
|
|
214
|
+
message: freeGB > 0.5 ? `${freeGB.toFixed(1)} GB free` : `${L('Sadece', 'Only')} ${(freeGB * 1024).toFixed(0)} ${L('MB kaldı — gerekli: 500 MB', 'MB left — need: 500 MB')}`,
|
|
213
215
|
};
|
|
214
216
|
} catch (e) {
|
|
215
217
|
return { pass: true, message: 'Unable to check disk space' };
|
|
@@ -233,9 +235,9 @@ function runCheck(name) {
|
|
|
233
235
|
if (!fs.existsSync(CONFIG_FILE)) return { pass: false, message: 'Config missing — run `natureco setup`' };
|
|
234
236
|
const cfg = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8'));
|
|
235
237
|
const key = cfg.providerApiKey || cfg.apiKey;
|
|
236
|
-
if (!key) return { pass: false, message: 'API key tanımlı değil' };
|
|
237
|
-
if (key.length < 10) return { pass: false, message: 'API key çok kısa — yanlış kopyalanmış olabilir' };
|
|
238
|
-
return { pass: true, message:
|
|
238
|
+
if (!key) return { pass: false, message: L('API key tanımlı değil', 'API key not set') };
|
|
239
|
+
if (key.length < 10) return { pass: false, message: L('API key çok kısa — yanlış kopyalanmış olabilir', 'API key too short — may be copied wrong') };
|
|
240
|
+
return { pass: true, message: `${L('Key uzunluğu', 'Key length')}: ${key.length} ${L('karakter', 'chars')}` };
|
|
239
241
|
} catch (e) {
|
|
240
242
|
return { pass: false, message: e.message };
|
|
241
243
|
}
|
|
@@ -246,10 +248,10 @@ function runCheck(name) {
|
|
|
246
248
|
if (!fs.existsSync(CONFIG_FILE)) return { pass: false, message: 'Config missing' };
|
|
247
249
|
const cfg = JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8'));
|
|
248
250
|
const url = cfg.providerUrl;
|
|
249
|
-
if (!url) return { pass: false, message: 'Provider URL tanımlı değil' };
|
|
251
|
+
if (!url) return { pass: false, message: L('Provider URL tanımlı değil', 'Provider URL not set') };
|
|
250
252
|
// URL format geçerli mi?
|
|
251
253
|
const parsed = new URL(url);
|
|
252
|
-
return { pass: true, message:
|
|
254
|
+
return { pass: true, message: `${L('URL geçerli', 'URL valid')}: ${parsed.host}` };
|
|
253
255
|
} catch (e) {
|
|
254
256
|
return { pass: false, message: e.message };
|
|
255
257
|
}
|
|
@@ -261,13 +263,13 @@ function runCheck(name) {
|
|
|
261
263
|
const REQUIRED = ['sources', 'concepts', 'cache', 'skills', 'memory', 'sessions', 'backups', 'hooks', 'audit'];
|
|
262
264
|
const missing = REQUIRED.filter(d => !fs.existsSync(path.join(BASE_DIR, d)));
|
|
263
265
|
if (missing.length === 0) {
|
|
264
|
-
return { pass: true, message: `${REQUIRED.length} dizin hazır` };
|
|
266
|
+
return { pass: true, message: `${REQUIRED.length} ${L('dizin hazır', 'directories ready')}` };
|
|
265
267
|
}
|
|
266
268
|
// Otomatik oluştur
|
|
267
269
|
for (const d of missing) {
|
|
268
270
|
try { fs.mkdirSync(path.join(BASE_DIR, d), { recursive: true }); } catch {}
|
|
269
271
|
}
|
|
270
|
-
return { pass: true, message:
|
|
272
|
+
return { pass: true, message: `${L('Eksik dizinler oluşturuldu', 'Created missing directories')}: ${missing.join(', ')}` };
|
|
271
273
|
} catch (e) {
|
|
272
274
|
return { pass: false, message: e.message };
|
|
273
275
|
}
|
|
@@ -278,7 +280,7 @@ function runCheck(name) {
|
|
|
278
280
|
// Audit log yazma testi
|
|
279
281
|
audit.logSync(audit.ACTIONS.INFO, { source: 'doctor', check: 'auditLog' });
|
|
280
282
|
const files = audit.listLogFiles();
|
|
281
|
-
return { pass: true, message: `${files.length} log dosyası, en son: ${files[0] || 'yok'}` };
|
|
283
|
+
return { pass: true, message: `${files.length} ${L('log dosyası, en son', 'log files, latest')}: ${files[0] || L('yok', 'none')}` };
|
|
282
284
|
} catch (e) {
|
|
283
285
|
return { pass: false, message: e.message };
|
|
284
286
|
}
|
|
@@ -307,12 +309,12 @@ function runCheck(name) {
|
|
|
307
309
|
return false;
|
|
308
310
|
});
|
|
309
311
|
if (realSecrets.length === 0) {
|
|
310
|
-
return { pass: true, message: 'Çalışma dizininde gerçek secret bulunamadı ✓' };
|
|
312
|
+
return { pass: true, message: L('Çalışma dizininde gerçek secret bulunamadı ✓', 'No real secrets found in working directory ✓') };
|
|
311
313
|
}
|
|
312
314
|
const sample = realSecrets.slice(0, 3).map(f => `${f.type}@${path.basename(f.file || '?')}`).join(', ');
|
|
313
315
|
return {
|
|
314
316
|
pass: false,
|
|
315
|
-
message: `${realSecrets.length} gerçek secret: ${sample}${realSecrets.length > 3 ? '...' : ''}`,
|
|
317
|
+
message: `${realSecrets.length} ${L('gerçek secret', 'real secrets')}: ${sample}${realSecrets.length > 3 ? '...' : ''}`,
|
|
316
318
|
};
|
|
317
319
|
} catch (e) {
|
|
318
320
|
return { pass: false, message: e.message };
|