create-fleetbo-project 1.2.42 → 1.2.43

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.
@@ -34,7 +34,7 @@ const command = args[0];
34
34
  process.env.DOTENV_SILENT = 'true';
35
35
  const envPath = path.join(process.cwd(), '.env');
36
36
  if (!fs.existsSync(envPath)) {
37
- console.error('\\\\x1b[31m%s\\\\x1b[0m', '❌ Error: Configuration file (.env) not found.');
37
+ console.error('\\x1b[31m%s\\x1b[0m', '❌ Error: Configuration file (.env) not found.');
38
38
  process.exit(1);
39
39
  }
40
40
  dotenv.config({ path: envPath, quiet: true });
@@ -48,19 +48,19 @@ const checkGitSecurity = () => {
48
48
  const gitignorePath = path.join(process.cwd(), '.gitignore');
49
49
  if (fs.existsSync(gitDir)) {
50
50
  if (!fs.existsSync(gitignorePath)) {
51
- console.error('\\\\n\\\\x1b[31m🚨 SECURITY ALERT:\\\\x1b[0m .git detected but no .gitignore found.');
51
+ console.error('\\n\\x1b[31m🚨 SECURITY ALERT:\\x1b[0m .git detected but no .gitignore found.');
52
52
  process.exit(1);
53
53
  }
54
54
  const gitignoreContent = fs.readFileSync(gitignorePath, 'utf8');
55
55
  if (!gitignoreContent.includes('.env')) {
56
- console.error('\\\\n\\\\x1b[31m🚨 CRITICAL RISK:\\\\x1b[0m .env is NOT ignored by Git.');
56
+ console.error('\\n\\x1b[31m🚨 CRITICAL RISK:\\x1b[0m .env is NOT ignored by Git.');
57
57
  process.exit(1);
58
58
  }
59
59
  }
60
60
  };
61
61
 
62
62
  if (!projectId) {
63
- console.error('\\\\n❌ Error: Project ID missing in .env.\\\\n');
63
+ console.error('\\n❌ Error: Project ID missing in .env.\\n');
64
64
  process.exit(1);
65
65
  }
66
66
 
@@ -73,17 +73,17 @@ const injectRouteIntoAppJs = (pageName, subPath = '') => {
73
73
 
74
74
  if (!content.includes(alexRouteAnchor)) return false;
75
75
 
76
- const pathPrefix = subPath ? \\\`\\\${subPath}/\\\` : '';
77
- const importLine = \\\`import \\\${pageName} from './pages/\\\${pathPrefix}\\\${pageName}';\\\`;
78
- const routeLine = \\\`<Route path="/\\\${pathPrefix.toLowerCase()}\\\${pageName.toLowerCase()}" element=<\\\${pageName} /> />\\\`;
76
+ const pathPrefix = subPath ? \`\${subPath}/\` : '';
77
+ const importLine = \`import \${pageName} from './pages/\${pathPrefix}\${pageName}';\`;
78
+ const routeLine = \`<Route path="/\${pathPrefix.toLowerCase()}\${pageName.toLowerCase()}" element=<\${\${pageName} />} />\`;
79
79
 
80
80
  let injected = false;
81
81
  if (!content.includes(importLine)) {
82
- content = content.replace(importAnchor, \\\`\\\${importLine}\\\\n\\\${importAnchor}\\\`);
82
+ content = content.replace(importAnchor, \`\${importLine}\\n\${importAnchor}\`);
83
83
  injected = true;
84
84
  }
85
85
  if (!content.includes(routeLine)) {
86
- content = content.replace(alexRouteAnchor, \\\`\\\${routeLine}\\\\n \\\${alexRouteAnchor}\\\`);
86
+ content = content.replace(alexRouteAnchor, \`\${routeLine}\\n \${alexRouteAnchor}\`);
87
87
  injected = true;
88
88
  }
89
89
 
@@ -95,10 +95,10 @@ const showEnergyTransfer = async () => {
95
95
  const width = 30;
96
96
  for (let i = 0; i <= width; i++) {
97
97
  const dots = "█".repeat(i); const empty = "░".repeat(width - i);
98
- process.stdout.write(\\\`\\\\r \\\\x1b[32m⚡ Alex Energy Sync:\\\\x1b[0m [\\\${dots}\\\${empty}] \\\${Math.round((i / width) * 100)}%\\\`);
98
+ process.stdout.write(\`\\r \\x1b[32m⚡ Alex Energy Sync:\\x1b[0m [\${dots}\${empty}] \${Math.round((i / width) * 100)}%\`);
99
99
  await new Promise(r => setTimeout(r, 45));
100
100
  }
101
- process.stdout.write('\\\\n');
101
+ process.stdout.write('\\n');
102
102
  };
103
103
 
104
104
  if (command === 'alex') {
@@ -106,43 +106,43 @@ if (command === 'alex') {
106
106
  const initialPrompt = args.slice(1).join(' ');
107
107
 
108
108
  const processAlexRequest = async (prompt) => {
109
- process.stdout.write('\\\\x1b[33m🧠 Alex is thinking...\\\\x1b[0m');
109
+ process.stdout.write('\\x1b[33m🧠 Alex is thinking...\\x1b[0m');
110
110
  try {
111
111
  const result = await axios.post(ALEX_ENGINE_URL, { prompt, projectType: 'android' }, {
112
112
  headers: { 'x-project-id': projectId }
113
113
  });
114
114
 
115
115
  const aiData = result.data;
116
- process.stdout.write('\\\\r' + ' '.repeat(50) + '\\\\r');
116
+ process.stdout.write('\\r' + ' '.repeat(50) + '\\r');
117
117
 
118
118
  if (aiData.status === 'quota_exceeded') {
119
- console.log(\\\`\\\\n\\\\x1b[31m⛔ ENGINE OUT OF FUEL:\\\\x1b[0m \\\${aiData.message}\\\`);
119
+ console.log(\`\\n\\x1b[31m⛔ ENGINE OUT OF FUEL:\\x1b[0m \${aiData.message}\`);
120
120
  return;
121
121
  }
122
122
 
123
123
  if (aiData.status === 'success' || aiData.status === 'message') {
124
124
  console.log('');
125
- console.log(\\\`\\\\x1b[32mAlex ❯\\\\x1b[0m \\\${aiData.message || "I'm ready."}\\\`);
125
+ console.log(\`\\x1b[32mAlex ❯\\x1b[0m \${aiData.message || "I'm ready."}\`);
126
126
 
127
127
  if (aiData.remainingTokens !== undefined) {
128
128
  const remaining = aiData.remainingTokens;
129
129
  const limit = aiData.limit || 2500;
130
130
  const percent = Math.round((remaining / limit) * 100);
131
- const energyColor = percent > 30 ? '\\\\x1b[32m' : '\\\\x1b[31m';
132
- console.log(\\\`\\\\x1b[36m📊 Energy:\\\\x1b[0m \\\${energyColor}\\\${percent}%\\\\x1b[0m (\\\${remaining}/\\\${limit} tokens left)\\\`);
131
+ const energyColor = percent > 30 ? '\\x1b[32m' : '\\x1b[31m';
132
+ console.log(\`\\x1b[36m📊 Energy:\\x1b[0m \${energyColor}\${percent}%\\x1b[0m (\${remaining}/\${limit} tokens left)\`);
133
133
  }
134
134
  }
135
135
 
136
136
  if (aiData.status === 'success' && aiData.moduleData) {
137
137
  const { fileName, code, mockFileName, mockCode, moduleName } = aiData.moduleData;
138
- console.log(\\\` \\\\x1b[90m⚙️ Architecting: \\\${moduleName}\\\\x1b[0m\\\`);
138
+ console.log(\` \\x1b[90m⚙️ Architecting: \${moduleName}\\x1b[0m\`);
139
139
 
140
140
  const writeFile = (dir, name, content) => {
141
141
  const fullPath = path.join(process.cwd(), dir);
142
142
  const filePath = path.join(fullPath, name);
143
143
  if (!fs.existsSync(fullPath)) fs.mkdirSync(fullPath, { recursive: true });
144
144
  fs.writeFileSync(filePath, content);
145
- console.log(\\\`\\\\x1b[32m[Written]\\\\x1b[0m \\\${dir}\\\${name}\\\`);
145
+ console.log(\`\\x1b[32m[Written]\\x1b[0m \${dir}\${name}\`);
146
146
  };
147
147
 
148
148
  if (code && fileName) {
@@ -156,13 +156,13 @@ if (command === 'alex') {
156
156
  }
157
157
  }
158
158
  } catch (error) {
159
- process.stdout.write('\\\\r' + ' '.repeat(50) + '\\\\r');
160
- console.error('\\\\n\\\\x1b[31m❌ Alex Error:\\\\x1b[0m ' + (error.response?.data?.message || error.message));
159
+ process.stdout.write('\\r' + ' '.repeat(50) + '\\r');
160
+ console.error('\\n\\x1b[31m❌ Alex Error:\\x1b[0m ' + (error.response?.data?.message || error.message));
161
161
  }
162
162
  };
163
163
 
164
164
  const startAlexSession = async () => {
165
- process.stdout.write('\\\\x1b[33m🛡️ Alex is checking runtime state...\\\\x1b[0m\\\\r');
165
+ process.stdout.write('\\x1b[33m🛡️ Alex is checking runtime state...\\x1b[0m\\r');
166
166
  let attempts = 0; const maxAttempts = 5; let isReady = false;
167
167
  while (attempts < maxAttempts && !isReady) {
168
168
  try {
@@ -172,17 +172,17 @@ if (command === 'alex') {
172
172
  } catch (error) { attempts++; await new Promise(r => setTimeout(r, 2000)); }
173
173
  }
174
174
  if (!isReady) {
175
- console.error('\\\\n\\\\x1b[31m⚠️ ENGINE OFFLINE:\\\\x1b[0m Start Fleetbo runtime first: "npm run fleetbo" ');
175
+ console.error('\\n\\x1b[31m⚠️ ENGINE OFFLINE:\\x1b[0m Start Fleetbo runtime first: "npm run fleetbo" ');
176
176
  process.exit(1);
177
177
  }
178
- process.stdout.write(' '.repeat(60) + '\\\\r');
179
- 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');
178
+ process.stdout.write(' '.repeat(60) + '\\r');
179
+ 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');
181
181
  const userName = testerEmail ? testerEmail.split('@')[0] : 'Dev';
182
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout, prompt: \\\`\\\\x1b[34m\\\${userName} ❯ \\\\x1b[0m\\\` });
182
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout, prompt: \`\\x1b[34m\${userName} ❯ \\x1b[0m\` });
183
183
  rl.prompt();
184
184
  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; }
185
+ if (['exit', 'quit'].includes(line.trim().toLowerCase())) { console.log('\\n\\x1b[90m👋 Alex session closed.\\x1b[0m'); rl.close(); return; }
186
186
  if (line.trim()) { await processAlexRequest(line.trim()); console.log(''); }
187
187
  rl.prompt();
188
188
  }).on('close', () => { process.exit(0); });
@@ -196,7 +196,7 @@ if (command === 'alex') {
196
196
  if (command === 'deploy') {
197
197
  checkGitSecurity();
198
198
  (async () => {
199
- console.log('\\\\n\\\\x1b[36m⚡ FLEETBO CLOUD ENGINE\\\\x1b[0m');
199
+ console.log('\\n\\x1b[36m⚡ FLEETBO CLOUD ENGINE\\x1b[0m');
200
200
  try {
201
201
  execSync('npm run build', { stdio: 'inherit' });
202
202
  let buildDir = fs.existsSync(path.join(process.cwd(), 'dist')) ? 'dist' : 'build';
@@ -207,10 +207,10 @@ if (command === 'deploy') {
207
207
  archive.directory(path.join(process.cwd(), buildDir), false);
208
208
  archive.finalize();
209
209
  });
210
- console.log('\\\\n📦 \\\\x1b[33mPreparing Neural Logic for Uplink...\\\\x1b[0m');
210
+ console.log('\\n📦 \\x1b[33mPreparing Neural Logic for Uplink...\\x1b[0m');
211
211
  await showEnergyTransfer();
212
212
  await axios.post(CLOUD_ENGINE_URL, zipBuffer, { headers: { 'Content-Type': 'application/zip', 'x-project-id': projectId } });
213
- console.log('\\\\n✅ \\\\x1b[1mDEPLOYMENT SUCCESSFUL\\\\x1b[0m | \\\\x1b[32mAlex ❯\\\\x1b[0m Runtime updated.');
213
+ console.log('\\n✅ \\x1b[1mDEPLOYMENT SUCCESSFUL\\x1b[0m | \\x1b[32mAlex ❯\\x1b[0m Runtime updated.');
214
214
  } catch (error) { process.exit(1); }
215
215
  })();
216
216
  return;
@@ -226,8 +226,8 @@ const NULL_DEV = process.platform === 'win32' ? '>nul 2>&1' : '2>/dev/null';
226
226
  function killProcessOnPort(port) {
227
227
  try {
228
228
  if (process.platform !== 'win32') {
229
- const pid = execSync(\\\`lsof -ti:\\\${port} \\\${NULL_DEV}\\\`).toString().trim();
230
- if (pid) execSync(\\\`kill -9 \\\${pid.split('\\\\n').join(' ')} \\\${NULL_DEV}\\\`);
229
+ const pid = execSync(\`lsof -ti:\${port} \${NULL_DEV}\`).toString().trim();
230
+ if (pid) execSync(\`kill -9 \${pid.split('\\n').join(' ')} \${NULL_DEV}\`);
231
231
  }
232
232
  } catch (e) {}
233
233
  }
@@ -241,7 +241,7 @@ function killNetworkService() {
241
241
  let isExiting = false;
242
242
  async function cleanupAndExit(code = 0) {
243
243
  if (isExiting) return; isExiting = true;
244
- console.log('\\\\n[Fleetbo] 🛑 Stopping environment...');
244
+ console.log('\\n[Fleetbo] 🛑 Stopping environment...');
245
245
  try { await axios.post(UPDATE_NETWORK_URL, { keyApp, networkUrl: '', tester: testerEmail }); } catch (e) {}
246
246
  killNetworkService(); killProcessOnPort(PORT); process.exit(code);
247
247
  }
@@ -251,16 +251,16 @@ process.on('SIGTERM', () => cleanupAndExit(0));
251
251
  async function syncFirebase(keyApp, networkUrl, testerEmail) {
252
252
  try {
253
253
  await axios.post(UPDATE_NETWORK_URL, { keyApp, networkUrl, tester: testerEmail });
254
- console.log(\\\`\\\\n\\\\x1b[32m[Fleetbo]\\\\x1b[0m -------------------------------------------------------------\\\`);
255
- console.log('\\\\x1b[32m[Fleetbo] GO GO GO ! FLEETBO STUDIO IS READY \\\\x1b[0m');
256
- console.log(\\\`\\\\x1b[32m[Fleetbo] Link: https://fleetbo.io/studio/\\\${keyApp}\\\\x1b[0m\\\`);
257
- console.log('\\\\x1b[32m[Fleetbo] You can now start coding and previewing in Studio. 🚀\\\\x1b[0m\\\`);
258
- console.log(\\\`\\\\x1b[32m[Fleetbo]\\\\x1b[0m -------------------------------------------------------------\\\`);
259
- } catch (err) { console.error(\\\`[Fleetbo] ❌ Sync Error: \\\${err.message}\\\`); }
254
+ console.log(\`\\n\\x1b[32m[Fleetbo]\\x1b[0m -------------------------------------------------------------\`);
255
+ console.log('\\x1b[32m[Fleetbo] GO GO GO ! FLEETBO STUDIO IS READY \\x1b[0m');
256
+ console.log(\`\\x1b[32m[Fleetbo] Link: https://fleetbo.io/studio/\${keyApp}\\x1b[0m\`);
257
+ console.log('\\x1b[32m[Fleetbo] You can now start coding and previewing in Studio. 🚀\\x1b[0m');
258
+ console.log(\`\\x1b[32m[Fleetbo]\\x1b[0m -------------------------------------------------------------\`);
259
+ } catch (err) { console.error(\`[Fleetbo] ❌ Sync Error: \${err.message}\`); }
260
260
  }
261
261
 
262
262
  async function runDevEnvironment() {
263
- console.log(\\\`[Fleetbo] 🛡️ Initializing Dev Environment...\\\`);
263
+ console.log(\`[Fleetbo] 🛡️ Initializing Dev Environment...\`);
264
264
  killNetworkService(); killProcessOnPort(PORT);
265
265
  const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
266
266
  const devServer = spawn(npmCmd, ['start'], { stdio: ['ignore', 'pipe', 'pipe'], shell: true, env: { ...process.env, BROWSER: 'none', PORT: PORT.toString() } });
@@ -270,18 +270,18 @@ async function runDevEnvironment() {
270
270
  const output = data.toString();
271
271
  if (!connectionStarted && (output.includes('Local:') || output.includes('Compiled successfully'))) {
272
272
  connectionStarted = true;
273
- 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] ---------------------------------------------------\\\`);
273
+ 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] ---------------------------------------------------\`);
275
275
  const npxCmd = process.platform === 'win32' ? 'npx.cmd' : 'npx';
276
- const uplink = spawn(npxCmd, ['cloudflared', 'tunnel', '--url', \\\`http://localhost:\\\${PORT}\\\`], { shell: true });
276
+ const uplink = spawn(npxCmd, ['cloudflared', 'tunnel', '--url', \`http://localhost:\${PORT}\`], { shell: true });
277
277
  uplink.stderr.on('data', (chunk) => {
278
- const match = chunk.toString().match(/https:\\\\/\\\\/[a-zA-Z0-9-]+\\\\.trycloudflare\\\\.com/);
278
+ const match = chunk.toString().match(/https:\\/\\/[a-zA-Z0-9-]+\\.trycloudflare\\.com/);
279
279
  if (match) syncFirebase(keyApp, match[0], testerEmail);
280
280
  });
281
281
  }
282
282
  });
283
283
  }
284
- runDevEnvironment();`;
284
+ runDevEnvironment();`.replace(/`/g, '\\`').replace(/\${/g, '\\${');
285
285
 
286
286
 
287
287
  const args = process.argv.slice(2);
@@ -353,11 +353,11 @@ async function setupProject() {
353
353
  if (fs.existsSync(projectDir)) throw new Error(`Directory "${projectName}" already exists.`);
354
354
  fs.mkdirSync(projectDir);
355
355
 
356
- console.log(' [1/6] 📥 Downloading Fleetbo Core Engine...');
356
+ console.log(' [1/7] 📥 Downloading Fleetbo Core Engine...');
357
357
  const archivePath = path.join(projectDir, 'engine.tar.gz');
358
358
  await downloadEngine(archiveUrl, archivePath);
359
359
 
360
- console.log(' [2/6] 📦 Scaffolding project structure...');
360
+ console.log(' [2/7] 📦 Scaffolding project structure...');
361
361
  try {
362
362
  execSync(`tar -xf "${archivePath}" -C "${projectDir}" --strip-components=1`, { stdio: 'ignore' });
363
363
  fs.unlinkSync(archivePath);
@@ -365,11 +365,11 @@ async function setupProject() {
365
365
 
366
366
  process.chdir(projectDir);
367
367
 
368
- console.log(' [3/6] 🔑 Authenticating with Fleetbo Cloud...');
368
+ console.log(' [3/7] 🔑 Authenticating with Fleetbo Cloud...');
369
369
  const keys = await fetchProjectKeys(bootstrapTokenArg);
370
370
  if (!keys.enterpriseId) throw new Error("Invalid keys.");
371
371
 
372
- console.log(' [4.1/6] ⚙️ Configuring environment & CLI...');
372
+ console.log(' [4/7] ⚙️ Configuring environment & CLI...');
373
373
 
374
374
  // Correction indentation .env
375
375
  const envContent = `REACT_APP_FLEETBO_DB_KEY=${keys.fleetboDBKey}
@@ -381,7 +381,7 @@ async function setupProject() {
381
381
 
382
382
  fs.writeFileSync(path.join(projectDir, '.env'), envContent, 'utf8');
383
383
 
384
- console.log(' [4.2/6] 🛡️ Securing environment (adding .gitignore)...');
384
+ console.log(' [5/7] 🛡️ Securing environment (adding .gitignore)...');
385
385
  const gitignoreContent = `# Fleetbo Security\n.env\n.env.local\nnode_modules/\ndist/\nbuild/\n.DS_Store\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n`;
386
386
  fs.writeFileSync(path.join(projectDir, '.gitignore'), gitignoreContent, 'utf8');
387
387
 
@@ -390,11 +390,11 @@ async function setupProject() {
390
390
  fs.writeFileSync(path.join(scriptsDir, 'cli.js'), CLI_SCRIPT_CONTENT, 'utf8');
391
391
  try { fs.chmodSync(path.join(scriptsDir, 'cli.js'), '755'); } catch (e) {}
392
392
 
393
- console.log(' [5/6] 📚 Installing dependencies...');
393
+ console.log(' [6/7] 📚 Installing dependencies...');
394
394
  execSync('npm install', { stdio: 'inherit' });
395
395
  execSync('npm install cloudflared dotenv axios archiver --save-dev', { stdio: 'ignore' });
396
396
 
397
- console.log(' [6/6] ✨ Finalizing setup...');
397
+ console.log(' [7/7] ✨ Finalizing setup...');
398
398
  const packageJsonPath = path.join(projectDir, 'package.json');
399
399
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
400
400
  packageJson.name = projectName;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-fleetbo-project",
3
- "version": "1.2.42",
3
+ "version": "1.2.43",
4
4
  "description": "Creates a new Fleetbo project.",
5
5
  "main": "install-react-template.js",
6
6
  "bin": {