fleetbo-cockpit-cli 1.0.140 → 1.0.141
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 +63 -42
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -641,58 +641,79 @@ if (command === 'alex') {
|
|
|
641
641
|
|
|
642
642
|
let inputBuffer = "";
|
|
643
643
|
let isProcessing = false;
|
|
644
|
-
let
|
|
644
|
+
let submitTimeout = null;
|
|
645
|
+
let isPasting = false;
|
|
646
|
+
|
|
647
|
+
// Fonction d'exécution isolée pour plus de propreté
|
|
648
|
+
const executePrompt = async (text) => {
|
|
649
|
+
if (['exit', 'quit'].includes(text.toLowerCase())) {
|
|
650
|
+
console.log('\n\x1b[90m Alex session closed.\x1b[0m');
|
|
651
|
+
rl.close();
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
if (text !== "") {
|
|
655
|
+
if (text.length > 4000) {
|
|
656
|
+
console.log(`\n\x1b[31m⛔ [Alex Safety] Mission rejected: Excessive size (${text.length}/4000 characters).\x1b[0m`);
|
|
657
|
+
rl.setPrompt(`\x1b[34m${dynamicUsername} ❯ \x1b[0m`);
|
|
658
|
+
rl.prompt();
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
isProcessing = true;
|
|
662
|
+
rl.setPrompt("");
|
|
663
|
+
await processAlexRequest(text);
|
|
664
|
+
isProcessing = false;
|
|
665
|
+
console.log('');
|
|
666
|
+
rl.setPrompt(`\x1b[34m${dynamicUsername} ❯ \x1b[0m`);
|
|
667
|
+
rl.prompt();
|
|
668
|
+
} else {
|
|
669
|
+
rl.setPrompt(`\x1b[34m${dynamicUsername} ❯ \x1b[0m`);
|
|
670
|
+
rl.prompt();
|
|
671
|
+
}
|
|
672
|
+
};
|
|
645
673
|
|
|
646
674
|
rl.on('line', async (line) => {
|
|
647
675
|
if (isProcessing) return;
|
|
648
676
|
|
|
649
|
-
// 1.
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
// 🪄 2. LE BOUCLIER VISUEL : On efface immédiatement le prompt.
|
|
653
|
-
// Ça empêche le terminal de spammer "jojo ❯" à chaque ligne du copier-coller !
|
|
654
|
-
rl.setPrompt("");
|
|
655
|
-
|
|
656
|
-
// 3. On annule le timer précédent
|
|
657
|
-
if (pasteTimeout) clearTimeout(pasteTimeout);
|
|
658
|
-
|
|
659
|
-
// 4. Timer légèrement augmenté à 50ms
|
|
660
|
-
pasteTimeout = setTimeout(async () => {
|
|
677
|
+
// 1. FIN DU MODE COPIER-COLLER : L'utilisateur appuie manuellement sur Entrée (ligne vide)
|
|
678
|
+
if (isPasting && line.trim() === "") {
|
|
661
679
|
const finalPrompt = inputBuffer.trim();
|
|
662
680
|
inputBuffer = "";
|
|
681
|
+
isPasting = false; // Désactivation du mode
|
|
682
|
+
await executePrompt(finalPrompt);
|
|
683
|
+
return;
|
|
684
|
+
}
|
|
663
685
|
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
console.log('\n\x1b[90m Alex session closed.\x1b[0m');
|
|
667
|
-
rl.close();
|
|
668
|
-
return;
|
|
669
|
-
}
|
|
686
|
+
// 2. On accumule la donnée
|
|
687
|
+
inputBuffer += (inputBuffer ? "\n" : "") + line;
|
|
670
688
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
if (finalPrompt.length > 4000) {
|
|
674
|
-
console.log(`\n\x1b[31m⛔ [Alex Safety] Mission rejected: Excessive size (${finalPrompt.length}/4000 characters).\x1b[0m`);
|
|
675
|
-
rl.setPrompt(`\x1b[34m${dynamicUsername} ❯ \x1b[0m`);
|
|
676
|
-
rl.prompt();
|
|
677
|
-
return;
|
|
678
|
-
}
|
|
689
|
+
// 3. Si on est DÉJÀ en mode paste, on accumule silencieusement et on attend ton feu vert
|
|
690
|
+
if (isPasting) return;
|
|
679
691
|
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
692
|
+
// 4. DÉTECTEUR DE COPIER-COLLER : Si un timer est déjà en cours, c'est la 2ème ligne instantanée !
|
|
693
|
+
if (submitTimeout) {
|
|
694
|
+
clearTimeout(submitTimeout);
|
|
695
|
+
submitTimeout = null;
|
|
696
|
+
isPasting = true; // 🚨 L'IA comprend que tu colles et passe en mode Manuel
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
// 5. FRAPPE NORMALE : On lance le chrono de 30ms
|
|
701
|
+
submitTimeout = setTimeout(async () => {
|
|
702
|
+
submitTimeout = null;
|
|
703
|
+
|
|
704
|
+
// 🛡️ SÉCURITÉ MAGIQUE : Si le terminal a encore des caractères non validés en mémoire (rl.line),
|
|
705
|
+
// c'est que tu as collé un texte sans saut de ligne final.
|
|
706
|
+
// L'IA annule l'envoi automatique et passe en mode Paste manuel.
|
|
707
|
+
if (rl.line && rl.line.length > 0) {
|
|
708
|
+
isPasting = true;
|
|
709
|
+
return;
|
|
694
710
|
}
|
|
695
|
-
|
|
711
|
+
|
|
712
|
+
// Envoi direct ! (Car c'est bien une frappe humaine unique)
|
|
713
|
+
const finalPrompt = inputBuffer.trim();
|
|
714
|
+
inputBuffer = "";
|
|
715
|
+
await executePrompt(finalPrompt);
|
|
716
|
+
}, 30);
|
|
696
717
|
});
|
|
697
718
|
};
|
|
698
719
|
|