genbox 1.0.73 → 1.0.75

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.
@@ -690,13 +690,15 @@ async function setupEnvironmentsAndServiceUrls(detected, existingEnvValues) {
690
690
  console.log('');
691
691
  console.log(chalk_1.default.blue('=== Environment Configuration ==='));
692
692
  console.log('');
693
- // Auto-detect database URLs from project
693
+ // Auto-detect database URLs from project (informational only)
694
+ // Note: These are typically LOCAL dev databases, not production sources for snapshots
694
695
  const detectedDbUrls = detectDatabaseUrls(detected._meta.scanned_root, detected);
695
696
  if (detectedDbUrls.length > 0) {
696
- console.log(chalk_1.default.dim('Detected database URLs in project:'));
697
+ console.log(chalk_1.default.dim('Detected database URLs in project (for reference):'));
697
698
  for (const db of detectedDbUrls) {
699
+ const info = db.varName ? `${db.varName} in ${db.source}` : db.source;
698
700
  console.log(chalk_1.default.dim(` • ${db.url}`));
699
- console.log(chalk_1.default.dim(` └─ from ${db.source}${db.database ? ` (database: ${db.database})` : ''}`));
701
+ console.log(chalk_1.default.dim(` └─ from ${info}${db.database ? ` (database: ${db.database})` : ''}`));
700
702
  }
701
703
  console.log('');
702
704
  }
@@ -714,11 +716,9 @@ async function setupEnvironmentsAndServiceUrls(detected, existingEnvValues) {
714
716
  if (envChoice !== 'skip') {
715
717
  console.log('');
716
718
  console.log(chalk_1.default.dim('These URLs will be used when connecting to external services.'));
717
- console.log(chalk_1.default.dim('MongoDB URLs are used for taking database snapshots to copy to genbox.'));
719
+ console.log(chalk_1.default.dim('MongoDB URLs should point to PRODUCTION/STAGING databases (source for snapshots).'));
718
720
  const configureStaging = envChoice === 'staging' || envChoice === 'both';
719
721
  const configureProduction = envChoice === 'production' || envChoice === 'both';
720
- // Build suggested MongoDB URL from detected sources
721
- const suggestedMongoUrl = buildMongoDbUrl(detectedDbUrls);
722
722
  if (configureStaging) {
723
723
  console.log('');
724
724
  console.log(chalk_1.default.cyan('Staging Environment:'));
@@ -730,13 +730,9 @@ async function setupEnvironmentsAndServiceUrls(detected, existingEnvValues) {
730
730
  };
731
731
  envVars['STAGING_API_URL'] = stagingApiUrl;
732
732
  }
733
- // Use auto-detected URL as default if no existing value
733
+ // Keep existing value - don't auto-suggest local dev URLs for snapshot sources
734
734
  const existingStagingMongo = existingEnvValues['STAGING_MONGODB_URL'];
735
- const stagingMongoDefault = existingStagingMongo || suggestedMongoUrl;
736
- if (stagingMongoDefault && !existingStagingMongo) {
737
- console.log(chalk_1.default.dim(` Auto-detected: ${stagingMongoDefault}`));
738
- }
739
- const stagingMongoUrl = await promptWithExisting(' Staging MongoDB URL (for snapshots):', stagingMongoDefault, true);
735
+ const stagingMongoUrl = await promptWithExisting(' Staging MongoDB URL (for snapshots):', existingStagingMongo, true);
740
736
  if (stagingMongoUrl) {
741
737
  envVars['STAGING_MONGODB_URL'] = stagingMongoUrl;
742
738
  }
@@ -756,13 +752,9 @@ async function setupEnvironmentsAndServiceUrls(detected, existingEnvValues) {
756
752
  };
757
753
  envVars['PRODUCTION_API_URL'] = prodApiUrl;
758
754
  }
759
- // Use auto-detected URL as default if no existing value
755
+ // Keep existing value - don't auto-suggest local dev URLs for snapshot sources
760
756
  const existingProdMongo = existingEnvValues['PROD_MONGODB_URL'] || existingEnvValues['PRODUCTION_MONGODB_URL'];
761
- const prodMongoDefault = existingProdMongo || suggestedMongoUrl;
762
- if (prodMongoDefault && !existingProdMongo) {
763
- console.log(chalk_1.default.dim(` Auto-detected: ${prodMongoDefault}`));
764
- }
765
- const prodMongoUrl = await promptWithExisting(' Production MongoDB URL (for snapshots):', prodMongoDefault, true);
757
+ const prodMongoUrl = await promptWithExisting(' Production MongoDB URL (for snapshots):', existingProdMongo, true);
766
758
  if (prodMongoUrl) {
767
759
  envVars['PROD_MONGODB_URL'] = prodMongoUrl;
768
760
  }
@@ -337,12 +337,17 @@ async function runSoftRebuild(options) {
337
337
  log(`Warning: Database restore failed: ${error.message}`, 'error');
338
338
  }
339
339
  }
340
- // Step 8: Start PM2 services
340
+ // Step 8: Start PM2 services (only for apps with runner: pm2 or unspecified)
341
341
  onStep?.('Starting application services...');
342
342
  for (const app of resolved.apps) {
343
343
  const appConfig = config.apps[app.name];
344
344
  if (!appConfig)
345
345
  continue;
346
+ // Skip apps with runner: docker - they're already running via Docker Compose
347
+ if (appConfig.runner === 'docker') {
348
+ log(`Skipping ${app.name} (runner: docker, already started via Docker Compose)`, 'dim');
349
+ continue;
350
+ }
346
351
  // Find the repo path for this app
347
352
  const appPath = appConfig.path || app.name;
348
353
  const repoPath = resolved.repos.find(r => r.name === app.name)?.path ||
@@ -362,11 +367,12 @@ async function runSoftRebuild(options) {
362
367
  }
363
368
  }
364
369
  else {
365
- // Check for start script in package.json
366
- const hasStartScript = await sshExec(ip, keyPath, `grep -q '"start"' ${repoPath}/package.json 2>/dev/null && echo yes || echo no`, 10);
367
- if (hasStartScript.output === 'yes') {
368
- log(`Starting ${app.name} with PM2 (npm start)...`, 'info');
369
- const pm2Result = await sshExecStream(ip, keyPath, `cd ${repoPath} && source ~/.nvm/nvm.sh && pm2 start npm --name ${app.name} -- start`, {
370
+ // Use configured dev command, or fall back to dev script, then start script
371
+ const devCommand = appConfig.commands?.dev;
372
+ if (devCommand) {
373
+ // Use the configured dev command
374
+ log(`Starting ${app.name} with PM2 (${devCommand})...`, 'info');
375
+ const pm2Result = await sshExecStream(ip, keyPath, `cd ${repoPath} && source ~/.nvm/nvm.sh && pm2 start "pnpm run ${devCommand}" --name ${app.name}`, {
370
376
  onStdout: (line) => log(line, 'dim'),
371
377
  timeoutSecs: 60,
372
378
  });
@@ -374,6 +380,34 @@ async function runSoftRebuild(options) {
374
380
  log(`✓ Started ${app.name}`, 'success');
375
381
  }
376
382
  }
383
+ else {
384
+ // Check for dev script in package.json first, then start
385
+ const hasDevScript = await sshExec(ip, keyPath, `grep -q '"dev"' ${repoPath}/package.json 2>/dev/null && echo yes || echo no`, 10);
386
+ if (hasDevScript.output === 'yes') {
387
+ log(`Starting ${app.name} with PM2 (pnpm dev)...`, 'info');
388
+ const pm2Result = await sshExecStream(ip, keyPath, `cd ${repoPath} && source ~/.nvm/nvm.sh && pm2 start "pnpm run dev" --name ${app.name}`, {
389
+ onStdout: (line) => log(line, 'dim'),
390
+ timeoutSecs: 60,
391
+ });
392
+ if (pm2Result.success) {
393
+ log(`✓ Started ${app.name}`, 'success');
394
+ }
395
+ }
396
+ else {
397
+ // Fall back to start script
398
+ const hasStartScript = await sshExec(ip, keyPath, `grep -q '"start"' ${repoPath}/package.json 2>/dev/null && echo yes || echo no`, 10);
399
+ if (hasStartScript.output === 'yes') {
400
+ log(`Starting ${app.name} with PM2 (pnpm start)...`, 'info');
401
+ const pm2Result = await sshExecStream(ip, keyPath, `cd ${repoPath} && source ~/.nvm/nvm.sh && pm2 start "pnpm run start" --name ${app.name}`, {
402
+ onStdout: (line) => log(line, 'dim'),
403
+ timeoutSecs: 60,
404
+ });
405
+ if (pm2Result.success) {
406
+ log(`✓ Started ${app.name}`, 'success');
407
+ }
408
+ }
409
+ }
410
+ }
377
411
  }
378
412
  }
379
413
  // Step 9: Save PM2 process list
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genbox",
3
- "version": "1.0.73",
3
+ "version": "1.0.75",
4
4
  "description": "Genbox CLI - AI-Powered Development Environments",
5
5
  "main": "dist/index.js",
6
6
  "bin": {