@base44-preview/cli 0.1.14-pr.626.999301d → 0.1.15-pr.623.32ad346

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" ? join29(replacement, currentDoc.split(`
31180
+ return mapDoc(doc, (currentDoc) => typeof currentDoc === "string" ? join28(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 join29(separator, docs) {
31260
+ function join28(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: join29,
31971
+ join: join28,
31972
31972
  line,
31973
31973
  softline,
31974
31974
  hardline,
@@ -228634,6 +228634,10 @@ class InternalError extends SystemError {
228634
228634
  }
228635
228635
  }
228636
228636
 
228637
+ class ResourceDeploymentError extends SystemError {
228638
+ code = "RESOURCE_DEPLOYMENT_FAILED";
228639
+ }
228640
+
228637
228641
  class TypeGenerationError extends SystemError {
228638
228642
  code = "TYPE_GENERATION_ERROR";
228639
228643
  constructor(message, entityName, cause) {
@@ -228779,7 +228783,7 @@ function normalizeBase44Env() {
228779
228783
  loadProjectEnvFiles();
228780
228784
 
228781
228785
  // src/cli/index.ts
228782
- import { dirname as dirname27, join as join38 } from "node:path";
228786
+ import { dirname as dirname28, join as join37 } from "node:path";
228783
228787
  import { fileURLToPath as fileURLToPath6 } from "node:url";
228784
228788
 
228785
228789
  // ../../node_modules/@clack/core/dist/index.mjs
@@ -229905,8 +229909,10 @@ var {
229905
229909
  Help: Help2
229906
229910
  } = exports_commander;
229907
229911
 
229908
- // src/cli/commands/agent-skills/pull.ts
229909
- import { dirname as dirname11, join as join18 } from "node:path";
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
+ }
229910
229916
  // ../../node_modules/chalk/source/vendor/ansi-styles/index.js
229911
229917
  var ANSI_BACKGROUND_OFFSET = 10;
229912
229918
  var wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
@@ -230720,6 +230726,7 @@ var ProjectConfigSchema = object({
230720
230726
  site: SiteConfigSchema.optional(),
230721
230727
  entitiesDir: string2().optional().default("entities"),
230722
230728
  functionsDir: string2().optional().default("functions"),
230729
+ actorsDir: string2().optional().default("actors"),
230723
230730
  agentsDir: string2().optional().default("agents"),
230724
230731
  agentSkillsDir: string2().optional().default("agent-skills"),
230725
230732
  connectorsDir: string2().optional().default("connectors"),
@@ -236672,7 +236679,7 @@ async function getSiteUrl() {
236672
236679
  return result.data.url;
236673
236680
  }
236674
236681
  // src/core/project/config.ts
236675
- import { dirname as dirname8, join as join11 } from "node:path";
236682
+ import { dirname as dirname10, join as join12 } from "node:path";
236676
236683
 
236677
236684
  // src/core/project/plugins.ts
236678
236685
  import { createRequire as createRequire2 } from "node:module";
@@ -236710,6 +236717,159 @@ function markPluginEntities(entities, pluginNamespace) {
236710
236717
  }));
236711
236718
  }
236712
236719
 
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
+ };
236713
236873
  // src/core/resources/agent/schema.ts
236714
236874
  var EntityOperationSchema = _enum(["create", "update", "delete", "read"]);
236715
236875
  var EntityToolConfigSchema = object({
@@ -236788,7 +236948,7 @@ async function fetchAgents() {
236788
236948
  return result.data;
236789
236949
  }
236790
236950
  // src/core/resources/agent/config.ts
236791
- import { join as join5, normalize } from "node:path";
236951
+ import { join as join6, normalize } from "node:path";
236792
236952
  import { isDeepStrictEqual } from "node:util";
236793
236953
  async function readAgentFile(agentPath) {
236794
236954
  const raw = await readJsonFile(agentPath);
@@ -236833,12 +236993,12 @@ async function readAllAgents(agentsDir) {
236833
236993
  return [...nameToEntry.values()].map((e) => e.data);
236834
236994
  }
236835
236995
  function findAvailablePath(agentsDir, name, claimedPaths) {
236836
- const base = join5(agentsDir, `${name}.${CONFIG_FILE_EXTENSION}`);
236996
+ const base = join6(agentsDir, `${name}.${CONFIG_FILE_EXTENSION}`);
236837
236997
  if (!claimedPaths.has(base)) {
236838
236998
  return base;
236839
236999
  }
236840
237000
  for (let i = 1;; i++) {
236841
- const candidate = join5(agentsDir, `${name}_${i}.${CONFIG_FILE_EXTENSION}`);
237001
+ const candidate = join6(agentsDir, `${name}_${i}.${CONFIG_FILE_EXTENSION}`);
236842
237002
  if (!claimedPaths.has(candidate)) {
236843
237003
  return candidate;
236844
237004
  }
@@ -236953,7 +237113,7 @@ async function pushAgentSkills(skills) {
236953
237113
  }
236954
237114
  // src/core/resources/agent-skill/config.ts
236955
237115
  var import_front_matter = __toESM(require_front_matter(), 1);
236956
- import { join as join6 } from "node:path";
237116
+ import { join as join7 } from "node:path";
236957
237117
 
236958
237118
  // ../../node_modules/yaml/dist/index.js
236959
237119
  var composer = require_composer();
@@ -237039,7 +237199,7 @@ async function writeAgentSkills(dir, remote) {
237039
237199
  const deleted = [];
237040
237200
  for (const skill of existing) {
237041
237201
  if (!remoteNames.has(skill.name)) {
237042
- await deleteFile(join6(dir, `${skill.name}.md`));
237202
+ await deleteFile(join7(dir, `${skill.name}.md`));
237043
237203
  deleted.push(skill.name);
237044
237204
  }
237045
237205
  }
@@ -237050,7 +237210,7 @@ async function writeAgentSkills(dir, remote) {
237050
237210
  if (prev && prev.description === skill.description && prev.body === skill.body) {
237051
237211
  continue;
237052
237212
  }
237053
- await writeFile(join6(dir, `${skill.name}.md`), serializeSkillFile(skill));
237213
+ await writeFile(join7(dir, `${skill.name}.md`), serializeSkillFile(skill));
237054
237214
  written.push(skill.name);
237055
237215
  }
237056
237216
  return { written, deleted };
@@ -237176,7 +237336,7 @@ async function pushAuthConfigToApi(config) {
237176
237336
  return result.data.authConfig;
237177
237337
  }
237178
237338
  // src/core/resources/auth-config/config.ts
237179
- import { join as join7 } from "node:path";
237339
+ import { join as join8 } from "node:path";
237180
237340
  import { isDeepStrictEqual as isDeepStrictEqual2 } from "node:util";
237181
237341
  var AUTH_CONFIG_FILENAME = `config.${CONFIG_FILE_EXTENSION}`;
237182
237342
  var DEFAULT_AUTH_CONFIG = {
@@ -237192,7 +237352,7 @@ var DEFAULT_AUTH_CONFIG = {
237192
237352
  useWorkspaceSSO: false
237193
237353
  };
237194
237354
  function getAuthConfigPath(authDir) {
237195
- return join7(authDir, AUTH_CONFIG_FILENAME);
237355
+ return join8(authDir, AUTH_CONFIG_FILENAME);
237196
237356
  }
237197
237357
  async function readAuthConfig(authDir) {
237198
237358
  const filePath = getAuthConfigPath(authDir);
@@ -237844,7 +238004,7 @@ async function removeStripe() {
237844
238004
  return result.data;
237845
238005
  }
237846
238006
  // src/core/resources/connector/config.ts
237847
- import { join as join8 } from "node:path";
238007
+ import { join as join9 } from "node:path";
237848
238008
  import { isDeepStrictEqual as isDeepStrictEqual3 } from "node:util";
237849
238009
  async function readConnectorFile(connectorPath) {
237850
238010
  const parsed = await readJsonFile(connectorPath);
@@ -237905,7 +238065,7 @@ async function writeConnectors(connectorsDir, remoteConnectors) {
237905
238065
  if (existing && isDeepStrictEqual3(existing.data, connector)) {
237906
238066
  continue;
237907
238067
  }
237908
- const filePath = existing?.filePath ?? join8(connectorsDir, `${connector.type}.${CONFIG_FILE_EXTENSION}`);
238068
+ const filePath = existing?.filePath ?? join9(connectorsDir, `${connector.type}.${CONFIG_FILE_EXTENSION}`);
237909
238069
  await writeJsonFile(filePath, connector);
237910
238070
  written.push(connector.type);
237911
238071
  }
@@ -238511,7 +238671,7 @@ async function fetchFunctionLogs(functionName, filters = {}) {
238511
238671
  return result.data;
238512
238672
  }
238513
238673
  // src/core/resources/function/config.ts
238514
- import { basename as basename3, dirname as dirname6, join as join9, relative, resolve as resolve2 } from "node:path";
238674
+ import { basename as basename4, dirname as dirname8, join as join10, relative as relative3, resolve as resolve2 } from "node:path";
238515
238675
  async function readSharedFiles(functionsDir) {
238516
238676
  const sharedDir = resolve2(functionsDir, "..", "shared");
238517
238677
  if (!await pathExists(sharedDir)) {
@@ -238529,8 +238689,8 @@ async function readFunctionConfig(configPath) {
238529
238689
  }
238530
238690
  async function readFunction(configPath, sharedFiles) {
238531
238691
  const config = await readFunctionConfig(configPath);
238532
- const functionDir = dirname6(configPath);
238533
- const entryPath = join9(functionDir, config.entry);
238692
+ const functionDir = dirname8(configPath);
238693
+ const entryPath = join10(functionDir, config.entry);
238534
238694
  if (!await pathExists(entryPath)) {
238535
238695
  throw new InvalidInputError(`Function entry file not found: ${entryPath} (referenced in ${configPath})`, {
238536
238696
  hints: [{ message: "Check the 'entry' field in your function config" }]
@@ -238562,18 +238722,18 @@ async function readAllFunctions(functionsDir) {
238562
238722
  absolute: true,
238563
238723
  ignore: ENTRY_IGNORE_DOT_PATHS
238564
238724
  });
238565
- const configFilesDirs = new Set(configFiles.map((f) => dirname6(f)));
238566
- const entryFilesWithoutConfig = entryFiles.filter((entryFile) => !configFilesDirs.has(dirname6(entryFile)));
238725
+ const configFilesDirs = new Set(configFiles.map((f) => dirname8(f)));
238726
+ const entryFilesWithoutConfig = entryFiles.filter((entryFile) => !configFilesDirs.has(dirname8(entryFile)));
238567
238727
  const sharedFiles = await readSharedFiles(functionsDir);
238568
238728
  const functionsFromConfig = await Promise.all(configFiles.map((configPath) => readFunction(configPath, sharedFiles)));
238569
238729
  const functionsWithoutConfig = await Promise.all(entryFilesWithoutConfig.map(async (entryFile) => {
238570
- const functionDir = dirname6(entryFile);
238730
+ const functionDir = dirname8(entryFile);
238571
238731
  const filePaths = await globby(BACKEND_FILE_GLOB, {
238572
238732
  cwd: functionDir,
238573
238733
  absolute: true
238574
238734
  });
238575
238735
  const allFilePaths = [...new Set([...filePaths, ...sharedFiles])];
238576
- const name = relative(functionsDir, functionDir).split(/[/\\]/).join("/");
238736
+ const name = relative3(functionsDir, functionDir).split(/[/\\]/).join("/");
238577
238737
  if (!name) {
238578
238738
  throw new InvalidInputError("entry.ts found directly in the functions directory — it must be inside a named subfolder", {
238579
238739
  hints: [
@@ -238583,7 +238743,7 @@ async function readAllFunctions(functionsDir) {
238583
238743
  ]
238584
238744
  });
238585
238745
  }
238586
- const entry = basename3(entryFile);
238746
+ const entry = basename4(entryFile);
238587
238747
  const functionData = {
238588
238748
  name,
238589
238749
  entry,
@@ -238610,17 +238770,17 @@ async function readAllFunctions(functionsDir) {
238610
238770
  return functions;
238611
238771
  }
238612
238772
  // src/core/resources/function/deploy.ts
238613
- import { dirname as dirname7, relative as relative2 } from "node:path";
238773
+ import { dirname as dirname9, relative as relative4 } from "node:path";
238614
238774
  async function loadFunctionCode(fn) {
238615
- const functionDir = dirname7(fn.entryPath);
238775
+ const functionDir = dirname9(fn.entryPath);
238616
238776
  const resolvedFiles = await Promise.all(fn.filePaths.map(async (filePath) => {
238617
238777
  const content = await readTextFile(filePath);
238618
- const path = relative2(functionDir, filePath).split(/[/\\]/).join("/");
238778
+ const path = relative4(functionDir, filePath).split(/[/\\]/).join("/");
238619
238779
  return { path, content };
238620
238780
  }));
238621
238781
  return { ...fn, files: resolvedFiles };
238622
238782
  }
238623
- async function deployOne(fn) {
238783
+ async function deployOne2(fn) {
238624
238784
  const start = Date.now();
238625
238785
  try {
238626
238786
  const functionWithCode = await loadFunctionCode(fn);
@@ -238648,7 +238808,7 @@ async function deployFunctionsSequentially(functions, options) {
238648
238808
  const results = [];
238649
238809
  for (const fn of functions) {
238650
238810
  options?.onStart?.([fn.name]);
238651
- const result = await deployOne(fn);
238811
+ const result = await deployOne2(fn);
238652
238812
  results.push(result);
238653
238813
  options?.onResult?.(result);
238654
238814
  }
@@ -238679,14 +238839,14 @@ async function pruneRemovedFunctions(localFunctionNames, options) {
238679
238839
  return results;
238680
238840
  }
238681
238841
  // src/core/resources/function/pull.ts
238682
- import { join as join10 } from "node:path";
238842
+ import { join as join11 } from "node:path";
238683
238843
  import { isDeepStrictEqual as isDeepStrictEqual4 } from "node:util";
238684
238844
  async function writeFunctions(functionsDir, functions) {
238685
238845
  const written = [];
238686
238846
  const skipped = [];
238687
238847
  for (const fn of functions) {
238688
- const functionDir = join10(functionsDir, fn.name);
238689
- const configPath = join10(functionDir, "function.jsonc");
238848
+ const functionDir = join11(functionsDir, fn.name);
238849
+ const configPath = join11(functionDir, "function.jsonc");
238690
238850
  if (await isFunctionUnchanged(functionDir, fn)) {
238691
238851
  skipped.push(fn.name);
238692
238852
  continue;
@@ -238700,7 +238860,7 @@ async function writeFunctions(functionsDir, functions) {
238700
238860
  }
238701
238861
  await writeJsonFile(configPath, config);
238702
238862
  for (const file of fn.files) {
238703
- await writeFile(join10(functionDir, file.path), file.content);
238863
+ await writeFile(join11(functionDir, file.path), file.content);
238704
238864
  }
238705
238865
  written.push(fn.name);
238706
238866
  }
@@ -238710,7 +238870,7 @@ async function isFunctionUnchanged(functionDir, fn) {
238710
238870
  if (!await pathExists(functionDir)) {
238711
238871
  return false;
238712
238872
  }
238713
- const configPath = join10(functionDir, "function.jsonc");
238873
+ const configPath = join11(functionDir, "function.jsonc");
238714
238874
  try {
238715
238875
  const localConfig = await readJsonFile(configPath);
238716
238876
  if (localConfig.entry !== fn.entry) {
@@ -238723,7 +238883,7 @@ async function isFunctionUnchanged(functionDir, fn) {
238723
238883
  return false;
238724
238884
  }
238725
238885
  for (const file of fn.files) {
238726
- const filePath = join10(functionDir, file.path);
238886
+ const filePath = join11(functionDir, file.path);
238727
238887
  if (!await pathExists(filePath)) {
238728
238888
  return false;
238729
238889
  }
@@ -238895,10 +239055,17 @@ class ProjectConfigReader {
238895
239055
  ...pluginResources.functions
238896
239056
  ];
238897
239057
  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
+ }
238898
239064
  return {
238899
239065
  project,
238900
239066
  entities,
238901
239067
  functions,
239068
+ actors: localResources.actors,
238902
239069
  agents: localResources.agents,
238903
239070
  agentSkills: localResources.agentSkills,
238904
239071
  connectors: localResources.connectors,
@@ -238926,17 +239093,34 @@ class ProjectConfigReader {
238926
239093
  }
238927
239094
  return result.data;
238928
239095
  }
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))
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))
238938
239114
  ]);
238939
- return { entities, functions, agents, agentSkills, connectors, authConfig };
239115
+ return {
239116
+ entities,
239117
+ functions,
239118
+ actors,
239119
+ agents,
239120
+ agentSkills,
239121
+ connectors,
239122
+ authConfig
239123
+ };
238940
239124
  }
238941
239125
  assertPluginProjectDoesNotLoadPlugins(project, configPath) {
238942
239126
  if (project.plugin && project.plugins.length > 0) {
@@ -238957,7 +239141,7 @@ class ProjectConfigReader {
238957
239141
  this.pluginSourceByNamespace.set(namespace, source);
238958
239142
  }
238959
239143
  async readPluginConfig(plugin, hostConfigPath) {
238960
- const pluginRoot = resolvePluginRoot(plugin.source, dirname8(hostConfigPath));
239144
+ const pluginRoot = resolvePluginRoot(plugin.source, dirname10(hostConfigPath));
238961
239145
  const { configPath } = await this.findConfigOrThrow(pluginRoot);
238962
239146
  const project = await this.readConfigFile(configPath);
238963
239147
  const namespace = requirePluginNamespace(project, plugin.source, configPath);
@@ -238965,10 +239149,11 @@ class ProjectConfigReader {
238965
239149
  return { configPath, namespace, project, source: plugin.source };
238966
239150
  }
238967
239151
  async readPluginResources(project, configPath, namespace) {
238968
- const resources = await this.readProjectResources(configPath, project);
239152
+ const resources = await this.readProjectResources(configPath, project, false);
238969
239153
  return {
238970
239154
  entities: markPluginEntities(resources.entities, namespace),
238971
239155
  functions: namespacePluginFunctions(resources.functions, namespace),
239156
+ actors: [],
238972
239157
  agents: [],
238973
239158
  agentSkills: [],
238974
239159
  connectors: [],
@@ -239007,6 +239192,7 @@ class ProjectConfigReader {
239007
239192
  return {
239008
239193
  entities,
239009
239194
  functions,
239195
+ actors: [],
239010
239196
  agents: [],
239011
239197
  agentSkills: [],
239012
239198
  connectors: [],
@@ -239041,16 +239227,16 @@ async function readProjectSettings(projectRoot) {
239041
239227
  // src/core/project/template.ts
239042
239228
  var import_ejs = __toESM(require_ejs(), 1);
239043
239229
  var import_front_matter2 = __toESM(require_front_matter(), 1);
239044
- import { dirname as dirname9, join as join13 } from "node:path";
239230
+ import { dirname as dirname11, join as join14 } from "node:path";
239045
239231
 
239046
239232
  // src/core/assets.ts
239047
239233
  import { cpSync, existsSync } from "node:fs";
239048
239234
  import { homedir as homedir2 } from "node:os";
239049
- import { join as join12 } from "node:path";
239235
+ import { join as join13 } from "node:path";
239050
239236
  // package.json
239051
239237
  var package_default = {
239052
239238
  name: "base44",
239053
- version: "0.1.14",
239239
+ version: "0.1.15",
239054
239240
  description: "Base44 CLI - Unified interface for managing Base44 applications",
239055
239241
  type: "module",
239056
239242
  bin: {
@@ -239153,21 +239339,21 @@ var package_default = {
239153
239339
  };
239154
239340
 
239155
239341
  // src/core/assets.ts
239156
- var ASSETS_DIR = join12(homedir2(), ".base44", "assets", package_default.version);
239342
+ var ASSETS_DIR = join13(homedir2(), ".base44", "assets", package_default.version);
239157
239343
  function getTemplatesDir() {
239158
- return join12(ASSETS_DIR, "templates");
239344
+ return join13(ASSETS_DIR, "templates");
239159
239345
  }
239160
239346
  function getTemplatesIndexPath() {
239161
- return join12(ASSETS_DIR, "templates", "templates.json");
239347
+ return join13(ASSETS_DIR, "templates", "templates.json");
239162
239348
  }
239163
239349
  function getBackendRuntimeDir() {
239164
- return join12(ASSETS_DIR, "backend-runtime");
239350
+ return join13(ASSETS_DIR, "backend-runtime");
239165
239351
  }
239166
239352
  function getDenoWrapperPath() {
239167
- return join12(getBackendRuntimeDir(), "main.ts");
239353
+ return join13(getBackendRuntimeDir(), "main.ts");
239168
239354
  }
239169
239355
  function getExecWrapperPath() {
239170
- return join12(getBackendRuntimeDir(), "exec.ts");
239356
+ return join13(getBackendRuntimeDir(), "exec.ts");
239171
239357
  }
239172
239358
  function ensureNpmAssets(sourceDir) {
239173
239359
  if (existsSync(ASSETS_DIR) && existsSync(getBackendRuntimeDir()))
@@ -239189,7 +239375,7 @@ async function listTemplates() {
239189
239375
  }
239190
239376
  async function renderTemplate(template, destPath, data, options = {}) {
239191
239377
  const { skipExisting = false } = options;
239192
- const templateDir = join13(getTemplatesDir(), template.path);
239378
+ const templateDir = join14(getTemplatesDir(), template.path);
239193
239379
  const files = await globby("**/*", {
239194
239380
  cwd: templateDir,
239195
239381
  dot: true,
@@ -239197,20 +239383,20 @@ async function renderTemplate(template, destPath, data, options = {}) {
239197
239383
  });
239198
239384
  const skipped = [];
239199
239385
  for (const file of files) {
239200
- const srcPath = join13(templateDir, file);
239386
+ const srcPath = join14(templateDir, file);
239201
239387
  try {
239202
239388
  if (file.endsWith(".ejs")) {
239203
239389
  const rendered = await import_ejs.default.renderFile(srcPath, data);
239204
239390
  const { attributes, body } = import_front_matter2.default(rendered);
239205
- const destFile = attributes.outputFileName ? join13(dirname9(file), attributes.outputFileName) : file.replace(/\.ejs$/, "");
239206
- const destFilePath = join13(destPath, destFile);
239391
+ const destFile = attributes.outputFileName ? join14(dirname11(file), attributes.outputFileName) : file.replace(/\.ejs$/, "");
239392
+ const destFilePath = join14(destPath, destFile);
239207
239393
  if (skipExisting && await pathExists(destFilePath)) {
239208
239394
  skipped.push(destFile);
239209
239395
  continue;
239210
239396
  }
239211
239397
  await writeFile(destFilePath, body);
239212
239398
  } else {
239213
- const destFilePath = join13(destPath, file);
239399
+ const destFilePath = join14(destPath, file);
239214
239400
  if (skipExisting && await pathExists(destFilePath)) {
239215
239401
  skipped.push(file);
239216
239402
  continue;
@@ -239364,7 +239550,7 @@ async function getSiteFilePaths(outputDir) {
239364
239550
  // src/core/site/deploy.ts
239365
239551
  import { randomUUID } from "node:crypto";
239366
239552
  import { tmpdir } from "node:os";
239367
- import { join as join14 } from "node:path";
239553
+ import { join as join15 } from "node:path";
239368
239554
  async function deploySite(siteOutputDir) {
239369
239555
  if (!await pathExists(siteOutputDir)) {
239370
239556
  throw new InvalidInputError(`Output directory does not exist: ${siteOutputDir}. Make sure to build your project first.`, {
@@ -239385,7 +239571,7 @@ async function deploySite(siteOutputDir) {
239385
239571
  ]
239386
239572
  });
239387
239573
  }
239388
- const archivePath = join14(tmpdir(), `base44-site-${randomUUID()}.tar.gz`);
239574
+ const archivePath = join15(tmpdir(), `base44-site-${randomUUID()}.tar.gz`);
239389
239575
  try {
239390
239576
  await createArchive(siteOutputDir, archivePath);
239391
239577
  return await uploadSite(archivePath);
@@ -239402,13 +239588,13 @@ async function createArchive(pathToArchive, targetArchivePath) {
239402
239588
  }
239403
239589
  // src/core/site/deployment.ts
239404
239590
  import { readFile as readFile3 } from "node:fs/promises";
239405
- import { join as join17 } from "node:path";
239591
+ import { join as join18 } from "node:path";
239406
239592
 
239407
239593
  // src/core/site/manifest.ts
239408
239594
  import { createHash } from "node:crypto";
239409
239595
  import { createReadStream } from "node:fs";
239410
239596
  import { stat } from "node:fs/promises";
239411
- import { basename as basename4, extname, join as join15 } from "node:path";
239597
+ import { basename as basename5, extname, join as join16 } from "node:path";
239412
239598
  var MAX_ASSET_COUNT = 1e5;
239413
239599
  var ASSETS_IGNORE_FILE = ".assetsignore";
239414
239600
  var ALWAYS_IGNORED = new Set([
@@ -239466,12 +239652,12 @@ async function buildAssetManifest(assetsDir, appId) {
239466
239652
  followSymbolicLinks: false,
239467
239653
  ignoreFiles: [ASSETS_IGNORE_FILE]
239468
239654
  });
239469
- const relativeFilePaths = found.filter((path) => !ALWAYS_IGNORED.has(basename4(path)));
239655
+ const relativeFilePaths = found.filter((path) => !ALWAYS_IGNORED.has(basename5(path)));
239470
239656
  if (relativeFilePaths.length > MAX_ASSET_COUNT) {
239471
239657
  throw new InvalidInputError(`Too many static assets: found ${relativeFilePaths.length}, the limit is ${MAX_ASSET_COUNT} files.`);
239472
239658
  }
239473
239659
  for (const relativePath of relativeFilePaths.sort()) {
239474
- const absolutePath = join15(assetsDir, ...relativePath.split("/"));
239660
+ const absolutePath = join16(assetsDir, ...relativePath.split("/"));
239475
239661
  const { size } = await stat(absolutePath);
239476
239662
  const hash = await hashAssetFile(appId, absolutePath);
239477
239663
  manifest[`/${relativePath}`] = { hash, size };
@@ -239489,7 +239675,7 @@ async function buildAssetManifest(assetsDir, appId) {
239489
239675
 
239490
239676
  // src/core/site/modules.ts
239491
239677
  import { stat as stat2 } from "node:fs/promises";
239492
- import { relative as relative3, resolve as resolve3, sep } from "node:path";
239678
+ import { relative as relative5, resolve as resolve3, sep } from "node:path";
239493
239679
  var MAX_TOTAL_MODULE_BYTES = 40 * 1024 * 1024;
239494
239680
  var MODULE_IGNORE = ["wrangler.json", ".dev.vars"];
239495
239681
  var RULE_TYPE_TO_MODULE_TYPE = {
@@ -239509,7 +239695,7 @@ async function collectModules(config) {
239509
239695
  });
239510
239696
  }
239511
239697
  const modulesByName = new Map;
239512
- const entryName = toPosix(relative3(config.configDir, entryPath));
239698
+ const entryName = toPosix(relative5(config.configDir, entryPath));
239513
239699
  modulesByName.set(entryName, {
239514
239700
  name: entryName,
239515
239701
  absolutePath: entryPath,
@@ -239518,7 +239704,7 @@ async function collectModules(config) {
239518
239704
  });
239519
239705
  const ignore = [...MODULE_IGNORE];
239520
239706
  if (config.assetsDirectory?.startsWith(config.configDir + sep)) {
239521
- ignore.push(`${toPosix(relative3(config.configDir, config.assetsDirectory))}/**`);
239707
+ ignore.push(`${toPosix(relative5(config.configDir, config.assetsDirectory))}/**`);
239522
239708
  }
239523
239709
  for (const rule of config.rules) {
239524
239710
  const type = RULE_TYPE_TO_MODULE_TYPE[rule.type];
@@ -239812,10 +239998,7 @@ async function uploadPresignedAsset(upload, assets) {
239812
239998
  try {
239813
239999
  await distribution_default.put(upload.url, {
239814
240000
  body: new Uint8Array(content),
239815
- headers: {
239816
- "Content-Type": upload.contentType,
239817
- ...upload.checksumSha256 ? { "x-amz-checksum-sha256": upload.checksumSha256 } : {}
239818
- },
240001
+ headers: { "Content-Type": upload.contentType },
239819
240002
  timeout: 120000,
239820
240003
  retry: UPLOAD_RETRY
239821
240004
  });
@@ -239825,8 +240008,8 @@ async function uploadPresignedAsset(upload, assets) {
239825
240008
  }
239826
240009
 
239827
240010
  // src/core/site/wrangler-config.ts
239828
- import { dirname as dirname10, join as join16, resolve as resolve4 } from "node:path";
239829
- var WRANGLER_REDIRECT_PATH = join16(".wrangler", "deploy", "config.json");
240011
+ import { dirname as dirname12, join as join17, resolve as resolve4 } from "node:path";
240012
+ var WRANGLER_REDIRECT_PATH = join17(".wrangler", "deploy", "config.json");
239830
240013
  var RedirectConfigSchema = looseObject({
239831
240014
  configPath: string2().min(1)
239832
240015
  });
@@ -239848,7 +240031,7 @@ var WranglerConfigSchema = looseObject({
239848
240031
  upload_source_maps: boolean2().optional()
239849
240032
  });
239850
240033
  async function detectFullStackArtifact(projectRoot) {
239851
- const redirectPath = join16(projectRoot, WRANGLER_REDIRECT_PATH);
240034
+ const redirectPath = join17(projectRoot, WRANGLER_REDIRECT_PATH);
239852
240035
  return await pathExists(redirectPath) ? redirectPath : null;
239853
240036
  }
239854
240037
  async function resolveWranglerConfig(redirectPath) {
@@ -239862,7 +240045,7 @@ async function resolveWranglerConfig(redirectPath) {
239862
240045
  if (config.no_bundle !== true) {
239863
240046
  throw new InvalidInputError("This framework's output requires bundling; not yet supported. Base44 only deploys pre-bundled Workers output (no_bundle: true).");
239864
240047
  }
239865
- const configDir = dirname10(configPath);
240048
+ const configDir = dirname12(configPath);
239866
240049
  const assetsDirectory = config.assets?.directory ? resolve4(configDir, config.assets.directory) : null;
239867
240050
  return {
239868
240051
  configPath,
@@ -239885,7 +240068,7 @@ async function resolveRedirectedConfigPath(redirectPath) {
239885
240068
  if (!result.success) {
239886
240069
  throw new ConfigInvalidError(`Invalid deploy redirect file: ${prettifyError(result.error)}`, redirectPath);
239887
240070
  }
239888
- const configPath = resolve4(dirname10(redirectPath), result.data.configPath);
240071
+ const configPath = resolve4(dirname12(redirectPath), result.data.configPath);
239889
240072
  if (!await pathExists(configPath)) {
239890
240073
  throw new ConfigInvalidError(`Wrangler config referenced by ${redirectPath} does not exist: ${configPath}`, redirectPath, {
239891
240074
  hints: [{ message: "Rebuild the project to regenerate the artifact" }]
@@ -239950,7 +240133,7 @@ async function readIndexHtml(assetsDir, assets) {
239950
240133
  if (!assetsDir || !assets.manifest["/index.html"]) {
239951
240134
  throw new InvalidInputError(`No index.html found in "${assetsDir ?? "the site output directory"}" — a static site needs one at the output directory root.`);
239952
240135
  }
239953
- return new Uint8Array(await readFile3(join17(assetsDir, "index.html")));
240136
+ return new Uint8Array(await readFile3(join18(assetsDir, "index.html")));
239954
240137
  }
239955
240138
  function buildAssetsConfig(assetsConfig, progress) {
239956
240139
  if (!assetsConfig)
@@ -246486,13 +246669,6 @@ async function resolveGitHash(projectRoot, explicit) {
246486
246669
  }
246487
246670
  return hash;
246488
246671
  }
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
- }
246496
246672
  async function gitHead(projectRoot) {
246497
246673
  try {
246498
246674
  const { stdout } = await execa("git", ["rev-parse", "HEAD"], {
@@ -246509,6 +246685,7 @@ function hasResourcesToDeploy(projectData) {
246509
246685
  project,
246510
246686
  entities,
246511
246687
  functions,
246688
+ actors,
246512
246689
  agents,
246513
246690
  agentSkills,
246514
246691
  connectors,
@@ -246517,18 +246694,20 @@ function hasResourcesToDeploy(projectData) {
246517
246694
  const hasSite = Boolean(project.site?.outputDirectory);
246518
246695
  const hasEntities = entities.length > 0;
246519
246696
  const hasFunctions = functions.length > 0;
246697
+ const hasActors = actors.length > 0;
246520
246698
  const hasAgents = agents.length > 0;
246521
246699
  const hasAgentSkills = agentSkills.length > 0;
246522
246700
  const hasConnectors = connectors.length > 0;
246523
246701
  const hasAuthConfig = authConfig.length > 0;
246524
246702
  const hasVisibility = Boolean(project.visibility);
246525
- return hasEntities || hasFunctions || hasAgents || hasAgentSkills || hasConnectors || hasAuthConfig || hasVisibility || hasSite;
246703
+ return hasEntities || hasFunctions || hasActors || hasAgents || hasAgentSkills || hasConnectors || hasAuthConfig || hasVisibility || hasSite;
246526
246704
  }
246527
246705
  async function deployAll(projectData, options) {
246528
246706
  const {
246529
246707
  project,
246530
246708
  entities,
246531
246709
  functions,
246710
+ actors,
246532
246711
  agents,
246533
246712
  agentSkills,
246534
246713
  connectors,
@@ -246539,10 +246718,33 @@ async function deployAll(projectData, options) {
246539
246718
  options?.onVisibilitySet?.(project.visibility);
246540
246719
  }
246541
246720
  await entityResource.push(entities);
246542
- await deployFunctionsSequentially(functions, {
246721
+ const functionResults = await deployFunctionsSequentially(functions, {
246543
246722
  onStart: options?.onFunctionStart,
246544
246723
  onResult: options?.onFunctionResult
246545
246724
  });
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
+ }
246546
246748
  await agentSkillResource.push(agentSkills);
246547
246749
  await agentResource.push(agents);
246548
246750
  await authConfigResource.push(authConfig);
@@ -247002,136 +247204,6 @@ async function resolveBranchName(name) {
247002
247204
  return matches[0].id;
247003
247205
  }
247004
247206
 
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
-
247135
247207
  // src/cli/utils/command/Base44Command.ts
247136
247208
  function writeJsonSuccess(result) {
247137
247209
  if (result.stdout) {
@@ -247149,10 +247221,6 @@ function writeJsonError(error) {
247149
247221
  const envelope = {
247150
247222
  error: error instanceof Error ? error.message : String(error)
247151
247223
  };
247152
- const step = stepOf(error);
247153
- if (step !== undefined) {
247154
- envelope.step = step;
247155
- }
247156
247224
  if (isCLIError(error)) {
247157
247225
  envelope.code = error.code;
247158
247226
  if (error.details.length > 0) {
@@ -247411,6 +247479,118 @@ function formatYaml(data, options = {}) {
247411
247479
  const replacer = stripEmpty ? stripEmptyReplacer : undefined;
247412
247480
  return $stringify(data, replacer, { indent: YAML_INDENT }).trimEnd();
247413
247481
  }
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";
247414
247594
  // src/core/utils/dependencies.ts
247415
247595
  import { spawnSync as spawnSync2 } from "node:child_process";
247416
247596
  function verifyDenoInstalled(context) {
@@ -247499,7 +247679,7 @@ async function pullAction({
247499
247679
  runTask
247500
247680
  }) {
247501
247681
  const { project } = await readProjectConfig();
247502
- const dir = join18(dirname11(project.configPath), project.agentSkillsDir);
247682
+ const dir = join19(dirname13(project.configPath), project.agentSkillsDir);
247503
247683
  const remote = await runTask("Fetching agent skills from Base44", () => fetchAgentSkills(), {
247504
247684
  successMessage: "Agent skills fetched successfully",
247505
247685
  errorMessage: "Failed to fetch agent skills"
@@ -247555,14 +247735,14 @@ function getAgentSkillsCommand() {
247555
247735
  }
247556
247736
 
247557
247737
  // src/cli/commands/agents/pull.ts
247558
- import { dirname as dirname12, join as join19 } from "node:path";
247738
+ import { dirname as dirname14, join as join20 } from "node:path";
247559
247739
  async function pullAgentsAction({
247560
247740
  log,
247561
247741
  runTask
247562
247742
  }) {
247563
247743
  const { project } = await readProjectConfig();
247564
- const configDir = dirname12(project.configPath);
247565
- const agentsDir = join19(configDir, project.agentsDir);
247744
+ const configDir = dirname14(project.configPath);
247745
+ const agentsDir = join20(configDir, project.agentsDir);
247566
247746
  const remoteAgents = await runTask("Fetching agents from Base44", async () => {
247567
247747
  return await fetchAgents();
247568
247748
  }, {
@@ -247632,12 +247812,12 @@ function getAgentsCommand() {
247632
247812
  }
247633
247813
 
247634
247814
  // src/cli/commands/auth/password-login.ts
247635
- import { dirname as dirname13, join as join20 } from "node:path";
247815
+ import { dirname as dirname15, join as join21 } from "node:path";
247636
247816
  async function passwordLoginAction({ log, runTask }, action) {
247637
247817
  const shouldEnable = action === "enable";
247638
247818
  const { project } = await readProjectConfig();
247639
- const configDir = dirname13(project.configPath);
247640
- const authDir = join20(configDir, project.authDir);
247819
+ const configDir = dirname15(project.configPath);
247820
+ const authDir = join21(configDir, project.authDir);
247641
247821
  const updated = await runTask("Updating local auth config", async () => {
247642
247822
  const current = await readAuthConfig(authDir) ?? DEFAULT_AUTH_CONFIG;
247643
247823
  const merged = { ...current, enableUsernamePassword: shouldEnable };
@@ -247657,14 +247837,14 @@ function getPasswordLoginCommand() {
247657
247837
  }
247658
247838
 
247659
247839
  // src/cli/commands/auth/pull.ts
247660
- import { dirname as dirname14, join as join21 } from "node:path";
247840
+ import { dirname as dirname16, join as join22 } from "node:path";
247661
247841
  async function pullAuthAction({
247662
247842
  log,
247663
247843
  runTask
247664
247844
  }) {
247665
247845
  const { project } = await readProjectConfig();
247666
- const configDir = dirname14(project.configPath);
247667
- const authDir = join21(configDir, project.authDir);
247846
+ const configDir = dirname16(project.configPath);
247847
+ const authDir = join22(configDir, project.authDir);
247668
247848
  const remoteConfig = await runTask("Fetching auth config from Base44", async () => {
247669
247849
  return await pullAuthConfig();
247670
247850
  }, {
@@ -247728,7 +247908,7 @@ function getAuthPushCommand() {
247728
247908
  }
247729
247909
 
247730
247910
  // src/cli/commands/auth/social-login.ts
247731
- import { dirname as dirname15, join as join22, resolve as resolve6 } from "node:path";
247911
+ import { dirname as dirname17, join as join23, resolve as resolve6 } from "node:path";
247732
247912
  var PROVIDER_LABELS = {
247733
247913
  google: "Google",
247734
247914
  microsoft: "Microsoft",
@@ -247798,8 +247978,8 @@ async function socialLoginAction({ log, isNonInteractive, runTask }, provider, a
247798
247978
  }
247799
247979
  }
247800
247980
  const { project } = await readProjectConfig();
247801
- const configDir = dirname15(project.configPath);
247802
- const authDir = join22(configDir, project.authDir);
247981
+ const configDir = dirname17(project.configPath);
247982
+ const authDir = join23(configDir, project.authDir);
247803
247983
  const { config: updated } = await runTask("Updating local auth config", async () => updateSocialLoginConfig(authDir, provider, shouldEnable, useCustomOAuth && options.clientId ? { clientId: options.clientId } : undefined));
247804
247984
  if (clientSecret) {
247805
247985
  await runTask("Saving client secret", async () => pushCustomOAuthSecret(provider, clientSecret));
@@ -247824,7 +248004,7 @@ function getSocialLoginCommand() {
247824
248004
  }
247825
248005
 
247826
248006
  // src/cli/commands/auth/sso.ts
247827
- import { dirname as dirname16, join as join23, resolve as resolve7 } from "node:path";
248007
+ import { dirname as dirname18, join as join24, resolve as resolve7 } from "node:path";
247828
248008
  var SSOConfigFileSchema = object({
247829
248009
  provider: _enum(Object.values(KNOWN_SSO_PROVIDERS)),
247830
248010
  clientId: string2(),
@@ -247987,8 +248167,8 @@ async function ssoEnableAction({ isNonInteractive, runTask }, options) {
247987
248167
  throw error;
247988
248168
  }
247989
248169
  const { project } = await readProjectConfig();
247990
- const configDir = dirname16(project.configPath);
247991
- const authDir = join23(configDir, project.authDir);
248170
+ const configDir = dirname18(project.configPath);
248171
+ const authDir = join24(configDir, project.authDir);
247992
248172
  await runTask("Updating local auth config", async () => updateSSOConfig(authDir, provider, true));
247993
248173
  await runTask("Saving SSO credentials", async () => pushSSOSecrets(secrets));
247994
248174
  return {
@@ -248003,8 +248183,8 @@ async function ssoDisableAction({ log, runTask }, options) {
248003
248183
  throw new InvalidInputError("Configuration options cannot be used with disable. To disable SSO: base44 auth sso disable");
248004
248184
  }
248005
248185
  const { project } = await readProjectConfig();
248006
- const configDir = dirname16(project.configPath);
248007
- const authDir = join23(configDir, project.authDir);
248186
+ const configDir = dirname18(project.configPath);
248187
+ const authDir = join24(configDir, project.authDir);
248008
248188
  const updated = await runTask("Updating local auth config", async () => updateSSOConfig(authDir, null, false));
248009
248189
  await runTask("Removing SSO credentials", async () => deleteSSOSecrets());
248010
248190
  if (!hasAnyLoginMethod(updated)) {
@@ -248886,13 +249066,13 @@ function getConnectorsListAvailableCommand() {
248886
249066
  }
248887
249067
 
248888
249068
  // src/cli/commands/connectors/pull.ts
248889
- import { dirname as dirname17, join as join24, resolve as resolve8 } from "node:path";
249069
+ import { dirname as dirname19, join as join25, resolve as resolve8 } from "node:path";
248890
249070
  async function resolveConnectorsDir(options) {
248891
249071
  if (!getAppContext().projectRoot) {
248892
249072
  return resolve8(options.dir ?? "connectors");
248893
249073
  }
248894
249074
  const { project } = await readProjectConfig();
248895
- return join24(dirname17(project.configPath), project.connectorsDir);
249075
+ return join25(dirname19(project.configPath), project.connectorsDir);
248896
249076
  }
248897
249077
  async function pullConnectorsAction({ log, runTask, jsonMode }, options) {
248898
249078
  const connectorsDir = await resolveConnectorsDir(options);
@@ -249147,43 +249327,22 @@ async function deleteFunctionsAction({ runTask }, names) {
249147
249327
  parts.push(`${errors} error${errors !== 1 ? "s" : ""}`);
249148
249328
  return { outroMessage: parts.join(", ") };
249149
249329
  }
249150
- function parseNames(args) {
249330
+ function parseNames2(args) {
249151
249331
  return args.flatMap((arg) => arg.split(",")).map((n) => n.trim()).filter(Boolean);
249152
249332
  }
249153
249333
  function validateNames(command) {
249154
- const names = parseNames(command.args);
249334
+ const names = parseNames2(command.args);
249155
249335
  if (names.length === 0) {
249156
249336
  command.error("At least one function name is required");
249157
249337
  }
249158
249338
  }
249159
- function getDeleteCommand() {
249339
+ function getDeleteCommand2() {
249160
249340
  return new Base44Command("delete").description("Delete deployed functions").argument("<names...>", "Function names to delete").hook("preAction", validateNames).action(async (ctx, rawNames) => {
249161
- const names = parseNames(rawNames);
249341
+ const names = parseNames2(rawNames);
249162
249342
  return deleteFunctionsAction(ctx, names);
249163
249343
  });
249164
249344
  }
249165
249345
 
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
-
249187
249346
  // src/cli/commands/functions/deploy.ts
249188
249347
  function resolveFunctionsToDeploy(names, allFunctions) {
249189
249348
  if (names.length === 0)
@@ -249270,9 +249429,9 @@ async function deployFunctionsAction({ log }, names, options) {
249270
249429
  }
249271
249430
  return { outroMessage: buildDeploySummary(results) };
249272
249431
  }
249273
- function getDeployCommand() {
249432
+ function getDeployCommand2() {
249274
249433
  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) => {
249275
- const names = parseNames2(rawNames);
249434
+ const names = parseNames(rawNames);
249276
249435
  return deployFunctionsAction(ctx, names, options);
249277
249436
  });
249278
249437
  }
@@ -249300,11 +249459,11 @@ function getListCommand() {
249300
249459
  }
249301
249460
 
249302
249461
  // src/cli/commands/functions/pull.ts
249303
- import { dirname as dirname18, join as join25 } from "node:path";
249462
+ import { dirname as dirname20, join as join26 } from "node:path";
249304
249463
  async function pullFunctionsAction({ log, runTask }, name) {
249305
249464
  const { project, functions } = await readProjectConfig();
249306
- const configDir = dirname18(project.configPath);
249307
- const functionsDir = join25(configDir, project.functionsDir);
249465
+ const configDir = dirname20(project.configPath);
249466
+ const functionsDir = join26(configDir, project.functionsDir);
249308
249467
  const pluginFunctionNames = new Set(functions.filter((fn) => fn.source.type === "plugin").map((fn) => fn.name));
249309
249468
  const remoteFunctions = await runTask("Fetching functions from Base44", async () => {
249310
249469
  const { functions } = await listDeployedFunctions();
@@ -249359,7 +249518,7 @@ function getPullCommand() {
249359
249518
 
249360
249519
  // src/cli/commands/functions/index.ts
249361
249520
  function getFunctionsCommand() {
249362
- return new Command2("functions").description("Manage backend functions").addCommand(getDeployCommand()).addCommand(getDeleteCommand()).addCommand(getListCommand()).addCommand(getPullCommand());
249521
+ return new Command2("functions").description("Manage backend functions").addCommand(getDeployCommand2()).addCommand(getDeleteCommand2()).addCommand(getListCommand()).addCommand(getPullCommand());
249363
249522
  }
249364
249523
 
249365
249524
  // src/cli/commands/project/site-build.ts
@@ -249404,161 +249563,33 @@ async function maybeAskToBuild(isNonInteractive, buildCommand) {
249404
249563
  });
249405
249564
  return !Ct(answer) && answer;
249406
249565
  }
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
- }
249566
+
249526
249567
  // src/cli/commands/project/build.ts
249527
- async function buildAction(ctx, options) {
249528
- const { app, jsonMode } = ctx;
249529
- const target = await resolvePublishTarget(app?.projectRoot, {
249530
- outputDir: options.outputDir
249531
- });
249568
+ async function buildAction(ctx) {
249569
+ 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);
249532
249574
  await runSiteBuild(ctx, {
249533
- root: target.root,
249534
- buildCommand: target.buildCommand,
249535
- appId: app?.id ?? ""
249575
+ root: project.root,
249576
+ buildCommand: project.site?.buildCommand,
249577
+ appId: app.id
249536
249578
  });
249537
- const files = await collectBuildOutput(requireOutputDir(target));
249538
- const totalBytes = files.reduce((sum, file) => sum + file.size, 0);
249539
249579
  return {
249540
- outroMessage: `Built ${files.length} files (${totalBytes} bytes) with app id ${theme.styles.bold(app?.id ?? "")}`,
249541
- stdout: jsonMode ? `${JSON.stringify({
249542
- outputDir: target.outputDir,
249543
- files: files.map(({ path, size, digest }) => ({
249544
- path,
249545
- size,
249546
- digest
249547
- }))
249548
- }, null, 2)}
249549
- ` : undefined
249580
+ outroMessage: `Site built with app id ${theme.styles.bold(app.id)}`
249550
249581
  };
249551
249582
  }
249552
249583
  function getBuildCommand() {
249553
- return new Base44Command("build", { requireAuth: false }).description("Build the site with the Base44 app id injected").option("--output-dir <dir>", "Build output directory (defaults to the project's, else dist)").action(buildAction);
249584
+ return new Base44Command("build").description("Build the site with the Base44 app id injected").action(buildAction);
249554
249585
  }
249555
249586
 
249556
249587
  // src/cli/commands/project/create.ts
249557
- import { basename as basename6, resolve as resolve11 } from "node:path";
249588
+ import { basename as basename6, resolve as resolve10 } from "node:path";
249558
249589
  var import_kebabCase = __toESM(require_kebabCase(), 1);
249559
249590
 
249560
249591
  // src/cli/commands/project/scaffold-shared.ts
249561
- import { join as join28 } from "node:path";
249592
+ import { join as join27 } from "node:path";
249562
249593
  var DEFAULT_TEMPLATE_ID = "backend-only";
249563
249594
  async function getTemplateById(templateId) {
249564
249595
  const templates = await listTemplates();
@@ -249621,7 +249652,7 @@ async function completeProjectSetup({
249621
249652
  env: { VITE_BASE44_APP_ID: projectId }
249622
249653
  })`${buildCommand}`;
249623
249654
  updateMessage("Deploying site...");
249624
- return await deploySite(join28(resolvedPath, outputDirectory));
249655
+ return await deploySite(join27(resolvedPath, outputDirectory));
249625
249656
  }, {
249626
249657
  successMessage: theme.colors.base44Orange("Site deployed successfully"),
249627
249658
  errorMessage: "Failed to deploy site"
@@ -249750,7 +249781,7 @@ async function createInteractive(options, ctx) {
249750
249781
  }, ctx);
249751
249782
  }
249752
249783
  async function createNonInteractive(options, ctx) {
249753
- ctx.log.info(`Creating a new project at ${resolve11(options.path)}`);
249784
+ ctx.log.info(`Creating a new project at ${resolve10(options.path)}`);
249754
249785
  const template = await getTemplateById(options.template ?? DEFAULT_TEMPLATE_ID);
249755
249786
  return await executeCreate({
249756
249787
  template,
@@ -249774,7 +249805,7 @@ async function executeCreate({
249774
249805
  }, ctx) {
249775
249806
  const { log, runTask } = ctx;
249776
249807
  const name = rawName.trim();
249777
- const resolvedPath = resolve11(projectPath);
249808
+ const resolvedPath = resolve10(projectPath);
249778
249809
  const organizationId = await resolveWorkspaceId(ctx, flagWorkspaceId, isInteractive);
249779
249810
  const { projectId } = await runTask("Setting up your project...", async () => {
249780
249811
  return await createProjectFiles({
@@ -249836,7 +249867,15 @@ async function deployAction(ctx, options = {}) {
249836
249867
  outroMessage: "No resources found to deploy"
249837
249868
  };
249838
249869
  }
249839
- const { project, entities, functions, agents, connectors, authConfig } = projectData;
249870
+ const {
249871
+ project,
249872
+ entities,
249873
+ functions,
249874
+ actors,
249875
+ agents,
249876
+ connectors,
249877
+ authConfig
249878
+ } = projectData;
249840
249879
  const summaryLines = [];
249841
249880
  if (entities.length > 0) {
249842
249881
  summaryLines.push(` - ${entities.length} ${entities.length === 1 ? "entity" : "entities"}`);
@@ -249844,6 +249883,9 @@ async function deployAction(ctx, options = {}) {
249844
249883
  if (functions.length > 0) {
249845
249884
  summaryLines.push(` - ${functions.length} ${functions.length === 1 ? "function" : "functions"}`);
249846
249885
  }
249886
+ if (actors.length > 0) {
249887
+ summaryLines.push(` - ${actors.length} ${actors.length === 1 ? "actor" : "actors"}`);
249888
+ }
249847
249889
  if (agents.length > 0) {
249848
249890
  summaryLines.push(` - ${agents.length} ${agents.length === 1 ? "agent" : "agents"}`);
249849
249891
  }
@@ -249877,6 +249919,7 @@ ${summaryLines.join(`
249877
249919
  await maybeBuildBeforeDeploy(ctx, project, options.build);
249878
249920
  let functionCompleted = 0;
249879
249921
  const functionTotal = functions.length;
249922
+ let actorCompleted = 0;
249880
249923
  const result = await deployAll(projectData, {
249881
249924
  onVisibilitySet: (level) => {
249882
249925
  log.success(`App visibility set to ${level}`);
@@ -249888,6 +249931,16 @@ ${summaryLines.join(`
249888
249931
  onFunctionResult: (r) => {
249889
249932
  functionCompleted++;
249890
249933
  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}`);
249891
249944
  }
249892
249945
  });
249893
249946
  const connectorResults = result.connectorResults ?? [];
@@ -249902,8 +249955,8 @@ ${summaryLines.join(`
249902
249955
  }
249903
249956
  return { outroMessage: "App deployed successfully" };
249904
249957
  }
249905
- function getDeployCommand2() {
249906
- 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);
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);
249907
249960
  }
249908
249961
  async function handleOAuthConnectors(connectorResults, isNonInteractive, options, log) {
249909
249962
  const needsOAuth = filterPendingOAuth(connectorResults);
@@ -250389,11 +250442,11 @@ async function logsAction(ctx, options) {
250389
250442
  function getLogsCommand() {
250390
250443
  return new Base44Command("logs").description("Fetch function logs for this app").option("--function <names>", "Filter by function name(s), comma-separated. If omitted, fetches logs for all deployed functions").option("--since <datetime>", "Show logs from this time. ISO datetime or relative shorthand (e.g. 1h, 30m, 2d)", normalizeDatetime).option("--until <datetime>", "Show logs until this time. ISO datetime or relative shorthand (e.g. 1h, 30m, 2d)", normalizeDatetime).addOption(new Option2("--level <level>", "Filter by log level").choices([
250391
250444
  ...LogLevelSchema.options
250392
- ])).option("-n, --limit <n>", "Results per page (1-1000; the server returns at most 500)").option("-f, --follow", "Stream new logs as they arrive").addOption(new Option2("--order <order>", "Sort order").choices(["asc", "desc"])).addOption(new Option2("--env <env>", "Which deployment to read logs from: preview (current draft) or prod (published). Default: preview").choices([...LogEnvSchema.options])).action(logsAction);
250445
+ ])).option("-n, --limit <n>", "Results per page (1-1000; the server returns at most 500)").option("-f, --follow", "Stream new logs as they arrive").addOption(new Option2("--order <order>", "Sort order").choices(["asc", "desc"])).addOption(new Option2("--env <env>", "Which deployment to read logs from: preview (current draft) or prod (published). Omit to read both.").choices([...LogEnvSchema.options])).action(logsAction);
250393
250446
  }
250394
250447
 
250395
250448
  // src/cli/commands/project/scaffold.ts
250396
- import { basename as basename7, resolve as resolve12 } from "node:path";
250449
+ import { basename as basename7, resolve as resolve11 } from "node:path";
250397
250450
  function resolveAppId(options) {
250398
250451
  const appId = options.appId;
250399
250452
  if (!appId) {
@@ -250409,7 +250462,7 @@ function resolveAppId(options) {
250409
250462
  async function scaffoldAction(ctx, name, options, command) {
250410
250463
  const { log, runTask } = ctx;
250411
250464
  const appId = resolveAppId(command.optsWithGlobals());
250412
- const resolvedPath = resolve12("./");
250465
+ const resolvedPath = resolve11("./");
250413
250466
  const projectName = (name ?? basename7(resolvedPath)).trim();
250414
250467
  const template = await getTemplateById("backend-only");
250415
250468
  log.info(`Scaffolding project at ${resolvedPath}`);
@@ -250457,62 +250510,6 @@ function getVisibilityCommand() {
250457
250510
  ])).action(setVisibility);
250458
250511
  }
250459
250512
 
250460
- // src/cli/commands/publish.ts
250461
- async function publishAction(ctx, options) {
250462
- const { runTask, log, jsonMode, app } = ctx;
250463
- const target = await resolvePublishTarget(app?.projectRoot, {
250464
- outputDir: options.outputDir
250465
- });
250466
- if (options.build !== false) {
250467
- await tagStep("build", () => runSiteBuild(ctx, {
250468
- root: target.root,
250469
- buildCommand: target.buildCommand,
250470
- appId: app?.id ?? ""
250471
- }));
250472
- }
250473
- const outputDir = requireOutputDir(target);
250474
- const gitHash = await resolveProvenanceCommit(target.root, options.gitHash);
250475
- const result = await runTask("Publishing...", async (updateMessage) => {
250476
- const artifacts = {
250477
- files: await collectBuildOutput(outputDir),
250478
- ...await collectResources(target.configDir, target)
250479
- };
250480
- return await publishVersion(artifacts, {
250481
- sourceCommit: gitHash,
250482
- target: options.target,
250483
- concurrency: options.concurrency,
250484
- progress: {
250485
- onDeclared: ({ fileCount, owedFiles }) => updateMessage(`Uploading ${owedFiles} of ${fileCount} files`),
250486
- onUpload: ({ uploadedFiles, totalFiles }) => updateMessage(`Uploaded ${uploadedFiles} of ${totalFiles} files`)
250487
- }
250488
- });
250489
- }, { successMessage: "Published", errorMessage: "Publish failed" });
250490
- if (!jsonMode) {
250491
- log.message(theme.styles.dim(`version ${result.versionId}${result.deduplicated ? " (existing content)" : ""}`));
250492
- }
250493
- return {
250494
- outroMessage: `Deployment ${result.deploymentId} at revision ${result.revision}`,
250495
- stdout: jsonMode ? `${JSON.stringify(result, null, 2)}
250496
- ` : undefined
250497
- };
250498
- }
250499
- function getPublishCommand() {
250500
- 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);
250501
- }
250502
- function parseGitHash(value) {
250503
- if (!isGitCommitHash(value)) {
250504
- throw new InvalidArgumentError2("Expected a git commit hash (7-64 hex chars).");
250505
- }
250506
- return value;
250507
- }
250508
- function parseConcurrency(value) {
250509
- const parsed = Number(value);
250510
- if (!Number.isInteger(parsed) || parsed < 1 || parsed > MAX_VERSION_UPLOAD_CONCURRENCY) {
250511
- throw new InvalidArgumentError2(`Expected a whole number between 1 and ${MAX_VERSION_UPLOAD_CONCURRENCY}.`);
250512
- }
250513
- return parsed;
250514
- }
250515
-
250516
250513
  // src/core/resources/sandbox/schema.ts
250517
250514
  var FileErrorSchema = object({
250518
250515
  code: string2(),
@@ -250882,7 +250879,7 @@ function getSecretsListCommand() {
250882
250879
  }
250883
250880
 
250884
250881
  // src/cli/commands/secrets/set.ts
250885
- import { resolve as resolve13 } from "node:path";
250882
+ import { resolve as resolve12 } from "node:path";
250886
250883
  function parseEntries(entries) {
250887
250884
  const secrets = {};
250888
250885
  for (const entry of entries) {
@@ -250913,7 +250910,7 @@ async function setSecretsAction({ log, runTask }, entries, options) {
250913
250910
  validateInput(entries, options);
250914
250911
  let secrets;
250915
250912
  if (options.envFile) {
250916
- secrets = await parseEnvFile(resolve13(options.envFile));
250913
+ secrets = await parseEnvFile(resolve12(options.envFile));
250917
250914
  if (Object.keys(secrets).length === 0) {
250918
250915
  throw new InvalidInputError("The env file contains no valid KEY=VALUE entries.");
250919
250916
  }
@@ -250942,7 +250939,7 @@ function getSecretsCommand() {
250942
250939
  }
250943
250940
 
250944
250941
  // src/cli/commands/site/deploy.ts
250945
- import { resolve as resolve14 } from "node:path";
250942
+ import { resolve as resolve13 } from "node:path";
250946
250943
  async function deployAction2(ctx, options) {
250947
250944
  const { isNonInteractive } = ctx;
250948
250945
  if (isNonInteractive && !options.yes) {
@@ -251020,23 +251017,23 @@ async function deployTarball({ runTask }, project) {
251020
251017
  }
251021
251018
  function siteOutputDir(project) {
251022
251019
  const outputDirectory = project.site?.outputDirectory;
251023
- return outputDirectory ? resolve14(project.root, outputDirectory) : null;
251020
+ return outputDirectory ? resolve13(project.root, outputDirectory) : null;
251024
251021
  }
251025
251022
  function getSiteDeployCommand() {
251026
251023
  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)");
251027
251024
  if (deploymentsApiEnabled()) {
251028
- command.addOption(new Option2("--git-hash <hash>", "Commit the build came from (defaults to the checkout's HEAD)").argParser(parseGitHash2));
251029
- command.addOption(new Option2("--concurrency <n>", "Parallel asset uploads").default(DEFAULT_UPLOAD_CONCURRENCY).argParser(parseConcurrency2));
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));
251030
251027
  }
251031
251028
  return command.action(deployAction2);
251032
251029
  }
251033
- function parseGitHash2(value) {
251030
+ function parseGitHash(value) {
251034
251031
  if (!isGitCommitHash(value)) {
251035
251032
  throw new InvalidArgumentError2("Expected a git commit hash (7-64 hex chars).");
251036
251033
  }
251037
251034
  return value;
251038
251035
  }
251039
- function parseConcurrency2(value) {
251036
+ function parseConcurrency(value) {
251040
251037
  const parsed = Number(value);
251041
251038
  if (!Number.isInteger(parsed) || parsed < 1 || parsed > MAX_UPLOAD_CONCURRENCY) {
251042
251039
  throw new InvalidArgumentError2(`Expected a whole number between 1 and ${MAX_UPLOAD_CONCURRENCY}.`);
@@ -251074,10 +251071,12 @@ var EMPTY_TEMPLATE = import_common_tags.stripIndent`
251074
251071
  // Auto-generated by Base44 CLI - DO NOT EDIT
251075
251072
  // Regenerate with: base44 types
251076
251073
  //
251077
- // No entities, functions, agents, or connectors found in project.
251078
- // Add resources to base44/entities/, base44/functions/, base44/agents/, or base44/connectors/
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/
251079
251076
  // and run \`base44 types generate\` again.
251080
251077
 
251078
+ import '@base44/sdk';
251079
+
251081
251080
  declare module '@base44/sdk' {
251082
251081
  // No types to augment - add resources and regenerate
251083
251082
  }
@@ -251087,8 +251086,8 @@ async function generateTypesFile(input) {
251087
251086
  await writeFile(getTypesOutputPath(input.projectRoot), content);
251088
251087
  }
251089
251088
  async function generateContent(input) {
251090
- const { entities, functions, agents, connectors } = input;
251091
- if (!entities.length && !functions.length && !agents.length && !connectors.length) {
251089
+ const { entities, functions, actors, agents, connectors } = input;
251090
+ if (!entities.length && !functions.length && !actors.length && !agents.length && !connectors.length) {
251092
251091
  return EMPTY_TEMPLATE;
251093
251092
  }
251094
251093
  const entityInterfaces = await Promise.all(entities.map((e) => compileEntity(e)));
@@ -251098,12 +251097,14 @@ async function generateContent(input) {
251098
251097
  entities.map((e) => `"${e.name}": ${toPascalCase(e.name)};`)
251099
251098
  ],
251100
251099
  ["FunctionNameRegistry", functions.map((f) => `"${f.name}": true;`)],
251100
+ ["ActorNameRegistry", actors.map((actor) => `"${actor.name}": true;`)],
251101
251101
  ["AgentNameRegistry", agents.map((a) => `"${a.name}": true;`)],
251102
251102
  ["ConnectorTypeRegistry", connectors.map((c) => `"${c.type}": true;`)]
251103
251103
  ];
251104
251104
  const registries = registryEntries.filter(([, entries]) => entries.length > 0).map(([name, entries]) => registry2(name, entries));
251105
251105
  return [
251106
251106
  HEADER2,
251107
+ "import '@base44/sdk';",
251107
251108
  entityInterfaces.join(`
251108
251109
 
251109
251110
  `),
@@ -251148,10 +251149,10 @@ function toPascalCase(name) {
251148
251149
  return name.split(/[-_\s]+/).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join("");
251149
251150
  }
251150
251151
  // src/core/types/update-project.ts
251151
- import { join as join31 } from "node:path";
251152
+ import { join as join30 } from "node:path";
251152
251153
  var TYPES_INCLUDE_PATH = `${PROJECT_SUBDIR}/${TYPES_OUTPUT_SUBDIR}/*.d.ts`;
251153
251154
  async function updateProjectConfig(projectRoot) {
251154
- const tsconfigPath = join31(projectRoot, "tsconfig.json");
251155
+ const tsconfigPath = join30(projectRoot, "tsconfig.json");
251155
251156
  if (!await pathExists(tsconfigPath)) {
251156
251157
  return false;
251157
251158
  }
@@ -251175,12 +251176,13 @@ var TYPES_FILE_PATH = "base44/.types/types.d.ts";
251175
251176
  async function generateTypesAction({
251176
251177
  runTask
251177
251178
  }) {
251178
- const { entities, functions, agents, connectors, project } = await readProjectConfig();
251179
+ const { entities, functions, actors, agents, connectors, project } = await readProjectConfig();
251179
251180
  await runTask("Generating types", async () => {
251180
251181
  await generateTypesFile({
251181
251182
  projectRoot: project.root,
251182
251183
  entities,
251183
251184
  functions,
251185
+ actors,
251184
251186
  agents,
251185
251187
  connectors
251186
251188
  });
@@ -251199,69 +251201,6 @@ function getTypesCommand() {
251199
251201
  return new Command2("types").description("Manage TypeScript type generation").addCommand(getTypesGenerateCommand());
251200
251202
  }
251201
251203
 
251202
- // src/cli/commands/versions/create.ts
251203
- async function createAction2({ runTask, jsonMode, app }, options) {
251204
- const target = await resolvePublishTarget(app?.projectRoot, {
251205
- outputDir: options.outputDir
251206
- });
251207
- const gitHash = await resolveProvenanceCommit(target.root, options.gitHash);
251208
- const version = await runTask("Creating version...", async (updateMessage) => await createVersion({
251209
- files: await collectBuildOutput(requireOutputDir(target)),
251210
- ...await collectResources(target.configDir, target)
251211
- }, {
251212
- sourceCommit: gitHash,
251213
- concurrency: options.concurrency,
251214
- progress: {
251215
- onDeclared: ({ fileCount, owedFiles }) => updateMessage(`Uploading ${owedFiles} of ${fileCount} files`),
251216
- onUpload: ({ uploadedFiles, totalFiles }) => updateMessage(`Uploaded ${uploadedFiles} of ${totalFiles} files`)
251217
- }
251218
- }), {
251219
- successMessage: "Version created",
251220
- errorMessage: "Create version failed"
251221
- });
251222
- return {
251223
- outroMessage: `Version ${version.versionId} (${version.manifestHash})`,
251224
- stdout: jsonMode ? `${JSON.stringify(version, null, 2)}
251225
- ` : undefined
251226
- };
251227
- }
251228
- function getVersionCreateCommand() {
251229
- 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) => {
251230
- if (!isGitCommitHash(value)) {
251231
- throw new InvalidArgumentError2("Expected a git commit hash (7-64 hex chars).");
251232
- }
251233
- return value;
251234
- })).addOption(new Option2("--concurrency <n>", "Parallel file uploads").default(DEFAULT_VERSION_UPLOAD_CONCURRENCY).argParser((value) => {
251235
- const parsed = Number(value);
251236
- if (!Number.isInteger(parsed) || parsed < 1 || parsed > MAX_VERSION_UPLOAD_CONCURRENCY) {
251237
- throw new InvalidArgumentError2(`Expected a whole number between 1 and ${MAX_VERSION_UPLOAD_CONCURRENCY}.`);
251238
- }
251239
- return parsed;
251240
- })).action(createAction2);
251241
- }
251242
-
251243
- // src/cli/commands/versions/deploy.ts
251244
- import { randomUUID as randomUUID5 } from "node:crypto";
251245
- async function deployAction3({ runTask, jsonMode }, versionId, options) {
251246
- const deployment = await runTask(`Deploying version ${versionId}...`, async () => await deployVersion(versionId, {
251247
- target: options.target,
251248
- idempotencyKey: randomUUID5()
251249
- }), { successMessage: "Version deployed", errorMessage: "Deploy failed" });
251250
- return {
251251
- outroMessage: `Deployment ${deployment.deploymentId} at revision ${deployment.revision}`,
251252
- stdout: jsonMode ? `${JSON.stringify(deployment, null, 2)}
251253
- ` : undefined
251254
- };
251255
- }
251256
- function getVersionDeployCommand() {
251257
- 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);
251258
- }
251259
-
251260
- // src/cli/commands/versions/index.ts
251261
- function getVersionsCommand() {
251262
- return new Command2("versions").description("Record app versions and serve them").addCommand(getVersionCreateCommand()).addCommand(getVersionDeployCommand());
251263
- }
251264
-
251265
251204
  // src/core/resources/workflow/schema.ts
251266
251205
  var WorkflowRunStatusSchema = _enum([
251267
251206
  "running",
@@ -251678,7 +251617,7 @@ function createDevLogger(label, labelColor = theme.styles.dim) {
251678
251617
  // src/cli/dev/dev-server/main.ts
251679
251618
  var import_cors = __toESM(require_lib4(), 1);
251680
251619
  var import_express6 = __toESM(require_express(), 1);
251681
- import { dirname as dirname25, join as join37 } from "node:path";
251620
+ import { dirname as dirname26, join as join36 } from "node:path";
251682
251621
 
251683
251622
  // ../../node_modules/get-port/index.js
251684
251623
  import net from "node:net";
@@ -251808,7 +251747,7 @@ var $tmpName = promisify11(tmp.tmpName);
251808
251747
 
251809
251748
  // src/cli/dev/dev-server/function-manager.ts
251810
251749
  import { spawn as spawn2 } from "node:child_process";
251811
- import { dirname as dirname22, join as join33 } from "node:path";
251750
+ import { dirname as dirname23, join as join31 } from "node:path";
251812
251751
  import { pathToFileURL } from "node:url";
251813
251752
 
251814
251753
  // src/cli/dev/dev-server/base-function-manager.ts
@@ -251913,7 +251852,7 @@ class FunctionManager extends BaseFunctionManager {
251913
251852
  }
251914
251853
  spawnFunction(func, port) {
251915
251854
  this.logger.log(`Spawning function "${func.name}" on port ${port}`);
251916
- const importMapPath = join33(dirname22(this.wrapperPath), "import-map.json");
251855
+ const importMapPath = join31(dirname23(this.wrapperPath), "import-map.json");
251917
251856
  const process2 = spawn2("deno", ["run", "--allow-all", "--import-map", importMapPath, this.wrapperPath], {
251918
251857
  env: {
251919
251858
  ...globalThis.process.env,
@@ -251987,7 +251926,7 @@ class FunctionManager extends BaseFunctionManager {
251987
251926
  import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "node:fs";
251988
251927
  import { isBuiltin } from "node:module";
251989
251928
  import { homedir as homedir3 } from "node:os";
251990
- import { join as join34 } from "node:path";
251929
+ import { join as join33 } from "node:path";
251991
251930
  import { pathToFileURL as pathToFileURL6 } from "node:url";
251992
251931
  var depsPromise;
251993
251932
  function loadDeps() {
@@ -252108,9 +252047,9 @@ export default {
252108
252047
  };
252109
252048
  `;
252110
252049
  function ensureBundlerConfig() {
252111
- const dir = join34(homedir3(), ".base44", "function-bundler");
252050
+ const dir = join33(homedir3(), ".base44", "function-bundler");
252112
252051
  mkdirSync2(dir, { recursive: true });
252113
- const configPath = join34(dir, "deno.json");
252052
+ const configPath = join33(dir, "deno.json");
252114
252053
  writeFileSync2(configPath, `${JSON.stringify({ nodeModulesDir: "auto" }, null, 2)}
252115
252054
  `);
252116
252055
  return configPath;
@@ -253491,11 +253430,11 @@ async function createEntityRoutes(db, logger, broadcast) {
253491
253430
  // src/cli/dev/dev-server/routes/integrations.ts
253492
253431
  var import_express5 = __toESM(require_express(), 1);
253493
253432
  var import_multer = __toESM(require_multer(), 1);
253494
- import { createHash as createHash3, randomUUID as randomUUID6 } from "node:crypto";
253433
+ import { createHash as createHash2, randomUUID as randomUUID4 } from "node:crypto";
253495
253434
  import fs28 from "node:fs";
253496
253435
  import path18 from "node:path";
253497
253436
  function createFileToken(fileUri) {
253498
- return createHash3("sha256").update(fileUri).digest("hex");
253437
+ return createHash2("sha256").update(fileUri).digest("hex");
253499
253438
  }
253500
253439
  function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
253501
253440
  const router = import_express5.Router({ mergeParams: true });
@@ -253508,14 +253447,14 @@ function createIntegrationRoutes(mediaFilesDir, baseUrl, remoteProxy, logger) {
253508
253447
  destination: mediaFilesDir,
253509
253448
  filename: (_req, file, cb) => {
253510
253449
  const ext = path18.extname(file.originalname);
253511
- cb(null, `${randomUUID6()}${ext}`);
253450
+ cb(null, `${randomUUID4()}${ext}`);
253512
253451
  }
253513
253452
  });
253514
253453
  const privateStorage = import_multer.default.diskStorage({
253515
253454
  destination: privateFilesDir,
253516
253455
  filename: (_req, file, cb) => {
253517
253456
  const ext = path18.extname(file.originalname);
253518
- cb(null, `${randomUUID6()}${ext}`);
253457
+ cb(null, `${randomUUID4()}${ext}`);
253519
253458
  }
253520
253459
  });
253521
253460
  const upload = import_multer.default({ storage, limits: { fileSize: MAX_FILE_SIZE } });
@@ -253580,16 +253519,16 @@ function createCustomIntegrationRoutes(remoteProxy, logger) {
253580
253519
 
253581
253520
  // src/cli/dev/dev-server/watcher.ts
253582
253521
  import { EventEmitter as EventEmitter4 } from "node:events";
253583
- import { relative as relative7 } from "node:path";
253522
+ import { relative as relative9 } from "node:path";
253584
253523
 
253585
253524
  // ../../node_modules/chokidar/index.js
253586
253525
  import { EventEmitter as EventEmitter3 } from "node:events";
253587
253526
  import { stat as statcb, Stats } from "node:fs";
253588
- import { readdir as readdir3, stat as stat7 } from "node:fs/promises";
253527
+ import { readdir as readdir3, stat as stat6 } from "node:fs/promises";
253589
253528
  import * as sp3 from "node:path";
253590
253529
 
253591
253530
  // ../../node_modules/readdirp/index.js
253592
- import { lstat as lstat2, readdir as readdir2, realpath, stat as stat5 } from "node:fs/promises";
253531
+ import { lstat as lstat2, readdir as readdir2, realpath, stat as stat4 } from "node:fs/promises";
253593
253532
  import { join as pjoin, relative as prelative, resolve as presolve, sep as psep } from "node:path";
253594
253533
  import { Readable as Readable6 } from "node:stream";
253595
253534
  var EntryTypes = {
@@ -253671,7 +253610,7 @@ class ReaddirpStream extends Readable6 {
253671
253610
  const { root, type } = opts;
253672
253611
  this._fileFilter = normalizeFilter(opts.fileFilter);
253673
253612
  this._directoryFilter = normalizeFilter(opts.directoryFilter);
253674
- const statMethod = opts.lstat ? lstat2 : stat5;
253613
+ const statMethod = opts.lstat ? lstat2 : stat4;
253675
253614
  if (wantBigintFsStats) {
253676
253615
  this._stat = (path) => statMethod(path, { bigint: true });
253677
253616
  } else {
@@ -253824,7 +253763,7 @@ function readdirp(root, options = {}) {
253824
253763
 
253825
253764
  // ../../node_modules/chokidar/handler.js
253826
253765
  import { watch as fs_watch, unwatchFile, watchFile } from "node:fs";
253827
- import { realpath as fsrealpath, lstat as lstat3, open as open2, stat as stat6 } from "node:fs/promises";
253766
+ import { realpath as fsrealpath, lstat as lstat3, open as open2, stat as stat5 } from "node:fs/promises";
253828
253767
  import { type as osType } from "node:os";
253829
253768
  import * as sp2 from "node:path";
253830
253769
  var STR_DATA = "data";
@@ -253850,7 +253789,7 @@ var EVENTS = {
253850
253789
  };
253851
253790
  var EV = EVENTS;
253852
253791
  var THROTTLE_MODE_WATCH = "watch";
253853
- var statMethods = { lstat: lstat3, stat: stat6 };
253792
+ var statMethods = { lstat: lstat3, stat: stat5 };
253854
253793
  var KEY_LISTENERS = "listeners";
253855
253794
  var KEY_ERR = "errHandlers";
253856
253795
  var KEY_RAW = "rawEmitters";
@@ -254321,7 +254260,7 @@ class NodeFsHandler {
254321
254260
  return;
254322
254261
  if (!newStats || newStats.mtimeMs === 0) {
254323
254262
  try {
254324
- const newStats = await stat6(file);
254263
+ const newStats = await stat5(file);
254325
254264
  if (this.fsw.closed)
254326
254265
  return;
254327
254266
  const at = newStats.atimeMs;
@@ -254993,7 +254932,7 @@ class FSWatcher extends EventEmitter3 {
254993
254932
  const fullPath = opts.cwd ? sp3.join(opts.cwd, path) : path;
254994
254933
  let stats;
254995
254934
  try {
254996
- stats = await stat7(fullPath);
254935
+ stats = await stat6(fullPath);
254997
254936
  } catch (err) {}
254998
254937
  if (!stats || this.closed)
254999
254938
  return;
@@ -255265,7 +255204,7 @@ class WatchBase44 extends EventEmitter4 {
255265
255204
  ignoreInitial: true
255266
255205
  });
255267
255206
  watcher.on("all", import_debounce.default(async (_event, path) => {
255268
- this.emit("change", name, relative7(targetPath, path));
255207
+ this.emit("change", name, relative9(targetPath, path));
255269
255208
  }, WATCH_DEBOUNCE_MS));
255270
255209
  watcher.on("error", (err) => {
255271
255210
  this.logger.error(`Watch handler failed for ${targetPath}`, err);
@@ -255302,6 +255241,11 @@ async function createDevServer(options) {
255302
255241
  next();
255303
255242
  });
255304
255243
  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
+ });
255305
255249
  const functionManager = await createFunctionRuntime(functions, devLogger, options.denoWrapperPath);
255306
255250
  const functionRoutes = createFunctionRouter(functionManager, devLogger);
255307
255251
  app.use("/api/apps/:appId/functions", functionRoutes);
@@ -255372,8 +255316,8 @@ async function createDevServer(options) {
255372
255316
  broadcastEntityEvent(io, appId, entityName, event);
255373
255317
  };
255374
255318
  const base44ConfigWatcher = new WatchBase44({
255375
- functions: join37(dirname25(project.configPath), project.functionsDir),
255376
- entities: join37(dirname25(project.configPath), project.entitiesDir)
255319
+ functions: join36(dirname26(project.configPath), project.functionsDir),
255320
+ entities: join36(dirname26(project.configPath), project.entitiesDir)
255377
255321
  }, devLogger);
255378
255322
  base44ConfigWatcher.on("change", async (name) => {
255379
255323
  try {
@@ -255770,7 +255714,7 @@ Examples:
255770
255714
  }
255771
255715
 
255772
255716
  // src/cli/commands/project/eject.ts
255773
- import { resolve as resolve18 } from "node:path";
255717
+ import { resolve as resolve17 } from "node:path";
255774
255718
  var import_kebabCase2 = __toESM(require_kebabCase(), 1);
255775
255719
  async function eject(ctx, options, command) {
255776
255720
  const { log, runTask, isNonInteractive } = ctx;
@@ -255834,7 +255778,7 @@ async function eject(ctx, options, command) {
255834
255778
  Ne("Operation cancelled.");
255835
255779
  throw new CLIExitError(0);
255836
255780
  }
255837
- const resolvedPath = resolve18(selectedPath);
255781
+ const resolvedPath = resolve17(selectedPath);
255838
255782
  await runTask("Downloading your project's code...", async (updateMessage) => {
255839
255783
  await createProjectFilesForExistingProject({
255840
255784
  projectId,
@@ -255901,7 +255845,7 @@ function createProgram(context) {
255901
255845
  program.addCommand(getScaffoldCommand());
255902
255846
  program.addCommand(getDashboardCommand());
255903
255847
  program.addCommand(getBuildCommand());
255904
- program.addCommand(getDeployCommand2());
255848
+ program.addCommand(getDeployCommand3());
255905
255849
  program.addCommand(getVisibilityCommand());
255906
255850
  program.addCommand(getLinkCommand());
255907
255851
  program.addCommand(getEjectCommand());
@@ -255911,14 +255855,13 @@ function createProgram(context) {
255911
255855
  program.addCommand(getAgentSkillsCommand());
255912
255856
  program.addCommand(getConnectorsCommand());
255913
255857
  program.addCommand(getFunctionsCommand());
255858
+ program.addCommand(getActorsCommand());
255914
255859
  program.addCommand(getWorkflowsCommand());
255915
255860
  program.addCommand(getSecretsCommand());
255916
255861
  program.addCommand(getSandboxCommand());
255917
255862
  program.addCommand(getBranchesCommand());
255918
255863
  program.addCommand(getAuthCommand());
255919
255864
  program.addCommand(getSiteCommand());
255920
- program.addCommand(getPublishCommand());
255921
- program.addCommand(getVersionsCommand());
255922
255865
  program.addCommand(getTypesCommand());
255923
255866
  program.addCommand(getExecCommand());
255924
255867
  program.addCommand(getDevCommand());
@@ -255931,7 +255874,7 @@ var import_detect_agent = __toESM(require_dist5(), 1);
255931
255874
  import { release, type } from "node:os";
255932
255875
 
255933
255876
  // ../../node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
255934
- import { dirname as dirname26, posix, sep as sep2 } from "path";
255877
+ import { dirname as dirname27, posix, sep as sep2 } from "path";
255935
255878
  function createModulerModifier() {
255936
255879
  const getModuleFromFileName = createGetModuleFromFilename();
255937
255880
  return async (frames) => {
@@ -255940,7 +255883,7 @@ function createModulerModifier() {
255940
255883
  return frames;
255941
255884
  };
255942
255885
  }
255943
- function createGetModuleFromFilename(basePath = process.argv[1] ? dirname26(process.argv[1]) : process.cwd(), isWindows = sep2 === "\\") {
255886
+ function createGetModuleFromFilename(basePath = process.argv[1] ? dirname27(process.argv[1]) : process.cwd(), isWindows = sep2 === "\\") {
255944
255887
  const normalizedBase = isWindows ? normalizeWindowsPath2(basePath) : basePath;
255945
255888
  return (filename) => {
255946
255889
  if (!filename)
@@ -257975,7 +257918,7 @@ class ReduceableCache {
257975
257918
  }
257976
257919
  }
257977
257920
  // ../../node_modules/posthog-node/dist/extensions/error-tracking/modifiers/context-lines.node.mjs
257978
- import { createReadStream as createReadStream4 } from "node:fs";
257921
+ import { createReadStream as createReadStream3 } from "node:fs";
257979
257922
  import { createInterface as createInterface2 } from "node:readline";
257980
257923
  var LRU_FILE_CONTENTS_CACHE = new ReduceableCache(25);
257981
257924
  var LRU_FILE_CONTENTS_FS_READ_FAILED = new ReduceableCache(20);
@@ -258019,7 +257962,7 @@ async function addSourceContext(frames) {
258019
257962
  }
258020
257963
  function getContextLinesFromFile(path, ranges, output) {
258021
257964
  return new Promise((resolve) => {
258022
- const stream = createReadStream4(path);
257965
+ const stream = createReadStream3(path);
258023
257966
  const lineReaded = createInterface2({
258024
257967
  input: stream
258025
257968
  });
@@ -259929,9 +259872,9 @@ function addCommandInfoToErrorReporter(program, errorReporter) {
259929
259872
  });
259930
259873
  }
259931
259874
  // src/cli/index.ts
259932
- var __dirname4 = dirname27(fileURLToPath6(import.meta.url));
259875
+ var __dirname4 = dirname28(fileURLToPath6(import.meta.url));
259933
259876
  async function runCLI(options) {
259934
- ensureNpmAssets(join38(__dirname4, "../assets"));
259877
+ ensureNpmAssets(join37(__dirname4, "../assets"));
259935
259878
  const errorReporter = new ErrorReporter;
259936
259879
  errorReporter.registerProcessErrorHandlers();
259937
259880
  const jsonMode = process.argv.includes("--json");
@@ -259970,4 +259913,4 @@ export {
259970
259913
  runCLI
259971
259914
  };
259972
259915
 
259973
- //# debugId=8ACC6798F4A12B0564756E2164756E21
259916
+ //# debugId=EF36A7D77029953264756E2164756E21