genbox 1.0.44 → 1.0.45

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.
@@ -221,9 +221,9 @@ exports.createCommand = new commander_1.Command('create')
221
221
  .option('--db <mode>', 'Database mode: none, local, copy, remote')
222
222
  .option('--db-source <source>', 'Database source: staging, production')
223
223
  .option('-s, --size <size>', 'Server size: small, medium, large, xl')
224
- .option('-b, --branch <branch>', 'Git branch to checkout')
225
- .option('-n, --new-branch <name>', 'Create a new branch with this name')
226
- .option('-f, --from-branch <branch>', 'Source branch to create new branch from (defaults to current/default branch)')
224
+ .option('-b, --branch <branch>', 'Use existing git branch (skips new branch creation)')
225
+ .option('-n, --new-branch <name>', 'Create a new branch with this name (defaults to env name)')
226
+ .option('-f, --from-branch <branch>', 'Source branch to create new branch from (defaults to main)')
227
227
  .option('-y, --yes', 'Skip interactive prompts')
228
228
  .option('--dry-run', 'Show what would be created without actually creating')
229
229
  .action(async (nameArg, options) => {
@@ -286,19 +286,19 @@ exports.createCommand = new commander_1.Command('create')
286
286
  }
287
287
  // Silently continue for other errors - the create API will validate
288
288
  }
289
- // Validate branch options
289
+ // Determine branch configuration
290
+ // Default: create new branch from 'main' with name = environment name
291
+ let newBranchName = options.newBranch;
292
+ let sourceBranch = options.fromBranch;
293
+ // If -n (--new-branch) is provided without -f (--from-branch), default source to 'main'
290
294
  if (options.newBranch && !options.fromBranch) {
291
- console.error(chalk_1.default.red('Error: --new-branch (-n) requires --from-branch (-f) to specify the source branch'));
292
- console.log(chalk_1.default.dim(' Example: genbox create my-env -n feature/new -f main'));
293
- return;
295
+ sourceBranch = 'main';
296
+ console.log(chalk_1.default.dim(` Source branch not specified, using 'main'`));
294
297
  }
295
- // Auto-generate branch name if only -f is provided
296
- let newBranchName = options.newBranch;
298
+ // If -f (--from-branch) is provided without -n (--new-branch), use env name as branch name
297
299
  if (options.fromBranch && !options.newBranch) {
298
- // Generate unique branch name: {genbox-name}-{short-timestamp}
299
- const timestamp = Date.now().toString(36); // Short alphanumeric timestamp
300
- newBranchName = `${name}-${timestamp}`;
301
- console.log(chalk_1.default.dim(` Auto-generated branch name: ${newBranchName}`));
300
+ newBranchName = name;
301
+ console.log(chalk_1.default.dim(` New branch name: ${newBranchName}`));
302
302
  }
303
303
  // Build create options
304
304
  const createOptions = {
@@ -312,7 +312,7 @@ exports.createCommand = new commander_1.Command('create')
312
312
  size: options.size,
313
313
  branch: options.branch,
314
314
  newBranch: newBranchName,
315
- sourceBranch: options.fromBranch,
315
+ sourceBranch: sourceBranch,
316
316
  yes: options.yes,
317
317
  dryRun: options.dryRun,
318
318
  };
@@ -323,7 +323,20 @@ exports.createCommand = new commander_1.Command('create')
323
323
  // Interactive branch selection if no branch options were specified
324
324
  // Skip if: -b (existing branch), -f (new branch from source), -n (explicit new branch name), or -y (skip prompts)
325
325
  if (!options.branch && !options.fromBranch && !options.newBranch && !options.yes && resolved.repos.length > 0) {
326
- resolved = await promptForBranchOptions(resolved, config);
326
+ resolved = await promptForBranchOptions(resolved, config, name);
327
+ }
328
+ // Default behavior when -y (non-interactive) and no branch options: create new branch from main
329
+ if (!options.branch && !options.fromBranch && !options.newBranch && options.yes && resolved.repos.length > 0) {
330
+ resolved = {
331
+ ...resolved,
332
+ repos: resolved.repos.map(repo => ({
333
+ ...repo,
334
+ branch: name, // Branch name same as environment name
335
+ newBranch: name,
336
+ sourceBranch: 'main',
337
+ })),
338
+ };
339
+ console.log(chalk_1.default.dim(` Creating new branch '${name}' from 'main'`));
327
340
  }
328
341
  // Display resolved configuration
329
342
  displayResolvedConfig(resolved);
@@ -515,59 +528,51 @@ function displayResolvedConfig(resolved) {
515
528
  }
516
529
  /**
517
530
  * Prompt for branch options interactively
531
+ * Default behavior: create new branch from 'main' with branch name = environment name
518
532
  */
519
- async function promptForBranchOptions(resolved, config) {
533
+ async function promptForBranchOptions(resolved, config, envName) {
520
534
  // Get the default branch from config or first repo
521
535
  const defaultBranch = config.defaults?.branch || resolved.repos[0]?.branch || 'main';
522
536
  console.log(chalk_1.default.blue('=== Branch Configuration ==='));
523
- console.log(chalk_1.default.dim(`Default branch: ${defaultBranch}`));
524
537
  console.log('');
525
538
  const branchChoice = await prompts.select({
526
539
  message: 'Branch option:',
527
540
  choices: [
528
541
  {
529
- name: `Use default branch (${defaultBranch})`,
530
- value: 'default',
542
+ name: `${chalk_1.default.green('Create new branch')} '${chalk_1.default.cyan(envName)}' from 'main' ${chalk_1.default.dim('(recommended)')}`,
543
+ value: 'new-from-main',
544
+ },
545
+ {
546
+ name: `Create new branch from a different source`,
547
+ value: 'new-custom',
531
548
  },
532
549
  {
533
- name: 'Use a different existing branch',
550
+ name: 'Use an existing branch',
534
551
  value: 'existing',
535
552
  },
536
553
  {
537
- name: 'Create a new branch',
538
- value: 'new',
554
+ name: `Use default branch (${defaultBranch}) without creating new branch`,
555
+ value: 'default',
539
556
  },
540
557
  ],
541
- default: 'default',
558
+ default: 'new-from-main',
542
559
  });
543
- if (branchChoice === 'default') {
544
- // Keep resolved repos as-is
545
- return resolved;
546
- }
547
- if (branchChoice === 'existing') {
548
- const branchName = await prompts.input({
549
- message: 'Enter branch name:',
550
- default: defaultBranch,
551
- validate: (value) => {
552
- if (!value.trim())
553
- return 'Branch name is required';
554
- return true;
555
- },
556
- });
557
- // Update all repos with the selected branch
560
+ if (branchChoice === 'new-from-main') {
561
+ // Create new branch from main with name = environment name
558
562
  return {
559
563
  ...resolved,
560
564
  repos: resolved.repos.map(repo => ({
561
565
  ...repo,
562
- branch: branchName.trim(),
563
- newBranch: undefined,
564
- sourceBranch: undefined,
566
+ branch: envName,
567
+ newBranch: envName,
568
+ sourceBranch: 'main',
565
569
  })),
566
570
  };
567
571
  }
568
- if (branchChoice === 'new') {
572
+ if (branchChoice === 'new-custom') {
569
573
  const newBranchName = await prompts.input({
570
574
  message: 'New branch name:',
575
+ default: envName,
571
576
  validate: (value) => {
572
577
  if (!value.trim())
573
578
  return 'Branch name is required';
@@ -578,7 +583,7 @@ async function promptForBranchOptions(resolved, config) {
578
583
  });
579
584
  const sourceBranch = await prompts.input({
580
585
  message: 'Create from branch:',
581
- default: defaultBranch,
586
+ default: 'main',
582
587
  validate: (value) => {
583
588
  if (!value.trim())
584
589
  return 'Source branch is required';
@@ -596,6 +601,31 @@ async function promptForBranchOptions(resolved, config) {
596
601
  })),
597
602
  };
598
603
  }
604
+ if (branchChoice === 'existing') {
605
+ const branchName = await prompts.input({
606
+ message: 'Enter branch name:',
607
+ default: defaultBranch,
608
+ validate: (value) => {
609
+ if (!value.trim())
610
+ return 'Branch name is required';
611
+ return true;
612
+ },
613
+ });
614
+ // Update all repos with the selected branch
615
+ return {
616
+ ...resolved,
617
+ repos: resolved.repos.map(repo => ({
618
+ ...repo,
619
+ branch: branchName.trim(),
620
+ newBranch: undefined,
621
+ sourceBranch: undefined,
622
+ })),
623
+ };
624
+ }
625
+ if (branchChoice === 'default') {
626
+ // Keep resolved repos as-is (no new branch)
627
+ return resolved;
628
+ }
599
629
  return resolved;
600
630
  }
601
631
  /**
@@ -830,6 +860,7 @@ function buildPayload(resolved, config, publicKey, privateKey, configLoader) {
830
860
  gitToken: envVars.GIT_TOKEN,
831
861
  gitUserName: gitConfig.userName,
832
862
  gitUserEmail: gitConfig.userEmail,
863
+ installClaudeCode: config.defaults?.install_claude_code,
833
864
  envVars: resolved.env,
834
865
  apps: resolved.apps.map(a => a.name),
835
866
  appConfigs: resolved.apps.map(a => ({
@@ -665,6 +665,16 @@ exports.initCommand = new commander_1.Command('init')
665
665
  v4Config.defaults = {};
666
666
  }
667
667
  v4Config.defaults.size = serverSize;
668
+ // Ask about Claude Code installation
669
+ if (!nonInteractive && !options.fromScan) {
670
+ const installClaudeCode = await prompts.confirm({
671
+ message: 'Install Claude Code CLI on genbox servers?',
672
+ default: true,
673
+ });
674
+ if (installClaudeCode) {
675
+ v4Config.defaults.install_claude_code = true;
676
+ }
677
+ }
668
678
  // Get default branch (use detected branch or allow override)
669
679
  const detectedBranch = scan.git?.branch || 'main';
670
680
  let defaultBranch = detectedBranch;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genbox",
3
- "version": "1.0.44",
3
+ "version": "1.0.45",
4
4
  "description": "Genbox CLI - AI-Powered Development Environments",
5
5
  "main": "dist/index.js",
6
6
  "bin": {