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.
- package/install-react-template.js +108 -20
- package/package.json +1 -1
|
@@ -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
|
-
|
|
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, {
|
|
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++;
|
|
172
|
-
|
|
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
|
-
|
|
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
|
|
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({
|
|
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())) {
|
|
186
|
-
|
|
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', () => {
|
|
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;
|
|
303
|
+
if (isExiting) return;
|
|
304
|
+
isExiting = true;
|
|
244
305
|
console.log('\\n[Fleetbo] 🛑 Stopping environment...');
|
|
245
|
-
try {
|
|
246
|
-
|
|
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) {
|
|
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();
|
|
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'], {
|
|
267
|
-
|
|
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
|
|
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
|
-
|
|
366
|
+
|
|
367
|
+
runDevEnvironment();
|
|
368
|
+
`;
|
|
369
|
+
|
|
370
|
+
// ------------------------------------------------------------------
|
|
371
|
+
// FIN CONTENU CLI
|
|
372
|
+
// ------------------------------------------------------------------
|
|
285
373
|
|
|
286
374
|
|
|
287
375
|
const args = process.argv.slice(2);
|