@base44-preview/cli 0.0.34-pr.321.2426836 → 0.0.34-pr.321.8eabb72

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/README.md CHANGED
@@ -57,6 +57,9 @@ The CLI will guide you through project setup. For step-by-step tutorials, see th
57
57
  | [`connectors push`](https://docs.base44.com/developers/references/cli/commands/connectors-push) | Push local connectors to Base44 |
58
58
  | [`entities push`](https://docs.base44.com/developers/references/cli/commands/entities-push) | Push local entities to Base44 |
59
59
  | [`functions deploy`](https://docs.base44.com/developers/references/cli/commands/functions-deploy) | Deploy local functions to Base44 |
60
+ | [`secrets delete`](https://docs.base44.com/developers/references/cli/commands/secrets-delete) | Delete one or more secrets |
61
+ | [`secrets list`](https://docs.base44.com/developers/references/cli/commands/secrets-list) | List secret names (values are masked) |
62
+ | [`secrets set`](https://docs.base44.com/developers/references/cli/commands/secrets-set) | Set one or more secrets (KEY=VALUE format) |
60
63
  | [`site deploy`](https://docs.base44.com/developers/references/cli/commands/site-deploy) | Deploy built site files to Base44 hosting |
61
64
  | [`site open`](https://docs.base44.com/developers/references/cli/commands/site-open) | Open the published site in your browser |
62
65
  | [`types generate`](https://docs.base44.com/developers/references/cli/commands/types-generate) | Generate TypeScript types from project resources |
package/dist/cli/index.js CHANGED
@@ -185389,18 +185389,16 @@ async function fetchAgents() {
185389
185389
  }
185390
185390
  // src/core/resources/agent/config.ts
185391
185391
  import { join as join3 } from "node:path";
185392
- function toFileSlug(name2) {
185393
- return name2.toLowerCase().replace(/[^a-z0-9_]/g, "_").replace(/_+/g, "_").replace(/^_|_$/g, "");
185394
- }
185392
+ import { isDeepStrictEqual } from "node:util";
185395
185393
  async function readAgentFile(agentPath) {
185396
- const parsed = await readJsonFile(agentPath);
185397
- const result = AgentConfigSchema.safeParse(parsed);
185394
+ const raw2 = await readJsonFile(agentPath);
185395
+ const result = AgentConfigSchema.safeParse(raw2);
185398
185396
  if (!result.success) {
185399
185397
  throw new SchemaValidationError("Invalid agent file", result.error, agentPath);
185400
185398
  }
185401
- return result.data;
185399
+ return { data: result.data, raw: raw2 };
185402
185400
  }
185403
- async function readAllAgents(agentsDir) {
185401
+ async function readAgentFiles(agentsDir) {
185404
185402
  if (!await pathExists(agentsDir)) {
185405
185403
  return [];
185406
185404
  }
@@ -185408,37 +185406,72 @@ async function readAllAgents(agentsDir) {
185408
185406
  cwd: agentsDir,
185409
185407
  absolute: true
185410
185408
  });
185411
- const agents = await Promise.all(files.map((filePath) => readAgentFile(filePath)));
185412
- const names = new Set;
185413
- for (const agent of agents) {
185414
- if (names.has(agent.name)) {
185415
- throw new Error(`Duplicate agent name "${agent.name}"`);
185409
+ return await Promise.all(files.map(async (filePath) => {
185410
+ const { data, raw: raw2 } = await readAgentFile(filePath);
185411
+ return { data, raw: raw2, filePath };
185412
+ }));
185413
+ }
185414
+ function buildNameToEntryMap(entries) {
185415
+ const nameToEntry = new Map;
185416
+ for (const entry of entries) {
185417
+ if (nameToEntry.has(entry.data.name)) {
185418
+ throw new InvalidInputError(`Duplicate agent name "${entry.data.name}"`, {
185419
+ hints: [
185420
+ {
185421
+ message: `Remove duplicate agents with name "${entry.data.name}" - only one agent per name is allowed`
185422
+ }
185423
+ ]
185424
+ });
185425
+ }
185426
+ nameToEntry.set(entry.data.name, entry);
185427
+ }
185428
+ return nameToEntry;
185429
+ }
185430
+ async function readAllAgents(agentsDir) {
185431
+ const entries = await readAgentFiles(agentsDir);
185432
+ const nameToEntry = buildNameToEntryMap(entries);
185433
+ return [...nameToEntry.values()].map((e2) => e2.data);
185434
+ }
185435
+ function findAvailablePath(agentsDir, name2, claimedPaths) {
185436
+ const base = join3(agentsDir, `${name2}.${CONFIG_FILE_EXTENSION}`);
185437
+ if (!claimedPaths.has(base)) {
185438
+ return base;
185439
+ }
185440
+ for (let i = 1;; i++) {
185441
+ const candidate = join3(agentsDir, `${name2}_${i}.${CONFIG_FILE_EXTENSION}`);
185442
+ if (!claimedPaths.has(candidate)) {
185443
+ return candidate;
185416
185444
  }
185417
- names.add(agent.name);
185418
185445
  }
185419
- return agents;
185420
185446
  }
185421
185447
  async function writeAgents(agentsDir, remoteAgents) {
185422
- const existingAgents = await readAllAgents(agentsDir);
185448
+ const entries = await readAgentFiles(agentsDir);
185449
+ const nameToEntry = buildNameToEntryMap(entries);
185423
185450
  const newNames = new Set(remoteAgents.map((a) => a.name));
185424
- const toDelete = existingAgents.filter((a) => !newNames.has(a.name));
185425
- for (const agent of toDelete) {
185426
- const slug = toFileSlug(agent.name);
185427
- const files = await globby(`${slug}.${CONFIG_FILE_EXTENSION_GLOB}`, {
185428
- cwd: agentsDir,
185429
- absolute: true
185430
- });
185431
- for (const filePath of files) {
185432
- await deleteFile(filePath);
185451
+ const deleted = [];
185452
+ for (const [name2, entry] of nameToEntry) {
185453
+ if (!newNames.has(name2)) {
185454
+ await deleteFile(entry.filePath);
185455
+ deleted.push(name2);
185456
+ }
185457
+ }
185458
+ const claimedPaths = new Set;
185459
+ for (const [name2, entry] of nameToEntry) {
185460
+ if (newNames.has(name2)) {
185461
+ claimedPaths.add(entry.filePath);
185433
185462
  }
185434
185463
  }
185464
+ const written = [];
185435
185465
  for (const agent of remoteAgents) {
185436
- const slug = toFileSlug(agent.name);
185437
- const filePath = join3(agentsDir, `${slug}.${CONFIG_FILE_EXTENSION}`);
185466
+ const existing = nameToEntry.get(agent.name);
185467
+ if (existing && isDeepStrictEqual(existing.raw, agent)) {
185468
+ continue;
185469
+ }
185470
+ const filePath = existing?.filePath ?? findAvailablePath(agentsDir, agent.name, claimedPaths);
185471
+ claimedPaths.add(filePath);
185438
185472
  await writeJsonFile(filePath, agent);
185473
+ written.push(agent.name);
185439
185474
  }
185440
- const written = remoteAgents.map((a) => a.name);
185441
- const deleted = toDelete.map((a) => a.name);
185442
185475
  return { written, deleted };
185443
185476
  }
185444
185477
  // src/core/resources/agent/resource.ts
@@ -185655,7 +185688,7 @@ async function removeConnector(integrationType) {
185655
185688
  }
185656
185689
  // src/core/resources/connector/config.ts
185657
185690
  import { join as join4 } from "node:path";
185658
- import { isDeepStrictEqual } from "node:util";
185691
+ import { isDeepStrictEqual as isDeepStrictEqual2 } from "node:util";
185659
185692
  async function readConnectorFile(connectorPath) {
185660
185693
  const parsed = await readJsonFile(connectorPath);
185661
185694
  const result = ConnectorResourceSchema.safeParse(parsed);
@@ -185716,7 +185749,7 @@ async function writeConnectors(connectorsDir, remoteConnectors) {
185716
185749
  type: connector.integrationType,
185717
185750
  scopes: connector.scopes
185718
185751
  };
185719
- if (existing && isDeepStrictEqual(existing.data, localConnector)) {
185752
+ if (existing && isDeepStrictEqual2(existing.data, localConnector)) {
185720
185753
  continue;
185721
185754
  }
185722
185755
  const filePath = existing?.filePath ?? join4(connectorsDir, `${connector.integrationType}.${CONFIG_FILE_EXTENSION}`);
@@ -194209,14 +194242,11 @@ async function pullAgentsAction() {
194209
194242
  successMessage: "Agents fetched successfully",
194210
194243
  errorMessage: "Failed to fetch agents"
194211
194244
  });
194212
- if (remoteAgents.items.length === 0) {
194213
- return { outroMessage: "No agents found on Base44" };
194214
- }
194215
- const { written, deleted } = await runTask("Writing agent files", async () => {
194245
+ const { written, deleted } = await runTask("Syncing agent files", async () => {
194216
194246
  return await writeAgents(agentsDir, remoteAgents.items);
194217
194247
  }, {
194218
- successMessage: "Agent files written successfully",
194219
- errorMessage: "Failed to write agent files"
194248
+ successMessage: "Agent files synced successfully",
194249
+ errorMessage: "Failed to sync agent files"
194220
194250
  });
194221
194251
  if (written.length > 0) {
194222
194252
  R2.success(`Written: ${written.join(", ")}`);
@@ -194224,6 +194254,9 @@ async function pullAgentsAction() {
194224
194254
  if (deleted.length > 0) {
194225
194255
  R2.warn(`Deleted: ${deleted.join(", ")}`);
194226
194256
  }
194257
+ if (written.length === 0 && deleted.length === 0) {
194258
+ R2.info("All agents are already up to date");
194259
+ }
194227
194260
  return {
194228
194261
  outroMessage: `Pulled ${remoteAgents.total} agents to ${agentsDir}`
194229
194262
  };
@@ -195700,6 +195733,9 @@ function getLogsCommand(context) {
195700
195733
 
195701
195734
  // src/cli/commands/secrets/delete.ts
195702
195735
  async function deleteSecretsAction(keys) {
195736
+ if (keys.length === 0) {
195737
+ throw new InvalidInputError("Provide one or more secret names to delete.");
195738
+ }
195703
195739
  for (const key of keys) {
195704
195740
  await runTask(`Deleting secret "${key}"`, async () => {
195705
195741
  return await deleteSecret(key);
@@ -195714,7 +195750,7 @@ async function deleteSecretsAction(keys) {
195714
195750
  };
195715
195751
  }
195716
195752
  function getSecretsDeleteCommand(context) {
195717
- return new Command("delete").description("Delete one or more secrets").argument("<keys...>", "Secret name(s) to delete").action(async (keys) => {
195753
+ return new Command("delete").description("Delete one or more secrets").argument("[keys...]", "Secret name(s) to delete").action(async (keys) => {
195718
195754
  await runCommand(() => deleteSecretsAction(keys), { requireAuth: true }, context);
195719
195755
  });
195720
195756
  }
@@ -195729,7 +195765,6 @@ async function listSecretsAction() {
195729
195765
  });
195730
195766
  const names = Object.keys(secrets);
195731
195767
  if (names.length === 0) {
195732
- R2.info("No secrets found for this project.");
195733
195768
  return { outroMessage: "No secrets configured." };
195734
195769
  }
195735
195770
  for (const [name2, maskedValue] of Object.entries(secrets)) {
@@ -195795,7 +195830,7 @@ async function setSecretsAction(entries, options) {
195795
195830
  };
195796
195831
  }
195797
195832
  function getSecretsSetCommand(context) {
195798
- return new Command("set").description("Set one or more secrets (KEY=VALUE format)").argument("[entries...]", "KEY=VALUE pairs (e.g. OPENAI_API_KEY=sk-abc123)").option("--env-file <path>", "Path to .env file").action(async (entries, options) => {
195833
+ return new Command("set").description("Set one or more secrets (KEY=VALUE format)").argument("[entries...]", "KEY=VALUE pairs (e.g. KEY1=VALUE1 KEY2=VALUE2)").option("--env-file <path>", "Path to .env file").action(async (entries, options) => {
195799
195834
  await runCommand(() => setSecretsAction(entries, options), { requireAuth: true }, context);
195800
195835
  });
195801
195836
  }
@@ -200792,4 +200827,4 @@ export {
200792
200827
  CLIExitError
200793
200828
  };
200794
200829
 
200795
- //# debugId=744F4836F1F0A62164756E2164756E21
200830
+ //# debugId=68767A23A2D2E4ED64756E2164756E21