@lumerahq/cli 0.19.8-dev.0 → 0.19.8-dev.1

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.
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  createApiClient,
6
6
  isApiErrorStatus
7
- } from "./chunk-BAQROJO7.js";
7
+ } from "./chunk-SMZESQV2.js";
8
8
  import {
9
9
  findProjectRoot,
10
10
  getAppName
@@ -241,21 +241,25 @@ var ApiClient = class {
241
241
  method: "DELETE"
242
242
  });
243
243
  }
244
- // Agent Skills (for slug-to-ID resolution)
245
- async listAgentSkills() {
246
- const result = await this.request("/api/lm_agent_skills?limit=100");
247
- return result.skills || [];
248
- }
249
- // Resolve a list of refs (slugs or IDs) to skill records. Unlike
250
- // listAgentSkills, this returns managed skills as well — the caller has
251
- // already named them, so there is no broad enumeration concern.
244
+ // Resolve a list of refs (slugs or IDs) to skill records. Chunks
245
+ // requests so callers don't have to think about the server-side
246
+ // per-request cap.
252
247
  async lookupAgentSkills(refs) {
253
248
  if (!refs || refs.length === 0) return [];
254
- const result = await this.request("/api/lm_agent_skills/lookup", {
255
- method: "POST",
256
- body: JSON.stringify({ refs })
257
- });
258
- return result.skills || [];
249
+ const CHUNK = 100;
250
+ const chunks = [];
251
+ for (let i = 0; i < refs.length; i += CHUNK) {
252
+ chunks.push(refs.slice(i, i + CHUNK));
253
+ }
254
+ const responses = await Promise.all(
255
+ chunks.map(
256
+ (chunk) => this.request("/api/lm_agent_skills/lookup", {
257
+ method: "POST",
258
+ body: JSON.stringify({ refs: chunk })
259
+ })
260
+ )
261
+ );
262
+ return responses.flatMap((r) => r.skills || []);
259
263
  }
260
264
  // Agent Invoke
261
265
  async invokeAgent(agentId, message, sessionId) {
@@ -2,9 +2,9 @@ import {
2
2
  deps,
3
3
  projectResourceDepsEnabled,
4
4
  syncDeps
5
- } from "./chunk-ZDN32JTT.js";
5
+ } from "./chunk-2WDZ3QKS.js";
6
6
  import "./chunk-2CR762KB.js";
7
- import "./chunk-BAQROJO7.js";
7
+ import "./chunk-SMZESQV2.js";
8
8
  import "./chunk-ZH3NVYEQ.js";
9
9
  import "./chunk-FJFIWC7G.js";
10
10
  import "./chunk-PNKVD2UK.js";
@@ -4,13 +4,13 @@ import {
4
4
  import {
5
5
  projectResourceDepsEnabled,
6
6
  syncDeps
7
- } from "./chunk-ZDN32JTT.js";
7
+ } from "./chunk-2WDZ3QKS.js";
8
8
  import {
9
9
  loadEnv
10
10
  } from "./chunk-2CR762KB.js";
11
11
  import {
12
12
  createApiClient
13
- } from "./chunk-BAQROJO7.js";
13
+ } from "./chunk-SMZESQV2.js";
14
14
  import {
15
15
  findProjectRoot,
16
16
  getApiUrl,
package/dist/index.js CHANGED
@@ -219,39 +219,39 @@ async function main() {
219
219
  switch (command) {
220
220
  // Resource commands
221
221
  case "plan":
222
- await import("./resources-VM42NAMH.js").then((m) => m.plan(args.slice(1)));
222
+ await import("./resources-EPCEYCFY.js").then((m) => m.plan(args.slice(1)));
223
223
  break;
224
224
  case "apply":
225
- await import("./resources-VM42NAMH.js").then((m) => m.apply(args.slice(1)));
225
+ await import("./resources-EPCEYCFY.js").then((m) => m.apply(args.slice(1)));
226
226
  break;
227
227
  case "pull":
228
- await import("./resources-VM42NAMH.js").then((m) => m.pull(args.slice(1)));
228
+ await import("./resources-EPCEYCFY.js").then((m) => m.pull(args.slice(1)));
229
229
  break;
230
230
  case "destroy":
231
- await import("./resources-VM42NAMH.js").then((m) => m.destroy(args.slice(1)));
231
+ await import("./resources-EPCEYCFY.js").then((m) => m.destroy(args.slice(1)));
232
232
  break;
233
233
  case "list":
234
- await import("./resources-VM42NAMH.js").then((m) => m.list(args.slice(1)));
234
+ await import("./resources-EPCEYCFY.js").then((m) => m.list(args.slice(1)));
235
235
  break;
236
236
  case "show":
237
- await import("./resources-VM42NAMH.js").then((m) => m.show(args.slice(1)));
237
+ await import("./resources-EPCEYCFY.js").then((m) => m.show(args.slice(1)));
238
238
  break;
239
239
  case "diff":
240
- await import("./resources-VM42NAMH.js").then((m) => m.diff(args.slice(1)));
240
+ await import("./resources-EPCEYCFY.js").then((m) => m.diff(args.slice(1)));
241
241
  break;
242
242
  // Development
243
243
  case "dev":
244
- await import("./dev-GNZ22LKP.js").then((m) => m.dev(args.slice(1)));
244
+ await import("./dev-RENAXSGD.js").then((m) => m.dev(args.slice(1)));
245
245
  break;
246
246
  case "run":
247
- await import("./run-QRFSRZXJ.js").then((m) => m.run(args.slice(1)));
247
+ await import("./run-XWXUBWWH.js").then((m) => m.run(args.slice(1)));
248
248
  break;
249
249
  // Project
250
250
  case "init":
251
- await import("./init-RS2ET656.js").then((m) => m.init(args.slice(1)));
251
+ await import("./init-J5BNFCSP.js").then((m) => m.init(args.slice(1)));
252
252
  break;
253
253
  case "register":
254
- await import("./register-MLYFAODC.js").then((m) => m.register(args.slice(1)));
254
+ await import("./register-ZYUFXURK.js").then((m) => m.register(args.slice(1)));
255
255
  break;
256
256
  case "templates":
257
257
  await import("./templates-LNUOTNLN.js").then((m) => m.templates(subcommand, args.slice(2)));
@@ -268,7 +268,7 @@ async function main() {
268
268
  break;
269
269
  // Dependencies
270
270
  case "deps":
271
- await import("./deps-DPB3L3EJ.js").then((m) => m.deps(args.slice(1)));
271
+ await import("./deps-53AOYHH2.js").then((m) => m.deps(args.slice(1)));
272
272
  break;
273
273
  // Auth
274
274
  case "login":
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-BHYDYR75.js";
8
8
  import {
9
9
  createApiClient
10
- } from "./chunk-BAQROJO7.js";
10
+ } from "./chunk-SMZESQV2.js";
11
11
  import {
12
12
  getToken,
13
13
  init_auth,
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-BHYDYR75.js";
7
7
  import {
8
8
  createApiClient
9
- } from "./chunk-BAQROJO7.js";
9
+ } from "./chunk-SMZESQV2.js";
10
10
  import {
11
11
  findProjectRoot,
12
12
  getAppName,
@@ -4,13 +4,13 @@ import {
4
4
  import {
5
5
  projectResourceDepsEnabled,
6
6
  syncDeps
7
- } from "./chunk-ZDN32JTT.js";
7
+ } from "./chunk-2WDZ3QKS.js";
8
8
  import {
9
9
  loadEnv
10
10
  } from "./chunk-2CR762KB.js";
11
11
  import {
12
12
  createApiClient
13
- } from "./chunk-BAQROJO7.js";
13
+ } from "./chunk-SMZESQV2.js";
14
14
  import {
15
15
  findProjectRoot,
16
16
  getApiUrl,
@@ -1847,7 +1847,7 @@ async function planAgents(api, localAgents, projectId) {
1847
1847
  const remoteByExternalId = new Map(
1848
1848
  remoteAgents.filter((a) => a.external_id && !a.managed).map((a) => [a.external_id, a])
1849
1849
  );
1850
- const skillSlugToId = /* @__PURE__ */ new Map();
1850
+ const refToId = /* @__PURE__ */ new Map();
1851
1851
  const skillIdToSlug = /* @__PURE__ */ new Map();
1852
1852
  const blockedRefs = /* @__PURE__ */ new Set();
1853
1853
  const planRefs = [
@@ -1862,20 +1862,24 @@ async function planAgents(api, localAgents, projectId) {
1862
1862
  for (const s of skills) {
1863
1863
  skillIdToSlug.set(s.id, s.slug);
1864
1864
  if (isAvailableToCustomAgents(s)) {
1865
- skillSlugToId.set(s.slug, s.id);
1865
+ refToId.set(s.slug, s.id);
1866
+ refToId.set(s.id, s.id);
1866
1867
  } else {
1867
1868
  blockedRefs.add(s.slug);
1868
1869
  blockedRefs.add(s.id);
1869
1870
  }
1870
1871
  }
1871
- } catch {
1872
+ } catch (e) {
1873
+ console.log(pc2.yellow(` \u26A0 Could not resolve skills for plan: ${e}`));
1872
1874
  }
1873
1875
  }
1874
1876
  for (const { agent, systemPrompt, policyScript } of localAgents) {
1875
1877
  const remote = remoteByExternalId.get(agent.external_id);
1876
1878
  for (const ref of agent.skills ?? []) {
1877
1879
  if (blockedRefs.has(ref)) {
1878
- console.log(pc2.yellow(` \u26A0 Skill "${ref}" is a Lumera platform skill, only available to Lumera-built agents \u2014 will be skipped on apply`));
1880
+ 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`));
1881
+ } else if (!refToId.has(ref)) {
1882
+ console.log(pc2.red(` \u2717 Skill "${ref}" not found \u2014 apply will fail for this agent`));
1879
1883
  }
1880
1884
  }
1881
1885
  if (!remote) {
@@ -1889,7 +1893,7 @@ async function planAgents(api, localAgents, projectId) {
1889
1893
  if ((remote.policy_script || "").trim() !== (policyScript || "").trim()) diffs.push("policy_script");
1890
1894
  if ((remote.policy_enabled || false) !== (agent.policy_enabled || false)) diffs.push("policy_enabled");
1891
1895
  if ((remote.policy_description || "") !== (agent.policy_description || "")) diffs.push("policy_description");
1892
- const localSkillIds = (agent.skills || []).filter((s) => !blockedRefs.has(s)).map((s) => skillSlugToId.get(s) || s).sort();
1896
+ const localSkillIds = (agent.skills || []).map((s) => refToId.get(s)).filter((id) => !!id).sort();
1893
1897
  const remoteSkillIds = [...remote.skill_ids || []].sort();
1894
1898
  if (localSkillIds.join(",") !== remoteSkillIds.join(",")) {
1895
1899
  const addedSlugs = localSkillIds.filter((id) => !remoteSkillIds.includes(id)).map((id) => skillIdToSlug.get(id) || id);
@@ -1946,18 +1950,32 @@ async function applyAgents(api, localAgents, projectId) {
1946
1950
  for (const { agent, systemPrompt, policyScript } of localAgents) {
1947
1951
  const remote = remoteByExternalId.get(agent.external_id);
1948
1952
  const skillIds = [];
1953
+ const blockedForAgent = [];
1954
+ const notFoundForAgent = [];
1949
1955
  if (agent.skills) {
1950
1956
  for (const ref of agent.skills) {
1951
1957
  const id = refToId.get(ref);
1952
1958
  if (id) {
1953
1959
  skillIds.push(id);
1954
1960
  } else if (blockedRefs.has(ref)) {
1955
- console.log(pc2.yellow(` \u26A0 Skill "${ref}" is a Lumera platform skill, only available to Lumera-built agents \u2014 skipping`));
1961
+ blockedForAgent.push(ref);
1956
1962
  } else {
1957
- console.log(pc2.yellow(` \u26A0 Skill "${ref}" not found, skipping (use the slug, e.g. "using-collections")`));
1963
+ notFoundForAgent.push(ref);
1958
1964
  }
1959
1965
  }
1960
1966
  }
1967
+ if (blockedForAgent.length > 0 || notFoundForAgent.length > 0) {
1968
+ console.log(pc2.red(" \u2717"), `${agent.name}:`);
1969
+ if (blockedForAgent.length > 0) {
1970
+ console.log(pc2.red(` skills not available for custom agents: ${blockedForAgent.join(", ")}`));
1971
+ }
1972
+ if (notFoundForAgent.length > 0) {
1973
+ console.log(pc2.red(` skills not found: ${notFoundForAgent.join(", ")}`));
1974
+ }
1975
+ console.log(pc2.dim(` pick skills from GET /api/skills (tags includes "available_to_custom_agents")`));
1976
+ errors++;
1977
+ continue;
1978
+ }
1961
1979
  const payload = {
1962
1980
  external_id: agent.external_id,
1963
1981
  name: agent.name,
@@ -1995,7 +2013,9 @@ async function pullAgents(api, platformDir, filterName, projectId) {
1995
2013
  try {
1996
2014
  const skills = await api.lookupAgentSkills(pullRefs);
1997
2015
  for (const s of skills) skillIdToSlug.set(s.id, s.slug);
1998
- } catch {
2016
+ } catch (e) {
2017
+ console.log(pc2.yellow(` \u26A0 Could not resolve skills for pull: ${e}`));
2018
+ console.log(pc2.yellow(` Pulled configs may omit skills \u2014 review before re-applying.`));
1999
2019
  }
2000
2020
  }
2001
2021
  for (const agent of agents) {
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-2CR762KB.js";
4
4
  import {
5
5
  createApiClient
6
- } from "./chunk-BAQROJO7.js";
6
+ } from "./chunk-SMZESQV2.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.19.8-dev.0",
3
+ "version": "0.19.8-dev.1",
4
4
  "description": "CLI for building and deploying Lumera apps",
5
5
  "type": "module",
6
6
  "engines": {