fleetbo-cockpit-cli 1.0.111 → 1.0.113
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 +87 -31
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -636,54 +636,110 @@ if (command === 'alex') {
|
|
|
636
636
|
prompt: `\x1b[34m${dynamicUsername} ❯ \x1b[0m`
|
|
637
637
|
});
|
|
638
638
|
|
|
639
|
-
|
|
640
|
-
|
|
639
|
+
// Active les events keypress sur stdin pour détecter le paste
|
|
640
|
+
readline.emitKeypressEvents(process.stdin, rl);
|
|
641
|
+
if (process.stdin.isTTY) process.stdin.setRawMode(true);
|
|
641
642
|
|
|
642
643
|
let inputBuffer = "";
|
|
643
644
|
let isProcessing = false;
|
|
645
|
+
let currentLine = "";
|
|
646
|
+
let isPasting = false;
|
|
647
|
+
let pasteTimer = null;
|
|
644
648
|
|
|
645
|
-
|
|
649
|
+
const resetPrompt = () => {
|
|
650
|
+
rl.setPrompt(`\x1b[34m${dynamicUsername} ❯ \x1b[0m`);
|
|
651
|
+
rl.prompt(true);
|
|
652
|
+
};
|
|
653
|
+
|
|
654
|
+
const submit = async () => {
|
|
655
|
+
const finalPrompt = inputBuffer.trim();
|
|
656
|
+
inputBuffer = "";
|
|
657
|
+
currentLine = "";
|
|
658
|
+
|
|
659
|
+
if (!finalPrompt) { resetPrompt(); return; }
|
|
660
|
+
|
|
661
|
+
if (finalPrompt.length > 1000) {
|
|
662
|
+
console.log(`\n\x1b[31m⛔ [Alex Safety] Mission rejected: Excessive size (${finalPrompt.length}/1000 characters).\x1b[0m`);
|
|
663
|
+
resetPrompt();
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
isProcessing = true;
|
|
668
|
+
rl.setPrompt("");
|
|
669
|
+
process.stdout.write('\n');
|
|
670
|
+
await processAlexRequest(finalPrompt);
|
|
671
|
+
isProcessing = false;
|
|
672
|
+
console.log('');
|
|
673
|
+
resetPrompt();
|
|
674
|
+
};
|
|
675
|
+
|
|
676
|
+
// Keypress : détecte si c'est un paste (chunk > 1 char) ou frappe normale
|
|
677
|
+
process.stdin.on('keypress', (char, key) => {
|
|
646
678
|
if (isProcessing) return;
|
|
647
679
|
|
|
648
|
-
|
|
680
|
+
// Ctrl+C
|
|
681
|
+
if (key && key.ctrl && key.name === 'c') {
|
|
682
|
+
console.log('\n\x1b[90mAlex session closed.\x1b[0m');
|
|
683
|
+
process.exit(0);
|
|
684
|
+
}
|
|
649
685
|
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
686
|
+
// Entrée : soumettre si buffer non vide
|
|
687
|
+
if (key && (key.name === 'return' || key.name === 'enter')) {
|
|
688
|
+
if (inputBuffer.trim() !== "") {
|
|
689
|
+
submit();
|
|
690
|
+
}
|
|
653
691
|
return;
|
|
654
692
|
}
|
|
655
693
|
|
|
656
|
-
|
|
657
|
-
|
|
694
|
+
// Paste : char arrive avec plusieurs caractères d'un coup
|
|
695
|
+
if (char && char.length > 1) {
|
|
696
|
+
isPasting = true;
|
|
697
|
+
if (pasteTimer) clearTimeout(pasteTimer);
|
|
698
|
+
// Accumule dans inputBuffer via readline line event
|
|
699
|
+
pasteTimer = setTimeout(() => {
|
|
700
|
+
isPasting = false;
|
|
701
|
+
// Affiche le hint après le paste
|
|
702
|
+
process.stdout.write(`\n\x1b[90m↵ to send · keep typing to add more\x1b[0m`);
|
|
703
|
+
rl.setPrompt(`\n\x1b[34m${dynamicUsername} ❯ \x1b[0m`);
|
|
704
|
+
rl.prompt(true);
|
|
705
|
+
}, 50);
|
|
706
|
+
}
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
// Line event : accumule les lignes dans le buffer
|
|
710
|
+
rl.on('line', (line) => {
|
|
711
|
+
if (isProcessing) return;
|
|
712
|
+
|
|
713
|
+
if (isPasting) {
|
|
714
|
+
// Pendant un paste : accumule sans soumettre
|
|
658
715
|
inputBuffer += (inputBuffer ? "\n" : "") + line;
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
} else {
|
|
662
|
-
if (inputBuffer.trim() !== "") {
|
|
663
|
-
const finalPrompt = inputBuffer.trim();
|
|
664
|
-
inputBuffer = "";
|
|
665
|
-
|
|
666
|
-
if (finalPrompt.length > 1000) {
|
|
667
|
-
console.log(`\n\x1b[31m⛔ [Alex Safety] Mission rejected: Excessive size (${finalPrompt.length}/1000 characters).\x1b[0m`);
|
|
668
|
-
rl.setPrompt(`\x1b[34m${dynamicUsername} ❯ \x1b[0m`);
|
|
669
|
-
rl.prompt();
|
|
670
|
-
return;
|
|
671
|
-
}
|
|
716
|
+
return;
|
|
717
|
+
}
|
|
672
718
|
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
719
|
+
const trimmed = line.trim();
|
|
720
|
+
if (['exit', 'quit'].includes(trimmed.toLowerCase())) {
|
|
721
|
+
console.log('\n\x1b[90mAlex session closed.\x1b[0m');
|
|
722
|
+
process.exit(0);
|
|
723
|
+
}
|
|
677
724
|
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
725
|
+
if (trimmed !== "") {
|
|
726
|
+
inputBuffer += (inputBuffer ? "\n" : "") + line;
|
|
727
|
+
// Hint de confirmation après frappe normale
|
|
728
|
+
process.stdout.write(`\x1b[90m ↵ to send · keep typing to add more\x1b[0m\n`);
|
|
729
|
+
rl.setPrompt(`\x1b[34m${dynamicUsername} ❯ \x1b[0m`);
|
|
730
|
+
rl.prompt(true);
|
|
731
|
+
} else {
|
|
732
|
+
// Ligne vide = soumettre
|
|
733
|
+
if (inputBuffer.trim()) {
|
|
734
|
+
submit();
|
|
681
735
|
} else {
|
|
682
|
-
|
|
683
|
-
rl.prompt();
|
|
736
|
+
resetPrompt();
|
|
684
737
|
}
|
|
685
738
|
}
|
|
686
739
|
});
|
|
740
|
+
|
|
741
|
+
process.stdout.write('\n');
|
|
742
|
+
resetPrompt();
|
|
687
743
|
};
|
|
688
744
|
|
|
689
745
|
if (!initialPrompt || initialPrompt === '?') startAlexSession();
|