@base44-preview/cli 0.0.17-pr.111.518a0e3 → 0.0.17-pr.112.8ae01a2

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.
Files changed (2) hide show
  1. package/dist/index.js +190 -26
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -7903,6 +7903,7 @@ var AuthValidationError = class extends Error {
7903
7903
  //#endregion
7904
7904
  //#region src/core/consts.ts
7905
7905
  const PROJECT_SUBDIR = "base44";
7906
+ const CONFIG_FILE_EXTENSION = "json";
7906
7907
  const CONFIG_FILE_EXTENSION_GLOB = "{json,jsonc}";
7907
7908
  const FUNCTION_CONFIG_FILE = `function.${CONFIG_FILE_EXTENSION_GLOB}`;
7908
7909
  const APP_CONFIG_PATTERN = `${PROJECT_SUBDIR}/.app.${CONFIG_FILE_EXTENSION_GLOB}`;
@@ -16681,6 +16682,125 @@ const functionResource = {
16681
16682
  push: pushFunctions
16682
16683
  };
16683
16684
 
16685
+ //#endregion
16686
+ //#region src/core/resources/agent/schema.ts
16687
+ const EntityToolConfigSchema = object({
16688
+ entity_name: string().min(1),
16689
+ allowed_operations: array(_enum([
16690
+ "read",
16691
+ "create",
16692
+ "update",
16693
+ "delete"
16694
+ ])).default([])
16695
+ });
16696
+ const BackendFunctionToolConfigSchema = object({
16697
+ function_name: string().min(1),
16698
+ description: string().default("agent backend function")
16699
+ });
16700
+ const ToolConfigSchema = union([EntityToolConfigSchema, BackendFunctionToolConfigSchema]);
16701
+ const AgentConfigSchema = object({
16702
+ name: string().regex(/^[a-z0-9_]+$/, "Agent name must be lowercase alphanumeric with underscores").min(1).max(100),
16703
+ description: string().min(1, "Agent description cannot be empty"),
16704
+ instructions: string().min(1, "Agent instructions cannot be empty"),
16705
+ tool_configs: array(ToolConfigSchema).default([]),
16706
+ whatsapp_greeting: string().nullable().optional()
16707
+ });
16708
+ const SyncAgentsResponseSchema = object({
16709
+ created: array(string()),
16710
+ updated: array(string()),
16711
+ deleted: array(string())
16712
+ });
16713
+ const AgentConfigApiResponseSchema = object({
16714
+ name: string(),
16715
+ description: string(),
16716
+ instructions: string(),
16717
+ tool_configs: array(ToolConfigSchema).default([]),
16718
+ whatsapp_greeting: string().nullable().optional()
16719
+ });
16720
+ const ListAgentsResponseSchema = object({
16721
+ items: array(AgentConfigApiResponseSchema),
16722
+ total: number()
16723
+ });
16724
+
16725
+ //#endregion
16726
+ //#region src/core/resources/agent/config.ts
16727
+ async function readAgentFile(agentPath) {
16728
+ const parsed = await readJsonFile(agentPath);
16729
+ const result = AgentConfigSchema.safeParse(parsed);
16730
+ if (!result.success) throw new Error(`Invalid agent configuration in ${agentPath}: ${result.error.issues.map((e$1) => e$1.message).join(", ")}`);
16731
+ return result.data;
16732
+ }
16733
+ async function readAllAgents(agentsDir) {
16734
+ if (!await pathExists(agentsDir)) return [];
16735
+ const files = await globby(`*.${CONFIG_FILE_EXTENSION_GLOB}`, {
16736
+ cwd: agentsDir,
16737
+ absolute: true
16738
+ });
16739
+ const agents = await Promise.all(files.map((filePath) => readAgentFile(filePath)));
16740
+ const names = /* @__PURE__ */ new Set();
16741
+ for (const agent of agents) {
16742
+ if (names.has(agent.name)) throw new Error(`Duplicate agent name "${agent.name}"`);
16743
+ names.add(agent.name);
16744
+ }
16745
+ return agents;
16746
+ }
16747
+ async function writeAgents(agentsDir, agents) {
16748
+ const existingAgents = await readAllAgents(agentsDir);
16749
+ const newNames = new Set(agents.map((a$1) => a$1.name));
16750
+ const toDelete = existingAgents.filter((a$1) => !newNames.has(a$1.name));
16751
+ for (const agent of toDelete) await deleteFile(join(agentsDir, `${agent.name}.${CONFIG_FILE_EXTENSION}`));
16752
+ for (const agent of agents) await writeJsonFile(join(agentsDir, `${agent.name}.${CONFIG_FILE_EXTENSION}`), {
16753
+ name: agent.name,
16754
+ description: agent.description,
16755
+ instructions: agent.instructions,
16756
+ tool_configs: agent.tool_configs,
16757
+ whatsapp_greeting: agent.whatsapp_greeting ?? null
16758
+ });
16759
+ return {
16760
+ written: agents.map((a$1) => a$1.name),
16761
+ deleted: toDelete.map((a$1) => a$1.name)
16762
+ };
16763
+ }
16764
+
16765
+ //#endregion
16766
+ //#region src/core/resources/agent/api.ts
16767
+ async function pushAgents(agents) {
16768
+ const appClient = getAppClient();
16769
+ const payload = { configs: agents.map((agent) => ({
16770
+ name: agent.name,
16771
+ description: agent.description,
16772
+ instructions: agent.instructions,
16773
+ tool_configs: agent.tool_configs,
16774
+ whatsapp_greeting: agent.whatsapp_greeting ?? null
16775
+ })) };
16776
+ const response = await appClient.put("agent-configs", {
16777
+ json: payload,
16778
+ throwHttpErrors: false
16779
+ });
16780
+ if (!response.ok) {
16781
+ const errorJson = await response.json();
16782
+ const errorMessage = errorJson.detail || errorJson.message || "Unknown error";
16783
+ throw new Error(`Error occurred while syncing agents: ${errorMessage}`);
16784
+ }
16785
+ return SyncAgentsResponseSchema.parse(await response.json());
16786
+ }
16787
+ async function fetchAgents() {
16788
+ const response = await getAppClient().get("agent-configs", { throwHttpErrors: false });
16789
+ if (!response.ok) {
16790
+ const errorJson = await response.json();
16791
+ const errorMessage = errorJson.detail || errorJson.message || "Unknown error";
16792
+ throw new Error(`Error occurred while fetching agents: ${errorMessage}`);
16793
+ }
16794
+ return ListAgentsResponseSchema.parse(await response.json());
16795
+ }
16796
+
16797
+ //#endregion
16798
+ //#region src/core/resources/agent/resource.ts
16799
+ const agentResource = {
16800
+ readAll: readAllAgents,
16801
+ push: pushAgents
16802
+ };
16803
+
16684
16804
  //#endregion
16685
16805
  //#region src/core/project/schema.ts
16686
16806
  const TemplateSchema = object({
@@ -16701,7 +16821,8 @@ const ProjectConfigSchema = object({
16701
16821
  description: string().optional(),
16702
16822
  site: SiteConfigSchema.optional(),
16703
16823
  entitiesDir: string().optional().default("entities"),
16704
- functionsDir: string().optional().default("functions")
16824
+ functionsDir: string().optional().default("functions"),
16825
+ agentsDir: string().optional().default("agents")
16705
16826
  });
16706
16827
  const AppConfigSchema = object({ id: string().min(1, "id cannot be empty") });
16707
16828
  const CreateProjectResponseSchema = looseObject({ id: string() });
@@ -16773,7 +16894,11 @@ async function readProjectConfig(projectRoot) {
16773
16894
  if (!result.success) throw new Error(`Invalid project configuration: ${result.error.message}`);
16774
16895
  const project = result.data;
16775
16896
  const configDir = dirname(configPath);
16776
- const [entities, functions] = await Promise.all([entityResource.readAll(join(configDir, project.entitiesDir)), functionResource.readAll(join(configDir, project.functionsDir))]);
16897
+ const [entities, functions, agents] = await Promise.all([
16898
+ entityResource.readAll(join(configDir, project.entitiesDir)),
16899
+ functionResource.readAll(join(configDir, project.functionsDir)),
16900
+ agentResource.readAll(join(configDir, project.agentsDir))
16901
+ ]);
16777
16902
  return {
16778
16903
  project: {
16779
16904
  ...project,
@@ -16781,7 +16906,8 @@ async function readProjectConfig(projectRoot) {
16781
16906
  configPath
16782
16907
  },
16783
16908
  entities,
16784
- functions
16909
+ functions,
16910
+ agents
16785
16911
  };
16786
16912
  }
16787
16913
 
@@ -31352,6 +31478,53 @@ const entitiesPushCommand = new Command("entities").description("Manage project
31352
31478
  await runCommand(pushEntitiesAction, { requireAuth: true });
31353
31479
  }));
31354
31480
 
31481
+ //#endregion
31482
+ //#region src/cli/commands/agents/pull.ts
31483
+ async function pullAgentsAction() {
31484
+ const { project } = await readProjectConfig();
31485
+ const agentsDir = join(dirname(project.configPath), project.agentsDir);
31486
+ const response = await runTask("Fetching agents from Base44", async () => {
31487
+ return await fetchAgents();
31488
+ }, {
31489
+ successMessage: "Agents fetched successfully",
31490
+ errorMessage: "Failed to fetch agents"
31491
+ });
31492
+ if (response.items.length === 0) return { outroMessage: "No agents found on Base44" };
31493
+ const { written, deleted } = await runTask("Writing agent files", async () => {
31494
+ return await writeAgents(agentsDir, response.items);
31495
+ }, {
31496
+ successMessage: "Agent files written successfully",
31497
+ errorMessage: "Failed to write agent files"
31498
+ });
31499
+ if (written.length > 0) M.success(`Written: ${written.join(", ")}`);
31500
+ if (deleted.length > 0) M.warn(`Deleted: ${deleted.join(", ")}`);
31501
+ return { outroMessage: `Pulled ${response.total} agents to ${agentsDir}` };
31502
+ }
31503
+ const agentsPullCommand = new Command("pull").description("Pull agents from Base44 to local files").action(async () => {
31504
+ await runCommand(pullAgentsAction, { requireAuth: true });
31505
+ });
31506
+
31507
+ //#endregion
31508
+ //#region src/cli/commands/agents/push.ts
31509
+ async function pushAgentsAction() {
31510
+ const { agents } = await readProjectConfig();
31511
+ if (agents.length === 0) return { outroMessage: "No agents found in project" };
31512
+ M.info(`Found ${agents.length} agents to push`);
31513
+ const result = await runTask("Pushing agents to Base44", async () => {
31514
+ return await pushAgents(agents);
31515
+ }, {
31516
+ successMessage: "Agents pushed successfully",
31517
+ errorMessage: "Failed to push agents"
31518
+ });
31519
+ if (result.created.length > 0) M.success(`Created: ${result.created.join(", ")}`);
31520
+ if (result.updated.length > 0) M.success(`Updated: ${result.updated.join(", ")}`);
31521
+ if (result.deleted.length > 0) M.warn(`Deleted: ${result.deleted.join(", ")}`);
31522
+ return {};
31523
+ }
31524
+ const agentsCommand = new Command("agents").description("Manage project agents").addCommand(new Command("push").description("Push local agents to Base44").action(async () => {
31525
+ await runCommand(pushAgentsAction, { requireAuth: true });
31526
+ })).addCommand(agentsPullCommand);
31527
+
31355
31528
  //#endregion
31356
31529
  //#region src/cli/commands/functions/deploy.ts
31357
31530
  async function deployFunctionsAction() {
@@ -38045,7 +38218,6 @@ var require_lodash = /* @__PURE__ */ __commonJSMin(((exports, module) => {
38045
38218
  //#region src/cli/commands/project/create.ts
38046
38219
  var import_lodash = /* @__PURE__ */ __toESM(require_lodash(), 1);
38047
38220
  const DEFAULT_TEMPLATE_ID = "backend-only";
38048
- const SUPPORTED_AGENTS = ["cursor", "claude-code"];
38049
38221
  async function getTemplateById(templateId) {
38050
38222
  const templates = await listTemplates();
38051
38223
  const template = templates.find((t) => t.id === templateId);
@@ -38188,29 +38360,20 @@ async function executeCreate({ template, name: rawName, description, projectPath
38188
38360
  const result = await ye({ message: "Add AI agent skills?" });
38189
38361
  shouldAddSkills = !pD(result) && result;
38190
38362
  } else shouldAddSkills = !!skills;
38191
- if (shouldAddSkills) {
38192
- const agentArgs = SUPPORTED_AGENTS.flatMap((agent) => ["-a", agent]);
38193
- M.step(`Installing skills for: ${SUPPORTED_AGENTS.join(", ")}`);
38194
- await runTask(`Installing skills for: ${SUPPORTED_AGENTS.join(", ")}`, async () => {
38195
- await execa("npx", [
38196
- "-y",
38197
- "add-skill",
38198
- "base44/skills",
38199
- "-y",
38200
- "-s",
38201
- "base44-cli",
38202
- "-s",
38203
- "base44-sdk",
38204
- ...agentArgs
38205
- ], {
38206
- cwd: resolvedPath,
38207
- stdio: "inherit"
38208
- });
38209
- }, {
38210
- successMessage: theme.colors.base44Orange("AI agent skills added successfully"),
38211
- errorMessage: "Failed to add AI agent skills - you can add them later with: npx add-skill base44/skills"
38363
+ if (shouldAddSkills) await runTask("Installing AI agent skills...", async () => {
38364
+ await execa("npx", [
38365
+ "-y",
38366
+ "add-skill",
38367
+ "base44/skills",
38368
+ "-y"
38369
+ ], {
38370
+ cwd: resolvedPath,
38371
+ stdio: "inherit"
38212
38372
  });
38213
- }
38373
+ }, {
38374
+ successMessage: theme.colors.base44Orange("AI agent skills added successfully"),
38375
+ errorMessage: "Failed to add AI agent skills - you can add them later with: npx add-skill base44/skills"
38376
+ });
38214
38377
  M.message(`${theme.styles.header("Project")}: ${theme.colors.base44Orange(name$1)}`);
38215
38378
  M.message(`${theme.styles.header("Dashboard")}: ${theme.colors.links(getDashboardUrl(projectId))}`);
38216
38379
  if (finalAppUrl) M.message(`${theme.styles.header("Site")}: ${theme.colors.links(finalAppUrl)}`);
@@ -38957,6 +39120,7 @@ program.addCommand(dashboardCommand);
38957
39120
  program.addCommand(deployCommand);
38958
39121
  program.addCommand(linkCommand);
38959
39122
  program.addCommand(entitiesPushCommand);
39123
+ program.addCommand(agentsCommand);
38960
39124
  program.addCommand(functionsDeployCommand);
38961
39125
  program.addCommand(siteDeployCommand);
38962
39126
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@base44-preview/cli",
3
- "version": "0.0.17-pr.111.518a0e3",
3
+ "version": "0.0.17-pr.112.8ae01a2",
4
4
  "description": "Base44 CLI - Unified interface for managing Base44 applications",
5
5
  "type": "module",
6
6
  "bin": {