@base44-preview/cli 0.1.7-pr.568.c08ba20 → 0.1.7-pr.580.aed6cc8

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.
@@ -9,7 +9,8 @@
9
9
  "preview": "vite preview"
10
10
  },
11
11
  "dependencies": {
12
- "@base44/sdk": "^0.8.3",
12
+ "@base44/sdk": "^0.8.40",
13
+ "@base44/vite-plugin": "^1.0.30",
13
14
  "lucide-react": "^0.475.0",
14
15
  "react": "^18.2.0",
15
16
  "react-dom": "^18.2.0"
@@ -0,0 +1,13 @@
1
+ import { createClient } from '@base44/sdk';
2
+ import { appParams } from '@/lib/app-params';
3
+
4
+ const { appId, token, functionsVersion, appBaseUrl } = appParams;
5
+
6
+ export const base44 = createClient({
7
+ appId,
8
+ token,
9
+ functionsVersion,
10
+ serverUrl: '',
11
+ requiresAuth: false,
12
+ appBaseUrl
13
+ });
@@ -0,0 +1,54 @@
1
+ const isNode = typeof window === 'undefined';
2
+ const windowObj = isNode ? { localStorage: new Map() } : window;
3
+ const storage = windowObj.localStorage;
4
+
5
+ const toSnakeCase = (str) => {
6
+ return str.replace(/([A-Z])/g, '_$1').toLowerCase();
7
+ }
8
+
9
+ const getAppParamValue = (paramName, { defaultValue = undefined, removeFromUrl = false } = {}) => {
10
+ if (isNode) {
11
+ return defaultValue;
12
+ }
13
+ const storageKey = `base44_${toSnakeCase(paramName)}`;
14
+ const urlParams = new URLSearchParams(window.location.search);
15
+ const searchParam = urlParams.get(paramName);
16
+ if (removeFromUrl) {
17
+ urlParams.delete(paramName);
18
+ const newUrl = `${window.location.pathname}${urlParams.toString() ? `?${urlParams.toString()}` : ""
19
+ }${window.location.hash}`;
20
+ window.history.replaceState({}, document.title, newUrl);
21
+ }
22
+ if (searchParam) {
23
+ storage.setItem(storageKey, searchParam);
24
+ return searchParam;
25
+ }
26
+ if (defaultValue) {
27
+ storage.setItem(storageKey, defaultValue);
28
+ return defaultValue;
29
+ }
30
+ const storedValue = storage.getItem(storageKey);
31
+ if (storedValue) {
32
+ return storedValue;
33
+ }
34
+ return null;
35
+ }
36
+
37
+ const getAppParams = () => {
38
+ if (getAppParamValue("clear_access_token") === 'true') {
39
+ storage.removeItem('base44_access_token');
40
+ storage.removeItem('token');
41
+ }
42
+ return {
43
+ appId: getAppParamValue("app_id", { defaultValue: import.meta.env.VITE_BASE44_APP_ID }),
44
+ token: getAppParamValue("access_token", { removeFromUrl: true }),
45
+ fromUrl: getAppParamValue("from_url", { defaultValue: window.location.href }),
46
+ functionsVersion: getAppParamValue("functions_version", { defaultValue: import.meta.env.VITE_BASE44_FUNCTIONS_VERSION }),
47
+ appBaseUrl: getAppParamValue("app_base_url", { defaultValue: import.meta.env.VITE_BASE44_APP_BASE_URL }),
48
+ }
49
+ }
50
+
51
+
52
+ export const appParams = {
53
+ ...getAppParams()
54
+ }
@@ -1,12 +1,7 @@
1
- import { defineConfig } from 'vite';
1
+ import base44 from '@base44/vite-plugin';
2
2
  import react from '@vitejs/plugin-react';
3
- import path from 'path';
3
+ import { defineConfig } from 'vite';
4
4
 
5
5
  export default defineConfig({
6
- plugins: [react()],
7
- resolve: {
8
- alias: {
9
- '@': path.resolve(__dirname, './src'),
10
- },
11
- },
6
+ plugins: [base44(), react()],
12
7
  });
package/dist/cli/index.js CHANGED
@@ -244912,15 +244912,14 @@ async function setAppVisibility(visibility) {
244912
244912
  throw await ApiError.fromHttpError(error48, "updating app visibility");
244913
244913
  }
244914
244914
  }
244915
- async function listProjects(options = {}) {
244915
+ async function listProjects() {
244916
244916
  let response;
244917
244917
  try {
244918
244918
  response = await base44Client.get("api/apps", {
244919
244919
  searchParams: {
244920
244920
  sort: "-updated_date",
244921
244921
  fields: "id,name,user_description,is_managed_source_code",
244922
- limit: 50,
244923
- ...options.workspaceId ? { workspace_id: options.workspaceId } : {}
244922
+ limit: 50
244924
244923
  }
244925
244924
  });
244926
244925
  } catch (error48) {
@@ -247480,7 +247479,9 @@ async function deploySite(siteOutputDir) {
247480
247479
  if (!await pathExists(siteOutputDir)) {
247481
247480
  throw new InvalidInputError(`Output directory does not exist: ${siteOutputDir}. Make sure to build your project first.`, {
247482
247481
  hints: [
247483
- { message: "Run your build command (e.g., 'npm run build') first" }
247482
+ {
247483
+ message: "Run 'base44 build' first (it injects your app id; a bare 'npm run build' does not)"
247484
+ }
247484
247485
  ]
247485
247486
  });
247486
247487
  }
@@ -247488,7 +247489,9 @@ async function deploySite(siteOutputDir) {
247488
247489
  if (filePaths.length === 0) {
247489
247490
  throw new ConfigInvalidError(`No files found in output directory: ${siteOutputDir}. Make sure to build your project first.`, siteOutputDir, {
247490
247491
  hints: [
247491
- { message: "Run your build command (e.g., 'npm run build') first" }
247492
+ {
247493
+ message: "Run 'base44 build' first (it injects your app id; a bare 'npm run build' does not)"
247494
+ }
247492
247495
  ]
247493
247496
  });
247494
247497
  }
@@ -256641,6 +256644,66 @@ function getFunctionsCommand() {
256641
256644
  return new Command("functions").description("Manage backend functions").addCommand(getDeployCommand()).addCommand(getDeleteCommand()).addCommand(getListCommand()).addCommand(getPullCommand());
256642
256645
  }
256643
256646
 
256647
+ // src/cli/commands/project/site-build.ts
256648
+ async function runSiteBuild({ runTask: runTask2 }, { root, buildCommand, appId }) {
256649
+ if (!buildCommand) {
256650
+ throw new ConfigNotFoundError("No site build command found.", {
256651
+ hints: [
256652
+ {
256653
+ message: `Add 'site.buildCommand' to your config.jsonc (e.g., "site": { "buildCommand": "npm run build" })`
256654
+ }
256655
+ ]
256656
+ });
256657
+ }
256658
+ await runTask2("Building site...", () => execa({
256659
+ cwd: root,
256660
+ shell: true,
256661
+ env: { VITE_BASE44_APP_ID: appId }
256662
+ })`${buildCommand}`, {
256663
+ successMessage: "Site built successfully",
256664
+ errorMessage: "Build failed"
256665
+ });
256666
+ }
256667
+ async function shouldBuildBeforeDeploy({
256668
+ build,
256669
+ isNonInteractive,
256670
+ buildCommand
256671
+ }) {
256672
+ if (!buildCommand) {
256673
+ return false;
256674
+ }
256675
+ if (build !== undefined) {
256676
+ return build;
256677
+ }
256678
+ if (isNonInteractive) {
256679
+ return false;
256680
+ }
256681
+ const answer = await Re({
256682
+ message: `Build the site first? (runs '${buildCommand}' with your app id)`
256683
+ });
256684
+ return !Ct(answer) && answer;
256685
+ }
256686
+
256687
+ // src/cli/commands/project/build.ts
256688
+ async function buildAction(ctx) {
256689
+ const { app } = ctx;
256690
+ if (!app?.projectRoot) {
256691
+ throw new ConfigInvalidError("base44 build requires a linked local project. Run it from a project with base44/.app.jsonc.");
256692
+ }
256693
+ const { project: project2 } = await readProjectConfig(app.projectRoot);
256694
+ await runSiteBuild(ctx, {
256695
+ root: project2.root,
256696
+ buildCommand: project2.site?.buildCommand,
256697
+ appId: app.id
256698
+ });
256699
+ return {
256700
+ outroMessage: `Site built with app id ${theme.styles.bold(app.id)}`
256701
+ };
256702
+ }
256703
+ function getBuildCommand() {
256704
+ return new Base44Command("build").description("Build the site with the Base44 app id injected").action(buildAction);
256705
+ }
256706
+
256644
256707
  // src/cli/commands/project/create.ts
256645
256708
  import { basename as basename4, resolve as resolve8 } from "node:path";
256646
256709
  var import_kebabCase = __toESM(require_kebabCase(), 1);
@@ -256703,7 +256766,11 @@ async function completeProjectSetup({
256703
256766
  const { appUrl } = await runTask2("Installing dependencies...", async (updateMessage) => {
256704
256767
  await execa({ cwd: resolvedPath, shell: true })`${installCommand}`;
256705
256768
  updateMessage("Building project...");
256706
- await execa({ cwd: resolvedPath, shell: true })`${buildCommand}`;
256769
+ await execa({
256770
+ cwd: resolvedPath,
256771
+ shell: true,
256772
+ env: { VITE_BASE44_APP_ID: projectId }
256773
+ })`${buildCommand}`;
256707
256774
  updateMessage("Deploying site...");
256708
256775
  return await deploySite(join23(resolvedPath, outputDirectory));
256709
256776
  }, {
@@ -256751,7 +256818,7 @@ function workspaceLabel(workspace2) {
256751
256818
  const suffix = workspace2.isPersonal ? "personal" : workspace2.userRole ?? "member";
256752
256819
  return `${workspace2.name} (${suffix})`;
256753
256820
  }
256754
- async function resolveWorkspaceId(ctx, flagWorkspaceId, isInteractive, options = {}) {
256821
+ async function resolveWorkspaceId(ctx, flagWorkspaceId, isInteractive) {
256755
256822
  if (flagWorkspaceId) {
256756
256823
  return flagWorkspaceId;
256757
256824
  }
@@ -256762,13 +256829,13 @@ async function resolveWorkspaceId(ctx, flagWorkspaceId, isInteractive, options =
256762
256829
  if (workspaces.length <= 1) {
256763
256830
  return;
256764
256831
  }
256765
- const promptOptions = workspaces.map((w) => ({
256832
+ const options = workspaces.map((w) => ({
256766
256833
  value: w.id,
256767
256834
  label: workspaceLabel(w)
256768
256835
  }));
256769
256836
  const selected = await Je({
256770
- message: options.promptMessage ?? "Which workspace should this app belong to?",
256771
- options: promptOptions,
256837
+ message: "Which workspace should this app belong to?",
256838
+ options,
256772
256839
  initialValue: workspaces[0].id
256773
256840
  });
256774
256841
  if (Ct(selected)) {
@@ -256909,7 +256976,8 @@ Examples:
256909
256976
  }
256910
256977
 
256911
256978
  // src/cli/commands/project/deploy.ts
256912
- async function deployAction({ isNonInteractive, log }, options = {}) {
256979
+ async function deployAction(ctx, options = {}) {
256980
+ const { isNonInteractive, log } = ctx;
256913
256981
  if (isNonInteractive && !options.yes) {
256914
256982
  throw new InvalidInputError("--yes is required in non-interactive mode");
256915
256983
  }
@@ -256957,6 +257025,20 @@ ${summaryLines.join(`
256957
257025
  ${summaryLines.join(`
256958
257026
  `)}`);
256959
257027
  }
257028
+ if (ctx.app && project2.site?.outputDirectory) {
257029
+ const shouldBuild = await shouldBuildBeforeDeploy({
257030
+ build: options.build,
257031
+ isNonInteractive,
257032
+ buildCommand: project2.site.buildCommand
257033
+ });
257034
+ if (shouldBuild) {
257035
+ await runSiteBuild(ctx, {
257036
+ root: project2.root,
257037
+ buildCommand: project2.site.buildCommand,
257038
+ appId: ctx.app.id
257039
+ });
257040
+ }
257041
+ }
256960
257042
  let functionCompleted = 0;
256961
257043
  const functionTotal = functions.length;
256962
257044
  const result = await deployAll(projectData, {
@@ -256985,7 +257067,7 @@ ${summaryLines.join(`
256985
257067
  return { outroMessage: "App deployed successfully" };
256986
257068
  }
256987
257069
  function getDeployCommand2() {
256988
- return new Base44Command("deploy").description("Deploy all project resources (entities, functions, agents, connectors, and site)").option("-y, --yes", "Skip confirmation prompt").action(deployAction);
257070
+ return new Base44Command("deploy").description("Deploy all project resources (entities, functions, agents, connectors, and site)").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)").action(deployAction);
256989
257071
  }
256990
257072
  async function handleOAuthConnectors(connectorResults, isNonInteractive, options, log) {
256991
257073
  const needsOAuth = filterPendingOAuth(connectorResults);
@@ -257101,36 +257183,6 @@ async function promptForExistingProject(projects) {
257101
257183
  }
257102
257184
  return selectedProject;
257103
257185
  }
257104
- async function resolveExplicitAppId(ctx, appId) {
257105
- await ctx.runTask("Validating app...", () => getApp(appId), {
257106
- errorMessage: "Could not validate app"
257107
- }).catch((error48) => {
257108
- if (error48 instanceof ApiError && (error48.statusCode === 404 || error48.statusCode === 403)) {
257109
- throw new InvalidInputError(`App "${appId}" not found, or you don't have access to it.`, {
257110
- hints: [
257111
- { message: "Check the app ID is correct" },
257112
- {
257113
- message: "Run 'base44 link' without --app-id to browse apps by workspace"
257114
- }
257115
- ]
257116
- });
257117
- }
257118
- throw error48;
257119
- });
257120
- return appId;
257121
- }
257122
- async function chooseProjectInteractively(ctx, options) {
257123
- const workspaceId = await resolveWorkspaceId(ctx, options.workspace ?? options.org, !ctx.isNonInteractive, { promptMessage: "Which workspace is the app in?" });
257124
- const projects = await ctx.runTask("Fetching projects...", () => listProjects({ workspaceId }), {
257125
- successMessage: "Projects fetched",
257126
- errorMessage: "Failed to fetch projects"
257127
- });
257128
- if (!projects.length) {
257129
- return;
257130
- }
257131
- const selectedProject = await promptForExistingProject(projects);
257132
- return selectedProject.id;
257133
- }
257134
257186
  async function link(ctx, options, command2) {
257135
257187
  const { log, runTask: runTask2, isNonInteractive } = ctx;
257136
257188
  const appId = readExplicitAppId(command2).value;
@@ -257154,10 +257206,31 @@ async function link(ctx, options, command2) {
257154
257206
  let finalAppId;
257155
257207
  const action = appId ? "choose" : options.create ? "create" : await promptForLinkAction();
257156
257208
  if (action === "choose") {
257157
- const linkedAppId = appId ? await resolveExplicitAppId(ctx, appId) : await chooseProjectInteractively(ctx, options);
257158
- if (!linkedAppId) {
257209
+ const projects = await runTask2("Fetching projects...", async () => listProjects(), {
257210
+ successMessage: "Projects fetched",
257211
+ errorMessage: "Failed to fetch projects"
257212
+ });
257213
+ if (!projects.length) {
257159
257214
  return { outroMessage: "No projects available for linking" };
257160
257215
  }
257216
+ let linkedAppId;
257217
+ if (appId) {
257218
+ const project2 = projects.find((p) => p.id === appId);
257219
+ if (!project2) {
257220
+ throw new InvalidInputError(`App with ID "${appId}" not found.`, {
257221
+ hints: [
257222
+ { message: "Check the app ID is correct" },
257223
+ {
257224
+ message: "Use 'base44 link' without --app-id to see available projects"
257225
+ }
257226
+ ]
257227
+ });
257228
+ }
257229
+ linkedAppId = appId;
257230
+ } else {
257231
+ const selectedProject = await promptForExistingProject(projects);
257232
+ linkedAppId = selectedProject.id;
257233
+ }
257161
257234
  await runTask2("Linking project...", async () => {
257162
257235
  await writeAppConfig(projectRoot.root, linkedAppId);
257163
257236
  setAppContext({ id: linkedAppId, projectRoot: projectRoot.root });
@@ -257186,7 +257259,7 @@ async function link(ctx, options, command2) {
257186
257259
  function getLinkCommand() {
257187
257260
  return new Base44Command("link", {
257188
257261
  requireAppContext: false
257189
- }).description("Link a local project to a Base44 project (create new or link existing)").configureHelp({ showGlobalOptions: true }).option("-c, --create", "Create a new project (skip selection prompt)").option("-n, --name <name>", "Project name (required when --create is used)").option("-d, --description <description>", "Project description").option("-w, --workspace <id>", "Workspace (organization) ID to scope the app picker to (or create the app in, with --create). Defaults to your personal workspace").addOption(new Option("--org <id>", "Alias for --workspace").hideHelp()).addOption(new Option("-p, --project-id <id>", "Project ID to link to an existing project").hideHelp()).addOption(new Option("--projectId <id>", "Project ID to link to an existing project").hideHelp()).hook("preAction", validateNonInteractiveFlags).action(link);
257262
+ }).description("Link a local project to a Base44 project (create new or link existing)").configureHelp({ showGlobalOptions: true }).option("-c, --create", "Create a new project (skip selection prompt)").option("-n, --name <name>", "Project name (required when --create is used)").option("-d, --description <description>", "Project description").option("-w, --workspace <id>", "Workspace (organization) ID to create the app in when using --create (defaults to your personal workspace)").addOption(new Option("--org <id>", "Alias for --workspace").hideHelp()).addOption(new Option("-p, --project-id <id>", "Project ID to link to an existing project").hideHelp()).addOption(new Option("--projectId <id>", "Project ID to link to an existing project").hideHelp()).hook("preAction", validateNonInteractiveFlags).action(link);
257190
257263
  }
257191
257264
 
257192
257265
  // src/cli/commands/project/logs.ts
@@ -257860,7 +257933,8 @@ function getSecretsCommand() {
257860
257933
 
257861
257934
  // src/cli/commands/site/deploy.ts
257862
257935
  import { resolve as resolve11 } from "node:path";
257863
- async function deployAction2({ isNonInteractive, runTask: runTask2 }, options) {
257936
+ async function deployAction2(ctx, options) {
257937
+ const { isNonInteractive, runTask: runTask2 } = ctx;
257864
257938
  if (isNonInteractive && !options.yes) {
257865
257939
  throw new InvalidInputError("--yes is required in non-interactive mode");
257866
257940
  }
@@ -257883,6 +257957,20 @@ async function deployAction2({ isNonInteractive, runTask: runTask2 }, options) {
257883
257957
  return { outroMessage: "Deployment cancelled" };
257884
257958
  }
257885
257959
  }
257960
+ if (ctx.app && project2.site?.outputDirectory) {
257961
+ const shouldBuild = await shouldBuildBeforeDeploy({
257962
+ build: options.build,
257963
+ isNonInteractive,
257964
+ buildCommand: project2.site.buildCommand
257965
+ });
257966
+ if (shouldBuild) {
257967
+ await runSiteBuild(ctx, {
257968
+ root: project2.root,
257969
+ buildCommand: project2.site.buildCommand,
257970
+ appId: ctx.app.id
257971
+ });
257972
+ }
257973
+ }
257886
257974
  const result = await runTask2("Creating archive and deploying site...", async () => {
257887
257975
  return await deploySite(outputDir);
257888
257976
  }, {
@@ -257892,7 +257980,7 @@ async function deployAction2({ isNonInteractive, runTask: runTask2 }, options) {
257892
257980
  return { outroMessage: `Visit your site at: ${result.appUrl}` };
257893
257981
  }
257894
257982
  function getSiteDeployCommand() {
257895
- return new Base44Command("deploy").description("Deploy built site files to Base44 hosting").option("-y, --yes", "Skip confirmation prompt").action(deployAction2);
257983
+ return 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)").action(deployAction2);
257896
257984
  }
257897
257985
 
257898
257986
  // src/cli/commands/site/open.ts
@@ -262114,6 +262202,10 @@ function validateDevOptions(command2) {
262114
262202
  if (appId !== undefined) {
262115
262203
  command2.error(`base44 dev cannot be used with --app-id or ${BASE44_APP_ID_ENV_VAR}.`);
262116
262204
  }
262205
+ const { port, remote } = command2.opts();
262206
+ if (remote && port !== undefined) {
262207
+ command2.error("--port applies to the local backend, which --remote does not start.");
262208
+ }
262117
262209
  }
262118
262210
  function requireLinkedProject({ app }) {
262119
262211
  if (!app?.projectRoot) {
@@ -262121,31 +262213,44 @@ function requireLinkedProject({ app }) {
262121
262213
  }
262122
262214
  return { id: app.id, projectRoot: app.projectRoot };
262123
262215
  }
262124
- async function createConfiguredServeRunner(app, backendUrl) {
262216
+ async function resolveConfiguredSite(app) {
262125
262217
  const { project: project2 } = await readProjectConfig(app.projectRoot);
262126
262218
  const serveCommand = project2.site?.serveCommand;
262127
- if (!serveCommand) {
262128
- return;
262129
- }
262130
- return createServeCommandRunner({
262131
- serveCommand,
262132
- projectRoot: project2.root,
262133
- appId: app.id,
262134
- appBaseUrl: backendUrl
262135
- });
262219
+ return serveCommand ? { serveCommand, projectRoot: project2.root } : undefined;
262136
262220
  }
262137
- function startServeCommand(runner, backend) {
262221
+ function stopRunnerOnProcessSignals(runner) {
262138
262222
  const stop2 = () => void runner.stop();
262139
262223
  process.on("SIGINT", stop2);
262140
262224
  process.on("SIGTERM", stop2);
262225
+ }
262226
+ function startServeCommand(runner, backend) {
262227
+ stopRunnerOnProcessSignals(runner);
262141
262228
  runner.onExit(() => {
262142
262229
  backend.shutdown().finally(() => process.exit(1));
262143
262230
  });
262144
262231
  createDevLogger("backend", theme.styles.info).log(`Backend running on ${backend.url}`);
262145
262232
  runner.start();
262146
262233
  }
262147
- async function devAction(ctx, options8) {
262148
- const app = requireLinkedProject(ctx);
262234
+ async function remoteDevAction(app) {
262235
+ const site2 = await resolveConfiguredSite(app);
262236
+ if (!site2) {
262237
+ throw new ConfigInvalidError("base44 dev --remote serves the frontend against the production backend, but this project has no site.serveCommand in base44/config.jsonc.");
262238
+ }
262239
+ const appBaseUrl = await getSiteUrl();
262240
+ const runner = createServeCommandRunner({
262241
+ ...site2,
262242
+ appId: app.id,
262243
+ appBaseUrl
262244
+ });
262245
+ stopRunnerOnProcessSignals(runner);
262246
+ runner.onExit((code2) => process.exit(code2 ?? 1));
262247
+ runner.start();
262248
+ return {
262249
+ outroMessage: `Frontend dev server targets ${theme.styles.bold(appBaseUrl)} — every write hits your live app`
262250
+ };
262251
+ }
262252
+ async function localDevAction(ctx, app, options8) {
262253
+ const site2 = await resolveConfiguredSite(app);
262149
262254
  const siteUrlPromise = getSiteUrl().catch(() => {
262150
262255
  return;
262151
262256
  });
@@ -262160,15 +262265,23 @@ async function devAction(ctx, options8) {
262160
262265
  }
262161
262266
  });
262162
262267
  const backendUrl = localServerUrl(backend.port);
262163
- const runner = await createConfiguredServeRunner(app, backendUrl);
262164
- if (runner) {
262268
+ if (site2) {
262269
+ const runner = createServeCommandRunner({
262270
+ ...site2,
262271
+ appId: app.id,
262272
+ appBaseUrl: backendUrl
262273
+ });
262165
262274
  startServeCommand(runner, { url: backendUrl, shutdown: backend.shutdown });
262166
262275
  }
262167
- const outroMessage = runner ? "Open your app using the frontend dev server URL" : `Dev server is available at ${theme.colors.links(backendUrl)}`;
262276
+ const outroMessage = site2 ? "Open your app using the frontend dev server URL" : `Dev server is available at ${theme.colors.links(backendUrl)}`;
262168
262277
  return { outroMessage };
262169
262278
  }
262279
+ async function devAction(ctx, options8) {
262280
+ const app = requireLinkedProject(ctx);
262281
+ return options8.remote ? remoteDevAction(app) : localDevAction(ctx, app, options8);
262282
+ }
262170
262283
  function getDevCommand() {
262171
- return new Base44Command("dev").description("Start the development server").option("-p, --port <number>", "Port for the development server").hook("preAction", validateDevOptions).action(devAction);
262284
+ return new Base44Command("dev").description("Start the development server").option("-p, --port <number>", "Port for the development server").option("--remote", "Serve the frontend against the production backend instead of a local one").hook("preAction", validateDevOptions).action(devAction);
262172
262285
  }
262173
262286
 
262174
262287
  // src/core/exec/run-script.ts
@@ -262387,7 +262500,11 @@ async function eject(ctx, options8, command2) {
262387
262500
  successMessage: theme.colors.base44Orange("Project built successfully"),
262388
262501
  errorMessage: "Failed to build project"
262389
262502
  });
262390
- await deployAction(ctx, { yes: true, projectRoot: resolvedPath });
262503
+ await deployAction(ctx, {
262504
+ yes: true,
262505
+ build: false,
262506
+ projectRoot: resolvedPath
262507
+ });
262391
262508
  }
262392
262509
  }
262393
262510
  return { outroMessage: "Your new project is set and ready to use" };
@@ -262416,6 +262533,7 @@ function createProgram(context) {
262416
262533
  program2.addCommand(getCreateCommand());
262417
262534
  program2.addCommand(getScaffoldCommand());
262418
262535
  program2.addCommand(getDashboardCommand());
262536
+ program2.addCommand(getBuildCommand());
262419
262537
  program2.addCommand(getDeployCommand2());
262420
262538
  program2.addCommand(getVisibilityCommand());
262421
262539
  program2.addCommand(getLinkCommand());
@@ -266681,4 +266799,4 @@ export {
266681
266799
  CLIExitError
266682
266800
  };
266683
266801
 
266684
- //# debugId=14B1FDDCC926290964756E2164756E21
266802
+ //# debugId=3F004A0C72A722E464756E2164756E21