@lumerahq/cli 0.30.0-dev.0 → 0.30.1-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.
package/dist/index.js CHANGED
@@ -240,25 +240,25 @@ async function main() {
240
240
  switch (command) {
241
241
  // Resource commands
242
242
  case "plan":
243
- await import("./resources-YEOQ7YN6.js").then((m) => m.plan(args.slice(1)));
243
+ await import("./resources-CZ32Y3KM.js").then((m) => m.plan(args.slice(1)));
244
244
  break;
245
245
  case "apply":
246
- await import("./resources-YEOQ7YN6.js").then((m) => m.apply(args.slice(1)));
246
+ await import("./resources-CZ32Y3KM.js").then((m) => m.apply(args.slice(1)));
247
247
  break;
248
248
  case "pull":
249
- await import("./resources-YEOQ7YN6.js").then((m) => m.pull(args.slice(1)));
249
+ await import("./resources-CZ32Y3KM.js").then((m) => m.pull(args.slice(1)));
250
250
  break;
251
251
  case "destroy":
252
- await import("./resources-YEOQ7YN6.js").then((m) => m.destroy(args.slice(1)));
252
+ await import("./resources-CZ32Y3KM.js").then((m) => m.destroy(args.slice(1)));
253
253
  break;
254
254
  case "list":
255
- await import("./resources-YEOQ7YN6.js").then((m) => m.list(args.slice(1)));
255
+ await import("./resources-CZ32Y3KM.js").then((m) => m.list(args.slice(1)));
256
256
  break;
257
257
  case "show":
258
- await import("./resources-YEOQ7YN6.js").then((m) => m.show(args.slice(1)));
258
+ await import("./resources-CZ32Y3KM.js").then((m) => m.show(args.slice(1)));
259
259
  break;
260
260
  case "diff":
261
- await import("./resources-YEOQ7YN6.js").then((m) => m.diff(args.slice(1)));
261
+ await import("./resources-CZ32Y3KM.js").then((m) => m.diff(args.slice(1)));
262
262
  break;
263
263
  // Development
264
264
  case "dev":
@@ -2177,6 +2177,7 @@ async function applyAutomations(api, localAutomations, projectId) {
2177
2177
  const remoteByExternalId = new Map(remoteAutomations.filter((a) => a.external_id).map((a) => [a.external_id, a]));
2178
2178
  for (const { automation, code } of localAutomations) {
2179
2179
  const remote = remoteByExternalId.get(automation.external_id);
2180
+ const appliedAction = remote ? "updated" : "created";
2180
2181
  const payload = {
2181
2182
  external_id: automation.external_id,
2182
2183
  name: automation.name,
@@ -2194,11 +2195,9 @@ async function applyAutomations(api, localAutomations, projectId) {
2194
2195
  if (remote) {
2195
2196
  await api.updateAutomation(remote.id, payload);
2196
2197
  automationId = remote.id;
2197
- console.log(pc2.green(" \u2713"), `${automation.name} (updated)`);
2198
2198
  } else {
2199
2199
  const created = await api.createAutomation(payload);
2200
2200
  automationId = created.id;
2201
- console.log(pc2.green(" \u2713"), `${automation.name} (created)`);
2202
2201
  }
2203
2202
  const localPresets = automation.inputs?.presets;
2204
2203
  if (localPresets) {
@@ -2221,6 +2220,7 @@ async function applyAutomations(api, localAutomations, projectId) {
2221
2220
  );
2222
2221
  }
2223
2222
  }
2223
+ console.log(pc2.green(" \u2713"), `${automation.name} (${appliedAction})`);
2224
2224
  } catch (e) {
2225
2225
  console.log(pc2.red(" \u2717"), `${automation.name}: ${e}`);
2226
2226
  errors++;
@@ -2269,19 +2269,27 @@ async function setSchedule(api, automationId, schedule, localPresets) {
2269
2269
  const remotePresets = await api.listPresets(automationId);
2270
2270
  const preset = remotePresets.find((p) => p.name === presetName);
2271
2271
  if (!preset) {
2272
- console.log(pc2.yellow(` \u26A0 Schedule preset '${schedule.preset}' not found, skipping schedule`));
2273
- return;
2272
+ throw new Error(`Schedule preset '${presetName}' not found`);
2274
2273
  }
2274
+ const expectedSchedule = {
2275
+ schedule: schedule.cron,
2276
+ schedule_tz: schedule.timezone || "UTC",
2277
+ schedule_preset_id: preset.id
2278
+ };
2279
+ await api.updateAutomation(automationId, expectedSchedule);
2280
+ let persisted;
2275
2281
  try {
2276
- await api.updateAutomation(automationId, {
2277
- schedule: schedule.cron,
2278
- schedule_tz: schedule.timezone || "UTC",
2279
- schedule_preset_id: preset.id
2280
- });
2281
- console.log(pc2.dim(` Set schedule: ${schedule.cron}`));
2282
+ persisted = await api.getAutomation(automationId);
2282
2283
  } catch (e) {
2283
- console.log(pc2.yellow(` \u26A0 Failed to set schedule: ${e}`));
2284
+ throw new Error(`Failed to verify persisted schedule: ${String(e)}`);
2284
2285
  }
2286
+ const mismatches = Object.keys(expectedSchedule).filter((field) => persisted[field] !== expectedSchedule[field]).map(
2287
+ (field) => `${field} expected ${JSON.stringify(expectedSchedule[field])}, got ${JSON.stringify(persisted[field])}`
2288
+ );
2289
+ if (mismatches.length > 0) {
2290
+ throw new Error(`Schedule update was not persisted: ${mismatches.join("; ")}`);
2291
+ }
2292
+ console.log(pc2.dim(` Set schedule: ${schedule.cron}`));
2285
2293
  }
2286
2294
  async function applyHooks(api, localHooks, collections, projectId) {
2287
2295
  let errors = 0;
@@ -2578,7 +2586,7 @@ function remoteSkillsByLocalSlug(remoteSkills, appName) {
2578
2586
  function projectSkillRefCandidates(refs, appName) {
2579
2587
  return [...new Set(refs.flatMap((ref) => appName && SKILL_SLUG_RE.test(ref) ? [scopedProjectSkillSlug(appName, ref), ref] : [ref]))];
2580
2588
  }
2581
- async function resolveAgentSkillRefs(api, refs, projectId, appName, pendingLocalSkillSlugs = /* @__PURE__ */ new Set()) {
2589
+ async function resolveAgentSkillRefs(api, refs, projectId, appName, localSourceSkillSlugs = /* @__PURE__ */ new Set()) {
2582
2590
  const refToId = /* @__PURE__ */ new Map();
2583
2591
  const skillIdToSlug = /* @__PURE__ */ new Map();
2584
2592
  const blockedRefs = /* @__PURE__ */ new Set();
@@ -2605,7 +2613,7 @@ async function resolveAgentSkillRefs(api, refs, projectId, appName, pendingLocal
2605
2613
  let selected = byID.get(ref);
2606
2614
  if (!selected && SKILL_SLUG_RE.test(ref)) {
2607
2615
  selected = projectByLocalSlug.get(ref);
2608
- if (!selected && pendingLocalSkillSlugs.has(ref)) {
2616
+ if (!selected && localSourceSkillSlugs.has(ref)) {
2609
2617
  continue;
2610
2618
  }
2611
2619
  }
@@ -2795,8 +2803,9 @@ function loadLocalAgents(platformDir, filterName, appName) {
2795
2803
  }
2796
2804
  return agents;
2797
2805
  }
2798
- async function planAgents(api, localAgents, projectId, localSkillSlugs = /* @__PURE__ */ new Set(), appName) {
2806
+ async function planAgents(api, localAgents, projectId, localSourceSkillSlugs = /* @__PURE__ */ new Set(), pendingLocalSkillSlugs = /* @__PURE__ */ new Set(), appName) {
2799
2807
  const changes = [];
2808
+ let validationErrors = 0;
2800
2809
  const remoteAgents = await api.listAgents(projectId ? { project_id: projectId } : void 0);
2801
2810
  const remoteByExternalId = new Map(
2802
2811
  remoteAgents.filter((a) => a.external_id && !a.managed).map((a) => [a.external_id, a])
@@ -2814,7 +2823,7 @@ async function planAgents(api, localAgents, projectId, localSkillSlugs = /* @__P
2814
2823
  outsideProjectRefs: /* @__PURE__ */ new Set()
2815
2824
  };
2816
2825
  try {
2817
- resolution = await resolveAgentSkillRefs(api, planRefs, projectId, appName, localSkillSlugs);
2826
+ resolution = await resolveAgentSkillRefs(api, planRefs, projectId, appName, localSourceSkillSlugs);
2818
2827
  } catch (e) {
2819
2828
  console.log(pc2.yellow(` \u26A0 Could not resolve skills for plan: ${e}`));
2820
2829
  }
@@ -2824,10 +2833,17 @@ async function planAgents(api, localAgents, projectId, localSkillSlugs = /* @__P
2824
2833
  for (const ref of agent.skills ?? []) {
2825
2834
  if (outsideProjectRefs.has(ref)) {
2826
2835
  console.log(pc2.red(` \u2717 Skill "${ref}" belongs to another project \u2014 apply will fail for this agent`));
2836
+ validationErrors++;
2827
2837
  } else if (blockedRefs.has(ref)) {
2828
2838
  console.log(pc2.red(` \u2717 Skill "${ref}" is a Lumera platform skill, only available to Lumera-built agents \u2014 apply will fail for this agent`));
2829
- } else if (!refToId.has(ref) && !localSkillSlugs.has(ref)) {
2830
- console.log(pc2.red(` \u2717 Skill "${ref}" not found \u2014 apply will fail for this agent`));
2839
+ validationErrors++;
2840
+ } else if (!refToId.has(ref) && !pendingLocalSkillSlugs.has(ref)) {
2841
+ if (localSourceSkillSlugs.has(ref)) {
2842
+ console.log(pc2.red(` \u2717 Skill "${ref}" exists in project source but is not deployed \u2014 run 'lumera apply skills' first or use 'lumera apply'`));
2843
+ } else {
2844
+ console.log(pc2.red(` \u2717 Skill "${ref}" not found \u2014 apply will fail for this agent`));
2845
+ }
2846
+ validationErrors++;
2831
2847
  }
2832
2848
  }
2833
2849
  if (!remote) {
@@ -2844,14 +2860,14 @@ async function planAgents(api, localAgents, projectId, localSkillSlugs = /* @__P
2844
2860
  if ((remote.policy_enabled || false) !== (agent.policy_enabled || false)) diffs.push("policy_enabled");
2845
2861
  if ((remote.policy_description || "") !== (agent.policy_description || "")) diffs.push("policy_description");
2846
2862
  const localSkillIds = (agent.skills || []).map((s) => refToId.get(s)).filter((id) => !!id).sort();
2847
- const pendingLocalSkillSlugs = (agent.skills || []).filter((ref) => localSkillSlugs.has(ref) && !refToId.has(ref));
2863
+ const pendingSkillSlugs = (agent.skills || []).filter((ref) => pendingLocalSkillSlugs.has(ref) && !refToId.has(ref));
2848
2864
  const remoteSkillIds = [...remote.skill_ids || []].sort();
2849
- if (localSkillIds.join(",") !== remoteSkillIds.join(",") || pendingLocalSkillSlugs.length > 0) {
2865
+ if (localSkillIds.join(",") !== remoteSkillIds.join(",") || pendingSkillSlugs.length > 0) {
2850
2866
  const addedSlugs = localSkillIds.filter((id) => !remoteSkillIds.includes(id)).map((id) => skillIdToSlug.get(id) || id);
2851
2867
  const removedSlugs = remoteSkillIds.filter((id) => !localSkillIds.includes(id)).map((id) => skillIdToSlug.get(id) || id);
2852
2868
  const parts = [];
2853
2869
  if (addedSlugs.length) parts.push(`+${addedSlugs.join(", +")}`);
2854
- if (pendingLocalSkillSlugs.length) parts.push(`+${pendingLocalSkillSlugs.join(", +")}`);
2870
+ if (pendingSkillSlugs.length) parts.push(`+${pendingSkillSlugs.join(", +")}`);
2855
2871
  if (removedSlugs.length) parts.push(`-${removedSlugs.join(", -")}`);
2856
2872
  diffs.push(`skills (${parts.join(", ")})`);
2857
2873
  }
@@ -2867,14 +2883,14 @@ async function planAgents(api, localAgents, projectId, localSkillSlugs = /* @__P
2867
2883
  }
2868
2884
  }
2869
2885
  }
2870
- return changes;
2886
+ return { changes, validationErrors };
2871
2887
  }
2872
2888
  var TAG_AVAILABLE_TO_CUSTOM_AGENTS = "available_to_custom_agents";
2873
2889
  function isAvailableToCustomAgents(skill) {
2874
2890
  if (!skill.managed) return true;
2875
2891
  return (skill.tags ?? []).includes(TAG_AVAILABLE_TO_CUSTOM_AGENTS);
2876
2892
  }
2877
- async function applyAgents(api, localAgents, projectId, localSkillSlugs = /* @__PURE__ */ new Set(), appName) {
2893
+ async function applyAgents(api, localAgents, projectId, localSourceSkillSlugs = /* @__PURE__ */ new Set(), appName) {
2878
2894
  let errors = 0;
2879
2895
  const remoteAgents = await api.listAgents(projectId ? { project_id: projectId } : void 0);
2880
2896
  const remoteByExternalId = new Map(
@@ -2888,7 +2904,7 @@ async function applyAgents(api, localAgents, projectId, localSkillSlugs = /* @__
2888
2904
  outsideProjectRefs: /* @__PURE__ */ new Set()
2889
2905
  };
2890
2906
  try {
2891
- resolution = await resolveAgentSkillRefs(api, refs, projectId, appName, localSkillSlugs);
2907
+ resolution = await resolveAgentSkillRefs(api, refs, projectId, appName, localSourceSkillSlugs);
2892
2908
  } catch (e) {
2893
2909
  console.log(pc2.yellow(` \u26A0 Could not resolve skills: ${e}`));
2894
2910
  }
@@ -2898,6 +2914,7 @@ async function applyAgents(api, localAgents, projectId, localSkillSlugs = /* @__
2898
2914
  const skillIds = [];
2899
2915
  const outsideProjectForAgent = [];
2900
2916
  const blockedForAgent = [];
2917
+ const undeployedLocalForAgent = [];
2901
2918
  const notFoundForAgent = [];
2902
2919
  if (agent.skills) {
2903
2920
  for (const ref of agent.skills) {
@@ -2908,12 +2925,14 @@ async function applyAgents(api, localAgents, projectId, localSkillSlugs = /* @__
2908
2925
  outsideProjectForAgent.push(ref);
2909
2926
  } else if (blockedRefs.has(ref)) {
2910
2927
  blockedForAgent.push(ref);
2928
+ } else if (localSourceSkillSlugs.has(ref)) {
2929
+ undeployedLocalForAgent.push(ref);
2911
2930
  } else {
2912
2931
  notFoundForAgent.push(ref);
2913
2932
  }
2914
2933
  }
2915
2934
  }
2916
- if (outsideProjectForAgent.length > 0 || blockedForAgent.length > 0 || notFoundForAgent.length > 0) {
2935
+ if (outsideProjectForAgent.length > 0 || blockedForAgent.length > 0 || undeployedLocalForAgent.length > 0 || notFoundForAgent.length > 0) {
2917
2936
  console.log(pc2.red(" \u2717"), `${agent.name}:`);
2918
2937
  if (outsideProjectForAgent.length > 0) {
2919
2938
  console.log(pc2.red(` skills outside the agent project: ${outsideProjectForAgent.join(", ")}`));
@@ -2921,10 +2940,14 @@ async function applyAgents(api, localAgents, projectId, localSkillSlugs = /* @__
2921
2940
  if (blockedForAgent.length > 0) {
2922
2941
  console.log(pc2.red(` skills not available for custom agents: ${blockedForAgent.join(", ")}`));
2923
2942
  }
2943
+ if (undeployedLocalForAgent.length > 0) {
2944
+ console.log(pc2.red(` locally authored skills not deployed: ${undeployedLocalForAgent.join(", ")}`));
2945
+ console.log(pc2.dim(` run 'lumera apply skills' first, or use 'lumera apply' to deploy skills and agents together`));
2946
+ }
2924
2947
  if (notFoundForAgent.length > 0) {
2925
2948
  console.log(pc2.red(` skills not found: ${notFoundForAgent.join(", ")}`));
2949
+ console.log(pc2.dim(` pick skills from GET /api/skills (tags includes "available_to_custom_agents")`));
2926
2950
  }
2927
- console.log(pc2.dim(` pick skills from GET /api/skills (tags includes "available_to_custom_agents")`));
2928
2951
  errors++;
2929
2952
  continue;
2930
2953
  }
@@ -3720,6 +3743,7 @@ async function plan(args) {
3720
3743
  }
3721
3744
  await syncDeps(projectRoot, { ignorePermissionDenied: true });
3722
3745
  const allChanges = [];
3746
+ let planValidationErrors = 0;
3723
3747
  let collections;
3724
3748
  try {
3725
3749
  const remoteCollections = await api.listCollections();
@@ -3750,15 +3774,18 @@ async function plan(args) {
3750
3774
  }
3751
3775
  }
3752
3776
  const localSkills = !type || type === "skills" ? loadLocalSkills(platformDir, name || void 0) : [];
3753
- const localSkillSlugs = new Set(!type || type === "skills" || type === "agents" ? (localSkills.length > 0 || type !== "agents" ? localSkills : loadLocalSkills(platformDir)).map((skill) => skill.slug) : []);
3777
+ const sourceSkillsForAgentResolution = type === "agents" ? loadLocalSkills(platformDir) : localSkills;
3778
+ const localSourceSkillSlugs = new Set(sourceSkillsForAgentResolution.map((skill) => skill.slug));
3779
+ const pendingLocalSkillSlugs = new Set(localSkills.map((skill) => skill.slug));
3754
3780
  if (localSkills.length > 0) {
3755
3781
  allChanges.push(...await planSkills(api, localSkills, projectId, appName));
3756
3782
  }
3757
3783
  if (!type || type === "agents") {
3758
3784
  const localAgents = loadLocalAgents(platformDir, name || void 0, appName);
3759
3785
  if (localAgents.length > 0) {
3760
- const changes = await planAgents(api, localAgents, projectId, localSkillSlugs, appName);
3761
- allChanges.push(...changes);
3786
+ const result = await planAgents(api, localAgents, projectId, localSourceSkillSlugs, pendingLocalSkillSlugs, appName);
3787
+ allChanges.push(...result.changes);
3788
+ planValidationErrors += result.validationErrors;
3762
3789
  }
3763
3790
  }
3764
3791
  if (!type || type === "mailboxes") {
@@ -3771,7 +3798,14 @@ async function plan(args) {
3771
3798
  const lintWarnings = await safeLint(projectRoot, localAutomations);
3772
3799
  if (allChanges.length === 0) {
3773
3800
  if (jsonOutput) {
3774
- console.log(JSON.stringify({ changes: [], warnings: [], lintWarnings: serializeLintWarnings(lintWarnings, projectRoot) }));
3801
+ console.log(JSON.stringify({ changes: [], warnings: [], validationErrors: planValidationErrors, lintWarnings: serializeLintWarnings(lintWarnings, projectRoot) }));
3802
+ if (planValidationErrors > 0) process.exitCode = 1;
3803
+ return;
3804
+ }
3805
+ if (planValidationErrors > 0) {
3806
+ console.log(pc2.red(` \u2717 Plan has ${planValidationErrors} agent skill validation error${planValidationErrors === 1 ? "" : "s"}.`));
3807
+ console.log();
3808
+ process.exitCode = 1;
3775
3809
  return;
3776
3810
  }
3777
3811
  console.log(pc2.green(" \u2713 No changes detected"));
@@ -3789,7 +3823,8 @@ async function plan(args) {
3789
3823
  }
3790
3824
  }
3791
3825
  }
3792
- console.log(JSON.stringify({ changes: allChanges, warnings, lintWarnings: serializeLintWarnings(lintWarnings, projectRoot) }));
3826
+ console.log(JSON.stringify({ changes: allChanges, warnings, validationErrors: planValidationErrors, lintWarnings: serializeLintWarnings(lintWarnings, projectRoot) }));
3827
+ if (planValidationErrors > 0) process.exitCode = 1;
3793
3828
  return;
3794
3829
  }
3795
3830
  console.log(pc2.bold(" Changes:"));
@@ -3830,7 +3865,12 @@ async function plan(args) {
3830
3865
  }
3831
3866
  console.log();
3832
3867
  safePrintLint(lintWarnings, projectRoot);
3833
- console.log(pc2.dim(` Run 'lumera apply' to apply these changes.`));
3868
+ if (planValidationErrors > 0) {
3869
+ console.log(pc2.red(` \u2717 Fix ${planValidationErrors} agent skill validation error${planValidationErrors === 1 ? "" : "s"} before applying.`));
3870
+ process.exitCode = 1;
3871
+ } else {
3872
+ console.log(pc2.dim(` Run 'lumera apply' to apply these changes.`));
3873
+ }
3834
3874
  console.log();
3835
3875
  }
3836
3876
  async function apply(args) {
@@ -3877,18 +3917,25 @@ async function apply(args) {
3877
3917
  collections = /* @__PURE__ */ new Map();
3878
3918
  }
3879
3919
  const allChanges = [];
3920
+ let planValidationErrors = 0;
3880
3921
  const localCollections = !type || type === "collections" ? loadLocalCollections(platformDir, name || void 0) : [];
3881
3922
  const localAutomations = !type || type === "automations" ? loadLocalAutomations(platformDir, name || void 0, appName) : [];
3882
3923
  const localHooks = !type || type === "hooks" ? loadLocalHooks(platformDir, name || void 0, appName) : [];
3883
3924
  const localSkills = !type || type === "skills" ? loadLocalSkills(platformDir, name || void 0) : [];
3884
- const localSkillSlugs = new Set(!type || type === "skills" || type === "agents" ? (localSkills.length > 0 || type !== "agents" ? localSkills : loadLocalSkills(platformDir)).map((skill) => skill.slug) : []);
3925
+ const sourceSkillsForAgentResolution = type === "agents" ? loadLocalSkills(platformDir) : localSkills;
3926
+ const localSourceSkillSlugs = new Set(sourceSkillsForAgentResolution.map((skill) => skill.slug));
3927
+ const pendingLocalSkillSlugs = new Set(localSkills.map((skill) => skill.slug));
3885
3928
  const localAgents = !type || type === "agents" ? loadLocalAgents(platformDir, name || void 0, appName) : [];
3886
3929
  const localMailboxes = !type || type === "mailboxes" ? loadLocalMailboxes(platformDir, name || void 0) : [];
3887
3930
  if (localCollections.length > 0) allChanges.push(...await planCollections(api, localCollections, appName, projectId));
3888
3931
  if (localAutomations.length > 0) allChanges.push(...await planAutomations(api, localAutomations, projectId));
3889
3932
  if (localHooks.length > 0) allChanges.push(...await planHooks(api, localHooks, collections, projectId));
3890
3933
  if (localSkills.length > 0) allChanges.push(...await planSkills(api, localSkills, projectId, appName));
3891
- if (localAgents.length > 0) allChanges.push(...await planAgents(api, localAgents, projectId, localSkillSlugs, appName));
3934
+ if (localAgents.length > 0) {
3935
+ const result = await planAgents(api, localAgents, projectId, localSourceSkillSlugs, pendingLocalSkillSlugs, appName);
3936
+ allChanges.push(...result.changes);
3937
+ planValidationErrors += result.validationErrors;
3938
+ }
3892
3939
  if (localMailboxes.length > 0) allChanges.push(...await planMailboxes(api, localMailboxes));
3893
3940
  if (name) {
3894
3941
  const hasLocal = localCollections.length > 0 || localAutomations.length > 0 || localHooks.length > 0 || localSkills.length > 0 || localAgents.length > 0 || localMailboxes.length > 0;
@@ -3898,6 +3945,12 @@ async function apply(args) {
3898
3945
  process.exit(1);
3899
3946
  }
3900
3947
  }
3948
+ if (planValidationErrors > 0) {
3949
+ console.log();
3950
+ console.log(pc2.red(` \u2717 Apply aborted: fix ${planValidationErrors} agent skill validation error${planValidationErrors === 1 ? "" : "s"} first.`));
3951
+ console.log();
3952
+ process.exit(1);
3953
+ }
3901
3954
  let willDeployApp = false;
3902
3955
  if (!type && !skipApp) {
3903
3956
  try {
@@ -3985,7 +4038,7 @@ async function apply(args) {
3985
4038
  }
3986
4039
  if (localAgents.length > 0) {
3987
4040
  console.log(pc2.bold(" Agents:"));
3988
- totalErrors += await applyAgents(api, localAgents, projectId, localSkillSlugs, appName);
4041
+ totalErrors += await applyAgents(api, localAgents, projectId, localSourceSkillSlugs, appName);
3989
4042
  console.log();
3990
4043
  }
3991
4044
  if (localMailboxes.length > 0) {
@@ -4050,11 +4103,13 @@ async function pull(args) {
4050
4103
  if (!type || type === "agents") {
4051
4104
  const localAgents = loadLocalAgents(platformDir, name || void 0, appName);
4052
4105
  if (localAgents.length > 0) {
4053
- const changes = await planAgents(
4106
+ const localSkillSlugs = new Set(loadLocalSkills(platformDir).map((skill) => skill.slug));
4107
+ const { changes } = await planAgents(
4054
4108
  api,
4055
4109
  localAgents,
4056
4110
  projectId,
4057
- new Set(loadLocalSkills(platformDir).map((skill) => skill.slug)),
4111
+ localSkillSlugs,
4112
+ localSkillSlugs,
4058
4113
  appName
4059
4114
  );
4060
4115
  for (const c of changes) {
@@ -4472,6 +4527,7 @@ async function diff(args) {
4472
4527
  export {
4473
4528
  apply,
4474
4529
  applyAgents,
4530
+ applyAutomations,
4475
4531
  applyCollections,
4476
4532
  applySkills,
4477
4533
  convertCollectionToApiFormat,
@@ -4482,6 +4538,7 @@ export {
4482
4538
  loadLocalSkills,
4483
4539
  localProjectSkillSlug,
4484
4540
  plan,
4541
+ planAgents,
4485
4542
  planCollections,
4486
4543
  planSkills,
4487
4544
  projectSkillRefCandidates,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumerahq/cli",
3
- "version": "0.30.0-dev.0",
3
+ "version": "0.30.1-dev.0",
4
4
  "description": "CLI for building and deploying Lumera apps",
5
5
  "type": "module",
6
6
  "engines": {