@base44-preview/cli 0.1.15-pr.630.ca4815b → 0.1.15-pr.630.f6b9987

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
@@ -269452,18 +269452,27 @@ function getAgentsCommand() {
269452
269452
 
269453
269453
  // src/core/model.ts
269454
269454
  var MODELS = [
269455
- { name: "default", id: null, note: "let Base44 choose" },
269455
+ {
269456
+ name: "Automatic",
269457
+ id: null,
269458
+ note: "matched with the best model",
269459
+ aliases: ["default", "auto"]
269460
+ },
269456
269461
  { name: "Opus 5", id: "claude_opus_5" },
269457
269462
  { name: "Sonnet 5", id: "claude-sonnet-5" },
269458
269463
  { name: "Fable 5", id: "claude_fable_5", note: "uses more credits" },
269459
269464
  { name: "GPT-5.6 Sol", id: "gpt_5_6_sol" },
269460
- { name: "Gemini 3.8 Flash", id: "gemini_3_8_flash", note: "fast" },
269465
+ {
269466
+ name: "Gemini 3.8 Flash",
269467
+ id: "gemini_3_8_flash",
269468
+ note: "fast responses for everyday tasks"
269469
+ },
269461
269470
  { name: "Base 1", id: "base1" }
269462
269471
  ];
269463
269472
  var fold = (s) => s.toLowerCase().replace(/[^a-z0-9]/g, "");
269464
269473
  function resolvePick(input) {
269465
269474
  const key = fold(input);
269466
- const byExact = MODELS.find((m) => fold(m.name) === key || m.id && fold(m.id) === key);
269475
+ const byExact = MODELS.find((m) => fold(m.name) === key || m.id && fold(m.id) === key || m.aliases?.some((a) => fold(a) === key));
269467
269476
  if (byExact)
269468
269477
  return byExact;
269469
269478
  const byContains = MODELS.filter((m) => fold(m.name).includes(key) || m.id && fold(m.id).includes(key));
@@ -269491,7 +269500,7 @@ async function saveBuilderModel(userId, modelId) {
269491
269500
  throw await ApiError.fromHttpError(error, "saving your model choice");
269492
269501
  }
269493
269502
  }
269494
- var displayName = (id) => MODELS.find((m) => m.id === id)?.name ?? id ?? "default";
269503
+ var displayName = (id) => MODELS.find((m) => m.id === id)?.name ?? id ?? "Automatic";
269495
269504
 
269496
269505
  // src/cli/commands/app/model.ts
269497
269506
  async function modelAction({ log, jsonMode }, input) {
@@ -269537,7 +269546,7 @@ function getModelCommand() {
269537
269546
 
269538
269547
  // src/cli/commands/app/shared.ts
269539
269548
  import { mkdir as mkdir3, writeFile as writeFile2 } from "node:fs/promises";
269540
- import { join as join21 } from "node:path";
269549
+ import { basename as basename6, join as join21, relative as relative6, resolve as resolve6 } from "node:path";
269541
269550
 
269542
269551
  // src/cli/commands/code/render.ts
269543
269552
  var TOOL_ALIASES = {
@@ -269974,11 +269983,17 @@ async function createAndLinkApp(options) {
269974
269983
  if (options.name && !APP_NAME_RE.test(options.name)) {
269975
269984
  throw new InvalidInputError("The name becomes a directory — letters, digits, dots, dashes and underscores only.");
269976
269985
  }
269977
- const name = options.name ?? (options.importRepo ? repoBasename(options.importRepo) : inventAppName(options.prompt));
269978
- const targetDir = join21(process.cwd(), name);
269986
+ const cwd = process.cwd();
269987
+ const fallbackName = () => options.importRepo ? repoBasename(options.importRepo) : inventAppName(options.prompt);
269988
+ const chosenDir = options.path ? resolve6(cwd, options.path) : await isDirEmpty(cwd) ? cwd : undefined;
269989
+ const dirBase = chosenDir ? basename6(chosenDir) : undefined;
269990
+ const name = options.name ?? (dirBase && APP_NAME_RE.test(dirBase) ? dirBase : fallbackName());
269991
+ const targetDir = chosenDir ?? join21(cwd, name);
269992
+ const here = targetDir === cwd;
269993
+ const dirName = here ? "." : relative6(cwd, targetDir) || name;
269979
269994
  await mkdir3(targetDir, { recursive: true });
269980
269995
  if (await appConfigExists(targetDir)) {
269981
- throw new InvalidInputError(`./${name} is already linked to a Base44 app. Pick another name.`);
269996
+ throw new InvalidInputError(here ? "This directory is already linked to a Base44 app. Run `base44 code` here to keep building it, or pass --path for a new one." : `./${dirName} is already linked to a Base44 app. Pick another name or --path.`);
269982
269997
  }
269983
269998
  const created = options.importRepo ? await createImportedApp({
269984
269999
  appName: name,
@@ -270002,16 +270017,18 @@ async function createAndLinkApp(options) {
270002
270017
  id: created.id,
270003
270018
  editorUrl: `${getBase44ApiUrl()}/apps/${created.id}/editor/preview`,
270004
270019
  repoUrl: created.imported_repo_url ?? undefined,
270005
- dirName: name,
270006
- targetDir
270020
+ dirName,
270021
+ targetDir,
270022
+ here
270007
270023
  };
270008
270024
  }
270009
270025
  function nextStepsLines(app) {
270026
+ const cd = app.here ? "" : `cd ${app.dirName} && `;
270010
270027
  return [
270011
270028
  "",
270012
- `${source_default.bold("Your app lives in")} ./${app.dirName}`,
270013
- source_default.dim(` cd ${app.dirName} && base44 code # keep building with the agent`),
270014
- source_default.dim(` cd ${app.dirName} && base44 app send "…" # one non-interactive turn`)
270029
+ `${source_default.bold("Your app lives in")} ${app.here ? "./ (this directory)" : `./${app.dirName}`}`,
270030
+ source_default.dim(` ${cd}base44 code # keep building with the agent`),
270031
+ source_default.dim(` ${cd}base44 app send "…" # one non-interactive turn`)
270015
270032
  ];
270016
270033
  }
270017
270034
  async function githubReauthLines(error) {
@@ -270244,7 +270261,8 @@ async function newAction({ log, runTask, jsonMode }, prompt, options) {
270244
270261
  importRepo: options.import,
270245
270262
  mode: options.mode,
270246
270263
  repoName: options.repoName,
270247
- fromBranch: options.fromBranch
270264
+ fromBranch: options.fromBranch,
270265
+ path: options.path
270248
270266
  }));
270249
270267
  } catch (error) {
270250
270268
  for (const line of await githubReauthLines(error) ?? [])
@@ -270255,7 +270273,7 @@ async function newAction({ log, runTask, jsonMode }, prompt, options) {
270255
270273
  if (app.repoUrl)
270256
270274
  log.message(source_default.dim(`repo ${app.repoUrl}`));
270257
270275
  log.message(source_default.dim(`editor ${app.editorUrl}`));
270258
- log.message(source_default.dim(`linked ./${app.dirName}`));
270276
+ log.message(source_default.dim(`linked ${app.here ? "./ (this directory)" : `./${app.dirName}`}`));
270259
270277
  }
270260
270278
  let finalState;
270261
270279
  let previewUrl;
@@ -270314,7 +270332,7 @@ async function newAction({ log, runTask, jsonMode }, prompt, options) {
270314
270332
  }
270315
270333
  function getNewCommand() {
270316
270334
  const command = new Base44Command("new", { requireAppContext: false });
270317
- command.description("Create an app and start building: from a prompt (the Base44 template), or over an existing GitHub repo with --import").argument("[prompt]", "What to build; the first agent turn starts immediately").option("--import <repo>", "Build over an existing GitHub repository instead of the template").option("--mode <mode>", "How to import: direct, fork, or copy (default: direct)").option("--name <name>", "Directory and app name (invented when omitted)").option("--repo-name <name>", "Name for the new GitHub repo when forking/copying").option("--from-branch <name>", "Import a specific branch of the repo").action(newAction);
270335
+ command.description("Create an app and start building: from a prompt (the Base44 template), or over an existing GitHub repo with --import").argument("[prompt]", "What to build; the first agent turn starts immediately").option("--import <repo>", "Build over an existing GitHub repository instead of the template").option("--mode <mode>", "How to import: direct, fork, or copy (default: direct)").option("--name <name>", "Directory and app name (invented when omitted)").option("--path <dir>", "Directory to link (default: the current directory when empty, else ./<name>)").option("--repo-name <name>", "Name for the new GitHub repo when forking/copying").option("--from-branch <name>", "Import a specific branch of the repo").action(newAction);
270318
270336
  return command;
270319
270337
  }
270320
270338
 
@@ -270524,7 +270542,7 @@ function getAuthPushCommand() {
270524
270542
  }
270525
270543
 
270526
270544
  // src/cli/commands/auth/social-login.ts
270527
- import { dirname as dirname17, join as join24, resolve as resolve6 } from "node:path";
270545
+ import { dirname as dirname17, join as join24, resolve as resolve7 } from "node:path";
270528
270546
  var PROVIDER_LABELS = {
270529
270547
  google: "Google",
270530
270548
  microsoft: "Microsoft",
@@ -270564,7 +270582,7 @@ async function socialLoginAction({ log, isNonInteractive, runTask }, provider, a
270564
270582
  let clientSecret;
270565
270583
  if (useCustomOAuth && oauth && oauthCli && hasSecretOptions(options)) {
270566
270584
  if (options.envFile) {
270567
- const secrets = await parseEnvFile(resolve6(options.envFile));
270585
+ const secrets = await parseEnvFile(resolve7(options.envFile));
270568
270586
  const value = secrets[oauthCli.envVar];
270569
270587
  if (!value) {
270570
270588
  throw new InvalidInputError(`Key "${oauthCli.envVar}" not found in ${options.envFile}.`);
@@ -270620,7 +270638,7 @@ function getSocialLoginCommand() {
270620
270638
  }
270621
270639
 
270622
270640
  // src/cli/commands/auth/sso.ts
270623
- import { dirname as dirname18, join as join25, resolve as resolve7 } from "node:path";
270641
+ import { dirname as dirname18, join as join25, resolve as resolve8 } from "node:path";
270624
270642
  var SSOConfigFileSchema = object({
270625
270643
  provider: _enum(Object.values(KNOWN_SSO_PROVIDERS)),
270626
270644
  clientId: string2(),
@@ -270636,7 +270654,7 @@ var SSOConfigFileSchema = object({
270636
270654
  ssoName: string2().optional()
270637
270655
  });
270638
270656
  async function loadSSOConfigFile(filePath) {
270639
- const resolved = resolve7(filePath);
270657
+ const resolved = resolve8(filePath);
270640
270658
  const raw = await readJsonFile(resolved);
270641
270659
  const result = SSOConfigFileSchema.safeParse(raw);
270642
270660
  if (!result.success) {
@@ -270724,7 +270742,7 @@ async function ssoEnableAction({ isNonInteractive, runTask }, options) {
270724
270742
  }
270725
270743
  let clientSecret;
270726
270744
  if (merged.envFile && !merged.clientSecret) {
270727
- const secrets = await parseEnvFile(resolve7(merged.envFile));
270745
+ const secrets = await parseEnvFile(resolve8(merged.envFile));
270728
270746
  const value = secrets.sso_client_secret;
270729
270747
  if (!value) {
270730
270748
  throw new InvalidInputError(`Key "sso_client_secret" not found in ${merged.envFile}.`);
@@ -276589,21 +276607,21 @@ async function runGenesisSession(options) {
276589
276607
 
276590
276608
  // src/cli/commands/code/index.ts
276591
276609
  var BRAND_ORANGE2 = "#E86B3C";
276592
- async function bootstrapApp(prompt, footer, emit, onCreated, importRepo) {
276610
+ async function bootstrapApp(prompt, footer, emit, onCreated, importRepo, path) {
276593
276611
  let app;
276594
276612
  try {
276595
- app = await createAndLinkApp({ prompt, importRepo });
276613
+ app = await createAndLinkApp({ prompt, importRepo, path });
276596
276614
  } catch (error) {
276597
276615
  for (const line of await githubReauthLines(error) ?? [])
276598
276616
  emit(line);
276599
276617
  throw error;
276600
276618
  }
276601
276619
  onCreated(app);
276602
- footer.push(source_default.dim(`dir ./${app.dirName}`));
276620
+ footer.push(source_default.dim(`dir ${app.here ? "./" : `./${app.dirName}`}`));
276603
276621
  if (app.repoUrl)
276604
276622
  footer.push(terminalLink("repo", app.repoUrl));
276605
276623
  footer.push(terminalLink("editor", app.editorUrl));
276606
- emit(source_default.dim(`linked ./${app.dirName} (cd ${app.dirName} after the session)`));
276624
+ emit(source_default.dim(app.here ? "linked ./ (this directory)" : `linked ./${app.dirName} (cd ${app.dirName} after the session)`));
276607
276625
  const branchId = await resolveActiveBranchId().catch(() => {
276608
276626
  return;
276609
276627
  });
@@ -276637,8 +276655,8 @@ async function codeAction({ log }, options) {
276637
276655
  linked = true;
276638
276656
  } catch {}
276639
276657
  if (linked) {
276640
- if (options.import) {
276641
- throw new InvalidInputError("--import creates a new app; run it outside a linked project.");
276658
+ if (options.import || options.path) {
276659
+ throw new InvalidInputError("--import and --path create a new app; run them outside a linked project.");
276642
276660
  }
276643
276661
  const branchId = await resolveActiveBranchId().catch(() => {
276644
276662
  return;
@@ -276666,7 +276684,7 @@ async function codeAction({ log }, options) {
276666
276684
  footer,
276667
276685
  createApp: (prompt, emit) => bootstrapApp(prompt, footer, emit, (app) => {
276668
276686
  created = app;
276669
- }, options.import)
276687
+ }, options.import, options.path)
276670
276688
  });
276671
276689
  if (!created) {
276672
276690
  return { outroMessage: "Session closed. No app was created." };
@@ -276678,7 +276696,7 @@ async function codeAction({ log }, options) {
276678
276696
  }
276679
276697
  function getCodeCommand() {
276680
276698
  const command = new Base44Command("code", { requireAppContext: false });
276681
- command.description("Open Base44 Code: an interactive agent session — in an empty directory your first prompt creates the app (add --import <repo> to build over an existing repository)").option("--import <repo>", "Build over an existing GitHub repository instead of the Base44 template").action(codeAction);
276699
+ command.description("Open Base44 Code: an interactive agent session — in an empty directory your first prompt creates the app (add --import <repo> to build over an existing repository)").option("--import <repo>", "Build over an existing GitHub repository instead of the Base44 template").option("--path <dir>", "Directory to link the new app to (default: the current directory when empty, else ./<name>)").action(codeAction);
276682
276700
  return command;
276683
276701
  }
276684
276702
 
@@ -277476,10 +277494,10 @@ function getConnectorsListAvailableCommand() {
277476
277494
  }
277477
277495
 
277478
277496
  // src/cli/commands/connectors/pull.ts
277479
- import { dirname as dirname19, join as join27, resolve as resolve8 } from "node:path";
277497
+ import { dirname as dirname19, join as join27, resolve as resolve9 } from "node:path";
277480
277498
  async function resolveConnectorsDir(options) {
277481
277499
  if (!getAppContext().projectRoot) {
277482
- return resolve8(options.dir ?? "connectors");
277500
+ return resolve9(options.dir ?? "connectors");
277483
277501
  }
277484
277502
  const { project } = await readProjectConfig();
277485
277503
  return join27(dirname19(project.configPath), project.connectorsDir);
@@ -277523,10 +277541,10 @@ function getConnectorsPullCommand() {
277523
277541
  }
277524
277542
 
277525
277543
  // src/cli/commands/connectors/push.ts
277526
- import { resolve as resolve9 } from "node:path";
277544
+ import { resolve as resolve10 } from "node:path";
277527
277545
  async function readConnectorsToPush(options) {
277528
277546
  if (!getAppContext().projectRoot) {
277529
- return readAllConnectors(resolve9(options.dir ?? "connectors"));
277547
+ return readAllConnectors(resolve10(options.dir ?? "connectors"));
277530
277548
  }
277531
277549
  const { connectors } = await readProjectConfig();
277532
277550
  return connectors;
@@ -277995,7 +278013,7 @@ function getBuildCommand() {
277995
278013
  }
277996
278014
 
277997
278015
  // src/cli/commands/project/create.ts
277998
- import { basename as basename6, resolve as resolve10 } from "node:path";
278016
+ import { basename as basename7, resolve as resolve11 } from "node:path";
277999
278017
  var import_kebabCase2 = __toESM(require_kebabCase(), 1);
278000
278018
 
278001
278019
  // src/cli/commands/project/scaffold-shared.ts
@@ -278160,8 +278178,8 @@ async function createInteractive(options, ctx) {
278160
278178
  name: () => {
278161
278179
  return options.name ? Promise.resolve(options.name) : Ze({
278162
278180
  message: "What is the name of your project?",
278163
- placeholder: basename6(process.cwd()),
278164
- initialValue: basename6(process.cwd()),
278181
+ placeholder: basename7(process.cwd()),
278182
+ initialValue: basename7(process.cwd()),
278165
278183
  validate: (value) => {
278166
278184
  if (!value || value.trim().length === 0) {
278167
278185
  return "Every project deserves a name";
@@ -278191,7 +278209,7 @@ async function createInteractive(options, ctx) {
278191
278209
  }, ctx);
278192
278210
  }
278193
278211
  async function createNonInteractive(options, ctx) {
278194
- ctx.log.info(`Creating a new project at ${resolve10(options.path)}`);
278212
+ ctx.log.info(`Creating a new project at ${resolve11(options.path)}`);
278195
278213
  const template = await getTemplateById(options.template ?? DEFAULT_TEMPLATE_ID);
278196
278214
  return await executeCreate({
278197
278215
  template,
@@ -278215,7 +278233,7 @@ async function executeCreate({
278215
278233
  }, ctx) {
278216
278234
  const { log, runTask } = ctx;
278217
278235
  const name = rawName.trim();
278218
- const resolvedPath = resolve10(projectPath);
278236
+ const resolvedPath = resolve11(projectPath);
278219
278237
  const organizationId = await resolveWorkspaceId(ctx, flagWorkspaceId, isInteractive);
278220
278238
  const { projectId } = await runTask("Setting up your project...", async () => {
278221
278239
  return await createProjectFiles({
@@ -278856,7 +278874,7 @@ function getLogsCommand() {
278856
278874
  }
278857
278875
 
278858
278876
  // src/cli/commands/project/scaffold.ts
278859
- import { basename as basename7, resolve as resolve11 } from "node:path";
278877
+ import { basename as basename8, resolve as resolve12 } from "node:path";
278860
278878
  function resolveAppId(options) {
278861
278879
  const appId = options.appId;
278862
278880
  if (!appId) {
@@ -278872,8 +278890,8 @@ function resolveAppId(options) {
278872
278890
  async function scaffoldAction(ctx, name, options, command) {
278873
278891
  const { log, runTask } = ctx;
278874
278892
  const appId = resolveAppId(command.optsWithGlobals());
278875
- const resolvedPath = resolve11("./");
278876
- const projectName = (name ?? basename7(resolvedPath)).trim();
278893
+ const resolvedPath = resolve12("./");
278894
+ const projectName = (name ?? basename8(resolvedPath)).trim();
278877
278895
  const template = await getTemplateById("backend-only");
278878
278896
  log.info(`Scaffolding project at ${resolvedPath}`);
278879
278897
  const { projectId } = await runTask("Setting up your project...", async () => {
@@ -279289,7 +279307,7 @@ function getSecretsListCommand() {
279289
279307
  }
279290
279308
 
279291
279309
  // src/cli/commands/secrets/set.ts
279292
- import { resolve as resolve12 } from "node:path";
279310
+ import { resolve as resolve13 } from "node:path";
279293
279311
  function parseEntries(entries) {
279294
279312
  const secrets = {};
279295
279313
  for (const entry of entries) {
@@ -279320,7 +279338,7 @@ async function setSecretsAction({ log, runTask }, entries, options) {
279320
279338
  validateInput(entries, options);
279321
279339
  let secrets;
279322
279340
  if (options.envFile) {
279323
- secrets = await parseEnvFile(resolve12(options.envFile));
279341
+ secrets = await parseEnvFile(resolve13(options.envFile));
279324
279342
  if (Object.keys(secrets).length === 0) {
279325
279343
  throw new InvalidInputError("The env file contains no valid KEY=VALUE entries.");
279326
279344
  }
@@ -279349,7 +279367,7 @@ function getSecretsCommand() {
279349
279367
  }
279350
279368
 
279351
279369
  // src/cli/commands/site/deploy.ts
279352
- import { resolve as resolve13 } from "node:path";
279370
+ import { resolve as resolve14 } from "node:path";
279353
279371
  async function deployAction2(ctx, options) {
279354
279372
  const { isNonInteractive } = ctx;
279355
279373
  if (isNonInteractive && !options.yes) {
@@ -279427,7 +279445,7 @@ async function deployTarball({ runTask }, project) {
279427
279445
  }
279428
279446
  function siteOutputDir(project) {
279429
279447
  const outputDirectory = project.site?.outputDirectory;
279430
- return outputDirectory ? resolve13(project.root, outputDirectory) : null;
279448
+ return outputDirectory ? resolve14(project.root, outputDirectory) : null;
279431
279449
  }
279432
279450
  function getSiteDeployCommand() {
279433
279451
  const command = new Base44Command("deploy").description("Deploy built site files to Base44 hosting").option("-y, --yes", "Skip confirmation prompt").option("--build", "Build the site before deploying (skips the prompt)").option("--no-build", "Deploy without building (skips the prompt)");
@@ -281929,7 +281947,7 @@ function createCustomIntegrationRoutes(remoteProxy, logger) {
281929
281947
 
281930
281948
  // src/cli/dev/dev-server/watcher.ts
281931
281949
  import { EventEmitter as EventEmitter6 } from "node:events";
281932
- import { relative as relative9 } from "node:path";
281950
+ import { relative as relative10 } from "node:path";
281933
281951
 
281934
281952
  // ../../node_modules/chokidar/index.js
281935
281953
  import { EventEmitter as EventEmitter5 } from "node:events";
@@ -283614,7 +283632,7 @@ class WatchBase44 extends EventEmitter6 {
283614
283632
  ignoreInitial: true
283615
283633
  });
283616
283634
  watcher.on("all", import_debounce4.default(async (_event, path) => {
283617
- this.emit("change", name, relative9(targetPath, path));
283635
+ this.emit("change", name, relative10(targetPath, path));
283618
283636
  }, WATCH_DEBOUNCE_MS));
283619
283637
  watcher.on("error", (err) => {
283620
283638
  this.logger.error(`Watch handler failed for ${targetPath}`, err);
@@ -284124,7 +284142,7 @@ Examples:
284124
284142
  }
284125
284143
 
284126
284144
  // src/cli/commands/project/eject.ts
284127
- import { resolve as resolve17 } from "node:path";
284145
+ import { resolve as resolve18 } from "node:path";
284128
284146
  var import_kebabCase3 = __toESM(require_kebabCase(), 1);
284129
284147
  async function eject(ctx, options, command) {
284130
284148
  const { log, runTask, isNonInteractive } = ctx;
@@ -284188,7 +284206,7 @@ async function eject(ctx, options, command) {
284188
284206
  Ne("Operation cancelled.");
284189
284207
  throw new CLIExitError(0);
284190
284208
  }
284191
- const resolvedPath = resolve17(selectedPath);
284209
+ const resolvedPath = resolve18(selectedPath);
284192
284210
  await runTask("Downloading your project's code...", async (updateMessage) => {
284193
284211
  await createProjectFilesForExistingProject({
284194
284212
  projectId,
@@ -288325,4 +288343,4 @@ export {
288325
288343
  runCLI
288326
288344
  };
288327
288345
 
288328
- //# debugId=3E91D87E1D11D84464756E2164756E21
288346
+ //# debugId=291EFF5BA3908B9064756E2164756E21