fleetbo-cockpit-cli 1.0.45 → 1.0.46
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/cli.js +31 -44
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -239,11 +239,10 @@ if (command === 'alex') {
|
|
|
239
239
|
console.log('\x1b[90mAlex prefers concise instructions. Please summarize.\x1b[0m');
|
|
240
240
|
return;
|
|
241
241
|
}
|
|
242
|
-
//process.stdout.write('\x1b[33m🧠 Alex is thinking...\x1b[0m');
|
|
243
242
|
console.log('\x1b[33m🧠 Alex is thinking...\x1b[0m');
|
|
244
243
|
|
|
245
244
|
try {
|
|
246
|
-
// ---
|
|
245
|
+
// --- SYSTÈME DE MÉMOIRE (SMART CACHE SCANNER) ---
|
|
247
246
|
let contextInjection = "";
|
|
248
247
|
const potentialModules = extractPotentialModules(prompt);
|
|
249
248
|
let referenceFound = false;
|
|
@@ -260,7 +259,6 @@ if (command === 'alex') {
|
|
|
260
259
|
? "MÉTAL EXISTANT (À MODIFIER)"
|
|
261
260
|
: "MÉTAL DE RÉFÉRENCE (POUR PARITÉ DES DONNÉES)";
|
|
262
261
|
|
|
263
|
-
// ⚠️ CHANGEMENT MAJEUR : ON N'ENVOIE QUE LE CODE NATIF
|
|
264
262
|
contextInjection = `
|
|
265
263
|
|
|
266
264
|
--- CONTEXTE SOUVERAIN : ${contextTitle} (${modName}) ---
|
|
@@ -280,7 +278,7 @@ if (command === 'alex') {
|
|
|
280
278
|
process.stdout.write(` \x1b[31mNOT FOUND\x1b[0m\n`);
|
|
281
279
|
}
|
|
282
280
|
}
|
|
283
|
-
// --- FIN MODIFICATION ---
|
|
281
|
+
// --- FIN MODIFICATION MÉMOIRE ---
|
|
284
282
|
|
|
285
283
|
const result = await axios.post(ALEX_ENGINE_URL, { prompt, projectType: 'android' }, {
|
|
286
284
|
headers: { 'x-project-id': projectId }
|
|
@@ -292,7 +290,6 @@ if (command === 'alex') {
|
|
|
292
290
|
try { aiData = JSON.parse(aiData); } catch (_) {}
|
|
293
291
|
}
|
|
294
292
|
|
|
295
|
-
//process.stdout.write('\r' + ' '.repeat(50) + '\r');
|
|
296
293
|
process.stdout.write('\x1b[A\r' + ' '.repeat(50) + '\r');
|
|
297
294
|
|
|
298
295
|
if (aiData.status === 'quota_exceeded') {
|
|
@@ -304,11 +301,7 @@ if (command === 'alex') {
|
|
|
304
301
|
console.log('');
|
|
305
302
|
let rawMsg = aiData.message || "I'm ready.";
|
|
306
303
|
|
|
307
|
-
// 🛡️ FIX DÉFINITIF: Gemini imbrique parfois le JSON complet dans "message"
|
|
308
|
-
// Le JSON imbriqué peut être tronqué (4000 tokens), donc JSON.parse échoue.
|
|
309
|
-
// On extrait le vrai message par découpe de string.
|
|
310
304
|
if (typeof rawMsg === 'string' && rawMsg.trimStart().startsWith('{')) {
|
|
311
|
-
// Tentative 1: Parse complet (JSON non tronqué)
|
|
312
305
|
try {
|
|
313
306
|
const nested = JSON.parse(rawMsg);
|
|
314
307
|
if (nested && nested.message) {
|
|
@@ -318,7 +311,6 @@ if (command === 'alex') {
|
|
|
318
311
|
}
|
|
319
312
|
}
|
|
320
313
|
} catch (_) {
|
|
321
|
-
// Tentative 2: Extraction par regex (JSON tronqué)
|
|
322
314
|
const msgMatch = rawMsg.match(/"message"\s*:\s*"((?:[^"\\]|\\.)*)"/);
|
|
323
315
|
if (msgMatch && msgMatch[1]) {
|
|
324
316
|
rawMsg = msgMatch[1].replace(/\\n/g, '\n').replace(/\\"/g, '"');
|
|
@@ -328,18 +320,15 @@ if (command === 'alex') {
|
|
|
328
320
|
}
|
|
329
321
|
}
|
|
330
322
|
|
|
331
|
-
// 🛡️ SAFETY: Si le message est un JSON stringifié ou contient du code brut,
|
|
332
|
-
// on extrait uniquement la partie lisible pour le terminal.
|
|
333
323
|
if (typeof rawMsg === 'object') {
|
|
334
324
|
rawMsg = rawMsg.message || rawMsg.text || "Module generated.";
|
|
335
325
|
}
|
|
336
|
-
// Détection d'un JSON brut accidentellement injecté dans le message
|
|
337
326
|
try {
|
|
338
327
|
const testParse = JSON.parse(rawMsg);
|
|
339
328
|
if (testParse && typeof testParse === 'object' && testParse.status) {
|
|
340
329
|
rawMsg = testParse.message || "Module generated.";
|
|
341
330
|
}
|
|
342
|
-
} catch (_) {
|
|
331
|
+
} catch (_) { }
|
|
343
332
|
|
|
344
333
|
const formattedMsg = wrapText(rawMsg, 85);
|
|
345
334
|
console.log('\x1b[32mAlex ❯\x1b[0m ' + formattedMsg);
|
|
@@ -393,22 +382,29 @@ if (command === 'alex') {
|
|
|
393
382
|
}
|
|
394
383
|
}
|
|
395
384
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
385
|
+
// --- CORRECTION : SYNCHRONISATION DU KERNEL (Cache + Dépendances INCONDITIONNELLE) ---
|
|
386
|
+
const depsCount = config_offload?.dependencies?.length || 0;
|
|
387
|
+
process.stdout.write(` \x1b[33m[Cloud Inject]\x1b[0m Archiving ${moduleName} to Kernel (${depsCount} libs)...`);
|
|
388
|
+
|
|
389
|
+
try {
|
|
390
|
+
await axios.post(INJECT_DEPS_URL, {
|
|
391
|
+
projectId: projectId,
|
|
392
|
+
fileData: {
|
|
393
|
+
path: fileName,
|
|
394
|
+
moduleName: moduleName, // INDISPENSABLE POUR LE CACHE
|
|
395
|
+
fileName: fileName,
|
|
396
|
+
code: code, // LE MÉTAL
|
|
397
|
+
mockFileName: mockFileName,
|
|
398
|
+
mockCode: mockCode, // LE MOCK
|
|
399
|
+
config_offload: config_offload || { dependencies: [], permissions: [] } // Sécurité
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
process.stdout.write(` \x1b[32mOK\x1b[0m\n`);
|
|
403
|
+
} catch (err) {
|
|
404
|
+
process.stdout.write(` \x1b[31mFAILED\x1b[0m\n`);
|
|
405
|
+
console.error(` ⚠️ Kernel sync failed: ${err.message}`);
|
|
411
406
|
}
|
|
407
|
+
// --- FIN CORRECTION ---
|
|
412
408
|
}
|
|
413
409
|
} catch (error) {
|
|
414
410
|
process.stdout.write('\r' + ' '.repeat(50) + '\r');
|
|
@@ -461,7 +457,7 @@ if (command === 'alex') {
|
|
|
461
457
|
console.log(' \x1b[1m🎬 High-Perf\x1b[0m\x1b[90m Infinite Feeds, Video Players, Swipe Decks\x1b[0m');
|
|
462
458
|
console.log(' \x1b[1m🏗️ Sovereign\x1b[0m\x1b[90m Full screens: form + photo + save-to-cloud\x1b[0m');
|
|
463
459
|
|
|
464
|
-
// 3. LA COLLABORATION
|
|
460
|
+
// 3. LA COLLABORATION
|
|
465
461
|
console.log('\n\x1b[36m💡 TELL ME "WHAT + WHY":\x1b[0m');
|
|
466
462
|
console.log('\x1b[90m I will analyze your need and recommend the perfect module to forge.\x1b[0m');
|
|
467
463
|
console.log('');
|
|
@@ -481,37 +477,29 @@ if (command === 'alex') {
|
|
|
481
477
|
process.stdout.write('\n\x1b[F');
|
|
482
478
|
rl.prompt();
|
|
483
479
|
|
|
484
|
-
// --- NATURAL MULTI-LINE BUFFER (ZERO GLITCH V2) ---
|
|
485
480
|
let inputBuffer = "";
|
|
486
481
|
let isProcessing = false;
|
|
487
482
|
|
|
488
483
|
rl.on('line', async (line) => {
|
|
489
|
-
if (isProcessing) return;
|
|
484
|
+
if (isProcessing) return;
|
|
490
485
|
|
|
491
486
|
const trimmedLine = line.trim();
|
|
492
487
|
|
|
493
|
-
// 1. COMMANDES DE SORTIE
|
|
494
488
|
if (['exit', 'quit'].includes(trimmedLine.toLowerCase())) {
|
|
495
489
|
console.log('\n\x1b[90m Alex session closed.\x1b[0m');
|
|
496
490
|
rl.close();
|
|
497
491
|
return;
|
|
498
492
|
}
|
|
499
493
|
|
|
500
|
-
// 2. ACCUMULATION (Si la ligne n'est pas vide)
|
|
501
494
|
if (trimmedLine !== "") {
|
|
502
495
|
inputBuffer += (inputBuffer ? "\n" : "") + line;
|
|
503
|
-
|
|
504
|
-
// 🛡️ LE SECRET EST LÀ : On vide le préfixe pour les lignes suivantes.
|
|
505
|
-
// Quand tu colles, NodeJS arrêtera de répéter "jojo ❯" partout !
|
|
506
496
|
rl.setPrompt("");
|
|
507
497
|
}
|
|
508
|
-
// 3. VALIDATION (Touche Entrée sur une ligne vide)
|
|
509
498
|
else {
|
|
510
499
|
if (inputBuffer.trim() !== "") {
|
|
511
500
|
const finalPrompt = inputBuffer.trim();
|
|
512
501
|
inputBuffer = "";
|
|
513
502
|
|
|
514
|
-
// 🛑 COUPE-CIRCUIT STRICT
|
|
515
503
|
if (finalPrompt.length > 1000) {
|
|
516
504
|
console.log(`\n\x1b[31m⛔ [Alex Safety] Mission rejetée : Taille excessive (${finalPrompt.length}/1000 caractères).\x1b[0m`);
|
|
517
505
|
console.log(`\x1b[90m Veuillez être plus concis et vous concentrer sur l'essentiel.\x1b[0m\n`);
|
|
@@ -520,18 +508,17 @@ if (command === 'alex') {
|
|
|
520
508
|
return;
|
|
521
509
|
}
|
|
522
510
|
|
|
523
|
-
// ✅ ON LANCE LA FORGE
|
|
524
511
|
isProcessing = true;
|
|
525
|
-
rl.setPrompt("");
|
|
512
|
+
rl.setPrompt("");
|
|
526
513
|
await processAlexRequest(finalPrompt);
|
|
527
514
|
isProcessing = false;
|
|
528
515
|
|
|
529
516
|
console.log('');
|
|
530
517
|
rl.setPrompt(`\x1b[34m${dynamicUsername} ❯ \x1b[0m`);
|
|
531
|
-
rl.prompt();
|
|
518
|
+
rl.prompt();
|
|
532
519
|
} else {
|
|
533
520
|
rl.setPrompt(`\x1b[34m${dynamicUsername} ❯ \x1b[0m`);
|
|
534
|
-
rl.prompt();
|
|
521
|
+
rl.prompt();
|
|
535
522
|
}
|
|
536
523
|
}
|
|
537
524
|
});
|
|
@@ -540,7 +527,7 @@ if (command === 'alex') {
|
|
|
540
527
|
if (!initialPrompt || initialPrompt === '?') startAlexSession();
|
|
541
528
|
else processAlexRequest(initialPrompt);
|
|
542
529
|
|
|
543
|
-
}
|
|
530
|
+
}
|
|
544
531
|
|
|
545
532
|
// ============================================
|
|
546
533
|
// COMMAND: rm (MODULE ANNIHILATION)
|