@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-
|
|
243
|
+
await import("./resources-CZ32Y3KM.js").then((m) => m.plan(args.slice(1)));
|
|
244
244
|
break;
|
|
245
245
|
case "apply":
|
|
246
|
-
await import("./resources-
|
|
246
|
+
await import("./resources-CZ32Y3KM.js").then((m) => m.apply(args.slice(1)));
|
|
247
247
|
break;
|
|
248
248
|
case "pull":
|
|
249
|
-
await import("./resources-
|
|
249
|
+
await import("./resources-CZ32Y3KM.js").then((m) => m.pull(args.slice(1)));
|
|
250
250
|
break;
|
|
251
251
|
case "destroy":
|
|
252
|
-
await import("./resources-
|
|
252
|
+
await import("./resources-CZ32Y3KM.js").then((m) => m.destroy(args.slice(1)));
|
|
253
253
|
break;
|
|
254
254
|
case "list":
|
|
255
|
-
await import("./resources-
|
|
255
|
+
await import("./resources-CZ32Y3KM.js").then((m) => m.list(args.slice(1)));
|
|
256
256
|
break;
|
|
257
257
|
case "show":
|
|
258
|
-
await import("./resources-
|
|
258
|
+
await import("./resources-CZ32Y3KM.js").then((m) => m.show(args.slice(1)));
|
|
259
259
|
break;
|
|
260
260
|
case "diff":
|
|
261
|
-
await import("./resources-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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,
|
|
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 &&
|
|
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,
|
|
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,
|
|
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
|
-
|
|
2830
|
-
|
|
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
|
|
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(",") ||
|
|
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 (
|
|
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,
|
|
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,
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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)
|
|
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,
|
|
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
|
|
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
|
-
|
|
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,
|