@base44-preview/cli 0.1.14-pr.621.e6723c1 → 0.1.14-pr.623.3dbbbbb

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/cli/index.js CHANGED
@@ -246959,6 +246959,39 @@ function showPlainError(error) {
246959
246959
  }
246960
246960
  }
246961
246961
 
246962
+ // src/core/resources/branch/api.ts
246963
+ var BranchesSchema = array(object({
246964
+ id: string2().min(1),
246965
+ branch_name: string2(),
246966
+ status: _enum(["active", "merged", "deleted"])
246967
+ }));
246968
+ async function listBranches() {
246969
+ let response;
246970
+ try {
246971
+ response = await getAppClient().get("branches", { timeout: 30000 });
246972
+ } catch (error) {
246973
+ throw await ApiError.fromHttpError(error, "listing branches");
246974
+ }
246975
+ const result = BranchesSchema.safeParse(await response.json());
246976
+ if (!result.success) {
246977
+ throw new SchemaValidationError("Invalid branches response from server", result.error);
246978
+ }
246979
+ return result.data.filter((branch) => branch.status === "active");
246980
+ }
246981
+ async function resolveBranchName(name) {
246982
+ if (name === "main")
246983
+ return;
246984
+ const branches = await listBranches();
246985
+ const matches = branches.filter((branch) => branch.branch_name === name);
246986
+ if (matches.length === 0) {
246987
+ throw new InvalidInputError(`Branch "${name}" was not found in this app.`);
246988
+ }
246989
+ if (matches.length > 1) {
246990
+ throw new InvalidInputError(`Branch name "${name}" is ambiguous. Give the branches unique names before retrying.`);
246991
+ }
246992
+ return matches[0].id;
246993
+ }
246994
+
246962
246995
  // src/cli/utils/command/Base44Command.ts
246963
246996
  function writeJsonSuccess(result) {
246964
246997
  if (result.stdout) {
@@ -247005,7 +247038,8 @@ class Base44Command extends Command2 {
247005
247038
  this._commandOptions = {
247006
247039
  requireAuth: options?.requireAuth ?? true,
247007
247040
  requireAppContext: options?.requireAppContext ?? true,
247008
- fullBanner: options?.fullBanner ?? false
247041
+ fullBanner: options?.fullBanner ?? false,
247042
+ supportsBranch: options?.supportsBranch ?? false
247009
247043
  };
247010
247044
  }
247011
247045
  setContext(context) {
@@ -247026,6 +247060,13 @@ class Base44Command extends Command2 {
247026
247060
  }
247027
247061
  const upgradeCheckPromise = startUpgradeCheck();
247028
247062
  try {
247063
+ const { branch } = this.optsWithGlobals();
247064
+ if (branch !== undefined && !this._commandOptions.supportsBranch) {
247065
+ throw new InvalidInputError("--branch is not supported by this command. Use sandbox commands to read or edit branch files; no app changes were made.");
247066
+ }
247067
+ if (branch !== undefined && !branch.trim()) {
247068
+ throw new InvalidInputError("--branch must not be empty.");
247069
+ }
247029
247070
  if (this._commandOptions.requireAuth) {
247030
247071
  await ensureAuth(this.context);
247031
247072
  }
@@ -247033,7 +247074,8 @@ class Base44Command extends Command2 {
247033
247074
  const { appId } = this.optsWithGlobals();
247034
247075
  await ensureAppContext(this.context, { appId });
247035
247076
  }
247036
- const result = await fn(this.context, ...args) ?? {};
247077
+ const resolvedBranchId = branch !== undefined ? await resolveBranchName(branch) : undefined;
247078
+ const result = await fn({ ...this.context, branchId: resolvedBranchId }, ...args) ?? {};
247037
247079
  if (!quiet) {
247038
247080
  await showCommandEnd(result, upgradeCheckPromise, this.context.distribution);
247039
247081
  } else if (jsonMode) {
@@ -247881,6 +247923,31 @@ function getWhoamiCommand() {
247881
247923
  return new Base44Command("whoami", { requireAppContext: false }).description("Display current authenticated user").action(whoami);
247882
247924
  }
247883
247925
 
247926
+ // src/cli/commands/branches/index.ts
247927
+ async function listBranchesAction({
247928
+ log,
247929
+ runTask,
247930
+ jsonMode
247931
+ }) {
247932
+ const remote = await runTask("Fetching branches", () => listBranches());
247933
+ const branches = [
247934
+ { name: "main", status: "active" },
247935
+ ...remote.map((branch) => ({
247936
+ name: branch.branch_name,
247937
+ status: branch.status
247938
+ }))
247939
+ ];
247940
+ if (jsonMode)
247941
+ return { stdout: `${JSON.stringify({ branches })}
247942
+ ` };
247943
+ for (const branch of branches)
247944
+ log.message(`${branch.name} (${branch.status})`);
247945
+ return { outroMessage: `${branches.length} branches` };
247946
+ }
247947
+ function getBranchesCommand() {
247948
+ return new Command2("branches").description("Discover an app's branches").addCommand(new Base44Command("list").description("List main and active branch names for use with --branch").action(listBranchesAction));
247949
+ }
247950
+
247884
247951
  // ../../node_modules/open/index.js
247885
247952
  import process20 from "node:process";
247886
247953
  import path16 from "node:path";
@@ -250294,13 +250361,16 @@ function parsePositiveInt(value, flagName) {
250294
250361
  }
250295
250362
 
250296
250363
  // src/cli/commands/sandbox/checkpoint.ts
250297
- async function checkpointAction({ runTask }, options) {
250364
+ async function checkpointAction({ runTask, branchId }, options) {
250298
250365
  const { id: appId } = getAppContext();
250299
- const result = await runTask("Creating checkpoint", () => createCheckpoint(appId, { name: options.name }));
250366
+ const result = await runTask("Creating checkpoint", () => createCheckpoint(appId, {
250367
+ name: options.name,
250368
+ branch_id: branchId
250369
+ }));
250300
250370
  return { outroMessage: "Created checkpoint", stdout: toJsonStdout(result) };
250301
250371
  }
250302
250372
  function getSandboxCheckpointCommand() {
250303
- return new Base44Command("checkpoint").description("Create a restore-point checkpoint of an app's remote sandbox").option("--name <name>", "Optional message/title for the checkpoint (defaults to an auto-generated title)").addHelpText("after", `
250373
+ return new Base44Command("checkpoint", { supportsBranch: true }).description("Create a restore-point checkpoint of an app's remote sandbox").option("--name <name>", "Optional message/title for the checkpoint (defaults to an auto-generated title)").addHelpText("after", `
250304
250374
  Examples:
250305
250375
  $ base44 sandbox checkpoint
250306
250376
  $ base44 sandbox checkpoint --name "before refactor"`).action(checkpointAction);
@@ -250325,18 +250395,23 @@ function parseEdits(raw) {
250325
250395
  }
250326
250396
  return result.data;
250327
250397
  }
250328
- async function editFileAction({ runTask }, path, options) {
250398
+ async function editFileAction({ runTask, branchId }, path, options) {
250329
250399
  const { id: appId } = getAppContext();
250330
250400
  const raw = await resolveFlagOrStdin(options.editsJson, "--edits-json");
250331
250401
  const edits = parseEdits(raw);
250332
- const result = await runTask(options.dryRun ? "Previewing edit" : "Editing file", () => editFile(appId, { path, edits, dry_run: options.dryRun }));
250402
+ const result = await runTask(options.dryRun ? "Previewing edit" : "Editing file", () => editFile(appId, {
250403
+ path,
250404
+ edits,
250405
+ dry_run: options.dryRun,
250406
+ branch_id: branchId
250407
+ }));
250333
250408
  return {
250334
250409
  outroMessage: options.dryRun ? "Previewed edit" : "Edited file",
250335
250410
  stdout: toJsonStdout(result)
250336
250411
  };
250337
250412
  }
250338
250413
  function getSandboxEditFileCommand() {
250339
- return new Base44Command("edit").description("Apply exact old→new string edits to a file in the sandbox").argument("<path>", "File path relative to the app root").option("--edits-json <json>", "JSON array of edits (if omitted, read from stdin)").option("--dry-run", "Return the unified diff without writing").addHelpText("after", `
250414
+ return new Base44Command("edit", { supportsBranch: true }).description("Apply exact old→new string edits to a file in the sandbox").argument("<path>", "File path relative to the app root").option("--edits-json <json>", "JSON array of edits (if omitted, read from stdin)").option("--dry-run", "Return the unified diff without writing").addHelpText("after", `
250340
250415
  Each edit is { "old_text": "...", "new_text": "...", "replace_all"?: true }.
250341
250416
 
250342
250417
  Examples:
@@ -250345,7 +250420,7 @@ Examples:
250345
250420
  }
250346
250421
 
250347
250422
  // src/cli/commands/sandbox/grep.ts
250348
- async function grepAction({ runTask }, pattern, options) {
250423
+ async function grepAction({ runTask, branchId }, pattern, options) {
250349
250424
  const { id: appId } = getAppContext();
250350
250425
  const maxResults = parsePositiveInt(options.maxResults, "--max-results");
250351
250426
  const result = await runTask("Searching files", () => grep(appId, {
@@ -250354,20 +250429,22 @@ async function grepAction({ runTask }, pattern, options) {
250354
250429
  is_regex: options.regex,
250355
250430
  case_sensitive: options.caseSensitive,
250356
250431
  glob: options.glob,
250357
- max_results: maxResults
250432
+ max_results: maxResults,
250433
+ branch_id: branchId
250358
250434
  }));
250359
250435
  return { outroMessage: "Searched files", stdout: toJsonStdout(result) };
250360
250436
  }
250361
250437
  function getSandboxGrepCommand() {
250362
- return new Base44Command("grep").description("Search files for a pattern in an app's remote sandbox").argument("<pattern>", "Search pattern").option("--path <path>", "Subtree to search, relative to the app root").option("--no-regex", "Treat the pattern as a literal string, not a regex").option("--case-sensitive", "Case-sensitive match").option("--glob <glob>", 'File glob filter, e.g. "*.tsx"').option("--max-results <n>", "Maximum number of match lines to return").action(grepAction);
250438
+ return new Base44Command("grep", { supportsBranch: true }).description("Search files for a pattern in an app's remote sandbox").argument("<pattern>", "Search pattern").option("--path <path>", "Subtree to search, relative to the app root").option("--no-regex", "Treat the pattern as a literal string, not a regex").option("--case-sensitive", "Case-sensitive match").option("--glob <glob>", 'File glob filter, e.g. "*.tsx"').option("--max-results <n>", "Maximum number of match lines to return").action(grepAction);
250363
250439
  }
250364
250440
 
250365
250441
  // src/cli/commands/sandbox/list-directory.ts
250366
- async function listDirectoryAction({ runTask }, path, options) {
250442
+ async function listDirectoryAction({ runTask, branchId }, path, options) {
250367
250443
  const { id: appId } = getAppContext();
250368
250444
  const maxDepth = parsePositiveInt(options.maxDepth, "--max-depth");
250369
250445
  const result = await runTask("Listing directory", () => listDirectory(appId, {
250370
250446
  path,
250447
+ branch_id: branchId,
250371
250448
  recursive: options.recursive,
250372
250449
  max_depth: maxDepth,
250373
250450
  include_hidden: options.includeHidden
@@ -250375,45 +250452,55 @@ async function listDirectoryAction({ runTask }, path, options) {
250375
250452
  return { outroMessage: "Listed directory", stdout: toJsonStdout(result) };
250376
250453
  }
250377
250454
  function getSandboxListDirectoryCommand() {
250378
- return new Base44Command("ls").description("List directory entries in an app's remote sandbox").argument("[path]", "Directory relative to the app root (default: app root)").option("--recursive", "List nested entries").option("--max-depth <n>", "Max depth when recursive (1-10, default 3)").option("--include-hidden", "Include dotfiles").action(listDirectoryAction);
250455
+ return new Base44Command("ls", { supportsBranch: true }).description("List directory entries in an app's remote sandbox").argument("[path]", "Directory relative to the app root (default: app root)").option("--recursive", "List nested entries").option("--max-depth <n>", "Max depth when recursive (1-10, default 3)").option("--include-hidden", "Include dotfiles").action(listDirectoryAction);
250379
250456
  }
250380
250457
 
250381
250458
  // src/cli/commands/sandbox/read-file.ts
250382
- async function readFileAction({ runTask }, paths, options) {
250459
+ async function readFileAction({ runTask, branchId }, paths, options) {
250383
250460
  const { id: appId } = getAppContext();
250384
250461
  const offset = parsePositiveInt(options.offset, "--offset");
250385
250462
  const limit = parsePositiveInt(options.limit, "--limit");
250386
- const result = await runTask("Reading file", () => readFile4(appId, { paths, offset, limit }));
250463
+ const result = await runTask("Reading file", () => readFile4(appId, { paths, offset, limit, branch_id: branchId }));
250387
250464
  return { outroMessage: "Read file", stdout: toJsonStdout(result) };
250388
250465
  }
250389
250466
  function getSandboxReadFileCommand() {
250390
- return new Base44Command("read").description("Read file contents from an app's remote sandbox").argument("<paths...>", "One or more file paths relative to the app root").option("--offset <n>", "1-based start line").option("--limit <n>", "Max lines to return from offset").action(readFileAction);
250467
+ return new Base44Command("read", { supportsBranch: true }).description("Read file contents from an app's remote sandbox").argument("<paths...>", "One or more file paths relative to the app root").option("--offset <n>", "1-based start line").option("--limit <n>", "Max lines to return from offset").action(readFileAction);
250391
250468
  }
250392
250469
 
250393
250470
  // src/cli/commands/sandbox/run-command.ts
250394
- async function runCommandAction({ runTask }, commandParts, options) {
250471
+ async function runCommandAction({ runTask, branchId }, commandParts, options) {
250395
250472
  const { id: appId } = getAppContext();
250396
250473
  const timeoutMs = parsePositiveInt(options.timeoutMs, "--timeout-ms");
250397
250474
  const command = commandParts.join(" ");
250398
- const result = await runTask("Running command", () => runCommand(appId, { command, cwd: options.cwd, timeout_ms: timeoutMs }));
250475
+ const result = await runTask("Running command", () => runCommand(appId, {
250476
+ command,
250477
+ cwd: options.cwd,
250478
+ timeout_ms: timeoutMs,
250479
+ branch_id: branchId
250480
+ }));
250399
250481
  return { outroMessage: "Ran command", stdout: toJsonStdout(result) };
250400
250482
  }
250401
250483
  function getSandboxRunCommandCommand() {
250402
- return new Base44Command("run").description("Run a shell command in an app's remote sandbox").argument("<command...>", "Shell command to execute (quote to keep as one)").option("--cwd <path>", "Working directory relative to the app root").option("--timeout-ms <n>", "Timeout in milliseconds (default 120000, max 600000)").addHelpText("after", `
250484
+ return new Base44Command("run", { supportsBranch: true }).description("Run a shell command in an app's remote sandbox").argument("<command...>", "Shell command to execute (quote to keep as one)").option("--cwd <path>", "Working directory relative to the app root").option("--timeout-ms <n>", "Timeout in milliseconds (default 120000, max 600000)").addHelpText("after", `
250403
250485
  Examples:
250404
250486
  $ base44 sandbox run "npm test"
250405
250487
  $ base44 sandbox run ls -la --cwd src`).action(runCommandAction);
250406
250488
  }
250407
250489
 
250408
250490
  // src/cli/commands/sandbox/write-file.ts
250409
- async function writeFileAction({ runTask }, path, options) {
250491
+ async function writeFileAction({ runTask, branchId }, path, options) {
250410
250492
  const { id: appId } = getAppContext();
250411
250493
  const content = await resolveFlagOrStdin(options.content, "--content");
250412
- const result = await runTask("Writing file", () => writeFile2(appId, { path, content, overwrite: options.overwrite }));
250494
+ const result = await runTask("Writing file", () => writeFile2(appId, {
250495
+ path,
250496
+ content,
250497
+ overwrite: options.overwrite,
250498
+ branch_id: branchId
250499
+ }));
250413
250500
  return { outroMessage: "Wrote file", stdout: toJsonStdout(result) };
250414
250501
  }
250415
250502
  function getSandboxWriteFileCommand() {
250416
- return new Base44Command("write").description("Create or overwrite a file in an app's remote sandbox").argument("<path>", "File path relative to the app root").option("--content <content>", "File content (if omitted, read from stdin)").option("--overwrite", "Overwrite the file if it already exists").addHelpText("after", `
250503
+ return new Base44Command("write", { supportsBranch: true }).description("Create or overwrite a file in an app's remote sandbox").argument("<path>", "File path relative to the app root").option("--content <content>", "File content (if omitted, read from stdin)").option("--overwrite", "Overwrite the file if it already exists").addHelpText("after", `
250417
250504
  Examples:
250418
250505
  $ echo "hello" | base44 sandbox write notes.txt
250419
250506
  $ base44 sandbox write notes.txt --content "hello" --overwrite`).action(writeFileAction);
@@ -255407,7 +255494,7 @@ function getEjectCommand() {
255407
255494
  // src/cli/program.ts
255408
255495
  function createProgram(context) {
255409
255496
  const program = new Command2;
255410
- program.name("base44").description("Base44 CLI - Unified interface for managing Base44 applications").version(package_default.version).addOption(new Option2("--app-id <id>", "Base44 app ID to use").env(BASE44_APP_ID_ENV_VAR)).addOption(new Option2("--json", "Output machine-readable JSON to stdout (status/logs go to stderr)"));
255497
+ program.name("base44").description("Base44 CLI - Unified interface for managing Base44 applications").version(package_default.version).option("--branch <name>", "Target an app branch by exact name (sandbox commands only)").addOption(new Option2("--app-id <id>", "Base44 app ID to use").env(BASE44_APP_ID_ENV_VAR)).addOption(new Option2("--json", "Output machine-readable JSON to stdout (status/logs go to stderr)"));
255411
255498
  program.configureHelp({
255412
255499
  sortSubcommands: true
255413
255500
  });
@@ -255436,6 +255523,7 @@ function createProgram(context) {
255436
255523
  program.addCommand(getWorkflowsCommand());
255437
255524
  program.addCommand(getSecretsCommand());
255438
255525
  program.addCommand(getSandboxCommand());
255526
+ program.addCommand(getBranchesCommand());
255439
255527
  program.addCommand(getAuthCommand());
255440
255528
  program.addCommand(getSiteCommand());
255441
255529
  program.addCommand(getTypesCommand());
@@ -259489,4 +259577,4 @@ export {
259489
259577
  runCLI
259490
259578
  };
259491
259579
 
259492
- //# debugId=08F7780409C3464664756E2164756E21
259580
+ //# debugId=DB7474A6029C0A5A64756E2164756E21