@lumerahq/cli 0.30.15 → 0.31.0-dev.0

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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  userContextHeaders
3
- } from "./chunk-KZEOP5YF.js";
3
+ } from "./chunk-E7YZ6QS6.js";
4
4
  import {
5
5
  fetchWithRetry
6
6
  } from "./chunk-FJFIWC7G.js";
@@ -275,6 +275,11 @@ var ApiClient = class {
275
275
  body: JSON.stringify(def)
276
276
  });
277
277
  }
278
+ async deleteMailbox(id) {
279
+ await this.request(`/api/mailboxes/${encodeURIComponent(id)}`, {
280
+ method: "DELETE"
281
+ });
282
+ }
278
283
  // Agents
279
284
  async listAgents(opts) {
280
285
  const params = new URLSearchParams({ limit: "100" });
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  createApiClient,
6
6
  isApiErrorStatus
7
- } from "./chunk-KZEOP5YF.js";
7
+ } from "./chunk-E7YZ6QS6.js";
8
8
  import {
9
9
  findProjectRoot,
10
10
  getAppName
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  deps,
3
3
  syncDeps
4
- } from "./chunk-2K2LYH5O.js";
4
+ } from "./chunk-ODANFLL7.js";
5
5
  import "./chunk-2CR762KB.js";
6
- import "./chunk-KZEOP5YF.js";
6
+ import "./chunk-E7YZ6QS6.js";
7
7
  import "./chunk-JLVVHTBY.js";
8
8
  import "./chunk-FJFIWC7G.js";
9
9
  import "./chunk-PNKVD2UK.js";
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  dev
3
- } from "./chunk-ASPEK3I6.js";
3
+ } from "./chunk-2K4ZYGCE.js";
4
4
  import {
5
5
  syncDeps
6
- } from "./chunk-2K2LYH5O.js";
6
+ } from "./chunk-ODANFLL7.js";
7
7
  import {
8
8
  loadEnv
9
9
  } from "./chunk-2CR762KB.js";
10
10
  import {
11
11
  createApiClient
12
- } from "./chunk-KZEOP5YF.js";
12
+ } from "./chunk-E7YZ6QS6.js";
13
13
  import {
14
14
  findProjectRoot,
15
15
  getApiUrl,
package/dist/index.js CHANGED
@@ -240,32 +240,32 @@ async function main() {
240
240
  switch (command) {
241
241
  // Resource commands
242
242
  case "plan":
243
- await import("./resources-TZD6KV4M.js").then((m) => m.plan(args.slice(1)));
243
+ await import("./resources-I6JSKGOX.js").then((m) => m.plan(args.slice(1)));
244
244
  break;
245
245
  case "apply":
246
- await import("./resources-TZD6KV4M.js").then((m) => m.apply(args.slice(1)));
246
+ await import("./resources-I6JSKGOX.js").then((m) => m.apply(args.slice(1)));
247
247
  break;
248
248
  case "pull":
249
- await import("./resources-TZD6KV4M.js").then((m) => m.pull(args.slice(1)));
249
+ await import("./resources-I6JSKGOX.js").then((m) => m.pull(args.slice(1)));
250
250
  break;
251
251
  case "destroy":
252
- await import("./resources-TZD6KV4M.js").then((m) => m.destroy(args.slice(1)));
252
+ await import("./resources-I6JSKGOX.js").then((m) => m.destroy(args.slice(1)));
253
253
  break;
254
254
  case "list":
255
- await import("./resources-TZD6KV4M.js").then((m) => m.list(args.slice(1)));
255
+ await import("./resources-I6JSKGOX.js").then((m) => m.list(args.slice(1)));
256
256
  break;
257
257
  case "show":
258
- await import("./resources-TZD6KV4M.js").then((m) => m.show(args.slice(1)));
258
+ await import("./resources-I6JSKGOX.js").then((m) => m.show(args.slice(1)));
259
259
  break;
260
260
  case "diff":
261
- await import("./resources-TZD6KV4M.js").then((m) => m.diff(args.slice(1)));
261
+ await import("./resources-I6JSKGOX.js").then((m) => m.diff(args.slice(1)));
262
262
  break;
263
263
  // Development
264
264
  case "dev":
265
- await import("./dev-XBOHUDPR.js").then((m) => m.dev(args.slice(1)));
265
+ await import("./dev-S5JVAXDD.js").then((m) => m.dev(args.slice(1)));
266
266
  break;
267
267
  case "run":
268
- await import("./run-EBTA3FKD.js").then((m) => m.run(args.slice(1)));
268
+ await import("./run-MSAMUYQH.js").then((m) => m.run(args.slice(1)));
269
269
  break;
270
270
  case "functions":
271
271
  await import("./functions-DZCNHDRJ.js").then(
@@ -279,10 +279,10 @@ async function main() {
279
279
  break;
280
280
  // Project
281
281
  case "init":
282
- await import("./init-L6D5OHMY.js").then((m) => m.init(args.slice(1)));
282
+ await import("./init-QVR42DUW.js").then((m) => m.init(args.slice(1)));
283
283
  break;
284
284
  case "register":
285
- await import("./register-SBXONOFY.js").then((m) => m.register(args.slice(1)));
285
+ await import("./register-G3YK77HE.js").then((m) => m.register(args.slice(1)));
286
286
  break;
287
287
  case "templates":
288
288
  await import("./templates-LNUOTNLN.js").then((m) => m.templates(subcommand, args.slice(2)));
@@ -299,7 +299,7 @@ async function main() {
299
299
  break;
300
300
  // Dependencies
301
301
  case "deps":
302
- await import("./deps-22CUIP2M.js").then((m) => m.deps(args.slice(1)));
302
+ await import("./deps-ZDRNDMUF.js").then((m) => m.deps(args.slice(1)));
303
303
  break;
304
304
  // Feature flags (read the in-sandbox snapshot)
305
305
  case "flags":
@@ -12,7 +12,7 @@ import {
12
12
  import {
13
13
  createApiClient,
14
14
  validateProjectNameLength
15
- } from "./chunk-KZEOP5YF.js";
15
+ } from "./chunk-E7YZ6QS6.js";
16
16
  import {
17
17
  getToken,
18
18
  init_auth,
@@ -7,7 +7,7 @@ import {
7
7
  import {
8
8
  createApiClient,
9
9
  validateProjectExternalId
10
- } from "./chunk-KZEOP5YF.js";
10
+ } from "./chunk-E7YZ6QS6.js";
11
11
  import {
12
12
  findProjectRoot,
13
13
  getAppName,
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  deploy
3
- } from "./chunk-ASPEK3I6.js";
3
+ } from "./chunk-2K4ZYGCE.js";
4
4
  import {
5
5
  syncDeps
6
- } from "./chunk-2K2LYH5O.js";
6
+ } from "./chunk-ODANFLL7.js";
7
7
  import {
8
8
  loadEnv
9
9
  } from "./chunk-2CR762KB.js";
@@ -12,7 +12,7 @@ import {
12
12
  createApiClient,
13
13
  isApiErrorStatus,
14
14
  validateCollectionNameLength
15
- } from "./chunk-KZEOP5YF.js";
15
+ } from "./chunk-E7YZ6QS6.js";
16
16
  import {
17
17
  findProjectRoot,
18
18
  getApiUrl,
@@ -1529,6 +1529,8 @@ ${pc2.dim("Resources:")}
1529
1529
  agents/<name> Destroy single agent
1530
1530
  skills Destroy only project skills
1531
1531
  skills/<slug> Destroy single project skill
1532
+ mailboxes Destroy only mailboxes
1533
+ mailboxes/<slug> Destroy single mailbox
1532
1534
  app Delete app registration
1533
1535
 
1534
1536
  ${pc2.dim("Options:")}
@@ -1538,6 +1540,7 @@ ${pc2.dim("Options:")}
1538
1540
  ${pc2.dim("Examples:")}
1539
1541
  lumera destroy # Destroy everything
1540
1542
  lumera destroy collections/users # Destroy single collection
1543
+ lumera destroy mailboxes/support # Destroy single mailbox
1541
1544
  lumera destroy app # Delete app registration
1542
1545
  `);
1543
1546
  }
@@ -2161,7 +2164,7 @@ async function planMailboxes(api, localMailboxes) {
2161
2164
  resource: "mailbox",
2162
2165
  id: existing.id,
2163
2166
  name: mb.slug,
2164
- details: "description differs (read-only remotely; update in UI or DB)"
2167
+ details: "description differs (no update endpoint)"
2165
2168
  });
2166
2169
  }
2167
2170
  }
@@ -2178,7 +2181,7 @@ async function applyMailboxes(api, localMailboxes) {
2178
2181
  const localDesc = (mb.description ?? "").trim();
2179
2182
  const remoteDesc = (existing.description ?? "").trim();
2180
2183
  if (localDesc !== remoteDesc) {
2181
- console.log(pc2.yellow(" \u26A0"), `mailbox ${mb.slug}: description drift not reconcilable by CLI (no PATCH endpoint yet) \u2014 update in the UI or DB`);
2184
+ console.log(pc2.yellow(" \u26A0"), `mailbox ${mb.slug}: description drift not reconcilable by CLI (no PATCH endpoint yet)`);
2182
2185
  } else {
2183
2186
  console.log(pc2.green(" \u2713"), pc2.dim(`mailbox ${mb.slug} already exists (${existing.email})`));
2184
2187
  }
@@ -2925,6 +2928,14 @@ function loadLocalAgents(platformDir, filterName, appName) {
2925
2928
  continue;
2926
2929
  }
2927
2930
  }
2931
+ if (config.allowed_user_tags !== void 0) {
2932
+ const tags = config.allowed_user_tags;
2933
+ if (!Array.isArray(tags) || tags.length > 100 || tags.some((tag) => typeof tag !== "string" || !tag || Buffer.byteLength(tag) > 64 || tag !== tag.trim() || tag !== tag.toLowerCase())) {
2934
+ errors.push(`${entry.name}: allowed_user_tags must be an array of at most 100 canonical tag keys (1\u201364 bytes each)`);
2935
+ continue;
2936
+ }
2937
+ config.allowed_user_tags = [...new Set(tags)].sort();
2938
+ }
2928
2939
  let systemPrompt = readFileSync2(promptPath, "utf-8");
2929
2940
  let policyScript = existsSync2(policyPath) ? readFileSync2(policyPath, "utf-8") : "";
2930
2941
  if (appName) {
@@ -2945,6 +2956,9 @@ function loadLocalAgents(platformDir, filterName, appName) {
2945
2956
  }
2946
2957
  return agents;
2947
2958
  }
2959
+ function allowedUserTagsChanged(local, remote) {
2960
+ return local.allowed_user_tags !== void 0 && JSON.stringify([...new Set(local.allowed_user_tags)].sort()) !== JSON.stringify([...new Set(remote.allowed_user_tags ?? [])].sort());
2961
+ }
2948
2962
  async function planAgents(api, localAgents, projectId, localSourceSkillSlugs = /* @__PURE__ */ new Set(), pendingLocalSkillSlugs = /* @__PURE__ */ new Set(), appName) {
2949
2963
  const changes = [];
2950
2964
  let validationErrors = 0;
@@ -2997,6 +3011,7 @@ async function planAgents(api, localAgents, projectId, localSourceSkillSlugs = /
2997
3011
  if ((remote.system_prompt || "").trim() !== systemPrompt.trim()) diffs.push("system_prompt");
2998
3012
  if ((remote.model || "") !== (agent.model || "")) diffs.push("model");
2999
3013
  if (agent.thinking_level !== void 0 && (remote.thinking_level || "") !== agent.thinking_level) diffs.push("thinking_level");
3014
+ if (allowedUserTagsChanged(agent, remote)) diffs.push("allowed_user_tags");
3000
3015
  if ((remote.idle_reap_timeout_seconds ?? 0) !== (agent.idle_reap_timeout_seconds ?? 0)) diffs.push("idle_reap_timeout_seconds");
3001
3016
  if ((remote.policy_script || "").trim() !== (policyScript || "").trim()) diffs.push("policy_script");
3002
3017
  if ((remote.policy_enabled || false) !== (agent.policy_enabled || false)) diffs.push("policy_enabled");
@@ -3100,6 +3115,7 @@ async function applyAgents(api, localAgents, projectId, localSourceSkillSlugs =
3100
3115
  system_prompt: systemPrompt,
3101
3116
  model: agent.model || "",
3102
3117
  ...agent.thinking_level !== void 0 ? { thinking_level: agent.thinking_level } : {},
3118
+ ...agent.allowed_user_tags !== void 0 ? { allowed_user_tags: agent.allowed_user_tags } : {},
3103
3119
  idle_reap_timeout_seconds: agent.idle_reap_timeout_seconds ?? 0,
3104
3120
  skill_ids: skillIds,
3105
3121
  policy_script: policyScript || "",
@@ -3161,6 +3177,7 @@ async function pullAgents(api, platformDir, filterName, projectId, appName) {
3161
3177
  if (agent.description) config.description = agent.description;
3162
3178
  if (agent.model) config.model = agent.model;
3163
3179
  if (agent.thinking_level) config.thinking_level = agent.thinking_level;
3180
+ if (agent.allowed_user_tags != null) config.allowed_user_tags = agent.allowed_user_tags;
3164
3181
  if (agent.idle_reap_timeout_seconds) config.idle_reap_timeout_seconds = agent.idle_reap_timeout_seconds;
3165
3182
  if (skillSlugs.length > 0) config.skills = skillSlugs;
3166
3183
  if (agent.policy_enabled) config.policy_enabled = true;
@@ -3471,6 +3488,17 @@ async function destroyResources(api, platformDir, resourceType, resourceName, sk
3471
3488
  }
3472
3489
  }
3473
3490
  }
3491
+ if (!resourceType || resourceType === "mailboxes") {
3492
+ const localMailboxes = loadLocalMailboxes(platformDir, resourceName || void 0);
3493
+ const remoteMailboxes = await api.listMailboxes();
3494
+ const remoteBySlug = new Map(remoteMailboxes.map((mailbox) => [mailbox.slug, mailbox]));
3495
+ for (const local of localMailboxes) {
3496
+ const remote = remoteBySlug.get(local.slug);
3497
+ if (remote) {
3498
+ toDelete.push({ type: "mailbox", id: local.slug, name: local.slug, remoteId: remote.id });
3499
+ }
3500
+ }
3501
+ }
3474
3502
  if (toDelete.length === 0) {
3475
3503
  console.log(pc2.green(" \u2713 No resources found to delete"));
3476
3504
  return;
@@ -3497,6 +3525,7 @@ async function destroyResources(api, platformDir, resourceType, resourceName, sk
3497
3525
  const skills = toDelete.filter((r) => r.type === "skill");
3498
3526
  const hooks = toDelete.filter((r) => r.type === "hook");
3499
3527
  const automations = toDelete.filter((r) => r.type === "automation");
3528
+ const mailboxes = toDelete.filter((r) => r.type === "mailbox");
3500
3529
  const collections = toDelete.filter((r) => r.type === "collection");
3501
3530
  let errors = 0;
3502
3531
  for (const resource of agents) {
@@ -3535,6 +3564,15 @@ async function destroyResources(api, platformDir, resourceType, resourceName, sk
3535
3564
  errors++;
3536
3565
  }
3537
3566
  }
3567
+ for (const resource of mailboxes) {
3568
+ try {
3569
+ await api.deleteMailbox(resource.remoteId);
3570
+ console.log(pc2.green(" \u2713"), `Deleted mailbox: ${resource.name}`);
3571
+ } catch (e) {
3572
+ console.log(pc2.red(" \u2717"), `Failed to delete mailbox ${resource.name}: ${e}`);
3573
+ errors++;
3574
+ }
3575
+ }
3538
3576
  const deletePlan = planCollectionDelete(collections, platformDir);
3539
3577
  if (deletePlan.cycleNames.length > 0 && !forceCycles) {
3540
3578
  console.log();
@@ -4559,7 +4597,11 @@ async function diff(args) {
4559
4597
  const promptChanged = (remote.system_prompt || "").trim() !== local.systemPrompt.trim();
4560
4598
  const policyChanged = (remote.policy_script || "").trim() !== (local.policyScript || "").trim();
4561
4599
  const thinkingLevelChanged = local.agent.thinking_level !== void 0 && (remote.thinking_level || "") !== local.agent.thinking_level;
4562
- if (!promptChanged && !policyChanged && !thinkingLevelChanged && remote.name === local.agent.name && (remote.description || "") === (local.agent.description || "") && (remote.model || "") === (local.agent.model || "") && (remote.idle_reap_timeout_seconds ?? 0) === (local.agent.idle_reap_timeout_seconds ?? 0) && (remote.policy_enabled || false) === (local.agent.policy_enabled || false)) {
4600
+ const userTagsChanged = allowedUserTagsChanged(local.agent, remote);
4601
+ if (userTagsChanged) {
4602
+ console.log(` allowed_user_tags: ${pc2.red(JSON.stringify(remote.allowed_user_tags ?? []))} \u2192 ${pc2.green(JSON.stringify(local.agent.allowed_user_tags))}`);
4603
+ }
4604
+ if (!promptChanged && !policyChanged && !thinkingLevelChanged && !userTagsChanged && remote.name === local.agent.name && (remote.description || "") === (local.agent.description || "") && (remote.model || "") === (local.agent.model || "") && (remote.idle_reap_timeout_seconds ?? 0) === (local.agent.idle_reap_timeout_seconds ?? 0) && (remote.policy_enabled || false) === (local.agent.policy_enabled || false)) {
4563
4605
  console.log(pc2.green(` \u2713 No changes`));
4564
4606
  } else {
4565
4607
  if (promptChanged) renderFullDiff("system_prompt.md", remote.system_prompt || "", local.systemPrompt);
@@ -4682,6 +4724,7 @@ export {
4682
4724
  destroy,
4683
4725
  diff,
4684
4726
  list,
4727
+ loadLocalAgents,
4685
4728
  loadLocalCollections,
4686
4729
  loadLocalSkills,
4687
4730
  localProjectSkillSlug,
@@ -4691,6 +4734,7 @@ export {
4691
4734
  planSkills,
4692
4735
  projectSkillRefCandidates,
4693
4736
  pull,
4737
+ pullAgents,
4694
4738
  pullCollections,
4695
4739
  pullSkills,
4696
4740
  resolveAgentSkillRefs,
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-2CR762KB.js";
4
4
  import {
5
5
  createApiClient
6
- } from "./chunk-KZEOP5YF.js";
6
+ } from "./chunk-E7YZ6QS6.js";
7
7
  import {
8
8
  findProjectRoot,
9
9
  getApiUrl,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumerahq/cli",
3
- "version": "0.30.15",
3
+ "version": "0.31.0-dev.0",
4
4
  "description": "CLI for building and deploying Lumera apps",
5
5
  "type": "module",
6
6
  "engines": {