fleetbo-cockpit-cli 1.0.43 → 1.0.45

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 +83 -55
  2. package/package.json +1 -1
package/cli.js CHANGED
@@ -144,28 +144,49 @@ const showEnergyTransfer = async () => {
144
144
  process.stdout.write('\n');
145
145
  };
146
146
 
147
- const promptContainsModification = (text) => {
148
- // J'ai ajouté : 'bug', 'crash', 'erreur', 'error', 'fix', 'fail', 'plante'
149
- const keywords = [
150
- 'modifier', 'update', 'change', 'corrige', 'fix',
151
- 'ajoute', 'edit', 'refactor', 'bug', 'crash', 'set',
152
- 'erreur', 'error', 'fail', 'plante', 'problème'
153
- ];
154
- const lower = text.toLowerCase();
155
- return keywords.some(k => lower.includes(k));
147
+ // Détecte TOUS les mots en PascalCase (ex: GuestCreator, CameraModule, Tab2)
148
+ const extractPotentialModules = (text) => {
149
+ const regex = /\b[A-Z][a-zA-Z0-9_]{2,}\b/g;
150
+ const matches = text.match(regex) || [];
151
+ return [...new Set(matches)]; // Dédoublonne les résultats
156
152
  };
157
153
 
158
- const extractModuleName = (text) => {
159
- const matchExplicit = text.match(/(?:module|mod)\s+([A-Z][a-zA-Z0-9_]*)/i);
160
- if (matchExplicit) return matchExplicit[1];
161
-
162
-
163
- const words = text.split(' ');
164
- for (let i = 1; i < words.length; i++) {
165
- const w = words[i].replace(/[^a-zA-Z0-9]/g, '');
166
- if (/^[A-Z][a-z0-9]+/.test(w) && w.length > 3) return w;
154
+ // 📋 INTERCEPTION : LISTER LES MODULES
155
+ const isListingRequest = /^(liste|list|quels modules|montre les modules)/i.test(finalPrompt);
156
+ if (isListingRequest) {
157
+ process.stdout.write(` \x1b[90m🔍 Scanning Kernel Cache...\x1b[0m\n`);
158
+ const cacheRes = await getModuleCache({ projectId, moduleName: null });
159
+
160
+ if (cacheRes.found !== false && cacheRes.modules) { // Modification de la condition pour matcher l'API
161
+ console.log(`\n\x1b[36m⚡ FLEETBO KERNEL MODULES (${cacheRes.modules.length}):\x1b[0m`);
162
+ cacheRes.modules.forEach(m => {
163
+ const metalColor = m.platform === 'android' ? '\x1b[32m' : '\x1b[34m'; // Vert Android, Bleu iOS
164
+ console.log(` ${metalColor}■\x1b[0m \x1b[1m${m.moduleName}\x1b[0m \x1b[90m(${m.platform})\x1b[0m`);
165
+ });
166
+ } else {
167
+ console.log(`\n \x1b[90mAucun module trouvé dans l'infrastructure de ce projet.\x1b[0m`);
167
168
  }
168
- return null;
169
+ console.log('');
170
+ rl.setPrompt(`\x1b[34m${dynamicUsername} ❯ \x1b[0m`);
171
+ rl.prompt();
172
+ return; // On arrête là, pas besoin d'appeler l'IA pour lister !
173
+ }
174
+
175
+ // Sert uniquement à définir le TON du contexte envoyé à Alex
176
+ const getContextIntent = (text) => {
177
+ const modifierKeywords = [
178
+ 'modifier', 'corrige', 'ajoute', 'erreur', 'plante', 'problème', 'bug', 'change',
179
+ 'update', 'fix', 'edit', 'error', 'fail', 'crash', 'issue', 'add'
180
+ ];
181
+ const inspireKeywords = [
182
+ 'inspire', 'base', 'comme', 'modèle', 'reference', 'reprends', 'copie',
183
+ 'inspire', 'based on', 'model', 'reference', 'like', 'copy', 'similar'
184
+ ];
185
+
186
+ const lower = text.toLowerCase();
187
+ if (modifierKeywords.some(k => lower.includes(k))) return "MODIFICATION";
188
+ if (inspireKeywords.some(k => lower.includes(k))) return "INSPIRATION";
189
+ return "REFERENCE";
169
190
  };
170
191
 
171
192
  const getModuleCache = async ({ projectId, moduleName }) => {
@@ -222,40 +243,41 @@ if (command === 'alex') {
222
243
  console.log('\x1b[33m🧠 Alex is thinking...\x1b[0m');
223
244
 
224
245
  try {
225
- // --- DÉBUT MODIFICATION : SYSTÈME DE MÉMOIRE (CACHE) ---
246
+ // --- DÉBUT MODIFICATION : SYSTÈME DE MÉMOIRE (SMART CACHE SCANNER) ---
226
247
  let contextInjection = "";
227
-
228
- // 1. On détecte si c'est une update
229
- if (promptContainsModification(prompt)) {
230
- const moduleName = extractModuleName(prompt);
248
+ const potentialModules = extractPotentialModules(prompt);
249
+ let referenceFound = false;
250
+
251
+ for (const modName of potentialModules) {
252
+ process.stdout.write(` \x1b[90m🔍 Checking kernel cache for ${modName}...\x1b[0m`);
253
+ const cache = await getModuleCache({ projectId, moduleName: modName });
231
254
 
232
- if (moduleName) {
233
- process.stdout.write(` \x1b[90m🔍 Searching cache for ${moduleName}...\x1b[0m`);
234
- const cache = await getModuleCache({ projectId, moduleName });
255
+ if (cache.found) {
256
+ process.stdout.write(` \x1b[32mFOUND METAL\x1b[0m\n`);
235
257
 
236
- if (cache.found) {
237
- process.stdout.write(` \x1b[32mFOUND\x1b[0m\n`);
238
- // On prépare le contexte pour Alex
239
- contextInjection = `
240
-
241
- --- CONTEXTE : CODE EXISTANT (${moduleName}) ---
242
- L'utilisateur veut modifier ce module existant.
243
- Tu DOIS te baser sur ce code et appliquer les changements demandés.
244
-
245
- [EXISTING KOTLIN]
246
- ${cache.module.code}
247
-
248
- [EXISTING MOCK]
249
- ${cache.module.mockCode}
250
-
251
- --- FIN DU CONTEXTE ---
252
- `;
253
-
254
- // On injecte le contexte AVANT la demande pour qu'il soit traité comme une base de travail
255
- prompt = contextInjection + "\n\n[INSTRUCTION PILOTE]\n" + prompt;
256
- } else {
257
- process.stdout.write(` \x1b[31mNOT FOUND (Creating new)\x1b[0m\n`);
258
- }
258
+ const intent = getContextIntent(prompt);
259
+ const contextTitle = intent === "MODIFICATION"
260
+ ? "MÉTAL EXISTANT MODIFIER)"
261
+ : "MÉTAL DE RÉFÉRENCE (POUR PARITÉ DES DONNÉES)";
262
+
263
+ // ⚠️ CHANGEMENT MAJEUR : ON N'ENVOIE QUE LE CODE NATIF
264
+ contextInjection = `
265
+
266
+ --- CONTEXTE SOUVERAIN : ${contextTitle} (${modName}) ---
267
+ DOGME: Le Métal est la source de vérité absolue. Le Mock n'est qu'une illusion.
268
+ Tu DOIS analyser ce code Natif pour comprendre EXACTEMENT comment les données ont été structurées, nommées (clés JSON) et sauvegardées.
269
+
270
+ [CODE NATIF EXISTANT]
271
+ ${cache.module.code}
272
+
273
+ --- FIN DU CONTEXTE ---
274
+ `;
275
+
276
+ prompt = contextInjection + "\n\n[INSTRUCTION DU PILOTE]\n" + prompt;
277
+ referenceFound = true;
278
+ break;
279
+ } else {
280
+ process.stdout.write(` \x1b[31mNOT FOUND\x1b[0m\n`);
259
281
  }
260
282
  }
261
283
  // --- FIN MODIFICATION ---
@@ -459,7 +481,7 @@ if (command === 'alex') {
459
481
  process.stdout.write('\n\x1b[F');
460
482
  rl.prompt();
461
483
 
462
- // --- NATURAL MULTI-LINE BUFFER (ZERO GLITCH) ---
484
+ // --- NATURAL MULTI-LINE BUFFER (ZERO GLITCH V2) ---
463
485
  let inputBuffer = "";
464
486
  let isProcessing = false;
465
487
 
@@ -475,11 +497,13 @@ if (command === 'alex') {
475
497
  return;
476
498
  }
477
499
 
478
- // 2. ACCUMULATION NATURELLE ET SILENCIEUSE
500
+ // 2. ACCUMULATION (Si la ligne n'est pas vide)
479
501
  if (trimmedLine !== "") {
480
502
  inputBuffer += (inputBuffer ? "\n" : "") + line;
481
- // 🛡️ MAGIE ICI : Zéro code visuel. Zéro setPrompt. Zéro prompt().
482
- // On laisse ton Mac afficher le texte collé naturellement.
503
+
504
+ // 🛡️ LE SECRET EST : On vide le préfixe pour les lignes suivantes.
505
+ // Quand tu colles, NodeJS arrêtera de répéter "jojo ❯" partout !
506
+ rl.setPrompt("");
483
507
  }
484
508
  // 3. VALIDATION (Touche Entrée sur une ligne vide)
485
509
  else {
@@ -491,18 +515,22 @@ if (command === 'alex') {
491
515
  if (finalPrompt.length > 1000) {
492
516
  console.log(`\n\x1b[31m⛔ [Alex Safety] Mission rejetée : Taille excessive (${finalPrompt.length}/1000 caractères).\x1b[0m`);
493
517
  console.log(`\x1b[90m Veuillez être plus concis et vous concentrer sur l'essentiel.\x1b[0m\n`);
518
+ rl.setPrompt(`\x1b[34m${dynamicUsername} ❯ \x1b[0m`);
494
519
  rl.prompt();
495
520
  return;
496
521
  }
497
522
 
498
523
  // ✅ ON LANCE LA FORGE
499
524
  isProcessing = true;
525
+ rl.setPrompt(""); // On masque le prompt pendant qu'Alex réfléchit
500
526
  await processAlexRequest(finalPrompt);
501
527
  isProcessing = false;
502
528
 
503
529
  console.log('');
504
- rl.prompt(); // On remet le prompt "jojo " pour la suite
530
+ rl.setPrompt(`\x1b[34m${dynamicUsername}\x1b[0m`);
531
+ rl.prompt(); // On remet le prompt "jojo ❯" pour la mission suivante
505
532
  } else {
533
+ rl.setPrompt(`\x1b[34m${dynamicUsername} ❯ \x1b[0m`);
506
534
  rl.prompt(); // Si appui sur Entrée dans le vide
507
535
  }
508
536
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fleetbo-cockpit-cli",
3
- "version": "1.0.43",
3
+ "version": "1.0.45",
4
4
  "description": "Fleetbo CLI - Build native mobile apps with React",
5
5
  "author": "Fleetbo",
6
6
  "license": "MIT",