fleetbo-cockpit-cli 1.0.34 → 1.0.36
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 +107 -19
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -181,6 +181,30 @@ const getModuleCache = async ({ projectId, moduleName }) => {
|
|
|
181
181
|
}
|
|
182
182
|
};
|
|
183
183
|
|
|
184
|
+
const removeRouteFromAppJs = (moduleName) => {
|
|
185
|
+
const appJsPath = path.join(process.cwd(), 'src', 'App.js');
|
|
186
|
+
if (!fs.existsSync(appJsPath)) return false;
|
|
187
|
+
|
|
188
|
+
let content = fs.readFileSync(appJsPath, 'utf8');
|
|
189
|
+
|
|
190
|
+
// Pattern exact pour l'import et la route (gestion du sous-dossier mocks/)
|
|
191
|
+
const importLine = `import ${moduleName} from './app/mocks/${moduleName}';`;
|
|
192
|
+
const routeLine = `<Route path="/mocks/${moduleName.toLowerCase()}" element={<${moduleName} />} />`;
|
|
193
|
+
|
|
194
|
+
const originalContent = content;
|
|
195
|
+
|
|
196
|
+
// On retire les lignes si elles existent (avec le retour à la ligne)
|
|
197
|
+
content = content.replace(new RegExp(`${importLine.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\n?`, 'g'), '');
|
|
198
|
+
content = content.replace(new RegExp(`\\s*${routeLine.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\n?`, 'g'), '');
|
|
199
|
+
|
|
200
|
+
if (content !== originalContent) {
|
|
201
|
+
fs.writeFileSync(appJsPath, content);
|
|
202
|
+
console.log(` \x1b[32m[Unrouted]\x1b[0m ${moduleName} supprimé de App.js.`);
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
return false;
|
|
206
|
+
};
|
|
207
|
+
|
|
184
208
|
// ============================================
|
|
185
209
|
// COMMAND: alex
|
|
186
210
|
// ============================================
|
|
@@ -415,20 +439,15 @@ if (command === 'alex') {
|
|
|
415
439
|
console.log(' \x1b[1m🎬 High-Perf\x1b[0m\x1b[90m Infinite Feeds, Video Players, Swipe Decks\x1b[0m');
|
|
416
440
|
console.log(' \x1b[1m🏗️ Sovereign\x1b[0m\x1b[90m Full screens: form + photo + save-to-cloud\x1b[0m');
|
|
417
441
|
|
|
418
|
-
// 3.
|
|
419
|
-
console.log('\n\x1b[36m💡 TELL ME WHAT + WHY:\x1b[0m');
|
|
442
|
+
// 3. LA COLLABORATION (Mise à jour V2)
|
|
443
|
+
console.log('\n\x1b[36m💡 TELL ME "WHAT + WHY":\x1b[0m');
|
|
444
|
+
console.log('\x1b[90m I will analyze your need and recommend the perfect module to forge.\x1b[0m');
|
|
420
445
|
console.log('');
|
|
421
|
-
console.log(' \x1b[33m"
|
|
422
|
-
console.log(' \x1b[33m"
|
|
423
|
-
console.log(' \x1b[33m"A QR code scanner for event check-in"\x1b[0m');
|
|
424
|
-
console.log(' \x1b[33m"A profile editor with avatar upload"\x1b[0m');
|
|
446
|
+
console.log(' \x1b[33m"I need a camera [WHAT] to scan receipts for my expense tracker [WHY]"\x1b[0m');
|
|
447
|
+
console.log(' \x1b[33m"I need a form [WHAT] to add products with photos to my catalog [WHY]"\x1b[0m');
|
|
425
448
|
|
|
426
449
|
// 4. LA PRISE DE COMMANDE
|
|
427
|
-
console.log('\n\x1b[32mAlex ❯\x1b[0m
|
|
428
|
-
console.log('');
|
|
429
|
-
|
|
430
|
-
// 3. LA PRISE DE COMMANDE
|
|
431
|
-
console.log('\x1b[32mAlex ❯\x1b[0m I am ready to forge the muscle. What module are we architecting today, Pilot?');
|
|
450
|
+
console.log('\n\x1b[32mAlex ❯\x1b[0m I am ready. Describe your feature, and I will architect the solution.');
|
|
432
451
|
console.log('');
|
|
433
452
|
|
|
434
453
|
const rl = readline.createInterface({
|
|
@@ -439,21 +458,45 @@ if (command === 'alex') {
|
|
|
439
458
|
|
|
440
459
|
process.stdout.write('\n\x1b[F');
|
|
441
460
|
rl.prompt();
|
|
442
|
-
|
|
461
|
+
|
|
462
|
+
// --- LOGIQUE DE BUFFER MULTILIGNE ---
|
|
463
|
+
let inputBuffer = ""; // La "salle d'attente" du texte
|
|
464
|
+
|
|
443
465
|
rl.on('line', async (line) => {
|
|
444
|
-
|
|
466
|
+
const trimmedLine = line.trim();
|
|
467
|
+
|
|
468
|
+
// 1. Sortie de session (exit/quit)
|
|
469
|
+
if (['exit', 'quit'].includes(trimmedLine.toLowerCase())) {
|
|
445
470
|
console.log('\n\x1b[90m Alex session closed.\x1b[0m');
|
|
446
471
|
rl.close();
|
|
447
472
|
return;
|
|
448
473
|
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
474
|
+
|
|
475
|
+
// 2. ACCUMULATION OU VALIDATION
|
|
476
|
+
if (trimmedLine !== "") {
|
|
477
|
+
// Si la ligne contient du texte, on l'ajoute au buffer
|
|
478
|
+
inputBuffer += (inputBuffer ? "\n" : "") + line;
|
|
479
|
+
|
|
480
|
+
// On change le prompt visuel pour montrer qu'on attend la suite (ligne suivante)
|
|
481
|
+
rl.setPrompt(`\x1b[34m > \x1b[0m`);
|
|
482
|
+
} else {
|
|
483
|
+
// Si la ligne est VIDE (Touche Entrée sur une ligne vide)
|
|
484
|
+
if (inputBuffer.trim() !== "") {
|
|
485
|
+
// On a du texte accumulé -> On envoie tout d'un coup à Alex
|
|
486
|
+
const finalPrompt = inputBuffer.trim();
|
|
487
|
+
inputBuffer = ""; // Reset du buffer pour la prochaine mission
|
|
488
|
+
|
|
489
|
+
// Remise à zéro du prompt visuel d'origine
|
|
490
|
+
rl.setPrompt(`\x1b[34m${dynamicUsername} ❯ \x1b[0m`);
|
|
491
|
+
|
|
492
|
+
// Lancement unique de la forge
|
|
493
|
+
await processAlexRequest(finalPrompt);
|
|
494
|
+
console.log('');
|
|
495
|
+
}
|
|
452
496
|
}
|
|
453
|
-
|
|
497
|
+
|
|
498
|
+
process.stdout.write('\n\x1b[F'); // Nettoyage visuel de la ligne
|
|
454
499
|
rl.prompt();
|
|
455
|
-
}).on('close', () => {
|
|
456
|
-
process.exit(0);
|
|
457
500
|
});
|
|
458
501
|
};
|
|
459
502
|
|
|
@@ -461,6 +504,51 @@ if (command === 'alex') {
|
|
|
461
504
|
else processAlexRequest(initialPrompt);
|
|
462
505
|
|
|
463
506
|
}
|
|
507
|
+
|
|
508
|
+
// ============================================
|
|
509
|
+
// COMMAND: rm (ANNIHILATION MODULE)
|
|
510
|
+
// ============================================
|
|
511
|
+
else if (command === 'rm') {
|
|
512
|
+
const moduleName = args[1];
|
|
513
|
+
if (!moduleName) {
|
|
514
|
+
console.error('\n\x1b[31m❌ Erreur : Nom du module requis.\x1b[0m');
|
|
515
|
+
console.log('\x1b[90mUsage: npm run fleetbo rm [ModuleName]\x1b[0m\n');
|
|
516
|
+
process.exit(1);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
console.log(`\n\x1b[33m🗑️ Annihilation du module : ${moduleName}...\x1b[0m`);
|
|
520
|
+
|
|
521
|
+
// 1. Définition des chemins physiques
|
|
522
|
+
const ktPath = path.join(process.cwd(), 'public', 'native', 'android', `${moduleName}.kt`);
|
|
523
|
+
const jsxPath = path.join(process.cwd(), 'src', 'app', 'mocks', `${moduleName}.jsx`);
|
|
524
|
+
|
|
525
|
+
let actionsDone = 0;
|
|
526
|
+
|
|
527
|
+
// 2. Suppression du Moteur (Kotlin)
|
|
528
|
+
if (fs.existsSync(ktPath)) {
|
|
529
|
+
fs.unlinkSync(ktPath);
|
|
530
|
+
console.log(` \x1b[32m[Deleted]\x1b[0m Fichier Métal (.kt) supprimé.`);
|
|
531
|
+
actionsDone++;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// 3. Suppression du Jumeau Numérique (Mock JSX)
|
|
535
|
+
if (fs.existsSync(jsxPath)) {
|
|
536
|
+
fs.unlinkSync(jsxPath);
|
|
537
|
+
console.log(` \x1b[32m[Deleted]\x1b[0m Fichier Virtuel (.jsx) supprimé.`);
|
|
538
|
+
actionsDone++;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// 4. Nettoyage du noyau (App.js)
|
|
542
|
+
const unrouted = removeRouteFromAppJs(moduleName);
|
|
543
|
+
if (unrouted) actionsDone++;
|
|
544
|
+
|
|
545
|
+
if (actionsDone === 0) {
|
|
546
|
+
console.log(`\n\x1b[31m⚠️ Aucune trace du module "${moduleName}" trouvée.\x1b[0m\n`);
|
|
547
|
+
} else {
|
|
548
|
+
console.log(`\n\x1b[32m✅ Module ${moduleName} éradiqué avec succès.\x1b[0m\n`);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
464
552
|
// ============================================
|
|
465
553
|
// COMMAND: android / ios (PROPULSION BUILD)
|
|
466
554
|
// ============================================
|