natureco-cli 5.6.15 → 5.6.16
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/memory-cmd.js +338 -338
- package/src/commands/reset.js +23 -12
- package/src/utils/dangerous.js +110 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "natureco-cli",
|
|
3
|
-
"version": "5.6.
|
|
3
|
+
"version": "5.6.16",
|
|
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"
|
|
@@ -1,338 +1,338 @@
|
|
|
1
|
-
const chalk = require('chalk');
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const os = require('os');
|
|
5
|
-
const { loadMemory, saveMemory, clearMemory } = require('../utils/memory');
|
|
6
|
-
const { getConfig } = require('../utils/config');
|
|
7
|
-
|
|
8
|
-
const MEMORY_DIR = path.join(os.homedir(), '.natureco', 'memory');
|
|
9
|
-
|
|
10
|
-
async function memoryCmd(args) {
|
|
11
|
-
const [action, ...params] = (args || []);
|
|
12
|
-
|
|
13
|
-
if (!action || action === 'status') return statusMemory();
|
|
14
|
-
if (action === 'list') return listMemory();
|
|
15
|
-
if (action === 'search') return searchMemory(params.join(' '));
|
|
16
|
-
if (action === 'show') return showMemory(params[0]);
|
|
17
|
-
if (action === 'clear') return clearMemoryCmd(params[0]);
|
|
18
|
-
if (action === 'index') return indexMemory();
|
|
19
|
-
if (action === 'export') return exportMemoryCmd(params[0], params[1]);
|
|
20
|
-
if (action === 'import') return importMemoryCmd(params[0], params[1]);
|
|
21
|
-
if (action === 'semantic') return semanticSearchCmd(params.join(' '));
|
|
22
|
-
// Wiki pages
|
|
23
|
-
if (action === 'wiki') return wikiCmd(params[0], params.slice(1));
|
|
24
|
-
if (action === 'wiki-create') return wikiCreateCmd(params[0], params.slice(1).join(' '));
|
|
25
|
-
if (action === 'wiki-list') return wikiListCmd();
|
|
26
|
-
if (action === 'wiki-search') return wikiSearchCmd(params.join(' '));
|
|
27
|
-
|
|
28
|
-
console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
|
|
29
|
-
console.log(chalk.gray(' Kullanım: natureco memory [status|list|search|show|clear|index|export|import|semantic|wiki|wiki-create|wiki-list|wiki-search]\n'));
|
|
30
|
-
process.exit(1);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function statusMemory() {
|
|
34
|
-
const config = getConfig();
|
|
35
|
-
const w = process.stdout.columns || 120;
|
|
36
|
-
const line = chalk.gray('─'.repeat(w));
|
|
37
|
-
|
|
38
|
-
console.log('');
|
|
39
|
-
console.log(line);
|
|
40
|
-
console.log(chalk.bold.cyan(' Hafıza Durumu'));
|
|
41
|
-
console.log(line);
|
|
42
|
-
|
|
43
|
-
if (!fs.existsSync(MEMORY_DIR)) {
|
|
44
|
-
console.log(chalk.gray('\n Hafıza dizini bulunamadı.\n'));
|
|
45
|
-
console.log(line);
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const files = fs.readdirSync(MEMORY_DIR).filter(f => f.endsWith('.json'));
|
|
50
|
-
|
|
51
|
-
if (files.length === 0) {
|
|
52
|
-
console.log(chalk.gray('\n Kayıtlı hafıza yok.\n'));
|
|
53
|
-
console.log(line);
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
let totalFacts = 0;
|
|
58
|
-
const activeBotName = config.botName || '';
|
|
59
|
-
|
|
60
|
-
console.log('');
|
|
61
|
-
files.forEach(file => {
|
|
62
|
-
const botId = file.replace('.json', '');
|
|
63
|
-
try {
|
|
64
|
-
const mem = loadMemory(botId);
|
|
65
|
-
const factCount = (mem.facts || []).length;
|
|
66
|
-
const prefCount = (mem.preferences || []).length;
|
|
67
|
-
totalFacts += factCount;
|
|
68
|
-
const isActive = activeBotName && (mem.botName === activeBotName);
|
|
69
|
-
const bar = isActive ? chalk.cyan('▌') : chalk.gray('▌');
|
|
70
|
-
|
|
71
|
-
console.log(bar + ' ' + chalk.bold.white(mem.botName || botId) + (isActive ? chalk.cyan(' ← aktif') : ''));
|
|
72
|
-
console.log(bar + ' ' + chalk.gray('Kullanıcı : ') + chalk.white(mem.name || '—'));
|
|
73
|
-
if (mem.nickname) {
|
|
74
|
-
console.log(bar + ' ' + chalk.gray('Lakap : ') + chalk.white(mem.nickname));
|
|
75
|
-
}
|
|
76
|
-
console.log(bar + ' ' + chalk.gray('Bilgi : ') + chalk.white(`${factCount} kayıt`));
|
|
77
|
-
console.log(bar + ' ' + chalk.gray('Tercihler : ') + chalk.white(`${prefCount} kayıt`));
|
|
78
|
-
if (mem.lastSeen) {
|
|
79
|
-
const d = new Date(mem.lastSeen);
|
|
80
|
-
console.log(bar + ' ' + chalk.gray('Son görüş : ') + chalk.white(d.toLocaleDateString('tr-TR')));
|
|
81
|
-
}
|
|
82
|
-
console.log('');
|
|
83
|
-
} catch {}
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
console.log(line);
|
|
87
|
-
console.log(chalk.gray(` ${files.length} bot · ${totalFacts} toplam bilgi · natureco memory search <sorgu>`));
|
|
88
|
-
console.log(line);
|
|
89
|
-
console.log('');
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function listMemory() {
|
|
93
|
-
if (!fs.existsSync(MEMORY_DIR)) {
|
|
94
|
-
console.log(chalk.gray('\n Hafıza dizini bulunamadı.\n'));
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const files = fs.readdirSync(MEMORY_DIR).filter(f => f.endsWith('.json'));
|
|
99
|
-
console.log(chalk.cyan.bold(`\n Hafıza Dosyaları (${files.length})\n`));
|
|
100
|
-
files.forEach(f => {
|
|
101
|
-
const botId = f.replace('.json', '');
|
|
102
|
-
const mem = loadMemory(botId);
|
|
103
|
-
console.log(chalk.white(` ${f}`));
|
|
104
|
-
console.log(chalk.gray(` Bot: ${mem.botName || botId} · ${(mem.facts || []).length} bilgi`));
|
|
105
|
-
});
|
|
106
|
-
console.log('');
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function searchMemory(query) {
|
|
110
|
-
if (!query) {
|
|
111
|
-
console.log(chalk.red('\n ❌ Arama sorgusu gerekli\n'));
|
|
112
|
-
console.log(chalk.gray(' Kullanım: natureco memory search <sorgu>\n'));
|
|
113
|
-
process.exit(1);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if (!fs.existsSync(MEMORY_DIR)) {
|
|
117
|
-
console.log(chalk.gray('\n Hafıza dizini bulunamadı.\n'));
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const files = fs.readdirSync(MEMORY_DIR).filter(f => f.endsWith('.json'));
|
|
122
|
-
const results = [];
|
|
123
|
-
|
|
124
|
-
files.forEach(file => {
|
|
125
|
-
const botId = file.replace('.json', '');
|
|
126
|
-
const mem = loadMemory(botId);
|
|
127
|
-
const q = query.toLowerCase();
|
|
128
|
-
|
|
129
|
-
if (mem.name?.toLowerCase().includes(q)) {
|
|
130
|
-
results.push({ bot: mem.botName || botId, field: 'İsim', value: mem.name });
|
|
131
|
-
}
|
|
132
|
-
if (mem.nickname?.toLowerCase().includes(q)) {
|
|
133
|
-
results.push({ bot: mem.botName || botId, field: 'Lakap', value: mem.nickname });
|
|
134
|
-
}
|
|
135
|
-
(mem.facts || []).forEach(f => {
|
|
136
|
-
const val = typeof f === 'string' ? f : f.value;
|
|
137
|
-
if (val?.toLowerCase().includes(q)) {
|
|
138
|
-
results.push({ bot: mem.botName || botId, field: 'Bilgi', value: val });
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
console.log(chalk.cyan.bold(`\n "${query}" için ${results.length} sonuç\n`));
|
|
144
|
-
if (results.length === 0) {
|
|
145
|
-
console.log(chalk.gray(' Sonuç bulunamadı.\n'));
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
results.forEach(r => {
|
|
149
|
-
console.log(chalk.white(` [${r.bot}] `) + chalk.gray(`${r.field}: `) + chalk.white(r.value));
|
|
150
|
-
});
|
|
151
|
-
console.log('');
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
function showMemory(botId) {
|
|
155
|
-
const config = getConfig();
|
|
156
|
-
const id = botId || 'universal-provider';
|
|
157
|
-
const mem = loadMemory(id);
|
|
158
|
-
|
|
159
|
-
console.log('');
|
|
160
|
-
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
161
|
-
console.log(chalk.cyan.bold(`\n Hafıza: ${mem.botName || id}\n`));
|
|
162
|
-
|
|
163
|
-
if (mem.name) console.log(chalk.gray(' İsim : ') + chalk.white(mem.name));
|
|
164
|
-
if (mem.nickname) console.log(chalk.gray(' Lakap : ') + chalk.white(mem.nickname));
|
|
165
|
-
if (mem.botName) console.log(chalk.gray(' Bot adı : ') + chalk.cyan(mem.botName));
|
|
166
|
-
|
|
167
|
-
const facts = mem.facts || [];
|
|
168
|
-
if (facts.length > 0) {
|
|
169
|
-
console.log(chalk.gray('\n Bilgiler:\n'));
|
|
170
|
-
facts.forEach((f, i) => {
|
|
171
|
-
const val = typeof f === 'string' ? f : f.value;
|
|
172
|
-
const score = typeof f === 'object' ? f.score : 5;
|
|
173
|
-
console.log(chalk.gray(` ${(i + 1).toString().padStart(2)}. `) + chalk.white(val) + chalk.gray(` (${score})`));
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
console.log('');
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
function clearMemoryCmd(botId) {
|
|
180
|
-
const id = botId || 'universal-provider';
|
|
181
|
-
clearMemory(id);
|
|
182
|
-
console.log(chalk.green(`\n ✓ Hafıza temizlendi: ${id}\n`));
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
function indexMemory() {
|
|
186
|
-
if (!fs.existsSync(MEMORY_DIR)) {
|
|
187
|
-
console.log(chalk.gray('\n Hafıza dizini bulunamadı.\n'));
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
const files = fs.readdirSync(MEMORY_DIR).filter(f => f.endsWith('.json'));
|
|
192
|
-
let indexed = 0;
|
|
193
|
-
|
|
194
|
-
files.forEach(file => {
|
|
195
|
-
const botId = file.replace('.json', '');
|
|
196
|
-
try {
|
|
197
|
-
const mem = loadMemory(botId);
|
|
198
|
-
// Bozuk fact'leri temizle
|
|
199
|
-
if (Array.isArray(mem.facts)) {
|
|
200
|
-
mem.facts = mem.facts.filter(f => {
|
|
201
|
-
const val = typeof f === 'string' ? f : f?.value;
|
|
202
|
-
return val && typeof val === 'string' && val.length > 0;
|
|
203
|
-
});
|
|
204
|
-
saveMemory(botId, mem);
|
|
205
|
-
indexed++;
|
|
206
|
-
}
|
|
207
|
-
} catch {}
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
console.log(chalk.green(`\n ✓ ${indexed} hafıza dosyası yeniden indexlendi\n`));
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// ── Export Memory ──────────────────────────────────────────────────────────────
|
|
214
|
-
function exportMemoryCmd(botId, outputFile) {
|
|
215
|
-
const id = botId || 'universal-provider';
|
|
216
|
-
const mem = exportMemory(id);
|
|
217
|
-
const filePath = outputFile || path.join(process.cwd(), `memory-${id}.json`);
|
|
218
|
-
fs.writeFileSync(filePath, JSON.stringify(mem, null, 2));
|
|
219
|
-
console.log(chalk.green(`\n ✓ Hafıza dışa aktarıldı: ${filePath}\n`));
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// ── Import Memory ──────────────────────────────────────────────────────────────
|
|
223
|
-
function importMemoryCmd(botId, sourceFile) {
|
|
224
|
-
if (!sourceFile) {
|
|
225
|
-
console.log(chalk.red('\n ❌ Kaynak dosya gerekli\n'));
|
|
226
|
-
console.log(chalk.gray(' Kullanım: natureco memory import <botId> <dosya.json>\n'));
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
const resolvedPath = path.resolve(sourceFile.replace(/^~/, os.homedir()));
|
|
230
|
-
if (!fs.existsSync(resolvedPath)) {
|
|
231
|
-
console.log(chalk.red(`\n ❌ Dosya bulunamadı: ${resolvedPath}\n`));
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
try {
|
|
235
|
-
const data = JSON.parse(fs.readFileSync(resolvedPath, 'utf-8'));
|
|
236
|
-
importMemory(botId || 'universal-provider', data);
|
|
237
|
-
console.log(chalk.green(`\n ✓ Hafıza içe aktarıldı: ${botId || 'universal-provider'}\n`));
|
|
238
|
-
} catch (err) {
|
|
239
|
-
console.log(chalk.red(`\n ❌ Hata: ${err.message}\n`));
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// ── Semantic Search ────────────────────────────────────────────────────────────
|
|
244
|
-
function semanticSearchCmd(query) {
|
|
245
|
-
if (!query) {
|
|
246
|
-
console.log(chalk.red('\n ❌ Arama sorgusu gerekli\n'));
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
const results = semanticSearchMemory(query, 10);
|
|
250
|
-
console.log(chalk.cyan.bold(`\n Semantic: "${query}" → ${results.length} sonuç\n`));
|
|
251
|
-
if (results.length === 0) {
|
|
252
|
-
console.log(chalk.gray(' Sonuç bulunamadı.\n'));
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
results.forEach((r, i) => {
|
|
256
|
-
const pct = Math.round(r.score * 100);
|
|
257
|
-
const bar = chalk.green('█'.repeat(Math.floor(pct / 10))) + chalk.gray('░'.repeat(10 - Math.floor(pct / 10)));
|
|
258
|
-
console.log(` ${chalk.white(`${i + 1}.`)} ${bar} ${chalk.white(r.value.slice(0, 70))}`);
|
|
259
|
-
console.log(chalk.gray(` [${r.bot}] alaka: %${pct}`));
|
|
260
|
-
});
|
|
261
|
-
console.log('');
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// ── Wiki Commands ──────────────────────────────────────────────────────────────
|
|
265
|
-
function wikiCmd(action, params) {
|
|
266
|
-
if (!action || action === 'list') return wikiListCmd();
|
|
267
|
-
if (action === 'show') {
|
|
268
|
-
const slug = params?.[0];
|
|
269
|
-
if (!slug) { console.log(chalk.red('\n ❌ Sayfa adı gerekli\n')); return; }
|
|
270
|
-
const page = getWikiPage(slug);
|
|
271
|
-
if (!page) { console.log(chalk.yellow(`\n ⚠ Sayfa bulunamadı: ${slug}\n`)); return; }
|
|
272
|
-
console.log(chalk.cyan.bold(`\n Wiki: ${page.slug}\n`));
|
|
273
|
-
console.log(chalk.white(page.content));
|
|
274
|
-
console.log(chalk.gray(`\n Son güncelleme: ${page.updatedAt}\n`));
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
277
|
-
if (action === 'create' || action === 'edit') {
|
|
278
|
-
const slug = params?.[0];
|
|
279
|
-
const content = params?.slice(1).join(' ');
|
|
280
|
-
if (!slug || !content) {
|
|
281
|
-
console.log(chalk.red('\n ❌ Kullanım: natureco memory wiki create <slug> <içerik>\n'));
|
|
282
|
-
return;
|
|
283
|
-
}
|
|
284
|
-
saveWikiPage(slug, content);
|
|
285
|
-
console.log(chalk.green(`\n ✓ Wiki sayfası kaydedildi: ${slug}\n`));
|
|
286
|
-
return;
|
|
287
|
-
}
|
|
288
|
-
if (action === 'search') {
|
|
289
|
-
const query = params?.join(' ');
|
|
290
|
-
if (!query) { console.log(chalk.red('\n ❌ Arama sorgusu gerekli\n')); return; }
|
|
291
|
-
const results = searchWikiPages(query);
|
|
292
|
-
console.log(chalk.cyan.bold(`\n Wiki: "${query}" → ${results.length} sonuç\n`));
|
|
293
|
-
if (results.length === 0) { console.log(chalk.gray(' Sonuç bulunamadı.\n')); return; }
|
|
294
|
-
results.forEach(p => {
|
|
295
|
-
console.log(` ${chalk.white(p.slug)} ${chalk.gray('—')} ${chalk.gray((p.content || '').slice(0, 60))}`);
|
|
296
|
-
});
|
|
297
|
-
console.log('');
|
|
298
|
-
return;
|
|
299
|
-
}
|
|
300
|
-
console.log(chalk.red(`\n ❌ Bilinmeyen wiki aksiyonu: ${action}\n`));
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
function wikiCreateCmd(slug, content) {
|
|
304
|
-
if (!slug || !content) {
|
|
305
|
-
console.log(chalk.red('\n ❌ Kullanım: natureco memory wiki-create <slug> <içerik>\n'));
|
|
306
|
-
return;
|
|
307
|
-
}
|
|
308
|
-
saveWikiPage(slug, content);
|
|
309
|
-
console.log(chalk.green(`\n ✓ Wiki sayfası oluşturuldu: ${slug}\n`));
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
function wikiListCmd() {
|
|
313
|
-
const pages = listWikiPages();
|
|
314
|
-
console.log(chalk.cyan.bold(`\n Wiki Sayfaları (${pages.length})\n`));
|
|
315
|
-
if (pages.length === 0) {
|
|
316
|
-
console.log(chalk.gray(' Henüz sayfa yok.\n'));
|
|
317
|
-
console.log(chalk.gray(' Oluşturmak: ') + chalk.cyan('natureco memory wiki create <slug> <içerik>\n'));
|
|
318
|
-
return;
|
|
319
|
-
}
|
|
320
|
-
pages.forEach(p => {
|
|
321
|
-
const preview = (p.content || '').slice(0, 60).replace(/\n/g, ' ');
|
|
322
|
-
console.log(` ${chalk.white(p.slug)} ${chalk.gray('—')} ${chalk.gray(preview)}`);
|
|
323
|
-
console.log(chalk.gray(` ${p.updatedAt}\n`));
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
function wikiSearchCmd(query) {
|
|
328
|
-
if (!query) { console.log(chalk.red('\n ❌ Arama sorgusu gerekli\n')); return; }
|
|
329
|
-
const results = searchWikiPages(query);
|
|
330
|
-
console.log(chalk.cyan.bold(`\n Wiki Ara: "${query}" → ${results.length} sonuç\n`));
|
|
331
|
-
if (results.length === 0) { console.log(chalk.gray(' Sonuç bulunamadı.\n')); return; }
|
|
332
|
-
results.forEach(p => {
|
|
333
|
-
console.log(` ${chalk.white(p.slug)}`);
|
|
334
|
-
console.log(chalk.gray(` ${(p.content || '').slice(0, 80)}\n`));
|
|
335
|
-
});
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
module.exports = memoryCmd;
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
const { loadMemory, saveMemory, clearMemory } = require('../utils/memory');
|
|
6
|
+
const { getConfig } = require('../utils/config');
|
|
7
|
+
|
|
8
|
+
const MEMORY_DIR = path.join(os.homedir(), '.natureco', 'memory');
|
|
9
|
+
|
|
10
|
+
async function memoryCmd(args) {
|
|
11
|
+
const [action, ...params] = (args || []);
|
|
12
|
+
|
|
13
|
+
if (!action || action === 'status') return statusMemory();
|
|
14
|
+
if (action === 'list') return listMemory();
|
|
15
|
+
if (action === 'search') return searchMemory(params.join(' '));
|
|
16
|
+
if (action === 'show') return showMemory(params[0]);
|
|
17
|
+
if (action === 'clear') return clearMemoryCmd(params[0]);
|
|
18
|
+
if (action === 'index') return indexMemory();
|
|
19
|
+
if (action === 'export') return exportMemoryCmd(params[0], params[1]);
|
|
20
|
+
if (action === 'import') return importMemoryCmd(params[0], params[1]);
|
|
21
|
+
if (action === 'semantic') return semanticSearchCmd(params.join(' '));
|
|
22
|
+
// Wiki pages
|
|
23
|
+
if (action === 'wiki') return wikiCmd(params[0], params.slice(1));
|
|
24
|
+
if (action === 'wiki-create') return wikiCreateCmd(params[0], params.slice(1).join(' '));
|
|
25
|
+
if (action === 'wiki-list') return wikiListCmd();
|
|
26
|
+
if (action === 'wiki-search') return wikiSearchCmd(params.join(' '));
|
|
27
|
+
|
|
28
|
+
console.log(chalk.red(`\n ❌ Bilinmeyen komut: ${action}\n`));
|
|
29
|
+
console.log(chalk.gray(' Kullanım: natureco memory [status|list|search|show|clear|index|export|import|semantic|wiki|wiki-create|wiki-list|wiki-search]\n'));
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function statusMemory() {
|
|
34
|
+
const config = getConfig();
|
|
35
|
+
const w = process.stdout.columns || 120;
|
|
36
|
+
const line = chalk.gray('─'.repeat(w));
|
|
37
|
+
|
|
38
|
+
console.log('');
|
|
39
|
+
console.log(line);
|
|
40
|
+
console.log(chalk.bold.cyan(' Hafıza Durumu'));
|
|
41
|
+
console.log(line);
|
|
42
|
+
|
|
43
|
+
if (!fs.existsSync(MEMORY_DIR)) {
|
|
44
|
+
console.log(chalk.gray('\n Hafıza dizini bulunamadı.\n'));
|
|
45
|
+
console.log(line);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const files = fs.readdirSync(MEMORY_DIR).filter(f => f.endsWith('.json'));
|
|
50
|
+
|
|
51
|
+
if (files.length === 0) {
|
|
52
|
+
console.log(chalk.gray('\n Kayıtlı hafıza yok.\n'));
|
|
53
|
+
console.log(line);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
let totalFacts = 0;
|
|
58
|
+
const activeBotName = config.botName || '';
|
|
59
|
+
|
|
60
|
+
console.log('');
|
|
61
|
+
files.forEach(file => {
|
|
62
|
+
const botId = file.replace('.json', '');
|
|
63
|
+
try {
|
|
64
|
+
const mem = loadMemory(botId);
|
|
65
|
+
const factCount = (mem.facts || []).length;
|
|
66
|
+
const prefCount = (mem.preferences || []).length;
|
|
67
|
+
totalFacts += factCount;
|
|
68
|
+
const isActive = activeBotName && (mem.botName === activeBotName);
|
|
69
|
+
const bar = isActive ? chalk.cyan('▌') : chalk.gray('▌');
|
|
70
|
+
|
|
71
|
+
console.log(bar + ' ' + chalk.bold.white(mem.botName || botId) + (isActive ? chalk.cyan(' ← aktif') : ''));
|
|
72
|
+
console.log(bar + ' ' + chalk.gray('Kullanıcı : ') + chalk.white(mem.name || '—'));
|
|
73
|
+
if (mem.nickname) {
|
|
74
|
+
console.log(bar + ' ' + chalk.gray('Lakap : ') + chalk.white(mem.nickname));
|
|
75
|
+
}
|
|
76
|
+
console.log(bar + ' ' + chalk.gray('Bilgi : ') + chalk.white(`${factCount} kayıt`));
|
|
77
|
+
console.log(bar + ' ' + chalk.gray('Tercihler : ') + chalk.white(`${prefCount} kayıt`));
|
|
78
|
+
if (mem.lastSeen) {
|
|
79
|
+
const d = new Date(mem.lastSeen);
|
|
80
|
+
console.log(bar + ' ' + chalk.gray('Son görüş : ') + chalk.white(d.toLocaleDateString('tr-TR')));
|
|
81
|
+
}
|
|
82
|
+
console.log('');
|
|
83
|
+
} catch {}
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
console.log(line);
|
|
87
|
+
console.log(chalk.gray(` ${files.length} bot · ${totalFacts} toplam bilgi · natureco memory search <sorgu>`));
|
|
88
|
+
console.log(line);
|
|
89
|
+
console.log('');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function listMemory() {
|
|
93
|
+
if (!fs.existsSync(MEMORY_DIR)) {
|
|
94
|
+
console.log(chalk.gray('\n Hafıza dizini bulunamadı.\n'));
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const files = fs.readdirSync(MEMORY_DIR).filter(f => f.endsWith('.json'));
|
|
99
|
+
console.log(chalk.cyan.bold(`\n Hafıza Dosyaları (${files.length})\n`));
|
|
100
|
+
files.forEach(f => {
|
|
101
|
+
const botId = f.replace('.json', '');
|
|
102
|
+
const mem = loadMemory(botId);
|
|
103
|
+
console.log(chalk.white(` ${f}`));
|
|
104
|
+
console.log(chalk.gray(` Bot: ${mem.botName || botId} · ${(mem.facts || []).length} bilgi`));
|
|
105
|
+
});
|
|
106
|
+
console.log('');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function searchMemory(query) {
|
|
110
|
+
if (!query) {
|
|
111
|
+
console.log(chalk.red('\n ❌ Arama sorgusu gerekli\n'));
|
|
112
|
+
console.log(chalk.gray(' Kullanım: natureco memory search <sorgu>\n'));
|
|
113
|
+
process.exit(1);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (!fs.existsSync(MEMORY_DIR)) {
|
|
117
|
+
console.log(chalk.gray('\n Hafıza dizini bulunamadı.\n'));
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const files = fs.readdirSync(MEMORY_DIR).filter(f => f.endsWith('.json'));
|
|
122
|
+
const results = [];
|
|
123
|
+
|
|
124
|
+
files.forEach(file => {
|
|
125
|
+
const botId = file.replace('.json', '');
|
|
126
|
+
const mem = loadMemory(botId);
|
|
127
|
+
const q = query.toLowerCase();
|
|
128
|
+
|
|
129
|
+
if (mem.name?.toLowerCase().includes(q)) {
|
|
130
|
+
results.push({ bot: mem.botName || botId, field: 'İsim', value: mem.name });
|
|
131
|
+
}
|
|
132
|
+
if (mem.nickname?.toLowerCase().includes(q)) {
|
|
133
|
+
results.push({ bot: mem.botName || botId, field: 'Lakap', value: mem.nickname });
|
|
134
|
+
}
|
|
135
|
+
(mem.facts || []).forEach(f => {
|
|
136
|
+
const val = typeof f === 'string' ? f : f.value;
|
|
137
|
+
if (val?.toLowerCase().includes(q)) {
|
|
138
|
+
results.push({ bot: mem.botName || botId, field: 'Bilgi', value: val });
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
console.log(chalk.cyan.bold(`\n "${query}" için ${results.length} sonuç\n`));
|
|
144
|
+
if (results.length === 0) {
|
|
145
|
+
console.log(chalk.gray(' Sonuç bulunamadı.\n'));
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
results.forEach(r => {
|
|
149
|
+
console.log(chalk.white(` [${r.bot}] `) + chalk.gray(`${r.field}: `) + chalk.white(r.value));
|
|
150
|
+
});
|
|
151
|
+
console.log('');
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function showMemory(botId) {
|
|
155
|
+
const config = getConfig();
|
|
156
|
+
const id = botId || 'universal-provider';
|
|
157
|
+
const mem = loadMemory(id);
|
|
158
|
+
|
|
159
|
+
console.log('');
|
|
160
|
+
console.log(chalk.gray(' ' + '─'.repeat(48)));
|
|
161
|
+
console.log(chalk.cyan.bold(`\n Hafıza: ${mem.botName || id}\n`));
|
|
162
|
+
|
|
163
|
+
if (mem.name) console.log(chalk.gray(' İsim : ') + chalk.white(mem.name));
|
|
164
|
+
if (mem.nickname) console.log(chalk.gray(' Lakap : ') + chalk.white(mem.nickname));
|
|
165
|
+
if (mem.botName) console.log(chalk.gray(' Bot adı : ') + chalk.cyan(mem.botName));
|
|
166
|
+
|
|
167
|
+
const facts = mem.facts || [];
|
|
168
|
+
if (facts.length > 0) {
|
|
169
|
+
console.log(chalk.gray('\n Bilgiler:\n'));
|
|
170
|
+
facts.forEach((f, i) => {
|
|
171
|
+
const val = typeof f === 'string' ? f : f.value;
|
|
172
|
+
const score = typeof f === 'object' ? f.score : 5;
|
|
173
|
+
console.log(chalk.gray(` ${(i + 1).toString().padStart(2)}. `) + chalk.white(val) + chalk.gray(` (${score})`));
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
console.log('');
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function clearMemoryCmd(botId) {
|
|
180
|
+
const id = botId || 'universal-provider';
|
|
181
|
+
clearMemory(id);
|
|
182
|
+
console.log(chalk.green(`\n ✓ Hafıza temizlendi: ${id}\n`));
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function indexMemory() {
|
|
186
|
+
if (!fs.existsSync(MEMORY_DIR)) {
|
|
187
|
+
console.log(chalk.gray('\n Hafıza dizini bulunamadı.\n'));
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const files = fs.readdirSync(MEMORY_DIR).filter(f => f.endsWith('.json'));
|
|
192
|
+
let indexed = 0;
|
|
193
|
+
|
|
194
|
+
files.forEach(file => {
|
|
195
|
+
const botId = file.replace('.json', '');
|
|
196
|
+
try {
|
|
197
|
+
const mem = loadMemory(botId);
|
|
198
|
+
// Bozuk fact'leri temizle
|
|
199
|
+
if (Array.isArray(mem.facts)) {
|
|
200
|
+
mem.facts = mem.facts.filter(f => {
|
|
201
|
+
const val = typeof f === 'string' ? f : f?.value;
|
|
202
|
+
return val && typeof val === 'string' && val.length > 0;
|
|
203
|
+
});
|
|
204
|
+
saveMemory(botId, mem);
|
|
205
|
+
indexed++;
|
|
206
|
+
}
|
|
207
|
+
} catch {}
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
console.log(chalk.green(`\n ✓ ${indexed} hafıza dosyası yeniden indexlendi\n`));
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// ── Export Memory ──────────────────────────────────────────────────────────────
|
|
214
|
+
function exportMemoryCmd(botId, outputFile) {
|
|
215
|
+
const id = botId || 'universal-provider';
|
|
216
|
+
const mem = exportMemory(id);
|
|
217
|
+
const filePath = outputFile || path.join(process.cwd(), `memory-${id}.json`);
|
|
218
|
+
fs.writeFileSync(filePath, JSON.stringify(mem, null, 2));
|
|
219
|
+
console.log(chalk.green(`\n ✓ Hafıza dışa aktarıldı: ${filePath}\n`));
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// ── Import Memory ──────────────────────────────────────────────────────────────
|
|
223
|
+
function importMemoryCmd(botId, sourceFile) {
|
|
224
|
+
if (!sourceFile) {
|
|
225
|
+
console.log(chalk.red('\n ❌ Kaynak dosya gerekli\n'));
|
|
226
|
+
console.log(chalk.gray(' Kullanım: natureco memory import <botId> <dosya.json>\n'));
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
const resolvedPath = path.resolve(sourceFile.replace(/^~/, os.homedir()));
|
|
230
|
+
if (!fs.existsSync(resolvedPath)) {
|
|
231
|
+
console.log(chalk.red(`\n ❌ Dosya bulunamadı: ${resolvedPath}\n`));
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
try {
|
|
235
|
+
const data = JSON.parse(fs.readFileSync(resolvedPath, 'utf-8'));
|
|
236
|
+
importMemory(botId || 'universal-provider', data);
|
|
237
|
+
console.log(chalk.green(`\n ✓ Hafıza içe aktarıldı: ${botId || 'universal-provider'}\n`));
|
|
238
|
+
} catch (err) {
|
|
239
|
+
console.log(chalk.red(`\n ❌ Hata: ${err.message}\n`));
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// ── Semantic Search ────────────────────────────────────────────────────────────
|
|
244
|
+
function semanticSearchCmd(query) {
|
|
245
|
+
if (!query) {
|
|
246
|
+
console.log(chalk.red('\n ❌ Arama sorgusu gerekli\n'));
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
const results = semanticSearchMemory(query, 10);
|
|
250
|
+
console.log(chalk.cyan.bold(`\n Semantic: "${query}" → ${results.length} sonuç\n`));
|
|
251
|
+
if (results.length === 0) {
|
|
252
|
+
console.log(chalk.gray(' Sonuç bulunamadı.\n'));
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
results.forEach((r, i) => {
|
|
256
|
+
const pct = Math.round(r.score * 100);
|
|
257
|
+
const bar = chalk.green('█'.repeat(Math.floor(pct / 10))) + chalk.gray('░'.repeat(10 - Math.floor(pct / 10)));
|
|
258
|
+
console.log(` ${chalk.white(`${i + 1}.`)} ${bar} ${chalk.white(r.value.slice(0, 70))}`);
|
|
259
|
+
console.log(chalk.gray(` [${r.bot}] alaka: %${pct}`));
|
|
260
|
+
});
|
|
261
|
+
console.log('');
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// ── Wiki Commands ──────────────────────────────────────────────────────────────
|
|
265
|
+
function wikiCmd(action, params) {
|
|
266
|
+
if (!action || action === 'list') return wikiListCmd();
|
|
267
|
+
if (action === 'show') {
|
|
268
|
+
const slug = params?.[0];
|
|
269
|
+
if (!slug) { console.log(chalk.red('\n ❌ Sayfa adı gerekli\n')); return; }
|
|
270
|
+
const page = getWikiPage(slug);
|
|
271
|
+
if (!page) { console.log(chalk.yellow(`\n ⚠ Sayfa bulunamadı: ${slug}\n`)); return; }
|
|
272
|
+
console.log(chalk.cyan.bold(`\n Wiki: ${page.slug}\n`));
|
|
273
|
+
console.log(chalk.white(page.content));
|
|
274
|
+
console.log(chalk.gray(`\n Son güncelleme: ${page.updatedAt}\n`));
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
if (action === 'create' || action === 'edit') {
|
|
278
|
+
const slug = params?.[0];
|
|
279
|
+
const content = params?.slice(1).join(' ');
|
|
280
|
+
if (!slug || !content) {
|
|
281
|
+
console.log(chalk.red('\n ❌ Kullanım: natureco memory wiki create <slug> <içerik>\n'));
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
saveWikiPage(slug, content);
|
|
285
|
+
console.log(chalk.green(`\n ✓ Wiki sayfası kaydedildi: ${slug}\n`));
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
if (action === 'search') {
|
|
289
|
+
const query = params?.join(' ');
|
|
290
|
+
if (!query) { console.log(chalk.red('\n ❌ Arama sorgusu gerekli\n')); return; }
|
|
291
|
+
const results = searchWikiPages(query);
|
|
292
|
+
console.log(chalk.cyan.bold(`\n Wiki: "${query}" → ${results.length} sonuç\n`));
|
|
293
|
+
if (results.length === 0) { console.log(chalk.gray(' Sonuç bulunamadı.\n')); return; }
|
|
294
|
+
results.forEach(p => {
|
|
295
|
+
console.log(` ${chalk.white(p.slug)} ${chalk.gray('—')} ${chalk.gray((p.content || '').slice(0, 60))}`);
|
|
296
|
+
});
|
|
297
|
+
console.log('');
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
console.log(chalk.red(`\n ❌ Bilinmeyen wiki aksiyonu: ${action}\n`));
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function wikiCreateCmd(slug, content) {
|
|
304
|
+
if (!slug || !content) {
|
|
305
|
+
console.log(chalk.red('\n ❌ Kullanım: natureco memory wiki-create <slug> <içerik>\n'));
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
saveWikiPage(slug, content);
|
|
309
|
+
console.log(chalk.green(`\n ✓ Wiki sayfası oluşturuldu: ${slug}\n`));
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function wikiListCmd() {
|
|
313
|
+
const pages = listWikiPages();
|
|
314
|
+
console.log(chalk.cyan.bold(`\n Wiki Sayfaları (${pages.length})\n`));
|
|
315
|
+
if (pages.length === 0) {
|
|
316
|
+
console.log(chalk.gray(' Henüz sayfa yok.\n'));
|
|
317
|
+
console.log(chalk.gray(' Oluşturmak: ') + chalk.cyan('natureco memory wiki create <slug> <içerik>\n'));
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
pages.forEach(p => {
|
|
321
|
+
const preview = (p.content || '').slice(0, 60).replace(/\n/g, ' ');
|
|
322
|
+
console.log(` ${chalk.white(p.slug)} ${chalk.gray('—')} ${chalk.gray(preview)}`);
|
|
323
|
+
console.log(chalk.gray(` ${p.updatedAt}\n`));
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
function wikiSearchCmd(query) {
|
|
328
|
+
if (!query) { console.log(chalk.red('\n ❌ Arama sorgusu gerekli\n')); return; }
|
|
329
|
+
const results = searchWikiPages(query);
|
|
330
|
+
console.log(chalk.cyan.bold(`\n Wiki Ara: "${query}" → ${results.length} sonuç\n`));
|
|
331
|
+
if (results.length === 0) { console.log(chalk.gray(' Sonuç bulunamadı.\n')); return; }
|
|
332
|
+
results.forEach(p => {
|
|
333
|
+
console.log(` ${chalk.white(p.slug)}`);
|
|
334
|
+
console.log(chalk.gray(` ${(p.content || '').slice(0, 80)}\n`));
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
module.exports = memoryCmd;
|
package/src/commands/reset.js
CHANGED
|
@@ -17,12 +17,34 @@ const path = require('path');
|
|
|
17
17
|
const os = require('os');
|
|
18
18
|
const inquirer = require('../utils/inquirer-wrapper');
|
|
19
19
|
const chalk = require('chalk');
|
|
20
|
+
const { requireApproval, RISK } = require('../utils/dangerous');
|
|
20
21
|
|
|
21
22
|
async function reset() {
|
|
22
23
|
const args = process.argv.slice(3);
|
|
23
24
|
const home = os.homedir();
|
|
24
25
|
const baseDir = path.join(home, '.natureco');
|
|
25
26
|
|
|
27
|
+
// v5.6.16: Dangerous command approval
|
|
28
|
+
const isFullReset = args.includes('--all') || args.includes('--personal');
|
|
29
|
+
const risk = isFullReset ? RISK.CRITICAL : RISK.HIGH;
|
|
30
|
+
const reason = isFullReset
|
|
31
|
+
? 'Tum kisisel veriler ve ayarlar silinecek (geri alinamaz)'
|
|
32
|
+
: 'Secili kapsamdaki veriler silinecek';
|
|
33
|
+
|
|
34
|
+
// --yes/-y bypass (eski davranis)
|
|
35
|
+
const skipApproval = args.includes('--yes') || args.includes('-y');
|
|
36
|
+
|
|
37
|
+
if (!skipApproval) {
|
|
38
|
+
const argsObj = {
|
|
39
|
+
flags: args.filter(a => a.startsWith('--') || a.startsWith('-'))
|
|
40
|
+
};
|
|
41
|
+
const approved = await requireApproval('natureco reset', argsObj, risk, reason);
|
|
42
|
+
if (!approved) {
|
|
43
|
+
console.log(chalk.gray('\nIptal edildi.\n'));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
26
48
|
console.log(chalk.yellow('\n\u26a0 RESET - Tum veriler silinecek!\n'));
|
|
27
49
|
|
|
28
50
|
const whatToReset = {
|
|
@@ -48,18 +70,7 @@ async function reset() {
|
|
|
48
70
|
if (whatToReset.soul) console.log(' - soul/ (generic default doner)');
|
|
49
71
|
if (whatToReset.personal) console.log(' - personal/');
|
|
50
72
|
|
|
51
|
-
|
|
52
|
-
const ans = await inquirer.prompt([{
|
|
53
|
-
type: 'confirm',
|
|
54
|
-
name: 'confirm',
|
|
55
|
-
message: 'Tum verileri silmek istediginize emin misiniz?',
|
|
56
|
-
default: false,
|
|
57
|
-
}]);
|
|
58
|
-
|
|
59
|
-
if (!ans.confirm) {
|
|
60
|
-
console.log(chalk.gray('\nIptal edildi.'));
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
73
|
+
|
|
63
74
|
|
|
64
75
|
// Sil
|
|
65
76
|
if (whatToReset.config) {
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dangerous Command Approval (v5.6.16)
|
|
3
|
+
*
|
|
4
|
+
* Hermes Agent'taki "Command required approval" mekanizmasinin
|
|
5
|
+
* NatureCo CLI versiyonu. Riskli komutlari calistirmadan once
|
|
6
|
+
* kullanici onayi alir.
|
|
7
|
+
*
|
|
8
|
+
* Kullanim:
|
|
9
|
+
* const { requireApproval, RISK } = require('../utils/dangerous');
|
|
10
|
+
* if (!await requireApproval('reset', { scope: 'full' }, RISK.CRITICAL)) return;
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const inquirer = require('../utils/inquirer-wrapper');
|
|
14
|
+
const chalk = require('chalk');
|
|
15
|
+
|
|
16
|
+
const RISK = {
|
|
17
|
+
LOW: 'low', // Otomatik onay
|
|
18
|
+
MEDIUM: 'medium', // Basit onay mesaji
|
|
19
|
+
HIGH: 'high', // Acik onay gerekli
|
|
20
|
+
CRITICAL: 'critical', // Tam yazim onay gerekli
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const RISK_LABELS = {
|
|
24
|
+
low: { color: 'gray', icon: '⚪', label: 'DUSUK RISK' },
|
|
25
|
+
medium: { color: 'yellow', icon: '🟡', label: 'ORTA RISK' },
|
|
26
|
+
high: { color: 'red', icon: '🔴', label: 'YUKSEK RISK' },
|
|
27
|
+
critical: { color: 'magenta', icon: '⛔', label: 'KRITIK - GERI ALINAMAZ' },
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const RISK_RANK = { low: 0, medium: 1, high: 2, critical: 3 };
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Komut calistirmadan once risk seviyesi goster, onay iste
|
|
34
|
+
* @param {string} command - komut adi ('reset', 'uninstall', 'memory clear', vs.)
|
|
35
|
+
* @param {object} args - komutun parametreleri
|
|
36
|
+
* @param {string} risk - RISK enum degeri
|
|
37
|
+
* @param {string} reason - neden tehlikeli
|
|
38
|
+
* @returns {Promise<boolean>} - onay verildi mi
|
|
39
|
+
*/
|
|
40
|
+
async function requireApproval(command, args = {}, risk = RISK.HIGH, reason = '') {
|
|
41
|
+
// --force veya --yes flag kontrolu (CLI tarafinda eklenir)
|
|
42
|
+
if (process.env.NATURECO_FORCE === '1' || args.force || args.yes) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const label = RISK_LABELS[risk] || RISK_LABELS.high;
|
|
47
|
+
|
|
48
|
+
console.log();
|
|
49
|
+
console.log(chalk[label.color](` ${label.icon} ${label.label}: ${command}`));
|
|
50
|
+
console.log(chalk.gray(' ' + '─'.repeat(60)));
|
|
51
|
+
console.log(chalk.white(` Komut: ${command}`));
|
|
52
|
+
if (Object.keys(args).length > 0) {
|
|
53
|
+
console.log(chalk.gray(` Argumanlar: ${JSON.stringify(args)}`));
|
|
54
|
+
}
|
|
55
|
+
if (reason) {
|
|
56
|
+
console.log(chalk[label.color](` Neden: ${reason}`));
|
|
57
|
+
}
|
|
58
|
+
console.log(chalk.gray(' ' + '─'.repeat(60)));
|
|
59
|
+
|
|
60
|
+
// Dusuk risk - otomatik onay, sadece mesaj goster
|
|
61
|
+
if (risk === RISK.LOW) {
|
|
62
|
+
console.log(chalk.gray(' Otomatik onaylandi (dusuk risk)'));
|
|
63
|
+
console.log();
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Kritik risk - tam yazim gerekli
|
|
68
|
+
if (risk === RISK.CRITICAL) {
|
|
69
|
+
console.log(chalk.red(' Bu islem geri alinamaz!'));
|
|
70
|
+
const { confirm } = await inquirer.prompt([{
|
|
71
|
+
type: 'input',
|
|
72
|
+
name: 'confirm',
|
|
73
|
+
message: chalk.red(' Devam etmek icin "EVET SIL" yazin (veya Enter ile iptal):'),
|
|
74
|
+
validate: (input) => input === 'EVET SIL' || input === ''
|
|
75
|
+
}]);
|
|
76
|
+
console.log();
|
|
77
|
+
return confirm === 'EVET SIL';
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Yuksek ve orta risk - basit onay
|
|
81
|
+
const promptType = risk === RISK.HIGH ? 'confirm' : 'confirm';
|
|
82
|
+
const { ok } = await inquirer.prompt([{
|
|
83
|
+
type: promptType,
|
|
84
|
+
name: 'ok',
|
|
85
|
+
message: chalk[label.color](` Bu komutu calistirmak istediginize emin misiniz?`),
|
|
86
|
+
default: false,
|
|
87
|
+
}]);
|
|
88
|
+
console.log();
|
|
89
|
+
return ok;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Komutun risk seviyesini goster, hizli onay al
|
|
94
|
+
* (sync versiyon, sadece mesaj gosterir)
|
|
95
|
+
*/
|
|
96
|
+
function showRisk(command, args = {}, risk = RISK.MEDIUM, reason = '') {
|
|
97
|
+
const label = RISK_LABELS[risk] || RISK_LABELS.medium;
|
|
98
|
+
console.log();
|
|
99
|
+
console.log(chalk[label.color](` ${label.icon} ${label.label}: ${command}`));
|
|
100
|
+
if (reason) console.log(chalk.gray(` ${reason}`));
|
|
101
|
+
console.log();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
module.exports = {
|
|
105
|
+
RISK,
|
|
106
|
+
RISK_LABELS,
|
|
107
|
+
RISK_RANK,
|
|
108
|
+
requireApproval,
|
|
109
|
+
showRisk,
|
|
110
|
+
};
|