genbox 1.0.8 → 1.0.10

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.
@@ -233,6 +233,14 @@ function displayResolvedConfig(resolved) {
233
233
  console.log(chalk_1.default.dim(` deps: ${deps}`));
234
234
  }
235
235
  }
236
+ if (resolved.repos.length > 0) {
237
+ console.log('');
238
+ console.log(` ${chalk_1.default.bold('Repos:')}`);
239
+ for (const repo of resolved.repos) {
240
+ console.log(` • ${repo.name}: ${repo.url}`);
241
+ console.log(chalk_1.default.dim(` → ${repo.path}`));
242
+ }
243
+ }
236
244
  if (resolved.infrastructure.length > 0) {
237
245
  console.log('');
238
246
  console.log(` ${chalk_1.default.bold('Infrastructure:')}`);
@@ -458,7 +466,10 @@ async function createLegacy(name, options) {
458
466
  });
459
467
  spinner.succeed(chalk_1.default.green(`Genbox '${name}' created!`));
460
468
  if (genbox.ipAddress) {
461
- (0, ssh_config_1.addSshConfigEntry)({ name, ipAddress: genbox.ipAddress });
469
+ const sshAdded = (0, ssh_config_1.addSshConfigEntry)({ name, ipAddress: genbox.ipAddress });
470
+ if (sshAdded) {
471
+ console.log(chalk_1.default.dim(` SSH config added: ssh ${(0, ssh_config_1.getSshAlias)(name)}`));
472
+ }
462
473
  }
463
474
  console.log(chalk_1.default.dim('───────────────────────────────────────────────'));
464
475
  console.log(` ${chalk_1.default.bold('Environment:')} ${name}`);
@@ -12,6 +12,7 @@ const api_1 = require("../api");
12
12
  const genbox_selector_1 = require("../genbox-selector");
13
13
  const ssh_config_1 = require("../ssh-config");
14
14
  exports.destroyCommand = new commander_1.Command('destroy')
15
+ .alias('delete')
15
16
  .description('Destroy a Genbox')
16
17
  .argument('[name]', 'Name of the Genbox to destroy (optional - will prompt if not provided)')
17
18
  .option('-y, --yes', 'Skip confirmation')
@@ -137,6 +137,7 @@ exports.initCommand = new commander_1.Command('init')
137
137
  const configPath = path_1.default.join(process.cwd(), CONFIG_FILENAME);
138
138
  const nonInteractive = options.yes || !process.stdin.isTTY;
139
139
  // Check for existing config
140
+ let overwriteExisting = options.force || false;
140
141
  if (fs_1.default.existsSync(configPath) && !options.force) {
141
142
  if (nonInteractive) {
142
143
  console.log(chalk_1.default.yellow('genbox.yaml already exists. Use --force to overwrite.'));
@@ -150,9 +151,12 @@ exports.initCommand = new commander_1.Command('init')
150
151
  if (!overwrite) {
151
152
  return;
152
153
  }
154
+ overwriteExisting = true;
153
155
  }
154
156
  console.log(chalk_1.default.blue('Initializing Genbox...'));
155
157
  console.log('');
158
+ // Track env vars to add to .env.genbox
159
+ const envVarsToAdd = {};
156
160
  // Get initial exclusions from CLI options only
157
161
  let exclude = [];
158
162
  if (options.exclude) {
@@ -291,6 +295,7 @@ exports.initCommand = new commander_1.Command('init')
291
295
  });
292
296
  if (selectedRepos.length > 0) {
293
297
  v3Config.repos = {};
298
+ let hasHttpsRepos = false;
294
299
  for (const repoName of selectedRepos) {
295
300
  const repo = appGitRepos.find(r => r.appName === repoName);
296
301
  v3Config.repos[repo.appName] = {
@@ -299,6 +304,31 @@ exports.initCommand = new commander_1.Command('init')
299
304
  branch: repo.branch !== 'main' && repo.branch !== 'master' ? repo.branch : undefined,
300
305
  auth: repo.type === 'ssh' ? 'ssh' : 'token',
301
306
  };
307
+ if (repo.type === 'https') {
308
+ hasHttpsRepos = true;
309
+ }
310
+ }
311
+ // Prompt for GIT_TOKEN if any HTTPS repos are selected
312
+ if (hasHttpsRepos) {
313
+ console.log('');
314
+ console.log(chalk_1.default.yellow('Private repositories require a GitHub token for cloning.'));
315
+ console.log('');
316
+ console.log(chalk_1.default.dim(' To create a token:'));
317
+ console.log(chalk_1.default.dim(' 1. Go to https://github.com/settings/tokens'));
318
+ console.log(chalk_1.default.dim(' 2. Click "Generate new token" → "Classic"'));
319
+ console.log(chalk_1.default.dim(' 3. Select scope: "repo" (Full control of private repositories)'));
320
+ console.log(chalk_1.default.dim(' 4. Generate and copy the token'));
321
+ console.log('');
322
+ const gitToken = await prompts.password({
323
+ message: 'GitHub Personal Access Token (leave empty to skip):',
324
+ });
325
+ if (gitToken) {
326
+ envVarsToAdd['GIT_TOKEN'] = gitToken;
327
+ console.log(chalk_1.default.green('✓ GIT_TOKEN will be added to .env.genbox'));
328
+ }
329
+ else {
330
+ console.log(chalk_1.default.dim(' Skipped - add GIT_TOKEN to .env.genbox later if needed'));
331
+ }
302
332
  }
303
333
  }
304
334
  }
@@ -425,7 +455,7 @@ exports.initCommand = new commander_1.Command('init')
425
455
  fs_1.default.writeFileSync(configPath, yamlContent);
426
456
  console.log(chalk_1.default.green(`\n✔ Configuration saved to ${CONFIG_FILENAME}`));
427
457
  // Generate .env.genbox
428
- await setupEnvFile(projectName, v3Config, nonInteractive, scan, isMultiRepo);
458
+ await setupEnvFile(projectName, v3Config, nonInteractive, scan, isMultiRepo, envVarsToAdd, overwriteExisting);
429
459
  // Show warnings
430
460
  if (generated.warnings.length > 0) {
431
461
  console.log('');
@@ -718,11 +748,17 @@ async function setupEnvironments(scan, config, isMultiRepo = false) {
718
748
  /**
719
749
  * Setup .env.genbox file
720
750
  */
721
- async function setupEnvFile(projectName, config, nonInteractive = false, scan, isMultiRepo = false) {
751
+ async function setupEnvFile(projectName, config, nonInteractive = false, scan, isMultiRepo = false, extraEnvVars = {}, overwriteExisting = false) {
722
752
  const envPath = path_1.default.join(process.cwd(), ENV_FILENAME);
753
+ // If overwriting, delete existing file
723
754
  if (fs_1.default.existsSync(envPath)) {
724
- console.log(chalk_1.default.dim(` ${ENV_FILENAME} already exists, skipping...`));
725
- return;
755
+ if (overwriteExisting) {
756
+ fs_1.default.unlinkSync(envPath);
757
+ }
758
+ else {
759
+ console.log(chalk_1.default.dim(` ${ENV_FILENAME} already exists, skipping...`));
760
+ return;
761
+ }
726
762
  }
727
763
  // For multi-repo: find env files in app directories
728
764
  if (isMultiRepo && scan) {
@@ -829,6 +865,18 @@ async function setupEnvFile(projectName, config, nonInteractive = false, scan, i
829
865
  }
830
866
  }
831
867
  }
868
+ // Append extra env vars (like GIT_TOKEN) to the file
869
+ if (Object.keys(extraEnvVars).length > 0 && fs_1.default.existsSync(envPath)) {
870
+ let content = fs_1.default.readFileSync(envPath, 'utf8');
871
+ // Add extra env vars section
872
+ let extraSection = '\n# === Added by genbox init ===\n';
873
+ for (const [key, value] of Object.entries(extraEnvVars)) {
874
+ // Remove any existing commented placeholder
875
+ content = content.replace(new RegExp(`^#\\s*${key}=.*$`, 'gm'), '');
876
+ extraSection += `${key}=${value}\n`;
877
+ }
878
+ fs_1.default.writeFileSync(envPath, content.trim() + '\n' + extraSection);
879
+ }
832
880
  // Add to .gitignore
833
881
  const gitignorePath = path_1.default.join(process.cwd(), '.gitignore');
834
882
  if (fs_1.default.existsSync(gitignorePath)) {
@@ -410,7 +410,7 @@ class ProfileResolver {
410
410
  const seen = new Set();
411
411
  for (const app of apps) {
412
412
  const appConfig = config.apps[app.name];
413
- // Check if app has specific repo
413
+ // Check if app has specific repo field
414
414
  if (appConfig?.repo && config.repos?.[appConfig.repo]) {
415
415
  const repoConfig = config.repos[appConfig.repo];
416
416
  if (!seen.has(repoConfig.url)) {
@@ -423,6 +423,19 @@ class ProfileResolver {
423
423
  seen.add(repoConfig.url);
424
424
  }
425
425
  }
426
+ // Auto-match: if app name matches a repo name, use that repo
427
+ else if (config.repos?.[app.name]) {
428
+ const repoConfig = config.repos[app.name];
429
+ if (!seen.has(repoConfig.url)) {
430
+ repos.push({
431
+ name: app.name,
432
+ url: repoConfig.url,
433
+ path: repoConfig.path,
434
+ branch: repoConfig.branch,
435
+ });
436
+ seen.add(repoConfig.url);
437
+ }
438
+ }
426
439
  }
427
440
  // If no specific repos, use main project repo
428
441
  if (repos.length === 0 && config.repos) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genbox",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "Genbox CLI - AI-Powered Development Environments",
5
5
  "main": "dist/index.js",
6
6
  "bin": {