fleetbo-cockpit-cli 1.0.100 → 1.0.102

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 +44 -12
  2. package/package.json +1 -1
package/cli.js CHANGED
@@ -274,6 +274,7 @@ if (command === 'alex') {
274
274
  }
275
275
 
276
276
  console.log('\x1b[33m🧠 Alex is thinking...\x1b[0m');
277
+ let spinnerTimer;
277
278
 
278
279
  try {
279
280
  // --- MEMORY SYSTEM (SMART CACHE SCANNER V3 - SOUVERAINETÉ DU MÉTAL) ---
@@ -295,30 +296,46 @@ if (command === 'alex') {
295
296
  modName = modName.replace('Schema', '');
296
297
  }
297
298
 
298
- process.stdout.write(` \x1b[90m🔍 Checking OS cache for ${modName}...\x1b[0m`);
299
+ process.stdout.write(` \x1b[90m🔍 Checking Alex memory for ${modName} module...\x1b[0m`);
299
300
  const cache = await getModuleCache({ projectId, moduleName: modName });
300
301
 
301
- if (cache.found) {
302
- process.stdout.write(` \x1b[32mFOUND METAL\x1b[0m\n`);
302
+ // 💡 LECTURE LOCALE DU VRAI CODE KOTLIN (La Vérité Absolue)
303
+ const localKtPath = path.join(process.cwd(), 'public', 'native', 'android', `${modName}.kt`);
304
+ let actualMetalCode = "";
305
+
306
+ if (fs.existsSync(localKtPath)) {
307
+ actualMetalCode = fs.readFileSync(localKtPath, 'utf8');
308
+ } else if (cache.found && cache.module.code) {
309
+ actualMetalCode = cache.module.code; // Fallback sur le cache si le fichier local n'est pas trouvé
310
+ }
311
+
312
+ if (actualMetalCode) {
313
+ const sourceText = fs.existsSync(localKtPath) ? "LOCAL" : "CACHE";
314
+ process.stdout.write(` \x1b[32mFOUND METAL (${sourceText})\x1b[0m\n`);
303
315
 
304
- // NOUVEAU BLOC : INJECTION DE LA DOUBLE MÉMOIRE
316
+ // Extraction des schémas mémoires (uniquement dispo dans le cache cloud)
305
317
  let memoryScript = "";
306
- if (cache.module.dataSchema) memoryScript += `\n[SCRIPT MÉMOIRE DONNÉES]\n${cache.module.dataSchema}\n`;
307
- if (cache.module.uiSchema) memoryScript += `\n[SCRIPT MÉMOIRE UI NATIF]\n${cache.module.uiSchema}\n`;
318
+ if (cache.found && cache.module.dataSchema) memoryScript += `\n[SCRIPT MÉMOIRE DONNÉES]\n${cache.module.dataSchema}\n`;
319
+ if (cache.found && cache.module.uiSchema) memoryScript += `\n[SCRIPT MÉMOIRE UI NATIF]\n${cache.module.uiSchema}\n`;
308
320
 
309
321
  if (!memoryScript) memoryScript = `\n[SCRIPT MÉMOIRE DU MODULE ${modName}]\nAucun schéma enregistré pour ce module.\n`;
310
322
 
323
+ // 🤖 PRÉ-ANALYSE DÉTERMINISTE DU CLI (Le bouclier anti-amnésie d'Alex)
324
+ const isTabModule = actualMetalCode.includes('action == "tab"');
325
+ const levelWarning = isTabModule
326
+ ? "\n🚨 ALERTE CRITIQUE DU SYSTÈME : Ce code natif contient 'action == \"tab\"'. Il s'agit DÉFINITIVEMENT d'un NIVEAU 5 (Fleetbo View / Sovereign Tab). Tu as l'INTERDICTION ABSOLUE de proposer Fleetbo.exec() pour ce module. Tu DOIS obligatoirement utiliser Fleetbo.openView('NomDuModule', true) dans un useEffect() pour l'intégrer, sous peine de détruire l'application.\n"
327
+ : "";
328
+
311
329
  if (isReferenceOnly) {
312
- // 🚨 CAS A : INSPIRATION (Lecture seule)
313
- referenceContexts += `\n--- CONTEXTE : MODULE DE RÉFÉRENCE (${modName}) ---\nDOGME : Ne modifie pas ce module (Lecture seule). Tu dois l'utiliser comme modèle. Aligne-toi sur ses Scripts Mémoires (Données et/ou UI) et sur son Code Natif en fonction de ce que le Pilote te demande d'imiter.\n${memoryScript}\n[CODE NATIF DE RÉFÉRENCE]\n${cache.module.code}\n`;
330
+ // 🚨 CAS A : INSPIRATION
331
+ referenceContexts += `\n--- CONTEXTE : MODULE DE RÉFÉRENCE (${modName}) ---\nDOGME : Ne modifie pas ce module. Aligne-toi sur ses Scripts Mémoires et son Code Natif.\n${memoryScript}\n[CODE NATIF DE RÉFÉRENCE]\n${actualMetalCode}\n`;
314
332
  } else if (!targetModuleContext) {
315
- // 🚨 CAS B : CIBLE PRINCIPALE (Modification)
316
- // LE MOCK EST BANI ! Le Métal est la seule source de vérité.
333
+ // 🚨 CAS B : CIBLE PRINCIPALE
317
334
  const intent = getContextIntent(prompt);
318
335
  if (intent === "MODIFICATION") {
319
- targetModuleContext = `\n--- CONTEXTE : MÉTAL EXISTANT À MODIFIER (${modName}) ---\nDOGME: Tu dois modifier ce code Natif. Ensuite, tu forgeras un Mock JSX entièrement neuf basé UNIQUEMENT sur ton nouveau code Natif.\n${memoryScript}\n[CODE NATIF EXISTANT]\n${cache.module.code}\n--- FIN DU CONTEXTE ---\n`;
336
+ targetModuleContext = `\n--- CONTEXTE : MÉTAL EXISTANT À MODIFIER (${modName}) ---\nDOGME: Tu dois modifier ce code Natif. Ensuite, tu forgeras un Mock JSX neuf basé UNIQUEMENT sur ton nouveau code Natif.${levelWarning}\n${memoryScript}\n[CODE NATIF EXISTANT]\n${actualMetalCode}\n--- FIN DU CONTEXTE ---\n`;
320
337
  } else {
321
- targetModuleContext = `\n--- CONTEXTE : LECTURE SEULE (${modName}) ---\nPour information, voici l'état actuel du module. Ne le modifie pas, utilise-le pour répondre précisément au Pilote.\n${memoryScript}\n[CODE NATIF]\n${cache.module.code}\n`;
338
+ targetModuleContext = `\n--- CONTEXTE : LECTURE SEULE (${modName}) ---\nPour information, voici l'état actuel du module. Ne le modifie pas, utilise-le pour répondre précisément au Pilote.${levelWarning}\n${memoryScript}\n[CODE NATIF]\n${actualMetalCode}\n`;
322
339
  }
323
340
  }
324
341
  } else {
@@ -339,10 +356,22 @@ if (command === 'alex') {
339
356
 
340
357
  const promptWithTime = prompt + `\n\n[SYSTEM INFO: The exact current timestamp is ${exactTime}. Use it STRICTLY for your signature '// ⚡ Forged by Alex on...' at the bottom of your files.]`;
341
358
 
359
+ // 🟢 DÉMARRAGE DE L'ANIMATION DU CURSEUR
360
+ const spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
361
+ let spinnerIdx = 0;
362
+ spinnerTimer = setInterval(() => {
363
+ process.stdout.write(`\r \x1b[36m${spinnerFrames[spinnerIdx]}\x1b[0m \x1b[90mAlex is forging...\x1b[0m`);
364
+ spinnerIdx = (spinnerIdx + 1) % spinnerFrames.length;
365
+ }, 80);
366
+
342
367
  const result = await axios.post(ALEX_ENGINE_URL, { prompt: promptWithTime, projectType: 'android' }, {
343
368
  headers: { 'x-project-id': projectId }
344
369
  });
345
370
 
371
+ // 🛑 ARRÊT DE L'ANIMATION
372
+ clearInterval(spinnerTimer);
373
+ process.stdout.write('\r' + ' '.repeat(80) + '\r'); // Nettoie la ligne de l'animation
374
+
346
375
  let aiData = result.data;
347
376
 
348
377
  // 🛡️ ROBUST PARSER: Unwrap all nesting levels until we find a valid aiData object
@@ -488,6 +517,9 @@ if (command === 'alex') {
488
517
  console.log(`\n\x1b[31m⚠️ Error: Alex replied, but source code could not be extracted. Try the command again.\x1b[0m\n`);
489
518
  }
490
519
  } catch (error) {
520
+ // 🛑 SÉCURITÉ : Arrête le spinner s'il y a un crash
521
+ if (spinnerTimer) clearInterval(spinnerTimer);
522
+
491
523
  process.stdout.write('\r' + ' '.repeat(50) + '\r');
492
524
  console.error('\n\x1b[31m Alex Error:\x1b[0m ' + (error.response?.data?.message || error.message));
493
525
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fleetbo-cockpit-cli",
3
- "version": "1.0.100",
3
+ "version": "1.0.102",
4
4
  "description": "Fleetbo CLI - Build native mobile apps with React",
5
5
  "author": "Fleetbo",
6
6
  "license": "MIT",