fleetbo-cockpit-cli 1.0.114 → 1.0.115

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.
Files changed (2) hide show
  1. package/cli.js +75 -62
  2. package/package.json +1 -1
package/cli.js CHANGED
@@ -587,102 +587,115 @@ if (command === 'alex') {
587
587
  const modelLabel = aiModel && aiModel !== 'auto' ? aiModel : 'auto';
588
588
 
589
589
  console.log('');
590
- console.log('\x1b[90m ┌─────────────────────────────────────────────────────────┐\x1b[0m');
591
- console.log('\x1b[90m │\x1b[0m \x1b[90m│\x1b[0m');
592
- console.log('\x1b[90m │\x1b[0m \x1b[1m\x1b[36m⚡ ALEX\x1b[0m \x1b[90m— System Architect · Fleetbo OS\x1b[0m \x1b[90m│\x1b[0m');
593
- console.log('\x1b[90m │\x1b[0m \x1b[90m│\x1b[0m');
594
- console.log('\x1b[90m │\x1b[0m \x1b[90mYour JS stays the brain. I forge the metal.\x1b[0m \x1b[90m│\x1b[0m');
595
- console.log('\x1b[90m │\x1b[0m \x1b[90m│\x1b[0m');
596
- console.log('\x1b[90m └─────────────────────────────────────────────────────────┘\x1b[0m');
590
+ console.log('\x1b[90m┌─────────────────────────────────────────────────────────┐\x1b[0m');
591
+ console.log('\x1b[90m│\x1b[0m \x1b[90m│\x1b[0m');
592
+ console.log('\x1b[90m│\x1b[0m \x1b[1m\x1b[36m⚡ ALEX\x1b[0m \x1b[90m— System Architect · Fleetbo OS\x1b[0m \x1b[90m│\x1b[0m');
593
+ console.log('\x1b[90m│\x1b[0m \x1b[90m│\x1b[0m');
594
+ console.log('\x1b[90m│\x1b[0m \x1b[90mYour JS stays the brain. I forge the metal.\x1b[0m \x1b[90m│\x1b[0m');
595
+ console.log('\x1b[90m│\x1b[0m \x1b[90m│\x1b[0m');
596
+ console.log('\x1b[90m└─────────────────────────────────────────────────────────┘\x1b[0m');
597
597
 
598
598
  // AI ENGINE STATUS
599
599
  console.log('');
600
- console.log(` \x1b[32m ✓\x1b[0m ${providerLabel} \x1b[90m· ${modelLabel}\x1b[0m`);
600
+ console.log(`\x1b[32m✓\x1b[0m ${providerLabel} \x1b[90m· ${modelLabel}\x1b[0m`);
601
601
 
602
602
  // FORGE CAPABILITIES
603
603
  console.log('');
604
- console.log(' \x1b[36m CAPABILITIES\x1b[0m');
605
- console.log(' \x1b[90m ─────────────────────────────────────────────────────\x1b[0m');
606
- console.log(' \x1b[1m Hardware\x1b[0m\x1b[90m Camera · Scanner · GPS · Biometrics\x1b[0m');
607
- console.log(' \x1b[1m High-Perf\x1b[0m\x1b[90m Video Feed · Swipe Deck · Audio\x1b[0m');
608
- console.log(' \x1b[1m Sovereign\x1b[0m\x1b[90m Form + Photo + Save-to-Cloud\x1b[0m');
609
- console.log(' \x1b[1m Fleetbo View\x1b[0m\x1b[90m Full native tab (120 FPS)\x1b[0m');
610
- console.log(' \x1b[90m ─────────────────────────────────────────────────────\x1b[0m');
604
+ console.log('\x1b[36mCAPABILITIES\x1b[0m');
605
+ console.log('\x1b[90m─────────────────────────────────────────────────────\x1b[0m');
606
+ console.log('\x1b[1mHardware\x1b[0m\x1b[90m Camera · Scanner · GPS · Biometrics\x1b[0m');
607
+ console.log('\x1b[1mHigh-Perf\x1b[0m\x1b[90m Video Feed · Swipe Deck · Audio\x1b[0m');
608
+ console.log('\x1b[1mSovereign\x1b[0m\x1b[90m Form + Photo + Save-to-Cloud\x1b[0m');
609
+ console.log('\x1b[1mFleetbo View\x1b[0m\x1b[90m Full native tab (120 FPS)\x1b[0m');
610
+ console.log('\x1b[90m─────────────────────────────────────────────────────\x1b[0m');
611
611
 
612
612
  // TRIGGER WORDS
613
613
  console.log('');
614
- console.log(' \x1b[36m TRIGGER WORDS\x1b[0m \x1b[90m(required to activate code generation)\x1b[0m');
614
+ console.log('\x1b[36mTRIGGER WORDS\x1b[0m \x1b[90m(required to activate code generation)\x1b[0m');
615
615
  console.log('');
616
- console.log(' \x1b[33m forge\x1b[0m \x1b[90m·\x1b[0m \x1b[33mcreate\x1b[0m \x1b[90m·\x1b[0m \x1b[33mupdate\x1b[0m \x1b[90m·\x1b[0m \x1b[33mmodify\x1b[0m \x1b[90m·\x1b[0m \x1b[33mfix\x1b[0m \x1b[90m·\x1b[0m \x1b[33medit\x1b[0m');
616
+ console.log('\x1b[33mforge\x1b[0m \x1b[90m·\x1b[0m \x1b[33mcreate\x1b[0m \x1b[90m·\x1b[0m \x1b[33mupdate\x1b[0m \x1b[90m·\x1b[0m \x1b[33mmodify\x1b[0m \x1b[90m·\x1b[0m \x1b[33mfix\x1b[0m \x1b[90m·\x1b[0m \x1b[33medit\x1b[0m');
617
617
  console.log('');
618
- console.log(' \x1b[90m Without a trigger word, Alex answers but does not generate code.\x1b[0m');
618
+ console.log('\x1b[90mWithout a trigger word, Alex answers but does not generate code.\x1b[0m');
619
619
 
620
620
  // EXAMPLES
621
621
  console.log('');
622
- console.log(' \x1b[36m EXAMPLES\x1b[0m');
622
+ console.log('\x1b[36mEXAMPLES\x1b[0m');
623
623
  console.log('');
624
- console.log(' \x1b[33m ›\x1b[0m \x1b[90m"\x1b[33mforge\x1b[90m a camera to scan receipts for my expense tracker"\x1b[0m');
625
- console.log(' \x1b[33m ›\x1b[0m \x1b[90m"\x1b[33mcreate\x1b[90m a form to add products with photos to my catalog"\x1b[0m');
626
- console.log(' \x1b[33m ›\x1b[0m \x1b[90m"\x1b[33mupdate\x1b[90m CloudCamera to save in the collection orders"\x1b[0m');
624
+ console.log('\x1b[33m›\x1b[0m \x1b[90m"\x1b[33mforge\x1b[90m a camera to scan receipts for my expense tracker"\x1b[0m');
625
+ console.log('\x1b[33m›\x1b[0m \x1b[90m"\x1b[33mcreate\x1b[90m a form to add products with photos to my catalog"\x1b[0m');
626
+ console.log('\x1b[33m›\x1b[0m \x1b[90m"\x1b[33mupdate\x1b[90m CloudCamera to save in the collection orders"\x1b[0m');
627
627
 
628
628
  // READY
629
629
  console.log('');
630
- console.log(' \x1b[32m Alex ❯\x1b[0m Describe your feature.');
630
+ console.log('\x1b[32mAlex ❯\x1b[0m Describe your feature.');
631
631
  console.log('');
632
-
633
- const rl = readline.createInterface({
634
- input: process.stdin,
632
+
633
+ const rl = readline.createInterface({
634
+ input: process.stdin,
635
635
  output: process.stdout,
636
- prompt: `\x1b[34m${dynamicUsername} ❯ \x1b[0m`
636
+ prompt: `\x1b[34m${dynamicUsername} ❯ \x1b[0m`
637
637
  });
638
-
639
- process.stdout.write('\n\x1b[F');
640
- rl.prompt();
641
638
 
642
- let inputBuffer = "";
643
- let isProcessing = false;
639
+ let inputBuffer = "";
640
+ let isProcessing = false;
641
+ let submitTimer = null; // fenêtre de 80ms : ignore les lignes vides d'un paste
642
+
643
+ const resetPrompt = () => {
644
+ rl.setPrompt(`\x1b[34m${dynamicUsername} ❯ \x1b[0m`);
645
+ rl.prompt(true);
646
+ };
647
+
648
+ const submit = async () => {
649
+ if (submitTimer) { clearTimeout(submitTimer); submitTimer = null; }
650
+ const finalPrompt = inputBuffer.trim();
651
+ inputBuffer = "";
652
+ if (!finalPrompt) { resetPrompt(); return; }
653
+
654
+ if (finalPrompt.length > 1000) {
655
+ console.log(`\n\x1b[31m⛔ [Alex Safety] Mission rejected: Excessive size (${finalPrompt.length}/1000 characters).\x1b[0m`);
656
+ resetPrompt();
657
+ return;
658
+ }
659
+
660
+ isProcessing = true;
661
+ rl.setPrompt("");
662
+ await processAlexRequest(finalPrompt);
663
+ isProcessing = false;
664
+ console.log('');
665
+ resetPrompt();
666
+ };
644
667
 
645
668
  rl.on('line', async (line) => {
646
- if (isProcessing) return;
669
+ if (isProcessing) return;
647
670
 
648
- const trimmedLine = line.trim();
671
+ const trimmed = line.trim();
649
672
 
650
- if (['exit', 'quit'].includes(trimmedLine.toLowerCase())) {
651
- console.log('\n\x1b[90m Alex session closed.\x1b[0m');
652
- rl.close();
653
- return;
673
+ if (['exit', 'quit'].includes(trimmed.toLowerCase())) {
674
+ console.log('\n\x1b[90mAlex session closed.\x1b[0m');
675
+ rl.close();
676
+ process.exit(0);
654
677
  }
655
678
 
656
- if (trimmedLine !== "") {
679
+ if (trimmed !== "") {
680
+ // Nouvelle ligne avec contenu : annule le timer de soumission en cours
681
+ // (cas paste : la ligne vide du paste n'aura pas eu le temps de soumettre)
682
+ if (submitTimer) { clearTimeout(submitTimer); submitTimer = null; }
657
683
  inputBuffer += (inputBuffer ? "\n" : "") + line;
658
- rl.setPrompt("");
659
- }
660
- else {
684
+ rl.setPrompt(`\x1b[90m ↵ to send · keep typing\x1b[0m\n\x1b[34m${dynamicUsername} ❯ \x1b[0m`);
685
+ rl.prompt(true);
686
+ } else {
661
687
  if (inputBuffer.trim() !== "") {
662
- const finalPrompt = inputBuffer.trim();
663
- inputBuffer = "";
664
-
665
- if (finalPrompt.length > 1000) {
666
- console.log(`\n\x1b[31m⛔ [Alex Safety] Mission rejected: Excessive size (${finalPrompt.length}/1000 characters).\x1b[0m`);
667
- rl.setPrompt(`\x1b[34m${dynamicUsername} ❯ \x1b[0m`);
668
- rl.prompt();
669
- return;
670
- }
671
-
672
- isProcessing = true;
673
- rl.setPrompt("");
674
- await processAlexRequest(finalPrompt);
675
- isProcessing = false;
676
-
677
- console.log('');
678
- rl.setPrompt(`\x1b[34m${dynamicUsername} ❯ \x1b[0m`);
679
- rl.prompt();
688
+ // Ligne vide reçue : attend 80ms avant de soumettre
689
+ // Si une autre ligne non-vide arrive dans ce délai (paste), on annule
690
+ submitTimer = setTimeout(() => submit(), 80);
680
691
  } else {
681
- rl.setPrompt(`\x1b[34m${dynamicUsername} ❯ \x1b[0m`);
682
- rl.prompt();
692
+ resetPrompt();
683
693
  }
684
694
  }
685
695
  });
696
+
697
+ process.stdout.write('\n');
698
+ resetPrompt();
686
699
  };
687
700
 
688
701
  if (!initialPrompt || initialPrompt === '?') startAlexSession();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fleetbo-cockpit-cli",
3
- "version": "1.0.114",
3
+ "version": "1.0.115",
4
4
  "description": "Fleetbo CLI - Build native mobile apps with React",
5
5
  "author": "Fleetbo",
6
6
  "license": "MIT",