fleetbo-cockpit-cli 1.0.25 → 1.0.27

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 +103 -5
  2. package/package.json +1 -1
package/cli.js CHANGED
@@ -17,6 +17,7 @@ const IOS_BUILD_URL = "https://fiosbuild-jqycakhlxa-uc.a.run.app";
17
17
  const UPDATE_NETWORK_URL = 'https://updatedevelopernetwork-jqycakhlxa-uc.a.run.app';
18
18
  const ALEX_ENGINE_URL = "https://generatenativemodule-jqycakhlxa-uc.a.run.app";
19
19
  const INJECT_DEPS_URL = "https://savegeneratedfile-jqycakhlxa-uc.a.run.app";
20
+ const CACHE_URL = "https://getmodulecache-jqycakhlxa-uc.a.run.app";
20
21
  const PORT = 3000;
21
22
 
22
23
  let uplinkProcess = null;
@@ -143,6 +144,43 @@ const showEnergyTransfer = async () => {
143
144
  process.stdout.write('\n');
144
145
  };
145
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));
156
+ };
157
+
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;
167
+ }
168
+ return null;
169
+ };
170
+
171
+ const getModuleCache = async ({ projectId, moduleName }) => {
172
+ try {
173
+ if (!moduleName) return { found: false };
174
+ const res = await axios.post(CACHE_URL, { projectId, moduleName });
175
+ if (res.data && res.data.found) {
176
+ return { found: true, module: res.data.module };
177
+ }
178
+ return { found: false };
179
+ } catch (e) {
180
+ return { found: false };
181
+ }
182
+ };
183
+
146
184
  // ============================================
147
185
  // COMMAND: alex
148
186
  // ============================================
@@ -160,10 +198,50 @@ if (command === 'alex') {
160
198
  console.log('\x1b[33m🧠 Alex is thinking...\x1b[0m');
161
199
 
162
200
  try {
201
+ // --- DÉBUT MODIFICATION : SYSTÈME DE MÉMOIRE (CACHE) ---
202
+ let contextInjection = "";
203
+
204
+ // 1. On détecte si c'est une update
205
+ if (promptContainsModification(prompt)) {
206
+ const moduleName = extractModuleName(prompt);
207
+
208
+ if (moduleName) {
209
+ process.stdout.write(` \x1b[90m🔍 Searching cache for ${moduleName}...\x1b[0m`);
210
+ const cache = await getModuleCache({ projectId, moduleName });
211
+
212
+ if (cache.found) {
213
+ process.stdout.write(` \x1b[32mFOUND\x1b[0m\n`);
214
+ // On prépare le contexte pour Alex
215
+ contextInjection = `
216
+
217
+ --- CONTEXTE : CODE EXISTANT (${moduleName}) ---
218
+ L'utilisateur veut modifier ce module existant.
219
+ Tu DOIS te baser sur ce code et appliquer les changements demandés.
220
+
221
+ [EXISTING KOTLIN]
222
+ ${cache.module.code}
223
+
224
+ [EXISTING MOCK]
225
+ ${cache.module.mockCode}
226
+
227
+ --- FIN DU CONTEXTE ---
228
+ `;
229
+
230
+ // On injecte le contexte AVANT la demande pour qu'il soit traité comme une base de travail
231
+ prompt = contextInjection + "\n\n[INSTRUCTION PILOTE]\n" + prompt;
232
+ } else {
233
+ process.stdout.write(` \x1b[31mNOT FOUND (Creating new)\x1b[0m\n`);
234
+ }
235
+ }
236
+ }
237
+ // --- FIN MODIFICATION ---
238
+
163
239
  const result = await axios.post(ALEX_ENGINE_URL, { prompt, projectType: 'android' }, {
164
240
  headers: { 'x-project-id': projectId }
165
241
  });
242
+
166
243
  let aiData = result.data;
244
+
167
245
  if (typeof aiData === 'string') {
168
246
  try { aiData = JSON.parse(aiData); } catch (_) {}
169
247
  }
@@ -413,21 +491,41 @@ else if (command === 'android' || command === 'ios') {
413
491
 
414
492
  try {
415
493
  // ==========================================================
416
- // PRE-FLIGHT CHECK QUOTAS
494
+ // PRE-FLIGHT CHECK QUOTAS & TIER
417
495
  // ==========================================================
418
- process.stdout.write(`\x1b[33m[0/3]\x1b[0m Checking Propulsion Quotas... `);
496
+ process.stdout.write(`\x1b[33m[0/3]\x1b[0m Checking Propulsion Access... `);
419
497
  try {
498
+ // On envoie le signal 'x-preflight' pour tester les droits sans builder
420
499
  await axios.post(targetUrl, {}, {
421
500
  headers: {
422
501
  'x-project-id': projectId,
423
502
  'x-preflight': 'true'
424
503
  }
425
504
  });
426
- process.stdout.write(`\x1b[32mOK\x1b[0m\n\n`);
505
+ // Si ça passe (200 OK), c'est un Senior ou un Junior autorisé (si vous changez d'avis)
506
+ process.stdout.write(`\x1b[32mOK (Senior Pilot)\x1b[0m\n\n`);
507
+
427
508
  } catch (preflightError) {
428
509
  process.stdout.write(`\x1b[31mDENIED\x1b[0m\n`);
429
- if (preflightError.response && preflightError.response.data && preflightError.response.data.error) {
430
- throw new Error(preflightError.response.data.error);
510
+
511
+ const errData = preflightError.response?.data;
512
+
513
+ // 🛑 1. INTERCEPTION SPÉCIFIQUE JUNIOR
514
+ // C'est ici qu'on lit le code renvoyé par index.js
515
+ if (errData?.code === 'junior_restriction') {
516
+ console.log(`\n\x1b[31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m`);
517
+ console.log(`\x1b[31m⛔ ACCESS DENIED: JUNIOR PILOT DETECTED\x1b[0m`);
518
+ console.log(`\x1b[31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m`);
519
+ console.log(``);
520
+ console.log(` \x1b[33m🔒 This feature is locked for Junior Pilots.\x1b[0m`);
521
+ console.log(` \x1b[32m👉 Upgrade to Senior on fleetbo.io to unlock Propulsion.\x1b[0m`);
522
+ console.log(``);
523
+ process.exit(1); // Arrêt immédiat et propre du script
524
+ }
525
+
526
+ // 2. Gestion des autres erreurs (Quota Senior dépassé, Serveur HS, etc.)
527
+ if (errData && errData.error) {
528
+ throw new Error(errData.error);
431
529
  }
432
530
  throw preflightError;
433
531
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fleetbo-cockpit-cli",
3
- "version": "1.0.25",
3
+ "version": "1.0.27",
4
4
  "description": "Fleetbo CLI - Build native mobile apps with React",
5
5
  "author": "Fleetbo",
6
6
  "license": "MIT",