@base44-preview/cli 0.1.14-pr.625.c566f53 → 0.1.14-pr.626.1f4a29d

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
@@ -31177,7 +31177,7 @@ function cleanDoc(doc) {
31177
31177
  return mapDoc(doc, (currentDoc) => cleanDocFn(currentDoc));
31178
31178
  }
31179
31179
  function replaceEndOfLine(doc, replacement = literalline) {
31180
- return mapDoc(doc, (currentDoc) => typeof currentDoc === "string" ? join28(replacement, currentDoc.split(`
31180
+ return mapDoc(doc, (currentDoc) => typeof currentDoc === "string" ? join29(replacement, currentDoc.split(`
31181
31181
  `)) : currentDoc);
31182
31182
  }
31183
31183
  function canBreakFn(doc) {
@@ -31257,7 +31257,7 @@ function indentIfBreak(contents, options) {
31257
31257
  negate: options.negate
31258
31258
  };
31259
31259
  }
31260
- function join28(separator, docs) {
31260
+ function join29(separator, docs) {
31261
31261
  assertDoc(separator);
31262
31262
  assertDocArray(docs);
31263
31263
  const parts = [];
@@ -31968,7 +31968,7 @@ var init_doc = __esm(() => {
31968
31968
  MODE_FLAT = Symbol("MODE_FLAT");
31969
31969
  DOC_FILL_PRINTED_LENGTH = Symbol("DOC_FILL_PRINTED_LENGTH");
31970
31970
  builders = {
31971
- join: join28,
31971
+ join: join29,
31972
31972
  line,
31973
31973
  softline,
31974
31974
  hardline,
@@ -228634,10 +228634,6 @@ class InternalError extends SystemError {
228634
228634
  }
228635
228635
  }
228636
228636
 
228637
- class ResourceDeploymentError extends SystemError {
228638
- code = "RESOURCE_DEPLOYMENT_FAILED";
228639
- }
228640
-
228641
228637
  class TypeGenerationError extends SystemError {
228642
228638
  code = "TYPE_GENERATION_ERROR";
228643
228639
  constructor(message, entityName, cause) {
@@ -228783,7 +228779,7 @@ function normalizeBase44Env() {
228783
228779
  loadProjectEnvFiles();
228784
228780
 
228785
228781
  // src/cli/index.ts
228786
- import { dirname as dirname28, join as join37 } from "node:path";
228782
+ import { dirname as dirname27, join as join38 } from "node:path";
228787
228783
  import { fileURLToPath as fileURLToPath6 } from "node:url";
228788
228784
 
228789
228785
  // ../../node_modules/@clack/core/dist/index.mjs
@@ -229909,10 +229905,8 @@ var {
229909
229905
  Help: Help2
229910
229906
  } = exports_commander;
229911
229907
 
229912
- // src/cli/commands/functions/parseNames.ts
229913
- function parseNames(args) {
229914
- return args.flatMap((arg) => arg.split(",")).map((n) => n.trim()).filter(Boolean);
229915
- }
229908
+ // src/cli/commands/agent-skills/pull.ts
229909
+ import { dirname as dirname11, join as join18 } from "node:path";
229916
229910
  // ../../node_modules/chalk/source/vendor/ansi-styles/index.js
229917
229911
  var ANSI_BACKGROUND_OFFSET = 10;
229918
229912
  var wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
@@ -230726,7 +230720,6 @@ var ProjectConfigSchema = object({
230726
230720
  site: SiteConfigSchema.optional(),
230727
230721
  entitiesDir: string2().optional().default("entities"),
230728
230722
  functionsDir: string2().optional().default("functions"),
230729
- actorsDir: string2().optional().default("actors"),
230730
230723
  agentsDir: string2().optional().default("agents"),
230731
230724
  agentSkillsDir: string2().optional().default("agent-skills"),
230732
230725
  connectorsDir: string2().optional().default("connectors"),
@@ -236679,7 +236672,7 @@ async function getSiteUrl() {
236679
236672
  return result.data.url;
236680
236673
  }
236681
236674
  // src/core/project/config.ts
236682
- import { dirname as dirname10, join as join12 } from "node:path";
236675
+ import { dirname as dirname8, join as join11 } from "node:path";
236683
236676
 
236684
236677
  // src/core/project/plugins.ts
236685
236678
  import { createRequire as createRequire2 } from "node:module";
@@ -236717,159 +236710,6 @@ function markPluginEntities(entities, pluginNamespace) {
236717
236710
  }));
236718
236711
  }
236719
236712
 
236720
- // src/core/resources/actor/schema.ts
236721
- var RESERVED_NAMES = new Set(("await break case catch class const continue debugger default delete do else " + "enum export extends false finally for function if import in instanceof let " + "new null return static super switch this throw true try typeof var void " + "while with yield implements interface package private protected public " + "eval arguments").split(" "));
236722
- var ActorNameSchema = string2().regex(/^[A-Za-z_][A-Za-z0-9_]{0,127}$(?![\s\S])/, "Actor names must be JavaScript identifiers of at most 128 characters (letters, digits, and underscores)").refine((name) => !RESERVED_NAMES.has(name), {
236723
- message: "Actor names cannot be JavaScript reserved words"
236724
- });
236725
- function validateActorName(name) {
236726
- const result = ActorNameSchema.safeParse(name);
236727
- if (!result.success) {
236728
- throw new SchemaValidationError(`Invalid actor name '${name}'`, result.error);
236729
- }
236730
- }
236731
- var ActorDefinitionSchema = object({
236732
- name: ActorNameSchema,
236733
- entry: _enum(["entry.ts", "entry.js"]),
236734
- entryPath: string2().min(1),
236735
- filePaths: array(string2()).min(1),
236736
- source: object({ type: literal("project") })
236737
- });
236738
- var ActorDeployPayloadSchema = object({
236739
- entry: _enum(["entry.ts", "entry.js"]),
236740
- files: array(object({ path: string2().min(1), content: string2() })).min(1)
236741
- });
236742
- var DeployActorResponseSchema = object({
236743
- status: _enum(["deployed", "unchanged"]),
236744
- warnings: array(string2()).optional().default([])
236745
- });
236746
- var DeleteActorResponseSchema = object({ status: literal("deleted"), handler_name: ActorNameSchema }).transform((data) => ({
236747
- status: data.status,
236748
- handlerName: data.handler_name
236749
- }));
236750
-
236751
- // src/core/resources/actor/api.ts
236752
- async function deploySingleActor(name, payload) {
236753
- validateActorName(name);
236754
- const input = ActorDeployPayloadSchema.safeParse(payload);
236755
- if (!input.success)
236756
- throw new SchemaValidationError("Invalid actor deployment", input.error);
236757
- let response;
236758
- try {
236759
- response = await getAppClient().put(`actors/${encodeURIComponent(name)}`, {
236760
- json: input.data,
236761
- timeout: false
236762
- });
236763
- } catch (error) {
236764
- throw await ApiError.fromHttpError(error, `deploying actor "${name}"`);
236765
- }
236766
- const result = DeployActorResponseSchema.safeParse(await response.json());
236767
- if (!result.success)
236768
- throw new SchemaValidationError("Invalid actor deployment response", result.error);
236769
- return result.data;
236770
- }
236771
- async function deleteSingleActor(name) {
236772
- validateActorName(name);
236773
- let response;
236774
- try {
236775
- response = await getAppClient().delete(`actors/${encodeURIComponent(name)}`, { timeout: 60000 });
236776
- } catch (error) {
236777
- throw await ApiError.fromHttpError(error, `deleting actor "${name}"`);
236778
- }
236779
- const result = DeleteActorResponseSchema.safeParse(await response.json());
236780
- if (!result.success)
236781
- throw new SchemaValidationError("Invalid actor deletion response", result.error);
236782
- return result.data;
236783
- }
236784
- // src/core/resources/actor/config.ts
236785
- import { basename as basename3, dirname as dirname6, join as join5, relative } from "node:path";
236786
- async function readAllActors(actorsDir) {
236787
- if (!await pathExists(actorsDir))
236788
- return [];
236789
- const entries = await globby(ENTRY_FILE_GLOB, {
236790
- cwd: actorsDir,
236791
- absolute: true,
236792
- ignore: ENTRY_IGNORE_DOT_PATHS
236793
- });
236794
- const actors = [];
236795
- const names = new Set;
236796
- for (const entryPath of entries.sort()) {
236797
- const actorDir = dirname6(entryPath);
236798
- const name = relative(actorsDir, actorDir).split(/[/\\]/).join("/");
236799
- if (!name) {
236800
- throw new InvalidInputError("entry.ts or entry.js found directly in the actors directory — it must be inside a named subfolder");
236801
- }
236802
- if (name.includes("/")) {
236803
- throw new InvalidInputError(`Invalid actor name '${name}' — actors cannot be nested`);
236804
- }
236805
- validateActorName(name);
236806
- if (names.has(name)) {
236807
- throw new ConfigInvalidError(`Duplicate actor name "${name}" in ${actorsDir}`, actorsDir);
236808
- }
236809
- names.add(name);
236810
- const filePaths = (await globby(BACKEND_FILE_GLOB, { cwd: actorDir, absolute: true })).sort();
236811
- const entry = basename3(entryPath) === "entry.js" ? "entry.js" : "entry.ts";
236812
- actors.push({
236813
- name,
236814
- entry,
236815
- entryPath: join5(actorDir, entry),
236816
- filePaths,
236817
- source: { type: "project" }
236818
- });
236819
- }
236820
- return actors;
236821
- }
236822
- // src/core/resources/actor/deploy.ts
236823
- import { dirname as dirname7, relative as relative2 } from "node:path";
236824
- function actorOperationError(name, error) {
236825
- return {
236826
- name,
236827
- status: "error",
236828
- error: error instanceof Error ? error.message : String(error),
236829
- ...error instanceof ApiError ? { statusCode: error.statusCode, requestId: error.requestId } : {}
236830
- };
236831
- }
236832
- function describeActorResult(result) {
236833
- if (result.status !== "error")
236834
- return `${result.name}: ${result.status}`;
236835
- const context = [
236836
- result.statusCode === undefined ? undefined : `HTTP ${result.statusCode}`,
236837
- result.requestId ? `request ${result.requestId}` : undefined
236838
- ].filter(Boolean).join(", ");
236839
- return `${result.name}: error — ${result.error}${context ? ` (${context})` : ""}`;
236840
- }
236841
- async function deployOne(actor) {
236842
- const start = Date.now();
236843
- try {
236844
- const actorDir = dirname7(actor.entryPath);
236845
- const files = await Promise.all(actor.filePaths.map(async (filePath) => ({
236846
- path: relative2(actorDir, filePath).split(/[/\\]/).join("/"),
236847
- content: await readTextFile(filePath)
236848
- })));
236849
- const response = await deploySingleActor(actor.name, {
236850
- entry: actor.entry,
236851
- files
236852
- });
236853
- return { name: actor.name, ...response, durationMs: Date.now() - start };
236854
- } catch (error) {
236855
- return actorOperationError(actor.name, error);
236856
- }
236857
- }
236858
- async function deployActorsSequentially(actors, options) {
236859
- const results = [];
236860
- for (const actor of actors) {
236861
- options?.onStart?.(actor.name);
236862
- const result = await deployOne(actor);
236863
- results.push(result);
236864
- options?.onResult?.(result);
236865
- }
236866
- return results;
236867
- }
236868
- // src/core/resources/actor/resource.ts
236869
- var actorResource = {
236870
- readAll: readAllActors,
236871
- push: deployActorsSequentially
236872
- };
236873
236713
  // src/core/resources/agent/schema.ts
236874
236714
  var EntityOperationSchema = _enum(["create", "update", "delete", "read"]);
236875
236715
  var EntityToolConfigSchema = object({
@@ -236948,7 +236788,7 @@ async function fetchAgents() {
236948
236788
  return result.data;
236949
236789
  }
236950
236790
  // src/core/resources/agent/config.ts
236951
- import { join as join6, normalize } from "node:path";
236791
+ import { join as join5, normalize } from "node:path";
236952
236792
  import { isDeepStrictEqual } from "node:util";
236953
236793
  async function readAgentFile(agentPath) {
236954
236794
  const raw = await readJsonFile(agentPath);
@@ -236993,12 +236833,12 @@ async function readAllAgents(agentsDir) {
236993
236833
  return [...nameToEntry.values()].map((e) => e.data);
236994
236834
  }
236995
236835
  function findAvailablePath(agentsDir, name, claimedPaths) {
236996
- const base = join6(agentsDir, `${name}.${CONFIG_FILE_EXTENSION}`);
236836
+ const base = join5(agentsDir, `${name}.${CONFIG_FILE_EXTENSION}`);
236997
236837
  if (!claimedPaths.has(base)) {
236998
236838
  return base;
236999
236839
  }
237000
236840
  for (let i = 1;; i++) {
237001
- const candidate = join6(agentsDir, `${name}_${i}.${CONFIG_FILE_EXTENSION}`);
236841
+ const candidate = join5(agentsDir, `${name}_${i}.${CONFIG_FILE_EXTENSION}`);
237002
236842
  if (!claimedPaths.has(candidate)) {
237003
236843
  return candidate;
237004
236844
  }
@@ -237113,7 +236953,7 @@ async function pushAgentSkills(skills) {
237113
236953
  }
237114
236954
  // src/core/resources/agent-skill/config.ts
237115
236955
  var import_front_matter = __toESM(require_front_matter(), 1);
237116
- import { join as join7 } from "node:path";
236956
+ import { join as join6 } from "node:path";
237117
236957
 
237118
236958
  // ../../node_modules/yaml/dist/index.js
237119
236959
  var composer = require_composer();
@@ -237199,7 +237039,7 @@ async function writeAgentSkills(dir, remote) {
237199
237039
  const deleted = [];
237200
237040
  for (const skill of existing) {
237201
237041
  if (!remoteNames.has(skill.name)) {
237202
- await deleteFile(join7(dir, `${skill.name}.md`));
237042
+ await deleteFile(join6(dir, `${skill.name}.md`));
237203
237043
  deleted.push(skill.name);
237204
237044
  }
237205
237045
  }
@@ -237210,7 +237050,7 @@ async function writeAgentSkills(dir, remote) {
237210
237050
  if (prev && prev.description === skill.description && prev.body === skill.body) {
237211
237051
  continue;
237212
237052
  }
237213
- await writeFile(join7(dir, `${skill.name}.md`), serializeSkillFile(skill));
237053
+ await writeFile(join6(dir, `${skill.name}.md`), serializeSkillFile(skill));
237214
237054
  written.push(skill.name);
237215
237055
  }
237216
237056
  return { written, deleted };
@@ -237336,7 +237176,7 @@ async function pushAuthConfigToApi(config) {
237336
237176
  return result.data.authConfig;
237337
237177
  }
237338
237178
  // src/core/resources/auth-config/config.ts
237339
- import { join as join8 } from "node:path";
237179
+ import { join as join7 } from "node:path";
237340
237180
  import { isDeepStrictEqual as isDeepStrictEqual2 } from "node:util";
237341
237181
  var AUTH_CONFIG_FILENAME = `config.${CONFIG_FILE_EXTENSION}`;
237342
237182
  var DEFAULT_AUTH_CONFIG = {
@@ -237352,7 +237192,7 @@ var DEFAULT_AUTH_CONFIG = {
237352
237192
  useWorkspaceSSO: false
237353
237193
  };
237354
237194
  function getAuthConfigPath(authDir) {
237355
- return join8(authDir, AUTH_CONFIG_FILENAME);
237195
+ return join7(authDir, AUTH_CONFIG_FILENAME);
237356
237196
  }
237357
237197
  async function readAuthConfig(authDir) {
237358
237198
  const filePath = getAuthConfigPath(authDir);
@@ -238004,7 +237844,7 @@ async function removeStripe() {
238004
237844
  return result.data;
238005
237845
  }
238006
237846
  // src/core/resources/connector/config.ts
238007
- import { join as join9 } from "node:path";
237847
+ import { join as join8 } from "node:path";
238008
237848
  import { isDeepStrictEqual as isDeepStrictEqual3 } from "node:util";
238009
237849
  async function readConnectorFile(connectorPath) {
238010
237850
  const parsed = await readJsonFile(connectorPath);
@@ -238065,7 +237905,7 @@ async function writeConnectors(connectorsDir, remoteConnectors) {
238065
237905
  if (existing && isDeepStrictEqual3(existing.data, connector)) {
238066
237906
  continue;
238067
237907
  }
238068
- const filePath = existing?.filePath ?? join9(connectorsDir, `${connector.type}.${CONFIG_FILE_EXTENSION}`);
237908
+ const filePath = existing?.filePath ?? join8(connectorsDir, `${connector.type}.${CONFIG_FILE_EXTENSION}`);
238069
237909
  await writeJsonFile(filePath, connector);
238070
237910
  written.push(connector.type);
238071
237911
  }
@@ -238671,7 +238511,7 @@ async function fetchFunctionLogs(functionName, filters = {}) {
238671
238511
  return result.data;
238672
238512
  }
238673
238513
  // src/core/resources/function/config.ts
238674
- import { basename as basename4, dirname as dirname8, join as join10, relative as relative3, resolve as resolve2 } from "node:path";
238514
+ import { basename as basename3, dirname as dirname6, join as join9, relative, resolve as resolve2 } from "node:path";
238675
238515
  async function readSharedFiles(functionsDir) {
238676
238516
  const sharedDir = resolve2(functionsDir, "..", "shared");
238677
238517
  if (!await pathExists(sharedDir)) {
@@ -238689,8 +238529,8 @@ async function readFunctionConfig(configPath) {
238689
238529
  }
238690
238530
  async function readFunction(configPath, sharedFiles) {
238691
238531
  const config = await readFunctionConfig(configPath);
238692
- const functionDir = dirname8(configPath);
238693
- const entryPath = join10(functionDir, config.entry);
238532
+ const functionDir = dirname6(configPath);
238533
+ const entryPath = join9(functionDir, config.entry);
238694
238534
  if (!await pathExists(entryPath)) {
238695
238535
  throw new InvalidInputError(`Function entry file not found: ${entryPath} (referenced in ${configPath})`, {
238696
238536
  hints: [{ message: "Check the 'entry' field in your function config" }]
@@ -238722,18 +238562,18 @@ async function readAllFunctions(functionsDir) {
238722
238562
  absolute: true,
238723
238563
  ignore: ENTRY_IGNORE_DOT_PATHS
238724
238564
  });
238725
- const configFilesDirs = new Set(configFiles.map((f) => dirname8(f)));
238726
- const entryFilesWithoutConfig = entryFiles.filter((entryFile) => !configFilesDirs.has(dirname8(entryFile)));
238565
+ const configFilesDirs = new Set(configFiles.map((f) => dirname6(f)));
238566
+ const entryFilesWithoutConfig = entryFiles.filter((entryFile) => !configFilesDirs.has(dirname6(entryFile)));
238727
238567
  const sharedFiles = await readSharedFiles(functionsDir);
238728
238568
  const functionsFromConfig = await Promise.all(configFiles.map((configPath) => readFunction(configPath, sharedFiles)));
238729
238569
  const functionsWithoutConfig = await Promise.all(entryFilesWithoutConfig.map(async (entryFile) => {
238730
- const functionDir = dirname8(entryFile);
238570
+ const functionDir = dirname6(entryFile);
238731
238571
  const filePaths = await globby(BACKEND_FILE_GLOB, {
238732
238572
  cwd: functionDir,
238733
238573
  absolute: true
238734
238574
  });
238735
238575
  const allFilePaths = [...new Set([...filePaths, ...sharedFiles])];
238736
- const name = relative3(functionsDir, functionDir).split(/[/\\]/).join("/");
238576
+ const name = relative(functionsDir, functionDir).split(/[/\\]/).join("/");
238737
238577
  if (!name) {
238738
238578
  throw new InvalidInputError("entry.ts found directly in the functions directory — it must be inside a named subfolder", {
238739
238579
  hints: [
@@ -238743,7 +238583,7 @@ async function readAllFunctions(functionsDir) {
238743
238583
  ]
238744
238584
  });
238745
238585
  }
238746
- const entry = basename4(entryFile);
238586
+ const entry = basename3(entryFile);
238747
238587
  const functionData = {
238748
238588
  name,
238749
238589
  entry,
@@ -238770,17 +238610,17 @@ async function readAllFunctions(functionsDir) {
238770
238610
  return functions;
238771
238611
  }
238772
238612
  // src/core/resources/function/deploy.ts
238773
- import { dirname as dirname9, relative as relative4 } from "node:path";
238613
+ import { dirname as dirname7, relative as relative2 } from "node:path";
238774
238614
  async function loadFunctionCode(fn) {
238775
- const functionDir = dirname9(fn.entryPath);
238615
+ const functionDir = dirname7(fn.entryPath);
238776
238616
  const resolvedFiles = await Promise.all(fn.filePaths.map(async (filePath) => {
238777
238617
  const content = await readTextFile(filePath);
238778
- const path = relative4(functionDir, filePath).split(/[/\\]/).join("/");
238618
+ const path = relative2(functionDir, filePath).split(/[/\\]/).join("/");
238779
238619
  return { path, content };
238780
238620
  }));
238781
238621
  return { ...fn, files: resolvedFiles };
238782
238622
  }
238783
- async function deployOne2(fn) {
238623
+ async function deployOne(fn) {
238784
238624
  const start = Date.now();
238785
238625
  try {
238786
238626
  const functionWithCode = await loadFunctionCode(fn);
@@ -238808,7 +238648,7 @@ async function deployFunctionsSequentially(functions, options) {
238808
238648
  const results = [];
238809
238649
  for (const fn of functions) {
238810
238650
  options?.onStart?.([fn.name]);
238811
- const result = await deployOne2(fn);
238651
+ const result = await deployOne(fn);
238812
238652
  results.push(result);
238813
238653
  options?.onResult?.(result);
238814
238654
  }
@@ -238839,14 +238679,14 @@ async function pruneRemovedFunctions(localFunctionNames, options) {
238839
238679
  return results;
238840
238680
  }
238841
238681
  // src/core/resources/function/pull.ts
238842
- import { join as join11 } from "node:path";
238682
+ import { join as join10 } from "node:path";
238843
238683
  import { isDeepStrictEqual as isDeepStrictEqual4 } from "node:util";
238844
238684
  async function writeFunctions(functionsDir, functions) {
238845
238685
  const written = [];
238846
238686
  const skipped = [];
238847
238687
  for (const fn of functions) {
238848
- const functionDir = join11(functionsDir, fn.name);
238849
- const configPath = join11(functionDir, "function.jsonc");
238688
+ const functionDir = join10(functionsDir, fn.name);
238689
+ const configPath = join10(functionDir, "function.jsonc");
238850
238690
  if (await isFunctionUnchanged(functionDir, fn)) {
238851
238691
  skipped.push(fn.name);
238852
238692
  continue;
@@ -238860,7 +238700,7 @@ async function writeFunctions(functionsDir, functions) {
238860
238700
  }
238861
238701
  await writeJsonFile(configPath, config);
238862
238702
  for (const file of fn.files) {
238863
- await writeFile(join11(functionDir, file.path), file.content);
238703
+ await writeFile(join10(functionDir, file.path), file.content);
238864
238704
  }
238865
238705
  written.push(fn.name);
238866
238706
  }
@@ -238870,7 +238710,7 @@ async function isFunctionUnchanged(functionDir, fn) {
238870
238710
  if (!await pathExists(functionDir)) {
238871
238711
  return false;
238872
238712
  }
238873
- const configPath = join11(functionDir, "function.jsonc");
238713
+ const configPath = join10(functionDir, "function.jsonc");
238874
238714
  try {
238875
238715
  const localConfig = await readJsonFile(configPath);
238876
238716
  if (localConfig.entry !== fn.entry) {
@@ -238883,7 +238723,7 @@ async function isFunctionUnchanged(functionDir, fn) {
238883
238723
  return false;
238884
238724
  }
238885
238725
  for (const file of fn.files) {
238886
- const filePath = join11(functionDir, file.path);
238726
+ const filePath = join10(functionDir, file.path);
238887
238727
  if (!await pathExists(filePath)) {
238888
238728
  return false;
238889
238729
  }
@@ -239055,17 +238895,10 @@ class ProjectConfigReader {
239055
238895
  ...pluginResources.functions
239056
238896
  ];
239057
238897
  this.validateFunctionNames(functions, configPath);
239058
- const functionNames = new Set(functions.map((fn) => fn.name));
239059
- for (const actor of localResources.actors) {
239060
- if (functionNames.has(actor.name)) {
239061
- throw new ConfigInvalidError(`'${actor.name}' exists as both a backend function and an actor`, configPath);
239062
- }
239063
- }
239064
238898
  return {
239065
238899
  project,
239066
238900
  entities,
239067
238901
  functions,
239068
- actors: localResources.actors,
239069
238902
  agents: localResources.agents,
239070
238903
  agentSkills: localResources.agentSkills,
239071
238904
  connectors: localResources.connectors,
@@ -239093,34 +238926,17 @@ class ProjectConfigReader {
239093
238926
  }
239094
238927
  return result.data;
239095
238928
  }
239096
- async readProjectResources(configPath, project, includeActors = true) {
239097
- const configDir = dirname10(configPath);
239098
- const [
239099
- entities,
239100
- functions,
239101
- actors,
239102
- agents,
239103
- agentSkills,
239104
- connectors,
239105
- authConfig
239106
- ] = await Promise.all([
239107
- entityResource.readAll(join12(configDir, project.entitiesDir)),
239108
- functionResource.readAll(join12(configDir, project.functionsDir)),
239109
- includeActors ? actorResource.readAll(join12(configDir, project.actorsDir)) : Promise.resolve([]),
239110
- agentResource.readAll(join12(configDir, project.agentsDir)),
239111
- agentSkillResource.readAll(join12(configDir, project.agentSkillsDir)),
239112
- connectorResource.readAll(join12(configDir, project.connectorsDir)),
239113
- authConfigResource.readAll(join12(configDir, project.authDir))
238929
+ async readProjectResources(configPath, project) {
238930
+ const configDir = dirname8(configPath);
238931
+ const [entities, functions, agents, agentSkills, connectors, authConfig] = await Promise.all([
238932
+ entityResource.readAll(join11(configDir, project.entitiesDir)),
238933
+ functionResource.readAll(join11(configDir, project.functionsDir)),
238934
+ agentResource.readAll(join11(configDir, project.agentsDir)),
238935
+ agentSkillResource.readAll(join11(configDir, project.agentSkillsDir)),
238936
+ connectorResource.readAll(join11(configDir, project.connectorsDir)),
238937
+ authConfigResource.readAll(join11(configDir, project.authDir))
239114
238938
  ]);
239115
- return {
239116
- entities,
239117
- functions,
239118
- actors,
239119
- agents,
239120
- agentSkills,
239121
- connectors,
239122
- authConfig
239123
- };
238939
+ return { entities, functions, agents, agentSkills, connectors, authConfig };
239124
238940
  }
239125
238941
  assertPluginProjectDoesNotLoadPlugins(project, configPath) {
239126
238942
  if (project.plugin && project.plugins.length > 0) {
@@ -239141,7 +238957,7 @@ class ProjectConfigReader {
239141
238957
  this.pluginSourceByNamespace.set(namespace, source);
239142
238958
  }
239143
238959
  async readPluginConfig(plugin, hostConfigPath) {
239144
- const pluginRoot = resolvePluginRoot(plugin.source, dirname10(hostConfigPath));
238960
+ const pluginRoot = resolvePluginRoot(plugin.source, dirname8(hostConfigPath));
239145
238961
  const { configPath } = await this.findConfigOrThrow(pluginRoot);
239146
238962
  const project = await this.readConfigFile(configPath);
239147
238963
  const namespace = requirePluginNamespace(project, plugin.source, configPath);
@@ -239149,11 +238965,10 @@ class ProjectConfigReader {
239149
238965
  return { configPath, namespace, project, source: plugin.source };
239150
238966
  }
239151
238967
  async readPluginResources(project, configPath, namespace) {
239152
- const resources = await this.readProjectResources(configPath, project, false);
238968
+ const resources = await this.readProjectResources(configPath, project);
239153
238969
  return {
239154
238970
  entities: markPluginEntities(resources.entities, namespace),
239155
238971
  functions: namespacePluginFunctions(resources.functions, namespace),
239156
- actors: [],
239157
238972
  agents: [],
239158
238973
  agentSkills: [],
239159
238974
  connectors: [],
@@ -239192,7 +239007,6 @@ class ProjectConfigReader {
239192
239007
  return {
239193
239008
  entities,
239194
239009
  functions,
239195
- actors: [],
239196
239010
  agents: [],
239197
239011
  agentSkills: [],
239198
239012
  connectors: [],
@@ -239227,12 +239041,12 @@ async function readProjectSettings(projectRoot) {
239227
239041
  // src/core/project/template.ts
239228
239042
  var import_ejs = __toESM(require_ejs(), 1);
239229
239043
  var import_front_matter2 = __toESM(require_front_matter(), 1);
239230
- import { dirname as dirname11, join as join14 } from "node:path";
239044
+ import { dirname as dirname9, join as join13 } from "node:path";
239231
239045
 
239232
239046
  // src/core/assets.ts
239233
239047
  import { cpSync, existsSync } from "node:fs";
239234
239048
  import { homedir as homedir2 } from "node:os";
239235
- import { join as join13 } from "node:path";
239049
+ import { join as join12 } from "node:path";
239236
239050
  // package.json
239237
239051
  var package_default = {
239238
239052
  name: "base44",
@@ -239339,21 +239153,21 @@ var package_default = {
239339
239153
  };
239340
239154
 
239341
239155
  // src/core/assets.ts
239342
- var ASSETS_DIR = join13(homedir2(), ".base44", "assets", package_default.version);
239156
+ var ASSETS_DIR = join12(homedir2(), ".base44", "assets", package_default.version);
239343
239157
  function getTemplatesDir() {
239344
- return join13(ASSETS_DIR, "templates");
239158
+ return join12(ASSETS_DIR, "templates");
239345
239159
  }
239346
239160
  function getTemplatesIndexPath() {
239347
- return join13(ASSETS_DIR, "templates", "templates.json");
239161
+ return join12(ASSETS_DIR, "templates", "templates.json");
239348
239162
  }
239349
239163
  function getBackendRuntimeDir() {
239350
- return join13(ASSETS_DIR, "backend-runtime");
239164
+ return join12(ASSETS_DIR, "backend-runtime");
239351
239165
  }
239352
239166
  function getDenoWrapperPath() {
239353
- return join13(getBackendRuntimeDir(), "main.ts");
239167
+ return join12(getBackendRuntimeDir(), "main.ts");
239354
239168
  }
239355
239169
  function getExecWrapperPath() {
239356
- return join13(getBackendRuntimeDir(), "exec.ts");
239170
+ return join12(getBackendRuntimeDir(), "exec.ts");
239357
239171
  }
239358
239172
  function ensureNpmAssets(sourceDir) {
239359
239173
  if (existsSync(ASSETS_DIR) && existsSync(getBackendRuntimeDir()))
@@ -239375,7 +239189,7 @@ async function listTemplates() {
239375
239189
  }
239376
239190
  async function renderTemplate(template, destPath, data, options = {}) {
239377
239191
  const { skipExisting = false } = options;
239378
- const templateDir = join14(getTemplatesDir(), template.path);
239192
+ const templateDir = join13(getTemplatesDir(), template.path);
239379
239193
  const files = await globby("**/*", {
239380
239194
  cwd: templateDir,
239381
239195
  dot: true,
@@ -239383,20 +239197,20 @@ async function renderTemplate(template, destPath, data, options = {}) {
239383
239197
  });
239384
239198
  const skipped = [];
239385
239199
  for (const file of files) {
239386
- const srcPath = join14(templateDir, file);
239200
+ const srcPath = join13(templateDir, file);
239387
239201
  try {
239388
239202
  if (file.endsWith(".ejs")) {
239389
239203
  const rendered = await import_ejs.default.renderFile(srcPath, data);
239390
239204
  const { attributes, body } = import_front_matter2.default(rendered);
239391
- const destFile = attributes.outputFileName ? join14(dirname11(file), attributes.outputFileName) : file.replace(/\.ejs$/, "");
239392
- const destFilePath = join14(destPath, destFile);
239205
+ const destFile = attributes.outputFileName ? join13(dirname9(file), attributes.outputFileName) : file.replace(/\.ejs$/, "");
239206
+ const destFilePath = join13(destPath, destFile);
239393
239207
  if (skipExisting && await pathExists(destFilePath)) {
239394
239208
  skipped.push(destFile);
239395
239209
  continue;
239396
239210
  }
239397
239211
  await writeFile(destFilePath, body);
239398
239212
  } else {
239399
- const destFilePath = join14(destPath, file);
239213
+ const destFilePath = join13(destPath, file);
239400
239214
  if (skipExisting && await pathExists(destFilePath)) {
239401
239215
  skipped.push(file);
239402
239216
  continue;
@@ -239550,7 +239364,7 @@ async function getSiteFilePaths(outputDir) {
239550
239364
  // src/core/site/deploy.ts
239551
239365
  import { randomUUID } from "node:crypto";
239552
239366
  import { tmpdir } from "node:os";
239553
- import { join as join15 } from "node:path";
239367
+ import { join as join14 } from "node:path";
239554
239368
  async function deploySite(siteOutputDir) {
239555
239369
  if (!await pathExists(siteOutputDir)) {
239556
239370
  throw new InvalidInputError(`Output directory does not exist: ${siteOutputDir}. Make sure to build your project first.`, {
@@ -239571,7 +239385,7 @@ async function deploySite(siteOutputDir) {
239571
239385
  ]
239572
239386
  });
239573
239387
  }
239574
- const archivePath = join15(tmpdir(), `base44-site-${randomUUID()}.tar.gz`);
239388
+ const archivePath = join14(tmpdir(), `base44-site-${randomUUID()}.tar.gz`);
239575
239389
  try {
239576
239390
  await createArchive(siteOutputDir, archivePath);
239577
239391
  return await uploadSite(archivePath);
@@ -239588,13 +239402,13 @@ async function createArchive(pathToArchive, targetArchivePath) {
239588
239402
  }
239589
239403
  // src/core/site/deployment.ts
239590
239404
  import { readFile as readFile3 } from "node:fs/promises";
239591
- import { join as join18 } from "node:path";
239405
+ import { join as join17 } from "node:path";
239592
239406
 
239593
239407
  // src/core/site/manifest.ts
239594
239408
  import { createHash } from "node:crypto";
239595
239409
  import { createReadStream } from "node:fs";
239596
239410
  import { stat } from "node:fs/promises";
239597
- import { basename as basename5, extname, join as join16 } from "node:path";
239411
+ import { basename as basename4, extname, join as join15 } from "node:path";
239598
239412
  var MAX_ASSET_COUNT = 1e5;
239599
239413
  var ASSETS_IGNORE_FILE = ".assetsignore";
239600
239414
  var ALWAYS_IGNORED = new Set([
@@ -239652,12 +239466,12 @@ async function buildAssetManifest(assetsDir, appId) {
239652
239466
  followSymbolicLinks: false,
239653
239467
  ignoreFiles: [ASSETS_IGNORE_FILE]
239654
239468
  });
239655
- const relativeFilePaths = found.filter((path) => !ALWAYS_IGNORED.has(basename5(path)));
239469
+ const relativeFilePaths = found.filter((path) => !ALWAYS_IGNORED.has(basename4(path)));
239656
239470
  if (relativeFilePaths.length > MAX_ASSET_COUNT) {
239657
239471
  throw new InvalidInputError(`Too many static assets: found ${relativeFilePaths.length}, the limit is ${MAX_ASSET_COUNT} files.`);
239658
239472
  }
239659
239473
  for (const relativePath of relativeFilePaths.sort()) {
239660
- const absolutePath = join16(assetsDir, ...relativePath.split("/"));
239474
+ const absolutePath = join15(assetsDir, ...relativePath.split("/"));
239661
239475
  const { size } = await stat(absolutePath);
239662
239476
  const hash = await hashAssetFile(appId, absolutePath);
239663
239477
  manifest[`/${relativePath}`] = { hash, size };
@@ -239675,7 +239489,7 @@ async function buildAssetManifest(assetsDir, appId) {
239675
239489
 
239676
239490
  // src/core/site/modules.ts
239677
239491
  import { stat as stat2 } from "node:fs/promises";
239678
- import { relative as relative5, resolve as resolve3, sep } from "node:path";
239492
+ import { relative as relative3, resolve as resolve3, sep } from "node:path";
239679
239493
  var MAX_TOTAL_MODULE_BYTES = 40 * 1024 * 1024;
239680
239494
  var MODULE_IGNORE = ["wrangler.json", ".dev.vars"];
239681
239495
  var RULE_TYPE_TO_MODULE_TYPE = {
@@ -239695,7 +239509,7 @@ async function collectModules(config) {
239695
239509
  });
239696
239510
  }
239697
239511
  const modulesByName = new Map;
239698
- const entryName = toPosix(relative5(config.configDir, entryPath));
239512
+ const entryName = toPosix(relative3(config.configDir, entryPath));
239699
239513
  modulesByName.set(entryName, {
239700
239514
  name: entryName,
239701
239515
  absolutePath: entryPath,
@@ -239704,7 +239518,7 @@ async function collectModules(config) {
239704
239518
  });
239705
239519
  const ignore = [...MODULE_IGNORE];
239706
239520
  if (config.assetsDirectory?.startsWith(config.configDir + sep)) {
239707
- ignore.push(`${toPosix(relative5(config.configDir, config.assetsDirectory))}/**`);
239521
+ ignore.push(`${toPosix(relative3(config.configDir, config.assetsDirectory))}/**`);
239708
239522
  }
239709
239523
  for (const rule of config.rules) {
239710
239524
  const type = RULE_TYPE_TO_MODULE_TYPE[rule.type];
@@ -239998,7 +239812,10 @@ async function uploadPresignedAsset(upload, assets) {
239998
239812
  try {
239999
239813
  await distribution_default.put(upload.url, {
240000
239814
  body: new Uint8Array(content),
240001
- headers: { "Content-Type": upload.contentType },
239815
+ headers: {
239816
+ "Content-Type": upload.contentType,
239817
+ ...upload.checksumSha256 ? { "x-amz-checksum-sha256": upload.checksumSha256 } : {}
239818
+ },
240002
239819
  timeout: 120000,
240003
239820
  retry: UPLOAD_RETRY
240004
239821
  });
@@ -240008,8 +239825,8 @@ async function uploadPresignedAsset(upload, assets) {
240008
239825
  }
240009
239826
 
240010
239827
  // src/core/site/wrangler-config.ts
240011
- import { dirname as dirname12, join as join17, resolve as resolve4 } from "node:path";
240012
- var WRANGLER_REDIRECT_PATH = join17(".wrangler", "deploy", "config.json");
239828
+ import { dirname as dirname10, join as join16, resolve as resolve4 } from "node:path";
239829
+ var WRANGLER_REDIRECT_PATH = join16(".wrangler", "deploy", "config.json");
240013
239830
  var RedirectConfigSchema = looseObject({
240014
239831
  configPath: string2().min(1)
240015
239832
  });
@@ -240031,7 +239848,7 @@ var WranglerConfigSchema = looseObject({
240031
239848
  upload_source_maps: boolean2().optional()
240032
239849
  });
240033
239850
  async function detectFullStackArtifact(projectRoot) {
240034
- const redirectPath = join17(projectRoot, WRANGLER_REDIRECT_PATH);
239851
+ const redirectPath = join16(projectRoot, WRANGLER_REDIRECT_PATH);
240035
239852
  return await pathExists(redirectPath) ? redirectPath : null;
240036
239853
  }
240037
239854
  async function resolveWranglerConfig(redirectPath) {
@@ -240045,7 +239862,7 @@ async function resolveWranglerConfig(redirectPath) {
240045
239862
  if (config.no_bundle !== true) {
240046
239863
  throw new InvalidInputError("This framework's output requires bundling; not yet supported. Base44 only deploys pre-bundled Workers output (no_bundle: true).");
240047
239864
  }
240048
- const configDir = dirname12(configPath);
239865
+ const configDir = dirname10(configPath);
240049
239866
  const assetsDirectory = config.assets?.directory ? resolve4(configDir, config.assets.directory) : null;
240050
239867
  return {
240051
239868
  configPath,
@@ -240068,7 +239885,7 @@ async function resolveRedirectedConfigPath(redirectPath) {
240068
239885
  if (!result.success) {
240069
239886
  throw new ConfigInvalidError(`Invalid deploy redirect file: ${prettifyError(result.error)}`, redirectPath);
240070
239887
  }
240071
- const configPath = resolve4(dirname12(redirectPath), result.data.configPath);
239888
+ const configPath = resolve4(dirname10(redirectPath), result.data.configPath);
240072
239889
  if (!await pathExists(configPath)) {
240073
239890
  throw new ConfigInvalidError(`Wrangler config referenced by ${redirectPath} does not exist: ${configPath}`, redirectPath, {
240074
239891
  hints: [{ message: "Rebuild the project to regenerate the artifact" }]
@@ -240133,7 +239950,7 @@ async function readIndexHtml(assetsDir, assets) {
240133
239950
  if (!assetsDir || !assets.manifest["/index.html"]) {
240134
239951
  throw new InvalidInputError(`No index.html found in "${assetsDir ?? "the site output directory"}" — a static site needs one at the output directory root.`);
240135
239952
  }
240136
- return new Uint8Array(await readFile3(join18(assetsDir, "index.html")));
239953
+ return new Uint8Array(await readFile3(join17(assetsDir, "index.html")));
240137
239954
  }
240138
239955
  function buildAssetsConfig(assetsConfig, progress) {
240139
239956
  if (!assetsConfig)
@@ -246669,6 +246486,13 @@ async function resolveGitHash(projectRoot, explicit) {
246669
246486
  }
246670
246487
  return hash;
246671
246488
  }
246489
+ async function resolveProvenanceCommit(projectRoot, explicit) {
246490
+ if (explicit) {
246491
+ return await resolveGitHash(projectRoot, explicit);
246492
+ }
246493
+ const hash = await gitHead(projectRoot);
246494
+ return hash && isGitCommitHash(hash) ? hash : undefined;
246495
+ }
246672
246496
  async function gitHead(projectRoot) {
246673
246497
  try {
246674
246498
  const { stdout } = await execa("git", ["rev-parse", "HEAD"], {
@@ -246685,7 +246509,6 @@ function hasResourcesToDeploy(projectData) {
246685
246509
  project,
246686
246510
  entities,
246687
246511
  functions,
246688
- actors,
246689
246512
  agents,
246690
246513
  agentSkills,
246691
246514
  connectors,
@@ -246694,20 +246517,18 @@ function hasResourcesToDeploy(projectData) {
246694
246517
  const hasSite = Boolean(project.site?.outputDirectory);
246695
246518
  const hasEntities = entities.length > 0;
246696
246519
  const hasFunctions = functions.length > 0;
246697
- const hasActors = actors.length > 0;
246698
246520
  const hasAgents = agents.length > 0;
246699
246521
  const hasAgentSkills = agentSkills.length > 0;
246700
246522
  const hasConnectors = connectors.length > 0;
246701
246523
  const hasAuthConfig = authConfig.length > 0;
246702
246524
  const hasVisibility = Boolean(project.visibility);
246703
- return hasEntities || hasFunctions || hasActors || hasAgents || hasAgentSkills || hasConnectors || hasAuthConfig || hasVisibility || hasSite;
246525
+ return hasEntities || hasFunctions || hasAgents || hasAgentSkills || hasConnectors || hasAuthConfig || hasVisibility || hasSite;
246704
246526
  }
246705
246527
  async function deployAll(projectData, options) {
246706
246528
  const {
246707
246529
  project,
246708
246530
  entities,
246709
246531
  functions,
246710
- actors,
246711
246532
  agents,
246712
246533
  agentSkills,
246713
246534
  connectors,
@@ -246718,33 +246539,10 @@ async function deployAll(projectData, options) {
246718
246539
  options?.onVisibilitySet?.(project.visibility);
246719
246540
  }
246720
246541
  await entityResource.push(entities);
246721
- const functionResults = await deployFunctionsSequentially(functions, {
246542
+ await deployFunctionsSequentially(functions, {
246722
246543
  onStart: options?.onFunctionStart,
246723
246544
  onResult: options?.onFunctionResult
246724
246545
  });
246725
- const completedStages = [
246726
- ...project.visibility ? [`Visibility set to ${project.visibility}`] : [],
246727
- ...entities.length ? [`Entities synced: ${entities.length}`] : []
246728
- ];
246729
- const functionDetails = functionResults.map((result) => `Function ${result.name}: ${result.status}${result.error ? ` — ${result.error}` : ""}`);
246730
- if (functionResults.some((result) => result.status === "error")) {
246731
- throw new ResourceDeploymentError("Function deployment failed; remaining deploy stages were not run", {
246732
- details: [...completedStages, ...functionDetails]
246733
- });
246734
- }
246735
- const actorResults = await deployActorsSequentially(actors, {
246736
- onStart: options?.onActorStart,
246737
- onResult: options?.onActorResult
246738
- });
246739
- if (actorResults.some((result) => result.status === "error")) {
246740
- throw new ResourceDeploymentError("Actor deployment failed; remaining deploy stages were not run", {
246741
- details: [
246742
- ...completedStages,
246743
- ...functionDetails,
246744
- ...actorResults.map(describeActorResult)
246745
- ]
246746
- });
246747
- }
246748
246546
  await agentSkillResource.push(agentSkills);
246749
246547
  await agentResource.push(agents);
246750
246548
  await authConfigResource.push(authConfig);
@@ -247204,6 +247002,136 @@ async function resolveBranchName(name) {
247204
247002
  return matches[0].id;
247205
247003
  }
247206
247004
 
247005
+ // src/core/version/publish.ts
247006
+ import { randomUUID as randomUUID4 } from "node:crypto";
247007
+
247008
+ // src/core/version/schema.ts
247009
+ var DeclareVersionResponseSchema = object({
247010
+ session_id: string2(),
247011
+ uploads: array(object({
247012
+ path: string2(),
247013
+ url: string2(),
247014
+ content_type: string2(),
247015
+ content_length: number2(),
247016
+ checksum_sha256: string2()
247017
+ }))
247018
+ }).transform((data) => ({
247019
+ sessionId: data.session_id,
247020
+ uploads: data.uploads.map((upload) => ({
247021
+ path: upload.path,
247022
+ url: upload.url,
247023
+ contentType: upload.content_type,
247024
+ contentLength: upload.content_length,
247025
+ checksumSha256: upload.checksum_sha256
247026
+ }))
247027
+ }));
247028
+ var CreateVersionResponseSchema = object({
247029
+ version_id: string2(),
247030
+ manifest_hash: string2(),
247031
+ deduplicated: boolean2()
247032
+ }).transform((data) => ({
247033
+ versionId: data.version_id,
247034
+ manifestHash: data.manifest_hash,
247035
+ deduplicated: data.deduplicated
247036
+ }));
247037
+ var DeployVersionResponseSchema = object({
247038
+ deployment_id: string2(),
247039
+ manifest_hash: string2(),
247040
+ revision: number2()
247041
+ }).transform((data) => ({
247042
+ deploymentId: data.deployment_id,
247043
+ manifestHash: data.manifest_hash,
247044
+ revision: data.revision
247045
+ }));
247046
+
247047
+ // src/core/version/api.ts
247048
+ var DEFAULT_VERSION_UPLOAD_CONCURRENCY = 8;
247049
+ var MAX_VERSION_UPLOAD_CONCURRENCY = 16;
247050
+ async function post(path, json, doing) {
247051
+ try {
247052
+ return await getAppClient().post(path, { json, timeout: 180000 });
247053
+ } catch (error) {
247054
+ throw await ApiError.fromHttpError(error, doing);
247055
+ }
247056
+ }
247057
+ function parse10(schema, body, what) {
247058
+ const result = schema.safeParse(body);
247059
+ if (!result.success) {
247060
+ throw new SchemaValidationError(`Invalid ${what} response from server`, result.error);
247061
+ }
247062
+ return result.data;
247063
+ }
247064
+ async function createVersion(artifacts, options = {}) {
247065
+ const declared = parse10(DeclareVersionResponseSchema, await (await post("versions", {
247066
+ static_bundle: artifacts.files.map(({ path, size, digest }) => ({
247067
+ path,
247068
+ size,
247069
+ digest
247070
+ })),
247071
+ entities: artifacts.entities,
247072
+ agents: artifacts.agents,
247073
+ source_commit: options.sourceCommit,
247074
+ frontend_commit: options.sourceCommit
247075
+ }, "declaring a version")).json(), "declare");
247076
+ options.progress?.onDeclared?.({
247077
+ fileCount: artifacts.files.length,
247078
+ owedFiles: declared.uploads.length
247079
+ });
247080
+ await uploadPresignedAssets(declared.uploads, {
247081
+ manifest: Object.fromEntries(artifacts.files.map((file) => [
247082
+ file.path,
247083
+ { hash: file.digest, size: file.size }
247084
+ ])),
247085
+ filesByHash: new Map(artifacts.files.map((file) => [
247086
+ file.digest,
247087
+ {
247088
+ absolutePath: file.absolutePath,
247089
+ hash: file.digest,
247090
+ size: file.size,
247091
+ contentType: "application/octet-stream"
247092
+ }
247093
+ ]))
247094
+ }, {
247095
+ concurrency: options.concurrency ?? DEFAULT_VERSION_UPLOAD_CONCURRENCY,
247096
+ onProgress: options.progress?.onUpload
247097
+ });
247098
+ return parse10(CreateVersionResponseSchema, await (await post(`versions/${encodeURIComponent(declared.sessionId)}/finalize`, {}, "creating a version")).json(), "create version");
247099
+ }
247100
+ async function deployVersion(versionId, options = {}) {
247101
+ return parse10(DeployVersionResponseSchema, await (await post(`versions/${encodeURIComponent(versionId)}/deployments`, {
247102
+ ...options.target ? { target: options.target } : {},
247103
+ ...options.idempotencyKey ? { idempotency_key: options.idempotencyKey } : {}
247104
+ }, "deploying a version")).json(), "deploy");
247105
+ }
247106
+
247107
+ // src/core/version/publish.ts
247108
+ var STEP = Symbol.for("base44.publishStep");
247109
+ async function tagStep(step, run) {
247110
+ try {
247111
+ return await run();
247112
+ } catch (error) {
247113
+ if (error !== null && typeof error === "object" && !(STEP in error)) {
247114
+ Object.defineProperty(error, STEP, { value: step, enumerable: false });
247115
+ }
247116
+ throw error;
247117
+ }
247118
+ }
247119
+ function stepOf(error) {
247120
+ return error !== null && typeof error === "object" && STEP in error ? error[STEP] : undefined;
247121
+ }
247122
+ async function publishVersion(artifacts, options = {}) {
247123
+ const version = await tagStep("create_version", () => createVersion(artifacts, {
247124
+ sourceCommit: options.sourceCommit,
247125
+ concurrency: options.concurrency,
247126
+ progress: options.progress
247127
+ }));
247128
+ const deployment = await tagStep("deploy", () => deployVersion(version.versionId, {
247129
+ target: options.target,
247130
+ idempotencyKey: randomUUID4()
247131
+ }));
247132
+ return { ...version, ...deployment };
247133
+ }
247134
+
247207
247135
  // src/cli/utils/command/Base44Command.ts
247208
247136
  function writeJsonSuccess(result) {
247209
247137
  if (result.stdout) {
@@ -247221,6 +247149,10 @@ function writeJsonError(error) {
247221
247149
  const envelope = {
247222
247150
  error: error instanceof Error ? error.message : String(error)
247223
247151
  };
247152
+ const step = stepOf(error);
247153
+ if (step !== undefined) {
247154
+ envelope.step = step;
247155
+ }
247224
247156
  if (isCLIError(error)) {
247225
247157
  envelope.code = error.code;
247226
247158
  if (error.details.length > 0) {
@@ -247479,118 +247411,6 @@ function formatYaml(data, options = {}) {
247479
247411
  const replacer = stripEmpty ? stripEmptyReplacer : undefined;
247480
247412
  return $stringify(data, replacer, { indent: YAML_INDENT }).trimEnd();
247481
247413
  }
247482
- // src/cli/commands/actors/delete.ts
247483
- async function deleteActorsAction({ log, jsonMode, runTask }, rawNames) {
247484
- const names = [...new Set(parseNames(rawNames))];
247485
- if (!names.length)
247486
- throw new InvalidInputError("At least one actor name is required");
247487
- names.forEach(validateActorName);
247488
- const results = [];
247489
- for (const name of names) {
247490
- try {
247491
- await runTask(`Deleting ${name}...`, () => deleteSingleActor(name), {
247492
- successMessage: `${name} deleted`,
247493
- errorMessage: `Failed to delete ${name}`
247494
- });
247495
- results.push({ name, status: "deleted" });
247496
- } catch (error) {
247497
- if (error instanceof ApiError && error.statusCode === 404) {
247498
- results.push({ name, status: "not_found" });
247499
- log.info(`${name} not found`);
247500
- } else {
247501
- const result = actorOperationError(name, error);
247502
- results.push(result);
247503
- log.error(describeActorResult(result));
247504
- }
247505
- }
247506
- }
247507
- const summary = {
247508
- deleted: results.filter((result) => result.status === "deleted").length,
247509
- notFound: results.filter((result) => result.status === "not_found").length,
247510
- failed: results.filter((result) => result.status === "error").length
247511
- };
247512
- if (summary.failed)
247513
- throw new ResourceDeploymentError("Actor deletion failed", {
247514
- details: results.map(describeActorResult)
247515
- });
247516
- return {
247517
- outroMessage: names.length === 1 ? `Actor "${names[0]}" ${summary.deleted ? "deleted" : "not found"}` : `${summary.deleted} deleted, ${summary.notFound} not found`,
247518
- stdout: jsonMode ? `${JSON.stringify({ actors: results, summary })}
247519
- ` : undefined
247520
- };
247521
- }
247522
- function getDeleteCommand() {
247523
- return new Base44Command("delete").description("Delete deployed actors").argument("[names...]", "Actor names to delete (required)").action(deleteActorsAction);
247524
- }
247525
-
247526
- // src/cli/commands/functions/formatDeployResult.ts
247527
- function formatDuration(ms) {
247528
- return `${(ms / 1000).toFixed(1)}s`;
247529
- }
247530
- function formatDeployResult(result, log) {
247531
- const label = result.name.padEnd(25);
247532
- if (result.status === "deployed") {
247533
- const timing = result.durationMs ? theme.styles.dim(` (${formatDuration(result.durationMs)})`) : "";
247534
- log.success(`${label} deployed${timing}`);
247535
- } else if (result.status === "unchanged") {
247536
- log.success(`${label} unchanged`);
247537
- } else {
247538
- log.error(`${label} error: ${result.error}`);
247539
- }
247540
- }
247541
-
247542
- // src/cli/commands/actors/deploy.ts
247543
- async function deployActorsAction({ log, jsonMode }, rawNames) {
247544
- const names = [...new Set(parseNames(rawNames))];
247545
- if (rawNames.length && !names.length)
247546
- throw new InvalidInputError("At least one actor name is required");
247547
- names.forEach(validateActorName);
247548
- const { actors, project } = await readProjectConfig();
247549
- const notFound = names.filter((name) => !actors.some((actor) => actor.name === name));
247550
- if (notFound.length)
247551
- throw new InvalidInputError(`Actor not found in project: ${notFound.join(", ")}`);
247552
- const selected = names.length ? actors.filter((actor) => names.includes(actor.name)) : actors;
247553
- let completed = 0;
247554
- if (selected.length)
247555
- log.info(`Found ${selected.length} ${selected.length === 1 ? "actor" : "actors"} to deploy`);
247556
- const results = await deployActorsSequentially(selected, {
247557
- onStart: (name) => log.step(theme.styles.dim(`[${completed + 1}/${selected.length}] Deploying ${name}...`)),
247558
- onResult: (result) => {
247559
- completed++;
247560
- formatDeployResult(result, log);
247561
- if (result.status !== "error")
247562
- for (const warning of result.warnings)
247563
- log.warn(`${result.name}: ${warning}`);
247564
- }
247565
- });
247566
- const summary = {
247567
- deployed: results.filter((result) => result.status === "deployed").length,
247568
- unchanged: results.filter((result) => result.status === "unchanged").length,
247569
- failed: results.filter((result) => result.status === "error").length
247570
- };
247571
- const message = Object.entries(summary).filter(([, count]) => count > 0).map(([status, count]) => `${count} ${status}`).join(", ");
247572
- if (summary.failed) {
247573
- throw new ResourceDeploymentError(message, {
247574
- details: results.map(describeActorResult)
247575
- });
247576
- }
247577
- return {
247578
- outroMessage: message || `No actors found. Create actors in the '${project.actorsDir}' directory.`,
247579
- stdout: jsonMode ? `${JSON.stringify({ actors: results, summary })}
247580
- ` : undefined
247581
- };
247582
- }
247583
- function getDeployCommand() {
247584
- return new Base44Command("deploy").description("Deploy actors to Base44").argument("[names...]", "Actor names to deploy (deploys all if omitted)").action(deployActorsAction);
247585
- }
247586
-
247587
- // src/cli/commands/actors/index.ts
247588
- function getActorsCommand() {
247589
- return new Command2("actors").description("Manage realtime actors").addCommand(getDeployCommand()).addCommand(getDeleteCommand());
247590
- }
247591
-
247592
- // src/cli/commands/agent-skills/pull.ts
247593
- import { dirname as dirname13, join as join19 } from "node:path";
247594
247414
  // src/core/utils/dependencies.ts
247595
247415
  import { spawnSync as spawnSync2 } from "node:child_process";
247596
247416
  function verifyDenoInstalled(context) {
@@ -247679,7 +247499,7 @@ async function pullAction({
247679
247499
  runTask
247680
247500
  }) {
247681
247501
  const { project } = await readProjectConfig();
247682
- const dir = join19(dirname13(project.configPath), project.agentSkillsDir);
247502
+ const dir = join18(dirname11(project.configPath), project.agentSkillsDir);
247683
247503
  const remote = await runTask("Fetching agent skills from Base44", () => fetchAgentSkills(), {
247684
247504
  successMessage: "Agent skills fetched successfully",
247685
247505
  errorMessage: "Failed to fetch agent skills"
@@ -247735,14 +247555,14 @@ function getAgentSkillsCommand() {
247735
247555
  }
247736
247556
 
247737
247557
  // src/cli/commands/agents/pull.ts
247738
- import { dirname as dirname14, join as join20 } from "node:path";
247558
+ import { dirname as dirname12, join as join19 } from "node:path";
247739
247559
  async function pullAgentsAction({
247740
247560
  log,
247741
247561
  runTask
247742
247562
  }) {
247743
247563
  const { project } = await readProjectConfig();
247744
- const configDir = dirname14(project.configPath);
247745
- const agentsDir = join20(configDir, project.agentsDir);
247564
+ const configDir = dirname12(project.configPath);
247565
+ const agentsDir = join19(configDir, project.agentsDir);
247746
247566
  const remoteAgents = await runTask("Fetching agents from Base44", async () => {
247747
247567
  return await fetchAgents();
247748
247568
  }, {
@@ -247812,12 +247632,12 @@ function getAgentsCommand() {
247812
247632
  }
247813
247633
 
247814
247634
  // src/cli/commands/auth/password-login.ts
247815
- import { dirname as dirname15, join as join21 } from "node:path";
247635
+ import { dirname as dirname13, join as join20 } from "node:path";
247816
247636
  async function passwordLoginAction({ log, runTask }, action) {
247817
247637
  const shouldEnable = action === "enable";
247818
247638
  const { project } = await readProjectConfig();
247819
- const configDir = dirname15(project.configPath);
247820
- const authDir = join21(configDir, project.authDir);
247639
+ const configDir = dirname13(project.configPath);
247640
+ const authDir = join20(configDir, project.authDir);
247821
247641
  const updated = await runTask("Updating local auth config", async () => {
247822
247642
  const current = await readAuthConfig(authDir) ?? DEFAULT_AUTH_CONFIG;
247823
247643
  const merged = { ...current, enableUsernamePassword: shouldEnable };
@@ -247837,14 +247657,14 @@ function getPasswordLoginCommand() {
247837
247657
  }
247838
247658
 
247839
247659
  // src/cli/commands/auth/pull.ts
247840
- import { dirname as dirname16, join as join22 } from "node:path";
247660
+ import { dirname as dirname14, join as join21 } from "node:path";
247841
247661
  async function pullAuthAction({
247842
247662
  log,
247843
247663
  runTask
247844
247664
  }) {
247845
247665
  const { project } = await readProjectConfig();
247846
- const configDir = dirname16(project.configPath);
247847
- const authDir = join22(configDir, project.authDir);
247666
+ const configDir = dirname14(project.configPath);
247667
+ const authDir = join21(configDir, project.authDir);
247848
247668
  const remoteConfig = await runTask("Fetching auth config from Base44", async () => {
247849
247669
  return await pullAuthConfig();
247850
247670
  }, {
@@ -247908,7 +247728,7 @@ function getAuthPushCommand() {
247908
247728
  }
247909
247729
 
247910
247730
  // src/cli/commands/auth/social-login.ts
247911
- import { dirname as dirname17, join as join23, resolve as resolve6 } from "node:path";
247731
+ import { dirname as dirname15, join as join22, resolve as resolve6 } from "node:path";
247912
247732
  var PROVIDER_LABELS = {
247913
247733
  google: "Google",
247914
247734
  microsoft: "Microsoft",
@@ -247978,8 +247798,8 @@ async function socialLoginAction({ log, isNonInteractive, runTask }, provider, a
247978
247798
  }
247979
247799
  }
247980
247800
  const { project } = await readProjectConfig();
247981
- const configDir = dirname17(project.configPath);
247982
- const authDir = join23(configDir, project.authDir);
247801
+ const configDir = dirname15(project.configPath);
247802
+ const authDir = join22(configDir, project.authDir);
247983
247803
  const { config: updated } = await runTask("Updating local auth config", async () => updateSocialLoginConfig(authDir, provider, shouldEnable, useCustomOAuth && options.clientId ? { clientId: options.clientId } : undefined));
247984
247804
  if (clientSecret) {
247985
247805
  await runTask("Saving client secret", async () => pushCustomOAuthSecret(provider, clientSecret));
@@ -248004,7 +247824,7 @@ function getSocialLoginCommand() {
248004
247824
  }
248005
247825
 
248006
247826
  // src/cli/commands/auth/sso.ts
248007
- import { dirname as dirname18, join as join24, resolve as resolve7 } from "node:path";
247827
+ import { dirname as dirname16, join as join23, resolve as resolve7 } from "node:path";
248008
247828
  var SSOConfigFileSchema = object({
248009
247829
  provider: _enum(Object.values(KNOWN_SSO_PROVIDERS)),
248010
247830
  clientId: string2(),
@@ -248167,8 +247987,8 @@ async function ssoEnableAction({ isNonInteractive, runTask }, options) {
248167
247987
  throw error;
248168
247988
  }
248169
247989
  const { project } = await readProjectConfig();
248170
- const configDir = dirname18(project.configPath);
248171
- const authDir = join24(configDir, project.authDir);
247990
+ const configDir = dirname16(project.configPath);
247991
+ const authDir = join23(configDir, project.authDir);
248172
247992
  await runTask("Updating local auth config", async () => updateSSOConfig(authDir, provider, true));
248173
247993
  await runTask("Saving SSO credentials", async () => pushSSOSecrets(secrets));
248174
247994
  return {
@@ -248183,8 +248003,8 @@ async function ssoDisableAction({ log, runTask }, options) {
248183
248003
  throw new InvalidInputError("Configuration options cannot be used with disable. To disable SSO: base44 auth sso disable");
248184
248004
  }
248185
248005
  const { project } = await readProjectConfig();
248186
- const configDir = dirname18(project.configPath);
248187
- const authDir = join24(configDir, project.authDir);
248006
+ const configDir = dirname16(project.configPath);
248007
+ const authDir = join23(configDir, project.authDir);
248188
248008
  const updated = await runTask("Updating local auth config", async () => updateSSOConfig(authDir, null, false));
248189
248009
  await runTask("Removing SSO credentials", async () => deleteSSOSecrets());
248190
248010
  if (!hasAnyLoginMethod(updated)) {
@@ -249066,13 +248886,13 @@ function getConnectorsListAvailableCommand() {
249066
248886
  }
249067
248887
 
249068
248888
  // src/cli/commands/connectors/pull.ts
249069
- import { dirname as dirname19, join as join25, resolve as resolve8 } from "node:path";
248889
+ import { dirname as dirname17, join as join24, resolve as resolve8 } from "node:path";
249070
248890
  async function resolveConnectorsDir(options) {
249071
248891
  if (!getAppContext().projectRoot) {
249072
248892
  return resolve8(options.dir ?? "connectors");
249073
248893
  }
249074
248894
  const { project } = await readProjectConfig();
249075
- return join25(dirname19(project.configPath), project.connectorsDir);
248895
+ return join24(dirname17(project.configPath), project.connectorsDir);
249076
248896
  }
249077
248897
  async function pullConnectorsAction({ log, runTask, jsonMode }, options) {
249078
248898
  const connectorsDir = await resolveConnectorsDir(options);
@@ -249327,22 +249147,43 @@ async function deleteFunctionsAction({ runTask }, names) {
249327
249147
  parts.push(`${errors} error${errors !== 1 ? "s" : ""}`);
249328
249148
  return { outroMessage: parts.join(", ") };
249329
249149
  }
249330
- function parseNames2(args) {
249150
+ function parseNames(args) {
249331
249151
  return args.flatMap((arg) => arg.split(",")).map((n) => n.trim()).filter(Boolean);
249332
249152
  }
249333
249153
  function validateNames(command) {
249334
- const names = parseNames2(command.args);
249154
+ const names = parseNames(command.args);
249335
249155
  if (names.length === 0) {
249336
249156
  command.error("At least one function name is required");
249337
249157
  }
249338
249158
  }
249339
- function getDeleteCommand2() {
249159
+ function getDeleteCommand() {
249340
249160
  return new Base44Command("delete").description("Delete deployed functions").argument("<names...>", "Function names to delete").hook("preAction", validateNames).action(async (ctx, rawNames) => {
249341
- const names = parseNames2(rawNames);
249161
+ const names = parseNames(rawNames);
249342
249162
  return deleteFunctionsAction(ctx, names);
249343
249163
  });
249344
249164
  }
249345
249165
 
249166
+ // src/cli/commands/functions/formatDeployResult.ts
249167
+ function formatDuration(ms) {
249168
+ return `${(ms / 1000).toFixed(1)}s`;
249169
+ }
249170
+ function formatDeployResult(result, log) {
249171
+ const label = result.name.padEnd(25);
249172
+ if (result.status === "deployed") {
249173
+ const timing = result.durationMs ? theme.styles.dim(` (${formatDuration(result.durationMs)})`) : "";
249174
+ log.success(`${label} deployed${timing}`);
249175
+ } else if (result.status === "unchanged") {
249176
+ log.success(`${label} unchanged`);
249177
+ } else {
249178
+ log.error(`${label} error: ${result.error}`);
249179
+ }
249180
+ }
249181
+
249182
+ // src/cli/commands/functions/parseNames.ts
249183
+ function parseNames2(args) {
249184
+ return args.flatMap((arg) => arg.split(",")).map((n) => n.trim()).filter(Boolean);
249185
+ }
249186
+
249346
249187
  // src/cli/commands/functions/deploy.ts
249347
249188
  function resolveFunctionsToDeploy(names, allFunctions) {
249348
249189
  if (names.length === 0)
@@ -249429,9 +249270,9 @@ async function deployFunctionsAction({ log }, names, options) {
249429
249270
  }
249430
249271
  return { outroMessage: buildDeploySummary(results) };
249431
249272
  }
249432
- function getDeployCommand2() {
249273
+ function getDeployCommand() {
249433
249274
  return new Base44Command("deploy").description("Deploy functions to Base44").argument("[names...]", "Function names to deploy (deploys all if omitted)").option("--force", "Delete remote functions not found locally").action(async (ctx, rawNames, options) => {
249434
- const names = parseNames(rawNames);
249275
+ const names = parseNames2(rawNames);
249435
249276
  return deployFunctionsAction(ctx, names, options);
249436
249277
  });
249437
249278
  }
@@ -249459,11 +249300,11 @@ function getListCommand() {
249459
249300
  }
249460
249301
 
249461
249302
  // src/cli/commands/functions/pull.ts
249462
- import { dirname as dirname20, join as join26 } from "node:path";
249303
+ import { dirname as dirname18, join as join25 } from "node:path";
249463
249304
  async function pullFunctionsAction({ log, runTask }, name) {
249464
249305
  const { project, functions } = await readProjectConfig();
249465
- const configDir = dirname20(project.configPath);
249466
- const functionsDir = join26(configDir, project.functionsDir);
249306
+ const configDir = dirname18(project.configPath);
249307
+ const functionsDir = join25(configDir, project.functionsDir);
249467
249308
  const pluginFunctionNames = new Set(functions.filter((fn) => fn.source.type === "plugin").map((fn) => fn.name));
249468
249309
  const remoteFunctions = await runTask("Fetching functions from Base44", async () => {
249469
249310
  const { functions } = await listDeployedFunctions();
@@ -249518,7 +249359,7 @@ function getPullCommand() {
249518
249359
 
249519
249360
  // src/cli/commands/functions/index.ts
249520
249361
  function getFunctionsCommand() {
249521
- return new Command2("functions").description("Manage backend functions").addCommand(getDeployCommand2()).addCommand(getDeleteCommand2()).addCommand(getListCommand()).addCommand(getPullCommand());
249362
+ return new Command2("functions").description("Manage backend functions").addCommand(getDeployCommand()).addCommand(getDeleteCommand()).addCommand(getListCommand()).addCommand(getPullCommand());
249522
249363
  }
249523
249364
 
249524
249365
  // src/cli/commands/project/site-build.ts
@@ -249563,33 +249404,148 @@ async function maybeAskToBuild(isNonInteractive, buildCommand) {
249563
249404
  });
249564
249405
  return !Ct(answer) && answer;
249565
249406
  }
249566
-
249407
+ // src/core/version/artifacts.ts
249408
+ import { createHash as createHash2 } from "node:crypto";
249409
+ import { createReadStream as createReadStream3 } from "node:fs";
249410
+ import { stat as stat3 } from "node:fs/promises";
249411
+ import { basename as basename5, join as join26 } from "node:path";
249412
+ var MAX_FILE_COUNT = 1e5;
249413
+ var ASSETS_IGNORE_FILE2 = ".assetsignore";
249414
+ var ALWAYS_IGNORED2 = new Set([
249415
+ ASSETS_IGNORE_FILE2,
249416
+ "wrangler.json",
249417
+ ".dev.vars"
249418
+ ]);
249419
+ var ENTRY2 = "index.html";
249420
+ async function digestFile(absolutePath) {
249421
+ const hash = createHash2("sha256");
249422
+ for await (const chunk of createReadStream3(absolutePath)) {
249423
+ hash.update(chunk);
249424
+ }
249425
+ return `sha256:${hash.digest("hex")}`;
249426
+ }
249427
+ async function collectBuildOutput(outputDir) {
249428
+ const found = await globby("**/*", {
249429
+ cwd: outputDir,
249430
+ dot: true,
249431
+ onlyFiles: true,
249432
+ followSymbolicLinks: false,
249433
+ ignoreFiles: [ASSETS_IGNORE_FILE2]
249434
+ });
249435
+ const relativePaths = found.filter((path) => !ALWAYS_IGNORED2.has(basename5(path))).sort();
249436
+ if (relativePaths.length === 0) {
249437
+ throw new InvalidInputError(`No files found in ${outputDir}. Build the site before creating a version.`, {
249438
+ hints: [
249439
+ { message: "Run 'base44 build' first", command: "base44 build" }
249440
+ ]
249441
+ });
249442
+ }
249443
+ if (relativePaths.length > MAX_FILE_COUNT) {
249444
+ throw new InvalidInputError(`Too many files: found ${relativePaths.length}, the limit is ${MAX_FILE_COUNT}.`);
249445
+ }
249446
+ if (!relativePaths.includes(ENTRY2)) {
249447
+ throw new InvalidInputError(`${outputDir} has no ${ENTRY2}, so nothing could enter the site.`);
249448
+ }
249449
+ return await Promise.all(relativePaths.map(async (path) => {
249450
+ const absolutePath = join26(outputDir, ...path.split("/"));
249451
+ const { size } = await stat3(absolutePath);
249452
+ return {
249453
+ path,
249454
+ absolutePath,
249455
+ size,
249456
+ digest: await digestFile(absolutePath)
249457
+ };
249458
+ }));
249459
+ }
249460
+ async function readRawResources(dir) {
249461
+ if (!await pathExists(dir)) {
249462
+ return {};
249463
+ }
249464
+ const files = await globby(`**/*.${CONFIG_FILE_EXTENSION_GLOB}`, {
249465
+ cwd: dir,
249466
+ onlyFiles: true,
249467
+ followSymbolicLinks: false
249468
+ });
249469
+ const payloads = {};
249470
+ for (const relativePath of files.sort()) {
249471
+ const name = relativePath.replace(/\.jsonc?$/, "");
249472
+ payloads[name] = await readJsonFile(join26(dir, ...relativePath.split("/")));
249473
+ }
249474
+ return payloads;
249475
+ }
249476
+ async function collectResources(configDir, dirs) {
249477
+ const [entities, agents] = await Promise.all([
249478
+ readRawResources(join26(configDir, dirs.entitiesDir)),
249479
+ readRawResources(join26(configDir, dirs.agentsDir))
249480
+ ]);
249481
+ return { entities, agents };
249482
+ }
249483
+ // src/core/version/project.ts
249484
+ import { dirname as dirname19, join as join27, resolve as resolve10 } from "node:path";
249485
+ var DEFAULT_BUILD_COMMAND = "npm run build";
249486
+ var DEFAULT_OUTPUT_DIRECTORY = "dist";
249487
+ async function resolvePublishTarget(projectRoot, overrides = {}) {
249488
+ const project = await readSettingsIfPresent(projectRoot);
249489
+ const root = project?.root ?? projectRoot ?? process.cwd();
249490
+ return {
249491
+ root,
249492
+ configDir: project ? dirname19(project.configPath) : join27(root, PROJECT_SUBDIR),
249493
+ buildCommand: project ? project.site?.buildCommand : DEFAULT_BUILD_COMMAND,
249494
+ outputDir: outputDirectory(project, root, overrides.outputDir),
249495
+ entitiesDir: project?.entitiesDir ?? "entities",
249496
+ agentsDir: project?.agentsDir ?? "agents"
249497
+ };
249498
+ }
249499
+ function outputDirectory(project, root, override) {
249500
+ const configured = override ?? (project ? project.site?.outputDirectory : DEFAULT_OUTPUT_DIRECTORY);
249501
+ return configured ? resolve10(root, configured) : null;
249502
+ }
249503
+ function requireOutputDir(target) {
249504
+ if (target.outputDir === null) {
249505
+ throw new ConfigNotFoundError("No site configuration found.", {
249506
+ hints: [
249507
+ {
249508
+ message: `Add 'site.outputDirectory' to your config.jsonc (e.g., "site": { "outputDirectory": "dist" })`
249509
+ },
249510
+ { message: `Or pass --output-dir <dir>, relative to ${target.root}` }
249511
+ ]
249512
+ });
249513
+ }
249514
+ return target.outputDir;
249515
+ }
249516
+ async function readSettingsIfPresent(projectRoot) {
249517
+ try {
249518
+ return await readProjectSettings(projectRoot);
249519
+ } catch (error) {
249520
+ if (error instanceof ConfigNotFoundError) {
249521
+ return null;
249522
+ }
249523
+ throw error;
249524
+ }
249525
+ }
249567
249526
  // src/cli/commands/project/build.ts
249568
249527
  async function buildAction(ctx) {
249569
249528
  const { app } = ctx;
249570
- if (!app?.projectRoot) {
249571
- throw new ConfigInvalidError("base44 build requires a linked local project. Run it from a project with base44/.app.jsonc.");
249572
- }
249573
- const { project } = await readProjectConfig(app.projectRoot);
249529
+ const target = await resolvePublishTarget(app?.projectRoot);
249574
249530
  await runSiteBuild(ctx, {
249575
- root: project.root,
249576
- buildCommand: project.site?.buildCommand,
249577
- appId: app.id
249531
+ root: target.root,
249532
+ buildCommand: target.buildCommand,
249533
+ appId: app?.id ?? ""
249578
249534
  });
249579
249535
  return {
249580
- outroMessage: `Site built with app id ${theme.styles.bold(app.id)}`
249536
+ outroMessage: `Site built with app id ${theme.styles.bold(app?.id ?? "")}`
249581
249537
  };
249582
249538
  }
249583
249539
  function getBuildCommand() {
249584
- return new Base44Command("build").description("Build the site with the Base44 app id injected").action(buildAction);
249540
+ return new Base44Command("build", { requireAuth: false }).description("Build the site with the Base44 app id injected").action(buildAction);
249585
249541
  }
249586
249542
 
249587
249543
  // src/cli/commands/project/create.ts
249588
- import { basename as basename6, resolve as resolve10 } from "node:path";
249544
+ import { basename as basename6, resolve as resolve11 } from "node:path";
249589
249545
  var import_kebabCase = __toESM(require_kebabCase(), 1);
249590
249546
 
249591
249547
  // src/cli/commands/project/scaffold-shared.ts
249592
- import { join as join27 } from "node:path";
249548
+ import { join as join28 } from "node:path";
249593
249549
  var DEFAULT_TEMPLATE_ID = "backend-only";
249594
249550
  async function getTemplateById(templateId) {
249595
249551
  const templates = await listTemplates();
@@ -249652,7 +249608,7 @@ async function completeProjectSetup({
249652
249608
  env: { VITE_BASE44_APP_ID: projectId }
249653
249609
  })`${buildCommand}`;
249654
249610
  updateMessage("Deploying site...");
249655
- return await deploySite(join27(resolvedPath, outputDirectory));
249611
+ return await deploySite(join28(resolvedPath, outputDirectory));
249656
249612
  }, {
249657
249613
  successMessage: theme.colors.base44Orange("Site deployed successfully"),
249658
249614
  errorMessage: "Failed to deploy site"
@@ -249781,7 +249737,7 @@ async function createInteractive(options, ctx) {
249781
249737
  }, ctx);
249782
249738
  }
249783
249739
  async function createNonInteractive(options, ctx) {
249784
- ctx.log.info(`Creating a new project at ${resolve10(options.path)}`);
249740
+ ctx.log.info(`Creating a new project at ${resolve11(options.path)}`);
249785
249741
  const template = await getTemplateById(options.template ?? DEFAULT_TEMPLATE_ID);
249786
249742
  return await executeCreate({
249787
249743
  template,
@@ -249805,7 +249761,7 @@ async function executeCreate({
249805
249761
  }, ctx) {
249806
249762
  const { log, runTask } = ctx;
249807
249763
  const name = rawName.trim();
249808
- const resolvedPath = resolve10(projectPath);
249764
+ const resolvedPath = resolve11(projectPath);
249809
249765
  const organizationId = await resolveWorkspaceId(ctx, flagWorkspaceId, isInteractive);
249810
249766
  const { projectId } = await runTask("Setting up your project...", async () => {
249811
249767
  return await createProjectFiles({
@@ -249867,15 +249823,7 @@ async function deployAction(ctx, options = {}) {
249867
249823
  outroMessage: "No resources found to deploy"
249868
249824
  };
249869
249825
  }
249870
- const {
249871
- project,
249872
- entities,
249873
- functions,
249874
- actors,
249875
- agents,
249876
- connectors,
249877
- authConfig
249878
- } = projectData;
249826
+ const { project, entities, functions, agents, connectors, authConfig } = projectData;
249879
249827
  const summaryLines = [];
249880
249828
  if (entities.length > 0) {
249881
249829
  summaryLines.push(` - ${entities.length} ${entities.length === 1 ? "entity" : "entities"}`);
@@ -249883,9 +249831,6 @@ async function deployAction(ctx, options = {}) {
249883
249831
  if (functions.length > 0) {
249884
249832
  summaryLines.push(` - ${functions.length} ${functions.length === 1 ? "function" : "functions"}`);
249885
249833
  }
249886
- if (actors.length > 0) {
249887
- summaryLines.push(` - ${actors.length} ${actors.length === 1 ? "actor" : "actors"}`);
249888
- }
249889
249834
  if (agents.length > 0) {
249890
249835
  summaryLines.push(` - ${agents.length} ${agents.length === 1 ? "agent" : "agents"}`);
249891
249836
  }
@@ -249919,7 +249864,6 @@ ${summaryLines.join(`
249919
249864
  await maybeBuildBeforeDeploy(ctx, project, options.build);
249920
249865
  let functionCompleted = 0;
249921
249866
  const functionTotal = functions.length;
249922
- let actorCompleted = 0;
249923
249867
  const result = await deployAll(projectData, {
249924
249868
  onVisibilitySet: (level) => {
249925
249869
  log.success(`App visibility set to ${level}`);
@@ -249931,16 +249875,6 @@ ${summaryLines.join(`
249931
249875
  onFunctionResult: (r) => {
249932
249876
  functionCompleted++;
249933
249877
  formatDeployResult(r, log);
249934
- },
249935
- onActorStart: (name) => {
249936
- log.step(theme.styles.dim(`[${actorCompleted + 1}/${actors.length}] Deploying ${name}...`));
249937
- },
249938
- onActorResult: (result) => {
249939
- actorCompleted++;
249940
- formatDeployResult(result, log);
249941
- if (result.status !== "error")
249942
- for (const warning of result.warnings)
249943
- log.warn(`${result.name}: ${warning}`);
249944
249878
  }
249945
249879
  });
249946
249880
  const connectorResults = result.connectorResults ?? [];
@@ -249955,8 +249889,8 @@ ${summaryLines.join(`
249955
249889
  }
249956
249890
  return { outroMessage: "App deployed successfully" };
249957
249891
  }
249958
- function getDeployCommand3() {
249959
- return new Base44Command("deploy").description("Deploy all project resources (entities, functions, actors, 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);
249892
+ function getDeployCommand2() {
249893
+ 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);
249960
249894
  }
249961
249895
  async function handleOAuthConnectors(connectorResults, isNonInteractive, options, log) {
249962
249896
  const needsOAuth = filterPendingOAuth(connectorResults);
@@ -250446,7 +250380,7 @@ function getLogsCommand() {
250446
250380
  }
250447
250381
 
250448
250382
  // src/cli/commands/project/scaffold.ts
250449
- import { basename as basename7, resolve as resolve11 } from "node:path";
250383
+ import { basename as basename7, resolve as resolve12 } from "node:path";
250450
250384
  function resolveAppId(options) {
250451
250385
  const appId = options.appId;
250452
250386
  if (!appId) {
@@ -250462,7 +250396,7 @@ function resolveAppId(options) {
250462
250396
  async function scaffoldAction(ctx, name, options, command) {
250463
250397
  const { log, runTask } = ctx;
250464
250398
  const appId = resolveAppId(command.optsWithGlobals());
250465
- const resolvedPath = resolve11("./");
250399
+ const resolvedPath = resolve12("./");
250466
250400
  const projectName = (name ?? basename7(resolvedPath)).trim();
250467
250401
  const template = await getTemplateById("backend-only");
250468
250402
  log.info(`Scaffolding project at ${resolvedPath}`);
@@ -250510,6 +250444,62 @@ function getVisibilityCommand() {
250510
250444
  ])).action(setVisibility);
250511
250445
  }
250512
250446
 
250447
+ // src/cli/commands/publish.ts
250448
+ async function publishAction(ctx, options) {
250449
+ const { runTask, log, jsonMode, app } = ctx;
250450
+ const target = await resolvePublishTarget(app?.projectRoot, {
250451
+ outputDir: options.outputDir
250452
+ });
250453
+ if (options.build !== false) {
250454
+ await tagStep("build", () => runSiteBuild(ctx, {
250455
+ root: target.root,
250456
+ buildCommand: target.buildCommand,
250457
+ appId: app?.id ?? ""
250458
+ }));
250459
+ }
250460
+ const outputDir = requireOutputDir(target);
250461
+ const gitHash = await resolveProvenanceCommit(target.root, options.gitHash);
250462
+ const result = await runTask("Publishing...", async (updateMessage) => {
250463
+ const artifacts = {
250464
+ files: await collectBuildOutput(outputDir),
250465
+ ...await collectResources(target.configDir, target)
250466
+ };
250467
+ return await publishVersion(artifacts, {
250468
+ sourceCommit: gitHash,
250469
+ target: options.target,
250470
+ concurrency: options.concurrency,
250471
+ progress: {
250472
+ onDeclared: ({ fileCount, owedFiles }) => updateMessage(`Uploading ${owedFiles} of ${fileCount} files`),
250473
+ onUpload: ({ uploadedFiles, totalFiles }) => updateMessage(`Uploaded ${uploadedFiles} of ${totalFiles} files`)
250474
+ }
250475
+ });
250476
+ }, { successMessage: "Published", errorMessage: "Publish failed" });
250477
+ if (!jsonMode) {
250478
+ log.message(theme.styles.dim(`version ${result.versionId}${result.deduplicated ? " (existing content)" : ""}`));
250479
+ }
250480
+ return {
250481
+ outroMessage: `Deployment ${result.deploymentId} at revision ${result.revision}`,
250482
+ stdout: jsonMode ? `${JSON.stringify(result, null, 2)}
250483
+ ` : undefined
250484
+ };
250485
+ }
250486
+ function getPublishCommand() {
250487
+ return new Base44Command("publish").description("Build the app, record it as a version, and serve that version").option("--no-build", "Publish the existing build output without rebuilding").option("--output-dir <dir>", "Build output directory (defaults to the project's, else dist)").option("--target <name>", "Environment to serve the version at").addOption(new Option2("--git-hash <hash>", "Commit the build came from (defaults to the checkout's HEAD)").argParser(parseGitHash)).addOption(new Option2("--concurrency <n>", "Parallel file uploads").default(DEFAULT_VERSION_UPLOAD_CONCURRENCY).argParser(parseConcurrency)).action(publishAction);
250488
+ }
250489
+ function parseGitHash(value) {
250490
+ if (!isGitCommitHash(value)) {
250491
+ throw new InvalidArgumentError2("Expected a git commit hash (7-64 hex chars).");
250492
+ }
250493
+ return value;
250494
+ }
250495
+ function parseConcurrency(value) {
250496
+ const parsed = Number(value);
250497
+ if (!Number.isInteger(parsed) || parsed < 1 || parsed > MAX_VERSION_UPLOAD_CONCURRENCY) {
250498
+ throw new InvalidArgumentError2(`Expected a whole number between 1 and ${MAX_VERSION_UPLOAD_CONCURRENCY}.`);
250499
+ }
250500
+ return parsed;
250501
+ }
250502
+
250513
250503
  // src/core/resources/sandbox/schema.ts
250514
250504
  var FileErrorSchema = object({
250515
250505
  code: string2(),
@@ -250879,7 +250869,7 @@ function getSecretsListCommand() {
250879
250869
  }
250880
250870
 
250881
250871
  // src/cli/commands/secrets/set.ts
250882
- import { resolve as resolve12 } from "node:path";
250872
+ import { resolve as resolve13 } from "node:path";
250883
250873
  function parseEntries(entries) {
250884
250874
  const secrets = {};
250885
250875
  for (const entry of entries) {
@@ -250910,7 +250900,7 @@ async function setSecretsAction({ log, runTask }, entries, options) {
250910
250900
  validateInput(entries, options);
250911
250901
  let secrets;
250912
250902
  if (options.envFile) {
250913
- secrets = await parseEnvFile(resolve12(options.envFile));
250903
+ secrets = await parseEnvFile(resolve13(options.envFile));
250914
250904
  if (Object.keys(secrets).length === 0) {
250915
250905
  throw new InvalidInputError("The env file contains no valid KEY=VALUE entries.");
250916
250906
  }
@@ -250939,7 +250929,7 @@ function getSecretsCommand() {
250939
250929
  }
250940
250930
 
250941
250931
  // src/cli/commands/site/deploy.ts
250942
- import { resolve as resolve13 } from "node:path";
250932
+ import { resolve as resolve14 } from "node:path";
250943
250933
  async function deployAction2(ctx, options) {
250944
250934
  const { isNonInteractive } = ctx;
250945
250935
  if (isNonInteractive && !options.yes) {
@@ -251017,23 +251007,23 @@ async function deployTarball({ runTask }, project) {
251017
251007
  }
251018
251008
  function siteOutputDir(project) {
251019
251009
  const outputDirectory = project.site?.outputDirectory;
251020
- return outputDirectory ? resolve13(project.root, outputDirectory) : null;
251010
+ return outputDirectory ? resolve14(project.root, outputDirectory) : null;
251021
251011
  }
251022
251012
  function getSiteDeployCommand() {
251023
251013
  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)");
251024
251014
  if (deploymentsApiEnabled()) {
251025
- command.addOption(new Option2("--git-hash <hash>", "Commit the build came from (defaults to the checkout's HEAD)").argParser(parseGitHash));
251026
- command.addOption(new Option2("--concurrency <n>", "Parallel asset uploads").default(DEFAULT_UPLOAD_CONCURRENCY).argParser(parseConcurrency));
251015
+ command.addOption(new Option2("--git-hash <hash>", "Commit the build came from (defaults to the checkout's HEAD)").argParser(parseGitHash2));
251016
+ command.addOption(new Option2("--concurrency <n>", "Parallel asset uploads").default(DEFAULT_UPLOAD_CONCURRENCY).argParser(parseConcurrency2));
251027
251017
  }
251028
251018
  return command.action(deployAction2);
251029
251019
  }
251030
- function parseGitHash(value) {
251020
+ function parseGitHash2(value) {
251031
251021
  if (!isGitCommitHash(value)) {
251032
251022
  throw new InvalidArgumentError2("Expected a git commit hash (7-64 hex chars).");
251033
251023
  }
251034
251024
  return value;
251035
251025
  }
251036
- function parseConcurrency(value) {
251026
+ function parseConcurrency2(value) {
251037
251027
  const parsed = Number(value);
251038
251028
  if (!Number.isInteger(parsed) || parsed < 1 || parsed > MAX_UPLOAD_CONCURRENCY) {
251039
251029
  throw new InvalidArgumentError2(`Expected a whole number between 1 and ${MAX_UPLOAD_CONCURRENCY}.`);
@@ -251071,12 +251061,10 @@ var EMPTY_TEMPLATE = import_common_tags.stripIndent`
251071
251061
  // Auto-generated by Base44 CLI - DO NOT EDIT
251072
251062
  // Regenerate with: base44 types
251073
251063
  //
251074
- // No entities, functions, actors, agents, or connectors found in project.
251075
- // Add resources to base44/entities/, base44/functions/, base44/actors/, base44/agents/, or base44/connectors/
251064
+ // No entities, functions, agents, or connectors found in project.
251065
+ // Add resources to base44/entities/, base44/functions/, base44/agents/, or base44/connectors/
251076
251066
  // and run \`base44 types generate\` again.
251077
251067
 
251078
- import '@base44/sdk';
251079
-
251080
251068
  declare module '@base44/sdk' {
251081
251069
  // No types to augment - add resources and regenerate
251082
251070
  }
@@ -251086,8 +251074,8 @@ async function generateTypesFile(input) {
251086
251074
  await writeFile(getTypesOutputPath(input.projectRoot), content);
251087
251075
  }
251088
251076
  async function generateContent(input) {
251089
- const { entities, functions, actors, agents, connectors } = input;
251090
- if (!entities.length && !functions.length && !actors.length && !agents.length && !connectors.length) {
251077
+ const { entities, functions, agents, connectors } = input;
251078
+ if (!entities.length && !functions.length && !agents.length && !connectors.length) {
251091
251079
  return EMPTY_TEMPLATE;
251092
251080
  }
251093
251081
  const entityInterfaces = await Promise.all(entities.map((e) => compileEntity(e)));
@@ -251097,14 +251085,12 @@ async function generateContent(input) {
251097
251085
  entities.map((e) => `"${e.name}": ${toPascalCase(e.name)};`)
251098
251086
  ],
251099
251087
  ["FunctionNameRegistry", functions.map((f) => `"${f.name}": true;`)],
251100
- ["ActorNameRegistry", actors.map((actor) => `"${actor.name}": true;`)],
251101
251088
  ["AgentNameRegistry", agents.map((a) => `"${a.name}": true;`)],
251102
251089
  ["ConnectorTypeRegistry", connectors.map((c) => `"${c.type}": true;`)]
251103
251090
  ];
251104
251091
  const registries = registryEntries.filter(([, entries]) => entries.length > 0).map(([name, entries]) => registry2(name, entries));
251105
251092
  return [
251106
251093
  HEADER2,
251107
- "import '@base44/sdk';",
251108
251094
  entityInterfaces.join(`
251109
251095
 
251110
251096
  `),
@@ -251149,10 +251135,10 @@ function toPascalCase(name) {
251149
251135
  return name.split(/[-_\s]+/).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join("");
251150
251136
  }
251151
251137
  // src/core/types/update-project.ts
251152
- import { join as join30 } from "node:path";
251138
+ import { join as join31 } from "node:path";
251153
251139
  var TYPES_INCLUDE_PATH = `${PROJECT_SUBDIR}/${TYPES_OUTPUT_SUBDIR}/*.d.ts`;
251154
251140
  async function updateProjectConfig(projectRoot) {
251155
- const tsconfigPath = join30(projectRoot, "tsconfig.json");
251141
+ const tsconfigPath = join31(projectRoot, "tsconfig.json");
251156
251142
  if (!await pathExists(tsconfigPath)) {
251157
251143
  return false;
251158
251144
  }
@@ -251176,13 +251162,12 @@ var TYPES_FILE_PATH = "base44/.types/types.d.ts";
251176
251162
  async function generateTypesAction({
251177
251163
  runTask
251178
251164
  }) {
251179
- const { entities, functions, actors, agents, connectors, project } = await readProjectConfig();
251165
+ const { entities, functions, agents, connectors, project } = await readProjectConfig();
251180
251166
  await runTask("Generating types", async () => {
251181
251167
  await generateTypesFile({
251182
251168
  projectRoot: project.root,
251183
251169
  entities,
251184
251170
  functions,
251185
- actors,
251186
251171
  agents,
251187
251172
  connectors
251188
251173
  });
@@ -251201,6 +251186,69 @@ function getTypesCommand() {
251201
251186
  return new Command2("types").description("Manage TypeScript type generation").addCommand(getTypesGenerateCommand());
251202
251187
  }
251203
251188
 
251189
+ // src/cli/commands/versions/create.ts
251190
+ async function createAction2({ runTask, jsonMode, app }, options) {
251191
+ const target = await resolvePublishTarget(app?.projectRoot, {
251192
+ outputDir: options.outputDir
251193
+ });
251194
+ const gitHash = await resolveProvenanceCommit(target.root, options.gitHash);
251195
+ const version = await runTask("Creating version...", async (updateMessage) => await createVersion({
251196
+ files: await collectBuildOutput(requireOutputDir(target)),
251197
+ ...await collectResources(target.configDir, target)
251198
+ }, {
251199
+ sourceCommit: gitHash,
251200
+ concurrency: options.concurrency,
251201
+ progress: {
251202
+ onDeclared: ({ fileCount, owedFiles }) => updateMessage(`Uploading ${owedFiles} of ${fileCount} files`),
251203
+ onUpload: ({ uploadedFiles, totalFiles }) => updateMessage(`Uploaded ${uploadedFiles} of ${totalFiles} files`)
251204
+ }
251205
+ }), {
251206
+ successMessage: "Version created",
251207
+ errorMessage: "Create version failed"
251208
+ });
251209
+ return {
251210
+ outroMessage: `Version ${version.versionId} (${version.manifestHash})`,
251211
+ stdout: jsonMode ? `${JSON.stringify(version, null, 2)}
251212
+ ` : undefined
251213
+ };
251214
+ }
251215
+ function getVersionCreateCommand() {
251216
+ return new Base44Command("create").description("Record the built output as a version, without deploying it").option("--output-dir <dir>", "Build output directory (defaults to the project's, else dist)").addOption(new Option2("--git-hash <hash>", "Commit the build came from (defaults to the checkout's HEAD)").argParser((value) => {
251217
+ if (!isGitCommitHash(value)) {
251218
+ throw new InvalidArgumentError2("Expected a git commit hash (7-64 hex chars).");
251219
+ }
251220
+ return value;
251221
+ })).addOption(new Option2("--concurrency <n>", "Parallel file uploads").default(DEFAULT_VERSION_UPLOAD_CONCURRENCY).argParser((value) => {
251222
+ const parsed = Number(value);
251223
+ if (!Number.isInteger(parsed) || parsed < 1 || parsed > MAX_VERSION_UPLOAD_CONCURRENCY) {
251224
+ throw new InvalidArgumentError2(`Expected a whole number between 1 and ${MAX_VERSION_UPLOAD_CONCURRENCY}.`);
251225
+ }
251226
+ return parsed;
251227
+ })).action(createAction2);
251228
+ }
251229
+
251230
+ // src/cli/commands/versions/deploy.ts
251231
+ import { randomUUID as randomUUID5 } from "node:crypto";
251232
+ async function deployAction3({ runTask, jsonMode }, versionId, options) {
251233
+ const deployment = await runTask(`Deploying version ${versionId}...`, async () => await deployVersion(versionId, {
251234
+ target: options.target,
251235
+ idempotencyKey: randomUUID5()
251236
+ }), { successMessage: "Version deployed", errorMessage: "Deploy failed" });
251237
+ return {
251238
+ outroMessage: `Deployment ${deployment.deploymentId} at revision ${deployment.revision}`,
251239
+ stdout: jsonMode ? `${JSON.stringify(deployment, null, 2)}
251240
+ ` : undefined
251241
+ };
251242
+ }
251243
+ function getVersionDeployCommand() {
251244
+ return new Base44Command("deploy").description("Serve an already-recorded version (also how a rollback is done)").argument("<version-id>", "The version to serve").option("--target <name>", "Environment to serve the version at").action(deployAction3);
251245
+ }
251246
+
251247
+ // src/cli/commands/versions/index.ts
251248
+ function getVersionsCommand() {
251249
+ return new Command2("versions").description("Record app versions and serve them").addCommand(getVersionCreateCommand()).addCommand(getVersionDeployCommand());
251250
+ }
251251
+
251204
251252
  // src/core/resources/workflow/schema.ts
251205
251253
  var WorkflowRunStatusSchema = _enum([
251206
251254
  "running",
@@ -251617,7 +251665,7 @@ function createDevLogger(label, labelColor = theme.styles.dim) {
251617
251665
  // src/cli/dev/dev-server/main.ts
251618
251666
  var import_cors = __toESM(require_lib4(), 1);
251619
251667
  var import_express6 = __toESM(require_express(), 1);
251620
- import { dirname as dirname26, join as join36 } from "node:path";
251668
+ import { dirname as dirname25, join as join37 } from "node:path";
251621
251669
 
251622
251670
  // ../../node_modules/get-port/index.js
251623
251671
  import net from "node:net";
@@ -251747,7 +251795,7 @@ var $tmpName = promisify11(tmp.tmpName);
251747
251795
 
251748
251796
  // src/cli/dev/dev-server/function-manager.ts
251749
251797
  import { spawn as spawn2 } from "node:child_process";
251750
- import { dirname as dirname23, join as join31 } from "node:path";
251798
+ import { dirname as dirname22, join as join33 } from "node:path";
251751
251799
  import { pathToFileURL } from "node:url";
251752
251800
 
251753
251801
  // src/cli/dev/dev-server/base-function-manager.ts
@@ -251852,7 +251900,7 @@ class FunctionManager extends BaseFunctionManager {
251852
251900
  }
251853
251901
  spawnFunction(func, port) {
251854
251902
  this.logger.log(`Spawning function "${func.name}" on port ${port}`);
251855
- const importMapPath = join31(dirname23(this.wrapperPath), "import-map.json");
251903
+ const importMapPath = join33(dirname22(this.wrapperPath), "import-map.json");
251856
251904
  const process2 = spawn2("deno", ["run", "--allow-all", "--import-map", importMapPath, this.wrapperPath], {
251857
251905
  env: {
251858
251906
  ...globalThis.process.env,
@@ -251926,7 +251974,7 @@ class FunctionManager extends BaseFunctionManager {
251926
251974
  import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "node:fs";
251927
251975
  import { isBuiltin } from "node:module";
251928
251976
  import { homedir as homedir3 } from "node:os";
251929
- import { join as join33 } from "node:path";
251977
+ import { join as join34 } from "node:path";
251930
251978
  import { pathToFileURL as pathToFileURL6 } from "node:url";
251931
251979
  var depsPromise;
251932
251980
  function loadDeps() {
@@ -252047,9 +252095,9 @@ export default {
252047
252095
  };
252048
252096
  `;
252049
252097
  function ensureBundlerConfig() {
252050
- const dir = join33(homedir3(), ".base44", "function-bundler");
252098
+ const dir = join34(homedir3(), ".base44", "function-bundler");
252051
252099
  mkdirSync2(dir, { recursive: true });
252052
- const configPath = join33(dir, "deno.json");
252100
+ const configPath = join34(dir, "deno.json");
252053
252101
  writeFileSync2(configPath, `${JSON.stringify({ nodeModulesDir: "auto" }, null, 2)}
252054
252102
  `);
252055
252103
  return configPath;
@@ -253430,11 +253478,11 @@ async function createEntityRoutes(db, logger, broadcast) {
253430
253478
  // src/cli/dev/dev-server/routes/integrations.ts
253431
253479
  var import_express5 = __toESM(require_express(), 1);
253432
253480
  var import_multer = __toESM(require_multer(), 1);
253433
- import { createHash as createHash2, randomUUID as randomUUID4 } from "node:crypto";
253481
+ import { createHash as createHash3, randomUUID as randomUUID6 } from "node:crypto";
253434
253482
  import fs28 from "node:fs";
253435
253483
  import path18 from "node:path";
253436
253484
  function createFileToken(fileUri) {
253437
- return createHash2("sha256").update(fileUri).digest("hex");
253485
+ return createHash3("sha256").update(fileUri).digest("hex");
253438
253486
  }
253439
253487
  function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
253440
253488
  const router = import_express5.Router({ mergeParams: true });
@@ -253447,14 +253495,14 @@ function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
253447
253495
  destination: mediaFilesDir,
253448
253496
  filename: (_req, file, cb) => {
253449
253497
  const ext = path18.extname(file.originalname);
253450
- cb(null, `${randomUUID4()}${ext}`);
253498
+ cb(null, `${randomUUID6()}${ext}`);
253451
253499
  }
253452
253500
  });
253453
253501
  const privateStorage = import_multer.default.diskStorage({
253454
253502
  destination: privateFilesDir,
253455
253503
  filename: (_req, file, cb) => {
253456
253504
  const ext = path18.extname(file.originalname);
253457
- cb(null, `${randomUUID4()}${ext}`);
253505
+ cb(null, `${randomUUID6()}${ext}`);
253458
253506
  }
253459
253507
  });
253460
253508
  const upload = import_multer.default({ storage, limits: { fileSize: MAX_FILE_SIZE } });
@@ -253519,16 +253567,16 @@ function createCustomIntegrationRoutes(remoteProxy, logger) {
253519
253567
 
253520
253568
  // src/cli/dev/dev-server/watcher.ts
253521
253569
  import { EventEmitter as EventEmitter4 } from "node:events";
253522
- import { relative as relative9 } from "node:path";
253570
+ import { relative as relative7 } from "node:path";
253523
253571
 
253524
253572
  // ../../node_modules/chokidar/index.js
253525
253573
  import { EventEmitter as EventEmitter3 } from "node:events";
253526
253574
  import { stat as statcb, Stats } from "node:fs";
253527
- import { readdir as readdir3, stat as stat6 } from "node:fs/promises";
253575
+ import { readdir as readdir3, stat as stat7 } from "node:fs/promises";
253528
253576
  import * as sp3 from "node:path";
253529
253577
 
253530
253578
  // ../../node_modules/readdirp/index.js
253531
- import { lstat as lstat2, readdir as readdir2, realpath, stat as stat4 } from "node:fs/promises";
253579
+ import { lstat as lstat2, readdir as readdir2, realpath, stat as stat5 } from "node:fs/promises";
253532
253580
  import { join as pjoin, relative as prelative, resolve as presolve, sep as psep } from "node:path";
253533
253581
  import { Readable as Readable6 } from "node:stream";
253534
253582
  var EntryTypes = {
@@ -253610,7 +253658,7 @@ class ReaddirpStream extends Readable6 {
253610
253658
  const { root, type } = opts;
253611
253659
  this._fileFilter = normalizeFilter(opts.fileFilter);
253612
253660
  this._directoryFilter = normalizeFilter(opts.directoryFilter);
253613
- const statMethod = opts.lstat ? lstat2 : stat4;
253661
+ const statMethod = opts.lstat ? lstat2 : stat5;
253614
253662
  if (wantBigintFsStats) {
253615
253663
  this._stat = (path) => statMethod(path, { bigint: true });
253616
253664
  } else {
@@ -253763,7 +253811,7 @@ function readdirp(root, options = {}) {
253763
253811
 
253764
253812
  // ../../node_modules/chokidar/handler.js
253765
253813
  import { watch as fs_watch, unwatchFile, watchFile } from "node:fs";
253766
- import { realpath as fsrealpath, lstat as lstat3, open as open2, stat as stat5 } from "node:fs/promises";
253814
+ import { realpath as fsrealpath, lstat as lstat3, open as open2, stat as stat6 } from "node:fs/promises";
253767
253815
  import { type as osType } from "node:os";
253768
253816
  import * as sp2 from "node:path";
253769
253817
  var STR_DATA = "data";
@@ -253789,7 +253837,7 @@ var EVENTS = {
253789
253837
  };
253790
253838
  var EV = EVENTS;
253791
253839
  var THROTTLE_MODE_WATCH = "watch";
253792
- var statMethods = { lstat: lstat3, stat: stat5 };
253840
+ var statMethods = { lstat: lstat3, stat: stat6 };
253793
253841
  var KEY_LISTENERS = "listeners";
253794
253842
  var KEY_ERR = "errHandlers";
253795
253843
  var KEY_RAW = "rawEmitters";
@@ -254260,7 +254308,7 @@ class NodeFsHandler {
254260
254308
  return;
254261
254309
  if (!newStats || newStats.mtimeMs === 0) {
254262
254310
  try {
254263
- const newStats = await stat5(file);
254311
+ const newStats = await stat6(file);
254264
254312
  if (this.fsw.closed)
254265
254313
  return;
254266
254314
  const at = newStats.atimeMs;
@@ -254932,7 +254980,7 @@ class FSWatcher extends EventEmitter3 {
254932
254980
  const fullPath = opts.cwd ? sp3.join(opts.cwd, path) : path;
254933
254981
  let stats;
254934
254982
  try {
254935
- stats = await stat6(fullPath);
254983
+ stats = await stat7(fullPath);
254936
254984
  } catch (err) {}
254937
254985
  if (!stats || this.closed)
254938
254986
  return;
@@ -255204,7 +255252,7 @@ class WatchBase44 extends EventEmitter4 {
255204
255252
  ignoreInitial: true
255205
255253
  });
255206
255254
  watcher.on("all", import_debounce.default(async (_event, path) => {
255207
- this.emit("change", name, relative9(targetPath, path));
255255
+ this.emit("change", name, relative7(targetPath, path));
255208
255256
  }, WATCH_DEBOUNCE_MS));
255209
255257
  watcher.on("error", (err) => {
255210
255258
  this.logger.error(`Watch handler failed for ${targetPath}`, err);
@@ -255241,11 +255289,6 @@ async function createDevServer(options) {
255241
255289
  next();
255242
255290
  });
255243
255291
  const devLogger = createDevLogger("backend", theme.styles.info);
255244
- app.use("/api/apps/:appId/actors", (_req, res) => {
255245
- const message = "Actors are not available in local development";
255246
- devLogger.error(message);
255247
- res.status(500).json({ error: message });
255248
- });
255249
255292
  const functionManager = await createFunctionRuntime(functions, devLogger, options.denoWrapperPath);
255250
255293
  const functionRoutes = createFunctionRouter(functionManager, devLogger);
255251
255294
  app.use("/api/apps/:appId/functions", functionRoutes);
@@ -255316,8 +255359,8 @@ async function createDevServer(options) {
255316
255359
  broadcastEntityEvent(io, appId, entityName, event);
255317
255360
  };
255318
255361
  const base44ConfigWatcher = new WatchBase44({
255319
- functions: join36(dirname26(project.configPath), project.functionsDir),
255320
- entities: join36(dirname26(project.configPath), project.entitiesDir)
255362
+ functions: join37(dirname25(project.configPath), project.functionsDir),
255363
+ entities: join37(dirname25(project.configPath), project.entitiesDir)
255321
255364
  }, devLogger);
255322
255365
  base44ConfigWatcher.on("change", async (name) => {
255323
255366
  try {
@@ -255714,7 +255757,7 @@ Examples:
255714
255757
  }
255715
255758
 
255716
255759
  // src/cli/commands/project/eject.ts
255717
- import { resolve as resolve17 } from "node:path";
255760
+ import { resolve as resolve18 } from "node:path";
255718
255761
  var import_kebabCase2 = __toESM(require_kebabCase(), 1);
255719
255762
  async function eject(ctx, options, command) {
255720
255763
  const { log, runTask, isNonInteractive } = ctx;
@@ -255778,7 +255821,7 @@ async function eject(ctx, options, command) {
255778
255821
  Ne("Operation cancelled.");
255779
255822
  throw new CLIExitError(0);
255780
255823
  }
255781
- const resolvedPath = resolve17(selectedPath);
255824
+ const resolvedPath = resolve18(selectedPath);
255782
255825
  await runTask("Downloading your project's code...", async (updateMessage) => {
255783
255826
  await createProjectFilesForExistingProject({
255784
255827
  projectId,
@@ -255845,7 +255888,7 @@ function createProgram(context) {
255845
255888
  program.addCommand(getScaffoldCommand());
255846
255889
  program.addCommand(getDashboardCommand());
255847
255890
  program.addCommand(getBuildCommand());
255848
- program.addCommand(getDeployCommand3());
255891
+ program.addCommand(getDeployCommand2());
255849
255892
  program.addCommand(getVisibilityCommand());
255850
255893
  program.addCommand(getLinkCommand());
255851
255894
  program.addCommand(getEjectCommand());
@@ -255855,13 +255898,14 @@ function createProgram(context) {
255855
255898
  program.addCommand(getAgentSkillsCommand());
255856
255899
  program.addCommand(getConnectorsCommand());
255857
255900
  program.addCommand(getFunctionsCommand());
255858
- program.addCommand(getActorsCommand());
255859
255901
  program.addCommand(getWorkflowsCommand());
255860
255902
  program.addCommand(getSecretsCommand());
255861
255903
  program.addCommand(getSandboxCommand());
255862
255904
  program.addCommand(getBranchesCommand());
255863
255905
  program.addCommand(getAuthCommand());
255864
255906
  program.addCommand(getSiteCommand());
255907
+ program.addCommand(getPublishCommand());
255908
+ program.addCommand(getVersionsCommand());
255865
255909
  program.addCommand(getTypesCommand());
255866
255910
  program.addCommand(getExecCommand());
255867
255911
  program.addCommand(getDevCommand());
@@ -255874,7 +255918,7 @@ var import_detect_agent = __toESM(require_dist5(), 1);
255874
255918
  import { release, type } from "node:os";
255875
255919
 
255876
255920
  // ../../node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
255877
- import { dirname as dirname27, posix, sep as sep2 } from "path";
255921
+ import { dirname as dirname26, posix, sep as sep2 } from "path";
255878
255922
  function createModulerModifier() {
255879
255923
  const getModuleFromFileName = createGetModuleFromFilename();
255880
255924
  return async (frames) => {
@@ -255883,7 +255927,7 @@ function createModulerModifier() {
255883
255927
  return frames;
255884
255928
  };
255885
255929
  }
255886
- function createGetModuleFromFilename(basePath = process.argv[1] ? dirname27(process.argv[1]) : process.cwd(), isWindows = sep2 === "\\") {
255930
+ function createGetModuleFromFilename(basePath = process.argv[1] ? dirname26(process.argv[1]) : process.cwd(), isWindows = sep2 === "\\") {
255887
255931
  const normalizedBase = isWindows ? normalizeWindowsPath2(basePath) : basePath;
255888
255932
  return (filename) => {
255889
255933
  if (!filename)
@@ -257918,7 +257962,7 @@ class ReduceableCache {
257918
257962
  }
257919
257963
  }
257920
257964
  // ../../node_modules/posthog-node/dist/extensions/error-tracking/modifiers/context-lines.node.mjs
257921
- import { createReadStream as createReadStream3 } from "node:fs";
257965
+ import { createReadStream as createReadStream4 } from "node:fs";
257922
257966
  import { createInterface as createInterface2 } from "node:readline";
257923
257967
  var LRU_FILE_CONTENTS_CACHE = new ReduceableCache(25);
257924
257968
  var LRU_FILE_CONTENTS_FS_READ_FAILED = new ReduceableCache(20);
@@ -257962,7 +258006,7 @@ async function addSourceContext(frames) {
257962
258006
  }
257963
258007
  function getContextLinesFromFile(path, ranges, output) {
257964
258008
  return new Promise((resolve) => {
257965
- const stream = createReadStream3(path);
258009
+ const stream = createReadStream4(path);
257966
258010
  const lineReaded = createInterface2({
257967
258011
  input: stream
257968
258012
  });
@@ -259872,9 +259916,9 @@ function addCommandInfoToErrorReporter(program, errorReporter) {
259872
259916
  });
259873
259917
  }
259874
259918
  // src/cli/index.ts
259875
- var __dirname4 = dirname28(fileURLToPath6(import.meta.url));
259919
+ var __dirname4 = dirname27(fileURLToPath6(import.meta.url));
259876
259920
  async function runCLI(options) {
259877
- ensureNpmAssets(join37(__dirname4, "../assets"));
259921
+ ensureNpmAssets(join38(__dirname4, "../assets"));
259878
259922
  const errorReporter = new ErrorReporter;
259879
259923
  errorReporter.registerProcessErrorHandlers();
259880
259924
  const jsonMode = process.argv.includes("--json");
@@ -259913,4 +259957,4 @@ export {
259913
259957
  runCLI
259914
259958
  };
259915
259959
 
259916
- //# debugId=B6FD4E544C62B70764756E2164756E21
259960
+ //# debugId=2D9E75E3489C289064756E2164756E21