create-fleetbo-project 1.2.43 → 1.2.44

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.
@@ -11,7 +11,9 @@ const branchName = 'master';
11
11
  const archiveUrl = `https://github.com/${repoOwner}/${repoName}/archive/refs/heads/${branchName}.tar.gz`;
12
12
  const bootstrapUrl = 'https://us-central1-myapp-259bf.cloudfunctions.net/bootstrapProject';
13
13
 
14
-
14
+ // ------------------------------------------------------------------
15
+ // CONTENU DU CLI (Intégré pour génération automatique)
16
+ // ------------------------------------------------------------------
15
17
  const CLI_SCRIPT_CONTENT = `#!/usr/bin/env node
16
18
  const { spawn, execSync } = require('child_process');
17
19
  const fs = require('fs');
@@ -73,6 +75,7 @@ const injectRouteIntoAppJs = (pageName, subPath = '') => {
73
75
 
74
76
  if (!content.includes(alexRouteAnchor)) return false;
75
77
 
78
+ // Chemin dynamique selon si c'est une page ou un mock
76
79
  const pathPrefix = subPath ? \`\${subPath}/\` : '';
77
80
  const importLine = \`import \${pageName} from './pages/\${pathPrefix}\${pageName}';\`;
78
81
  const routeLine = \`<Route path="/\${pathPrefix.toLowerCase()}\${pageName.toLowerCase()}" element=<\${\${pageName} />} />\`;
@@ -83,6 +86,7 @@ const injectRouteIntoAppJs = (pageName, subPath = '') => {
83
86
  injected = true;
84
87
  }
85
88
  if (!content.includes(routeLine)) {
89
+ // Injection précise dans l'ancre Alex
86
90
  content = content.replace(alexRouteAnchor, \`\${routeLine}\\n \${alexRouteAnchor}\`);
87
91
  injected = true;
88
92
  }
@@ -113,17 +117,24 @@ if (command === 'alex') {
113
117
  });
114
118
 
115
119
  const aiData = result.data;
120
+ // 1. On efface "Alex is thinking..."
116
121
  process.stdout.write('\\r' + ' '.repeat(50) + '\\r');
117
122
 
123
+ // --- 1. GESTION DU QUOTA (EN ROUGE) ---
118
124
  if (aiData.status === 'quota_exceeded') {
119
125
  console.log(\`\\n\\x1b[31m⛔ ENGINE OUT OF FUEL:\\x1b[0m \${aiData.message}\`);
120
126
  return;
121
127
  }
122
128
 
129
+ // --- 2. AFFICHAGE DE LA RÉPONSE ---
123
130
  if (aiData.status === 'success' || aiData.status === 'message') {
131
+ // ✅ AJOUT : Saut de ligne pour séparer de votre commande "username ❯"
124
132
  console.log('');
133
+
134
+ // Alex répond en Vert
125
135
  console.log(\`\\x1b[32mAlex ❯\\x1b[0m \${aiData.message || "I'm ready."}\`);
126
136
 
137
+ // Jauge d'énergie (Bleu/Vert/Rouge)
127
138
  if (aiData.remainingTokens !== undefined) {
128
139
  const remaining = aiData.remainingTokens;
129
140
  const limit = aiData.limit || 2500;
@@ -133,6 +144,7 @@ if (command === 'alex') {
133
144
  }
134
145
  }
135
146
 
147
+ // --- 4. TRAITEMENT DES FICHIERS (SI PRÉSENTS) ---
136
148
  if (aiData.status === 'success' && aiData.moduleData) {
137
149
  const { fileName, code, mockFileName, mockCode, moduleName } = aiData.moduleData;
138
150
  console.log(\` \\x1b[90m⚙️ Architecting: \${moduleName}\\x1b[0m\`);
@@ -155,6 +167,7 @@ if (command === 'alex') {
155
167
  writeFile('src/pages/mocks/', 'Quick.jsx', mockCode);
156
168
  }
157
169
  }
170
+
158
171
  } catch (error) {
159
172
  process.stdout.write('\\r' + ' '.repeat(50) + '\\r');
160
173
  console.error('\\n\\x1b[31m❌ Alex Error:\\x1b[0m ' + (error.response?.data?.message || error.message));
@@ -163,29 +176,68 @@ if (command === 'alex') {
163
176
 
164
177
  const startAlexSession = async () => {
165
178
  process.stdout.write('\\x1b[33m🛡️ Alex is checking runtime state...\\x1b[0m\\r');
166
- let attempts = 0; const maxAttempts = 5; let isReady = false;
179
+
180
+ let attempts = 0;
181
+ const maxAttempts = 5;
182
+ let isReady = false;
183
+
167
184
  while (attempts < maxAttempts && !isReady) {
168
185
  try {
169
- const validation = await axios.post(ALEX_ENGINE_URL, { prompt: "ping", validateProject: true, checkNetwork: true }, { headers: { 'x-project-id': projectId }, timeout: 5000 });
186
+ const validation = await axios.post(ALEX_ENGINE_URL, {
187
+ prompt: "ping", validateProject: true, checkNetwork: true
188
+ }, { headers: { 'x-project-id': projectId }, timeout: 5000 });
189
+
170
190
  if (validation.data?.isRunning) { isReady = true; break; }
171
- attempts++; if (attempts < maxAttempts) await new Promise(r => setTimeout(r, 2000));
172
- } catch (error) { attempts++; await new Promise(r => setTimeout(r, 2000)); }
191
+ attempts++;
192
+ if (attempts < maxAttempts) await new Promise(r => setTimeout(r, 2000));
193
+ } catch (error) {
194
+ attempts++;
195
+ await new Promise(r => setTimeout(r, 2000));
196
+ }
173
197
  }
198
+
174
199
  if (!isReady) {
175
200
  console.error('\\n\\x1b[31m⚠️ ENGINE OFFLINE:\\x1b[0m Start Fleetbo runtime first: "npm run fleetbo" ');
176
201
  process.exit(1);
177
202
  }
178
- process.stdout.write(' '.repeat(60) + '\\r');
203
+
204
+ // --- INITIALISATION DE L'INTERFACE VISUELLE ---
205
+ process.stdout.write(' '.repeat(60) + '\\r'); // Efface le status de validation
206
+
207
+ // 1. Accueil Alex (Vert)
179
208
  console.log('\\n\\x1b[32m🤖 Alex is now online.\\x1b[0m');
180
- console.log('\\x1b[32mAlex ❯\\x1b[0m Welcome! I am Alex, your architect. What are we building today?\\n');
209
+ console.log('\\x1b[32mAlex ❯\\x1b[0m Welcome! I am Alex, your architect. What are we building today?');
210
+
211
+ // 2. Premier saut de ligne pour l'esthétique
212
+ console.log('');
213
+
214
+ // 3. Configuration du prompt Développeur (Bleu)
181
215
  const userName = testerEmail ? testerEmail.split('@')[0] : 'Dev';
182
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout, prompt: \`\\x1b[34m\${userName} ❯ \\x1b[0m\` });
216
+ const rl = readline.createInterface({
217
+ input: process.stdin,
218
+ output: process.stdout,
219
+ prompt: \`\\x1b[34m\${userName} ❯ \\x1b[0m\`
220
+ });
221
+
183
222
  rl.prompt();
223
+
184
224
  rl.on('line', async (line) => {
185
- if (['exit', 'quit'].includes(line.trim().toLowerCase())) { console.log('\\n\\x1b[90m👋 Alex session closed.\\x1b[0m'); rl.close(); return; }
186
- if (line.trim()) { await processAlexRequest(line.trim()); console.log(''); }
225
+ if (['exit', 'quit'].includes(line.trim().toLowerCase())) {
226
+ console.log('\\n\\x1b[90m👋 Alex session closed.\\x1b[0m');
227
+ rl.close();
228
+ return;
229
+ }
230
+
231
+ if (line.trim()) {
232
+ await processAlexRequest(line.trim());
233
+ // ✅ SAUT DE LIGNE après la réponse d'Alex
234
+ console.log('');
235
+ }
236
+
187
237
  rl.prompt();
188
- }).on('close', () => { process.exit(0); });
238
+ }).on('close', () => {
239
+ process.exit(0);
240
+ });
189
241
  };
190
242
 
191
243
  if (!initialPrompt || initialPrompt === '?') startAlexSession();
@@ -216,13 +268,20 @@ if (command === 'deploy') {
216
268
  return;
217
269
  }
218
270
 
271
+ // ==========================================
272
+ // 2. COMMANDE: GENERATE (Original préservé)
273
+ // ==========================================
219
274
  const GENERATOR_COMMANDS = ['page', 'g', 'generate', 'android', 'ios'];
220
275
  if (GENERATOR_COMMANDS.includes(command)) {
221
276
  try { require('./page.js'); } catch (e) { console.error(e.message); process.exit(1); }
222
277
  return;
223
278
  }
224
279
 
280
+ // ==========================================
281
+ // 3. COMMANDE: DEV / CLEANUP (Original préservé)
282
+ // ==========================================
225
283
  const NULL_DEV = process.platform === 'win32' ? '>nul 2>&1' : '2>/dev/null';
284
+
226
285
  function killProcessOnPort(port) {
227
286
  try {
228
287
  if (process.platform !== 'win32') {
@@ -231,6 +290,7 @@ function killProcessOnPort(port) {
231
290
  }
232
291
  } catch (e) {}
233
292
  }
293
+
234
294
  function killNetworkService() {
235
295
  try {
236
296
  const cmd = process.platform === 'win32' ? 'taskkill /IM cloudflared.exe /F' : 'pkill cloudflared';
@@ -240,10 +300,15 @@ function killNetworkService() {
240
300
 
241
301
  let isExiting = false;
242
302
  async function cleanupAndExit(code = 0) {
243
- if (isExiting) return; isExiting = true;
303
+ if (isExiting) return;
304
+ isExiting = true;
244
305
  console.log('\\n[Fleetbo] 🛑 Stopping environment...');
245
- try { await axios.post(UPDATE_NETWORK_URL, { keyApp, networkUrl: '', tester: testerEmail }); } catch (e) {}
246
- killNetworkService(); killProcessOnPort(PORT); process.exit(code);
306
+ try {
307
+ await axios.post(UPDATE_NETWORK_URL, { keyApp, networkUrl: '', tester: testerEmail });
308
+ } catch (e) {}
309
+ killNetworkService();
310
+ killProcessOnPort(PORT);
311
+ process.exit(code);
247
312
  }
248
313
  process.on('SIGINT', () => cleanupAndExit(0));
249
314
  process.on('SIGTERM', () => cleanupAndExit(0));
@@ -251,27 +316,44 @@ process.on('SIGTERM', () => cleanupAndExit(0));
251
316
  async function syncFirebase(keyApp, networkUrl, testerEmail) {
252
317
  try {
253
318
  await axios.post(UPDATE_NETWORK_URL, { keyApp, networkUrl, tester: testerEmail });
319
+
254
320
  console.log(\`\\n\\x1b[32m[Fleetbo]\\x1b[0m -------------------------------------------------------------\`);
255
321
  console.log('\\x1b[32m[Fleetbo] GO GO GO ! FLEETBO STUDIO IS READY \\x1b[0m');
256
322
  console.log(\`\\x1b[32m[Fleetbo] Link: https://fleetbo.io/studio/\${keyApp}\\x1b[0m\`);
257
323
  console.log('\\x1b[32m[Fleetbo] You can now start coding and previewing in Studio. 🚀\\x1b[0m');
258
324
  console.log(\`\\x1b[32m[Fleetbo]\\x1b[0m -------------------------------------------------------------\`);
259
- } catch (err) { console.error(\`[Fleetbo] ❌ Sync Error: \${err.message}\`); }
325
+ } catch (err) {
326
+ console.error(\`[Fleetbo] ❌ Sync Error: \${err.message}\`);
327
+ }
260
328
  }
261
329
 
262
330
  async function runDevEnvironment() {
263
331
  console.log(\`[Fleetbo] 🛡️ Initializing Dev Environment...\`);
264
- killNetworkService(); killProcessOnPort(PORT);
332
+ killNetworkService();
333
+ killProcessOnPort(PORT);
334
+ if (!testerEmail) { console.error('Error: REACT_APP_TESTER_EMAIL missing'); process.exit(1); }
335
+
265
336
  const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
266
- const devServer = spawn(npmCmd, ['start'], { stdio: ['ignore', 'pipe', 'pipe'], shell: true, env: { ...process.env, BROWSER: 'none', PORT: PORT.toString() } });
267
- devServer.stdout.pipe(process.stdout); devServer.stderr.pipe(process.stderr);
337
+ const devServer = spawn(npmCmd, ['start'], {
338
+ stdio: ['ignore', 'pipe', 'pipe'],
339
+ shell: true,
340
+ env: { ...process.env, BROWSER: 'none', PORT: PORT.toString() }
341
+ });
342
+ devServer.stdout.pipe(process.stdout);
343
+ devServer.stderr.pipe(process.stderr);
344
+
268
345
  let connectionStarted = false;
269
346
  devServer.stdout.on('data', (data) => {
270
347
  const output = data.toString();
271
348
  if (!connectionStarted && (output.includes('Local:') || output.includes('Compiled successfully'))) {
272
349
  connectionStarted = true;
350
+
273
351
  console.log('\\n[Fleetbo] ---------------------------------------------------');
274
- console.log(\`[Fleetbo] 🔗 Establishing Secure Uplink...\\n[Fleetbo] 🛑 DO NOT open the Fleetbo Studio yet.\\n[Fleetbo] ⏳ Please wait green message...\\n[Fleetbo] ---------------------------------------------------\`);
352
+ console.log(\`[Fleetbo] 🔗 Establishing Secure Uplink...\`);
353
+ console.log(\`[Fleetbo] 🛑 DO NOT open the Fleetbo Studio yet. \`);
354
+ console.log(\`[Fleetbo] ⏳ Please wait green message...\`);
355
+ console.log('[Fleetbo] ---------------------------------------------------');
356
+
275
357
  const npxCmd = process.platform === 'win32' ? 'npx.cmd' : 'npx';
276
358
  const uplink = spawn(npxCmd, ['cloudflared', 'tunnel', '--url', \`http://localhost:\${PORT}\`], { shell: true });
277
359
  uplink.stderr.on('data', (chunk) => {
@@ -281,7 +363,13 @@ async function runDevEnvironment() {
281
363
  }
282
364
  });
283
365
  }
284
- runDevEnvironment();`.replace(/`/g, '\\`').replace(/\${/g, '\\${');
366
+
367
+ runDevEnvironment();
368
+ `;
369
+
370
+ // ------------------------------------------------------------------
371
+ // FIN CONTENU CLI
372
+ // ------------------------------------------------------------------
285
373
 
286
374
 
287
375
  const args = process.argv.slice(2);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-fleetbo-project",
3
- "version": "1.2.43",
3
+ "version": "1.2.44",
4
4
  "description": "Creates a new Fleetbo project.",
5
5
  "main": "install-react-template.js",
6
6
  "bin": {