genbox 1.0.44 → 1.0.46
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/dist/commands/create.js +77 -45
- package/dist/commands/init.js +15 -2
- package/dist/commands/scan.js +1 -1
- package/package.json +1 -1
package/dist/commands/create.js
CHANGED
|
@@ -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>', '
|
|
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
|
|
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 config default or 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
|
-
//
|
|
289
|
+
// Determine branch configuration
|
|
290
|
+
// Default: create new branch from configured default (or '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 configured default branch
|
|
290
294
|
if (options.newBranch && !options.fromBranch) {
|
|
291
|
-
|
|
292
|
-
console.log(chalk_1.default.dim(
|
|
293
|
-
return;
|
|
295
|
+
sourceBranch = config.defaults?.branch || 'main';
|
|
296
|
+
console.log(chalk_1.default.dim(` Source branch not specified, using '${sourceBranch}'`));
|
|
294
297
|
}
|
|
295
|
-
//
|
|
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
|
-
|
|
299
|
-
|
|
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:
|
|
315
|
+
sourceBranch: sourceBranch,
|
|
316
316
|
yes: options.yes,
|
|
317
317
|
dryRun: options.dryRun,
|
|
318
318
|
};
|
|
@@ -323,7 +323,21 @@ 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 configured default
|
|
329
|
+
if (!options.branch && !options.fromBranch && !options.newBranch && options.yes && resolved.repos.length > 0) {
|
|
330
|
+
const baseBranch = config.defaults?.branch || 'main';
|
|
331
|
+
resolved = {
|
|
332
|
+
...resolved,
|
|
333
|
+
repos: resolved.repos.map(repo => ({
|
|
334
|
+
...repo,
|
|
335
|
+
branch: name, // Branch name same as environment name
|
|
336
|
+
newBranch: name,
|
|
337
|
+
sourceBranch: baseBranch,
|
|
338
|
+
})),
|
|
339
|
+
};
|
|
340
|
+
console.log(chalk_1.default.dim(` Creating new branch '${name}' from '${baseBranch}'`));
|
|
327
341
|
}
|
|
328
342
|
// Display resolved configuration
|
|
329
343
|
displayResolvedConfig(resolved);
|
|
@@ -515,59 +529,51 @@ function displayResolvedConfig(resolved) {
|
|
|
515
529
|
}
|
|
516
530
|
/**
|
|
517
531
|
* Prompt for branch options interactively
|
|
532
|
+
* Default behavior: create new branch from configured default (or 'main') with branch name = environment name
|
|
518
533
|
*/
|
|
519
|
-
async function promptForBranchOptions(resolved, config) {
|
|
520
|
-
// Get the default branch from config
|
|
521
|
-
const
|
|
534
|
+
async function promptForBranchOptions(resolved, config, envName) {
|
|
535
|
+
// Get the default/base branch from config (used as source for new branches)
|
|
536
|
+
const baseBranch = config.defaults?.branch || 'main';
|
|
522
537
|
console.log(chalk_1.default.blue('=== Branch Configuration ==='));
|
|
523
|
-
console.log(chalk_1.default.dim(`Default branch: ${defaultBranch}`));
|
|
524
538
|
console.log('');
|
|
525
539
|
const branchChoice = await prompts.select({
|
|
526
540
|
message: 'Branch option:',
|
|
527
541
|
choices: [
|
|
528
542
|
{
|
|
529
|
-
name:
|
|
530
|
-
value: 'default',
|
|
543
|
+
name: `${chalk_1.default.green('Create new branch')} '${chalk_1.default.cyan(envName)}' from '${baseBranch}' ${chalk_1.default.dim('(recommended)')}`,
|
|
544
|
+
value: 'new-from-default',
|
|
545
|
+
},
|
|
546
|
+
{
|
|
547
|
+
name: `Create new branch from a different source`,
|
|
548
|
+
value: 'new-custom',
|
|
531
549
|
},
|
|
532
550
|
{
|
|
533
|
-
name: 'Use
|
|
551
|
+
name: 'Use an existing branch',
|
|
534
552
|
value: 'existing',
|
|
535
553
|
},
|
|
536
554
|
{
|
|
537
|
-
name: '
|
|
538
|
-
value: '
|
|
555
|
+
name: `Use '${baseBranch}' directly without creating new branch`,
|
|
556
|
+
value: 'default',
|
|
539
557
|
},
|
|
540
558
|
],
|
|
541
|
-
default: 'default',
|
|
559
|
+
default: 'new-from-default',
|
|
542
560
|
});
|
|
543
|
-
if (branchChoice === 'default') {
|
|
544
|
-
//
|
|
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
|
|
561
|
+
if (branchChoice === 'new-from-default') {
|
|
562
|
+
// Create new branch from configured default with name = environment name
|
|
558
563
|
return {
|
|
559
564
|
...resolved,
|
|
560
565
|
repos: resolved.repos.map(repo => ({
|
|
561
566
|
...repo,
|
|
562
|
-
branch:
|
|
563
|
-
newBranch:
|
|
564
|
-
sourceBranch:
|
|
567
|
+
branch: envName,
|
|
568
|
+
newBranch: envName,
|
|
569
|
+
sourceBranch: baseBranch,
|
|
565
570
|
})),
|
|
566
571
|
};
|
|
567
572
|
}
|
|
568
|
-
if (branchChoice === 'new') {
|
|
573
|
+
if (branchChoice === 'new-custom') {
|
|
569
574
|
const newBranchName = await prompts.input({
|
|
570
575
|
message: 'New branch name:',
|
|
576
|
+
default: envName,
|
|
571
577
|
validate: (value) => {
|
|
572
578
|
if (!value.trim())
|
|
573
579
|
return 'Branch name is required';
|
|
@@ -578,7 +584,7 @@ async function promptForBranchOptions(resolved, config) {
|
|
|
578
584
|
});
|
|
579
585
|
const sourceBranch = await prompts.input({
|
|
580
586
|
message: 'Create from branch:',
|
|
581
|
-
default:
|
|
587
|
+
default: 'main',
|
|
582
588
|
validate: (value) => {
|
|
583
589
|
if (!value.trim())
|
|
584
590
|
return 'Source branch is required';
|
|
@@ -596,6 +602,31 @@ async function promptForBranchOptions(resolved, config) {
|
|
|
596
602
|
})),
|
|
597
603
|
};
|
|
598
604
|
}
|
|
605
|
+
if (branchChoice === 'existing') {
|
|
606
|
+
const branchName = await prompts.input({
|
|
607
|
+
message: 'Enter branch name:',
|
|
608
|
+
default: baseBranch,
|
|
609
|
+
validate: (value) => {
|
|
610
|
+
if (!value.trim())
|
|
611
|
+
return 'Branch name is required';
|
|
612
|
+
return true;
|
|
613
|
+
},
|
|
614
|
+
});
|
|
615
|
+
// Update all repos with the selected branch
|
|
616
|
+
return {
|
|
617
|
+
...resolved,
|
|
618
|
+
repos: resolved.repos.map(repo => ({
|
|
619
|
+
...repo,
|
|
620
|
+
branch: branchName.trim(),
|
|
621
|
+
newBranch: undefined,
|
|
622
|
+
sourceBranch: undefined,
|
|
623
|
+
})),
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
if (branchChoice === 'default') {
|
|
627
|
+
// Keep resolved repos as-is (no new branch)
|
|
628
|
+
return resolved;
|
|
629
|
+
}
|
|
599
630
|
return resolved;
|
|
600
631
|
}
|
|
601
632
|
/**
|
|
@@ -830,6 +861,7 @@ function buildPayload(resolved, config, publicKey, privateKey, configLoader) {
|
|
|
830
861
|
gitToken: envVars.GIT_TOKEN,
|
|
831
862
|
gitUserName: gitConfig.userName,
|
|
832
863
|
gitUserEmail: gitConfig.userEmail,
|
|
864
|
+
installClaudeCode: config.defaults?.install_claude_code,
|
|
833
865
|
envVars: resolved.env,
|
|
834
866
|
apps: resolved.apps.map(a => a.name),
|
|
835
867
|
appConfigs: resolved.apps.map(a => ({
|
package/dist/commands/init.js
CHANGED
|
@@ -665,12 +665,25 @@ exports.initCommand = new commander_1.Command('init')
|
|
|
665
665
|
v4Config.defaults = {};
|
|
666
666
|
}
|
|
667
667
|
v4Config.defaults.size = serverSize;
|
|
668
|
-
//
|
|
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
|
+
}
|
|
678
|
+
// Get default/base branch (source branch for creating new environment branches)
|
|
669
679
|
const detectedBranch = scan.git?.branch || 'main';
|
|
670
680
|
let defaultBranch = detectedBranch;
|
|
671
681
|
if (!nonInteractive && !options.fromScan) {
|
|
682
|
+
console.log('');
|
|
683
|
+
console.log(chalk_1.default.dim(' When creating environments, a new branch is created from this base branch.'));
|
|
684
|
+
console.log(chalk_1.default.dim(' The new branch name defaults to the environment name.'));
|
|
672
685
|
const branchInput = await prompts.input({
|
|
673
|
-
message: '
|
|
686
|
+
message: 'Base branch for new environment branches:',
|
|
674
687
|
default: detectedBranch,
|
|
675
688
|
});
|
|
676
689
|
defaultBranch = branchInput || detectedBranch;
|
package/dist/commands/scan.js
CHANGED
|
@@ -1132,7 +1132,7 @@ function showSummary(detected) {
|
|
|
1132
1132
|
if (detected.git?.remote) {
|
|
1133
1133
|
console.log(`\n Git: ${detected.git.provider || 'git'} (${detected.git.type})`);
|
|
1134
1134
|
console.log(` Remote: ${chalk_1.default.dim(detected.git.remote)}`);
|
|
1135
|
-
console.log(` Branch: ${chalk_1.default.cyan(detected.git.branch || 'main')} ${chalk_1.default.dim('←
|
|
1135
|
+
console.log(` Branch: ${chalk_1.default.cyan(detected.git.branch || 'main')} ${chalk_1.default.dim('← base branch for new environment branches')}`);
|
|
1136
1136
|
}
|
|
1137
1137
|
// Per-app git repos (for multi-repo workspaces)
|
|
1138
1138
|
const appsWithGit = Object.entries(detected.apps).filter(([, app]) => app.git);
|