fleetbo-cockpit-cli 1.0.221 → 1.0.224
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/cli.js +14 -65
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// ABSOLUTE SILENCE: Executes in 0.1ms to kill NPM plumbing
|
|
4
3
|
process.stdout.write("\x1b[1A\x1b[2K".repeat(4));
|
|
5
4
|
console.clear();
|
|
6
5
|
|
|
@@ -13,10 +12,6 @@ const os = require('os');
|
|
|
13
12
|
const archiver = require('archiver');
|
|
14
13
|
const readline = require('readline');
|
|
15
14
|
|
|
16
|
-
// ============================================
|
|
17
|
-
// FLEETBO CLI - Centralized Package
|
|
18
|
-
// ============================================
|
|
19
|
-
|
|
20
15
|
const ANDROID_BUILD_URL = "https://fandroidbuild-jqycakhlxa-uc.a.run.app";
|
|
21
16
|
const IOS_BUILD_URL = "https://fiosbuild-jqycakhlxa-uc.a.run.app";
|
|
22
17
|
const UPDATE_NETWORK_URL = 'https://updatedevelopernetwork-jqycakhlxa-uc.a.run.app';
|
|
@@ -29,9 +24,6 @@ let uplinkProcess = null;
|
|
|
29
24
|
const args = process.argv.slice(2);
|
|
30
25
|
const command = args[0];
|
|
31
26
|
|
|
32
|
-
// ============================================
|
|
33
|
-
// CONFIGURATION (.env of dev project)
|
|
34
|
-
// ============================================
|
|
35
27
|
process.env.DOTENV_SILENT = 'true';
|
|
36
28
|
const envPath = path.join(process.cwd(), '.env');
|
|
37
29
|
|
|
@@ -47,9 +39,6 @@ const projectId = process.env.VITE_FLEETBO_ENTERPRISE_ID;
|
|
|
47
39
|
const keyApp = process.env.VITE_FLEETBO_KEY_APP;
|
|
48
40
|
const testerEmail = process.env.VITE_FLEETBO_TESTER_EMAIL;
|
|
49
41
|
|
|
50
|
-
// =======================================================
|
|
51
|
-
// AUTOMATIC JS FRAMEWORK DETECTION (React or Vue)
|
|
52
|
-
// =======================================================
|
|
53
42
|
const detectFramework = () => {
|
|
54
43
|
try {
|
|
55
44
|
const pkgPath = path.join(process.cwd(), 'package.json');
|
|
@@ -69,21 +58,17 @@ if (!projectId) {
|
|
|
69
58
|
process.exit(1);
|
|
70
59
|
}
|
|
71
60
|
|
|
72
|
-
// ============================================
|
|
73
|
-
// HELPERS
|
|
74
|
-
// ============================================
|
|
75
|
-
|
|
76
61
|
const checkGitSecurity = () => {
|
|
77
62
|
const gitDir = path.join(process.cwd(), '.git');
|
|
78
63
|
const gitignorePath = path.join(process.cwd(), '.gitignore');
|
|
79
64
|
if (fs.existsSync(gitDir)) {
|
|
80
65
|
if (!fs.existsSync(gitignorePath)) {
|
|
81
|
-
console.error('\x1b[31m[
|
|
66
|
+
console.error('\x1b[31m[Security Alert]\x1b[0m .git detected but no .gitignore found.');
|
|
82
67
|
process.exit(1);
|
|
83
68
|
}
|
|
84
69
|
const gitignoreContent = fs.readFileSync(gitignorePath, 'utf8');
|
|
85
70
|
if (!gitignoreContent.includes('.env')) {
|
|
86
|
-
console.error('\x1b[31m[
|
|
71
|
+
console.error('\x1b[31m[Critical Risk]\x1b[0m .env is NOT ignored by Git.');
|
|
87
72
|
process.exit(1);
|
|
88
73
|
}
|
|
89
74
|
}
|
|
@@ -227,9 +212,6 @@ const removeRouteFromAppJs = (moduleName) => {
|
|
|
227
212
|
return false;
|
|
228
213
|
};
|
|
229
214
|
|
|
230
|
-
// ============================================
|
|
231
|
-
// COMMAND: alex
|
|
232
|
-
// ============================================
|
|
233
215
|
if (command === 'alex') {
|
|
234
216
|
checkGitSecurity();
|
|
235
217
|
const initialPrompt = args.slice(1).join(' ');
|
|
@@ -239,16 +221,12 @@ if (command === 'alex') {
|
|
|
239
221
|
console.log('\x1b[31m[Alex Safety] Request too long (' + prompt.length + '/4000 chars).\x1b[0m');
|
|
240
222
|
return;
|
|
241
223
|
}
|
|
242
|
-
|
|
243
|
-
/* =====================================================================
|
|
244
|
-
STRICT PATCH MANUAL COMMIT INTERCEPTION
|
|
245
|
-
===================================================================== */
|
|
246
224
|
|
|
247
225
|
const patchMatch = prompt.match(/^patch\s+module\s+([a-zA-Z0-9_]+)\s+(android|ios)/i);
|
|
248
226
|
const partialPatchMatch = prompt.match(/^patch\s+module\s+([a-zA-Z0-9_]+)$/i);
|
|
249
227
|
|
|
250
228
|
if (partialPatchMatch && !patchMatch) {
|
|
251
|
-
console.log(`\x1b[31m[
|
|
229
|
+
console.log(`\x1b[31m[Rejected]\x1b[0m Ambiguous command. Platform is mandatory to avoid Metal corruption.`);
|
|
252
230
|
console.log(`Type: patch module ${partialPatchMatch[1]} android`);
|
|
253
231
|
console.log(`Or: patch module ${partialPatchMatch[1]} ios`);
|
|
254
232
|
return;
|
|
@@ -262,7 +240,7 @@ if (command === 'alex') {
|
|
|
262
240
|
|
|
263
241
|
const cacheRes = await getModuleCache({ projectId, moduleName: modName });
|
|
264
242
|
if (!cacheRes.found) {
|
|
265
|
-
console.log(`\x1b[31m[
|
|
243
|
+
console.log(`\x1b[31m[Rejected]\x1b[0m Module "${modName}" does not exist in the Cloud. The first draft must ALWAYS be forged by Alex.`);
|
|
266
244
|
return;
|
|
267
245
|
}
|
|
268
246
|
|
|
@@ -275,7 +253,7 @@ if (command === 'alex') {
|
|
|
275
253
|
const mockPath = path.join(process.cwd(), 'src', 'app', 'mocks', `${modName}.${mockExt}`);
|
|
276
254
|
|
|
277
255
|
if (!fs.existsSync(nativePathFull)) {
|
|
278
|
-
console.log(`\x1b[31m[
|
|
256
|
+
console.log(`\x1b[31m[Fatal Error]\x1b[0m Target file not found on disk (${nativePathAPI}).`);
|
|
279
257
|
return;
|
|
280
258
|
}
|
|
281
259
|
|
|
@@ -297,7 +275,7 @@ if (command === 'alex') {
|
|
|
297
275
|
}
|
|
298
276
|
});
|
|
299
277
|
process.stdout.write(`\x1b[32m[OK]\x1b[0m\n`);
|
|
300
|
-
console.log(`\x1b[32m[
|
|
278
|
+
console.log(`\x1b[32m[Success]\x1b[0m Local version of ${nativeFileName} is now the official reference in the Cloud.`);
|
|
301
279
|
} catch (err) {
|
|
302
280
|
process.stdout.write(`\x1b[31m[FAILED]\x1b[0m\n`);
|
|
303
281
|
console.error(`\x1b[31m[Error] OS sync failed: ${err.message}\x1b[0m`);
|
|
@@ -305,7 +283,6 @@ if (command === 'alex') {
|
|
|
305
283
|
return;
|
|
306
284
|
}
|
|
307
285
|
|
|
308
|
-
// INTERCEPTION: LIST MODULES
|
|
309
286
|
const isListingRequest = /^(liste|list|listar|lista|quels modules|montre les modules|affiche les modules|show modules|what modules|display modules|qu[eé] m[oó]dulos|muestra los m[oó]dulos|ver m[oó]dulos)/i.test(prompt);
|
|
310
287
|
if (isListingRequest) {
|
|
311
288
|
process.stdout.write(`\x1b[90m[Scan] Checking OS Cache...\x1b[0m\n`);
|
|
@@ -325,7 +302,6 @@ if (command === 'alex') {
|
|
|
325
302
|
console.log('\x1b[33m[Alex] Processing request...\x1b[0m');
|
|
326
303
|
|
|
327
304
|
try {
|
|
328
|
-
// --- MEMORY SYSTEM (SMART CACHE SCANNER V3) ---
|
|
329
305
|
let contextInjection = "";
|
|
330
306
|
const potentialModules = extractPotentialModules(prompt);
|
|
331
307
|
|
|
@@ -394,10 +370,6 @@ if (command === 'alex') {
|
|
|
394
370
|
|
|
395
371
|
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.]`;
|
|
396
372
|
|
|
397
|
-
// =================================================================
|
|
398
|
-
// THE AUTOMATED 3-STEP WORKFLOW (Cross-Platform)
|
|
399
|
-
// =================================================================
|
|
400
|
-
|
|
401
373
|
const deepUnwrap = (raw, depth = 0) => {
|
|
402
374
|
if (depth > 5) return raw;
|
|
403
375
|
if (typeof raw === 'string') {
|
|
@@ -441,18 +413,17 @@ if (command === 'alex') {
|
|
|
441
413
|
|
|
442
414
|
process.stdout.write('\x1b[A\r' + ' '.repeat(50) + '\r');
|
|
443
415
|
|
|
444
|
-
let
|
|
416
|
+
let totalOutputTokens = 0;
|
|
445
417
|
|
|
446
|
-
// --- STEP 1: NATIVE ---
|
|
447
418
|
logStep('[1/3]', '\x1b[33mAlex is forging native foundations...\x1b[0m');
|
|
448
419
|
let aiData = await fetchStep('native_only');
|
|
449
420
|
|
|
450
421
|
if (aiData.status === 'quota_exceeded') {
|
|
451
|
-
console.log(`\n\x1b[31m[Architect Quota Reached]
|
|
422
|
+
console.log(`\n\x1b[31m[Architect Quota Reached]\x1b[0m ${aiData.message}`);
|
|
452
423
|
return;
|
|
453
424
|
}
|
|
454
425
|
|
|
455
|
-
|
|
426
|
+
totalOutputTokens += aiData.outputTokensUsed || 0;
|
|
456
427
|
|
|
457
428
|
let mergedModuleData = aiData.moduleData || {};
|
|
458
429
|
let aiDataMessage = aiData.message;
|
|
@@ -462,7 +433,6 @@ if (command === 'alex') {
|
|
|
462
433
|
if (isCloudUpdated && mergedModuleData.code) {
|
|
463
434
|
logStep('[1/3]', '\x1b[32mNative code generated.\x1b[0m\n');
|
|
464
435
|
|
|
465
|
-
// --- STEP 2: MOCK ---
|
|
466
436
|
logStep('[2/3]', '\x1b[33mAnalyzing native code and generating Interface (Mock)...\x1b[0m');
|
|
467
437
|
const aiData2 = await fetchStep('mock_only', { nativeCode: mergedModuleData.code });
|
|
468
438
|
|
|
@@ -470,10 +440,9 @@ if (command === 'alex') {
|
|
|
470
440
|
mergedModuleData.mockCode = aiData2.moduleData.mockCode;
|
|
471
441
|
mergedModuleData.mockFileName = aiData2.moduleData.mockFileName;
|
|
472
442
|
}
|
|
473
|
-
|
|
443
|
+
totalOutputTokens += aiData2.outputTokensUsed || 0;
|
|
474
444
|
logStep('[2/3]', '\x1b[32mInterface Mock generated.\x1b[0m\n');
|
|
475
445
|
|
|
476
|
-
// --- STEP 3: JSON CONFIG ---
|
|
477
446
|
logStep('[3/3]', '\x1b[33mFinalizing JSON configuration...\x1b[0m');
|
|
478
447
|
const aiData3 = await fetchStep('json_only', {
|
|
479
448
|
nativeCode: mergedModuleData.code,
|
|
@@ -485,7 +454,7 @@ if (command === 'alex') {
|
|
|
485
454
|
mergedModuleData.dataSchema = aiData3.moduleData.dataSchema;
|
|
486
455
|
mergedModuleData.uiSchema = aiData3.moduleData.uiSchema;
|
|
487
456
|
}
|
|
488
|
-
|
|
457
|
+
totalOutputTokens += aiData3.outputTokensUsed || 0;
|
|
489
458
|
logStep('[3/3]', '\x1b[32mConfiguration completed.\x1b[0m\n');
|
|
490
459
|
} else {
|
|
491
460
|
process.stdout.write(`\x1b[2K\r`);
|
|
@@ -503,7 +472,6 @@ if (command === 'alex') {
|
|
|
503
472
|
console.log(`[ALEX_START]${rawMsg}[ALEX_END]`);
|
|
504
473
|
}
|
|
505
474
|
|
|
506
|
-
// --- FILE CREATION LOGIC ---
|
|
507
475
|
if (aiData.status === 'success' && mergedModuleData && Object.keys(mergedModuleData).length > 0) {
|
|
508
476
|
let { fileName, code, mockFileName, mockCode, moduleName, config_offload, dataSchema, uiSchema } = mergedModuleData;
|
|
509
477
|
|
|
@@ -533,7 +501,6 @@ if (command === 'alex') {
|
|
|
533
501
|
const injected = injectRouteIntoAppJs(pageName, 'mocks');
|
|
534
502
|
}
|
|
535
503
|
|
|
536
|
-
// --- KERNEL SYNCHRONIZATION ---
|
|
537
504
|
const depsCount = config_offload?.dependencies?.length || 0;
|
|
538
505
|
process.stdout.write(`\x1b[33m[OS Sync]\x1b[0m Archiving ${moduleName} to OS (${depsCount} libs)... `);
|
|
539
506
|
|
|
@@ -563,8 +530,8 @@ if (command === 'alex') {
|
|
|
563
530
|
console.log('\x1b[90mTo eradicate this module later, open a new terminal and type:\x1b[0m');
|
|
564
531
|
console.log(`\x1b[31mnpm run fleetbo rm\x1b[0m \x1b[36m${moduleName}\x1b[0m`);
|
|
565
532
|
|
|
566
|
-
if (
|
|
567
|
-
console.log(`\x1b[90m[Telemetry]
|
|
533
|
+
if (totalOutputTokens > 0) {
|
|
534
|
+
console.log(`\n\x1b[90m[Telemetry] Output tokens generated: ${totalOutputTokens} (Limit: 8192/step)\x1b[0m\n`);
|
|
568
535
|
}
|
|
569
536
|
|
|
570
537
|
} else if (aiData.status === 'success' && (!mergedModuleData || Object.keys(mergedModuleData).length === 0)) {
|
|
@@ -576,10 +543,6 @@ if (command === 'alex') {
|
|
|
576
543
|
}
|
|
577
544
|
};
|
|
578
545
|
|
|
579
|
-
// ============================================================
|
|
580
|
-
// START INTERACTIVE SESSION
|
|
581
|
-
// ============================================================
|
|
582
|
-
|
|
583
546
|
const startAlexSession = async () => {
|
|
584
547
|
process.stdout.write('\x1b[33m[Alex] Checking runtime state...\x1b[0m\r');
|
|
585
548
|
let attempts = 0;
|
|
@@ -640,7 +603,7 @@ if (command === 'alex') {
|
|
|
640
603
|
|
|
641
604
|
console.log('\x1b[90m┌─────────────────────────────────────────────────────────┐\x1b[0m');
|
|
642
605
|
console.log('\x1b[90m│ │\x1b[0m');
|
|
643
|
-
console.log('\x1b[90m│\x1b[0m \x1b[1m\x1b[36m[ALEX]\x1b[0m \x1b[90m— System Architect · Fleetbo OS\x1b[0m
|
|
606
|
+
console.log('\x1b[90m│\x1b[0m \x1b[1m\x1b[36m[ALEX]\x1b[0m \x1b[90m— System Architect · Fleetbo OS\x1b[0m \x1b[90m│\x1b[0m');
|
|
644
607
|
console.log('\x1b[90m│ │\x1b[0m');
|
|
645
608
|
console.log('\x1b[90m│\x1b[0m \x1b[90mYour JS stays the brain. I forge the metal.\x1b[0m \x1b[90m│\x1b[0m');
|
|
646
609
|
console.log('\x1b[90m│ │\x1b[0m');
|
|
@@ -663,8 +626,6 @@ if (command === 'alex') {
|
|
|
663
626
|
console.log('\x1b[90mExample: \x1b[0m\x1b[33mupdate\x1b[0m module \x1b[36mProfileManager\x1b[0m \x1b[90mwith a red button\x1b[0m\n');
|
|
664
627
|
|
|
665
628
|
console.log('\x1b[32mAlex ❯\x1b[0m Describe your feature using the Compose panel...');
|
|
666
|
-
|
|
667
|
-
console.log('');
|
|
668
629
|
|
|
669
630
|
const rl = readline.createInterface({
|
|
670
631
|
input: process.stdin,
|
|
@@ -724,9 +685,6 @@ if (command === 'alex') {
|
|
|
724
685
|
|
|
725
686
|
}
|
|
726
687
|
|
|
727
|
-
// ============================================
|
|
728
|
-
// COMMAND: rm (MODULE ANNIHILATION)
|
|
729
|
-
// ============================================
|
|
730
688
|
else if (command === 'rm') {
|
|
731
689
|
const moduleName = args[1];
|
|
732
690
|
if (!moduleName) {
|
|
@@ -767,9 +725,6 @@ else if (command === 'rm') {
|
|
|
767
725
|
}
|
|
768
726
|
}
|
|
769
727
|
|
|
770
|
-
// ============================================
|
|
771
|
-
// COMMAND: android / ios (PROPULSION BUILD)
|
|
772
|
-
// ============================================
|
|
773
728
|
else if (command === 'android' || command === 'ios') {
|
|
774
729
|
|
|
775
730
|
(async () => {
|
|
@@ -930,9 +885,6 @@ else if (command === 'android' || command === 'ios') {
|
|
|
930
885
|
|
|
931
886
|
})();
|
|
932
887
|
}
|
|
933
|
-
// ============================================
|
|
934
|
-
// COMMAND: page / g / generate
|
|
935
|
-
// ============================================
|
|
936
888
|
else if (['page', 'g', 'generate'].includes(command)) {
|
|
937
889
|
const pageGeneratorPath = path.join(__dirname, 'page.js');
|
|
938
890
|
try {
|
|
@@ -942,9 +894,6 @@ else if (['page', 'g', 'generate'].includes(command)) {
|
|
|
942
894
|
process.exit(1);
|
|
943
895
|
}
|
|
944
896
|
}
|
|
945
|
-
// ============================================
|
|
946
|
-
// COMMAND: (default) - Start Dev Environment
|
|
947
|
-
// ============================================
|
|
948
897
|
else {
|
|
949
898
|
const NULL_DEV = process.platform === 'win32' ? '>nul 2>&1' : '2>/dev/null';
|
|
950
899
|
|