@hasna/skills 0.10.61 → 0.10.62

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
@@ -11832,9 +11832,10 @@ function replaceSkillSession(expected, replacement, plan, options = {}, beforeCo
11832
11832
  });
11833
11833
  }
11834
11834
  // package.json
11835
+ var version = "0.10.62";
11835
11836
  var package_default = {
11836
11837
  name: "@hasna/skills",
11837
- version: "0.10.61",
11838
+ version,
11838
11839
  description: "Skills library for AI coding agents",
11839
11840
  type: "module",
11840
11841
  bin: {
@@ -11875,6 +11876,7 @@ var package_default = {
11875
11876
  "migrations/",
11876
11877
  "docs/skill-standard.md",
11877
11878
  "docs/plugin-admission.md",
11879
+ "docs/runtime-activation.md",
11878
11880
  "schemas/",
11879
11881
  "LICENSE",
11880
11882
  "README.md",
@@ -11885,8 +11887,8 @@ var package_default = {
11885
11887
  types: "./dist/index.d.ts",
11886
11888
  scripts: {
11887
11889
  clean: "rm -rf bin/ dist/",
11888
- build: "bun run clean && bun build --external @hasna/contracts/kernel-lock ./src/cli/index.tsx --outdir ./bin --target bun && bun build --external @modelcontextprotocol/sdk ./src/mcp/index.ts --outfile ./bin/mcp.js --target bun && bun build --external @hasna/contracts/kernel-lock ./src/server/index.ts --outfile ./bin/server.js --target bun && bun build --external @hasna/contracts/kernel-lock ./src/server/worker.ts --outfile ./bin/worker.js --target bun && bun build --external @hasna/contracts/kernel-lock ./src/server/migrate.ts --outfile ./bin/migrate.js --target bun && bun build --external @hasna/contracts/kernel-lock ./src/server/maintenance.ts --outfile ./bin/maintenance.js --target bun && bun build ./src/index.ts ./src/storage.ts ./src/sdk/index.ts ./src/admin-contract.ts --outdir ./dist --target bun && tsc --emitDeclarationOnly --declaration --outDir dist && bun scripts/stage-kernel-lock-assets.ts",
11889
- "build:js": "rm -rf dist && bun build ./src/index.ts ./src/storage.ts ./src/sdk/index.ts ./src/admin-contract.ts --outdir ./dist --target bun && tsc --emitDeclarationOnly --declaration --outDir dist && bun scripts/stage-kernel-lock-assets.ts",
11890
+ build: "bun run clean && bun build --external @hasna/contracts/kernel-lock ./src/cli/index.tsx --outdir ./bin --target bun && bun build --external @modelcontextprotocol/sdk ./src/mcp/index.ts --outfile ./bin/mcp.js --target bun && bun build --external @hasna/contracts/kernel-lock ./src/server/index.ts --outfile ./bin/server.js --target bun && bun build --external @hasna/contracts/kernel-lock ./src/server/worker.ts --outfile ./bin/worker.js --target bun && bun build --external @hasna/contracts/kernel-lock ./src/server/migrate.ts --outfile ./bin/migrate.js --target bun && bun build --external @hasna/contracts/kernel-lock ./src/server/maintenance.ts --outfile ./bin/maintenance.js --target bun && bun build ./src/index.ts ./src/storage.ts ./src/sdk/index.ts ./src/admin-contract.ts ./src/runtime-prerequisites.ts --outdir ./dist --target bun && tsc --emitDeclarationOnly --declaration --outDir dist && bun scripts/stage-kernel-lock-assets.ts",
11891
+ "build:js": "rm -rf dist && bun build ./src/index.ts ./src/storage.ts ./src/sdk/index.ts ./src/admin-contract.ts ./src/runtime-prerequisites.ts --outdir ./dist --target bun && tsc --emitDeclarationOnly --declaration --outDir dist && bun scripts/stage-kernel-lock-assets.ts",
11890
11892
  test: "bun test --timeout 30000",
11891
11893
  dev: "bun run ./src/cli/index.tsx",
11892
11894
  "dev:watch": "bun --watch run ./src/cli/index.tsx",
@@ -11963,6 +11965,10 @@ var package_default = {
11963
11965
  homepage: "https://github.com/hasna/skills/tree/main/apps/skills",
11964
11966
  bugs: {
11965
11967
  url: "https://github.com/hasna/skills/issues"
11968
+ },
11969
+ skillsRuntimePrerequisites: {
11970
+ version: 1,
11971
+ entry: "dist/runtime-prerequisites.js"
11966
11972
  }
11967
11973
  };
11968
11974
 
@@ -13441,10 +13447,10 @@ class HttpProfileClient {
13441
13447
  invalid();
13442
13448
  return result;
13443
13449
  }
13444
- async getBundle(slug, version) {
13445
- if (!identifier(slug) || !/^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/.test(version) || version.includes(".."))
13450
+ async getBundle(slug, version2) {
13451
+ if (!identifier(slug) || !/^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/.test(version2) || version2.includes(".."))
13446
13452
  throw new Error("Invalid immutable skill reference");
13447
- return this.request(`/skills/${encodeURIComponent(slug)}/versions/${encodeURIComponent(version)}/bundle`);
13453
+ return this.request(`/skills/${encodeURIComponent(slug)}/versions/${encodeURIComponent(version2)}/bundle`);
13448
13454
  }
13449
13455
  }
13450
13456
  async function createProfileClient(signal) {
@@ -14279,14 +14285,14 @@ async function connectCodexHookRpc(options) {
14279
14285
  const binary = realpathSync5(found), stat = statSync8(binary);
14280
14286
  if (!stat.isFile() || (stat.mode & 18) !== 0)
14281
14287
  throw new Error("CODEX_HOOK_TRUST_UNSAFE_EXECUTABLE");
14282
- let version;
14288
+ let version2;
14283
14289
  try {
14284
14290
  const output = await promisify(execFile)(binary, ["--version"], { timeout: Math.min(5000, timeoutMs), maxBuffer: 4096 });
14285
- version = output.stdout.trim();
14291
+ version2 = output.stdout.trim();
14286
14292
  } catch {
14287
14293
  throw new Error("CODEX_HOOK_TRUST_NATIVE_UNAVAILABLE");
14288
14294
  }
14289
- if (!supportsCodexNativeCapability(version, "hooks"))
14295
+ if (!supportsCodexNativeCapability(version2, "hooks"))
14290
14296
  throw new Error("CODEX_HOOK_TRUST_NATIVE_UNSUPPORTED_VERSION");
14291
14297
  const current = statSync8(binary);
14292
14298
  if (realpathSync5(found) !== binary || ["dev", "ino", "size", "mtimeMs", "ctimeMs"].some((k) => stat[k] !== current[k]))
@@ -14366,7 +14372,7 @@ async function connectCodexHookRpc(options) {
14366
14372
  }
14367
14373
  });
14368
14374
  const rpc = {
14369
- version,
14375
+ version: version2,
14370
14376
  processId: child2.pid,
14371
14377
  request(method, params) {
14372
14378
  if (stopped)
@@ -14405,7 +14411,7 @@ async function connectCodexHookRpc(options) {
14405
14411
  };
14406
14412
  try {
14407
14413
  const initialized = await rpc.request("initialize", { clientInfo: { name: "skills-native-hook-enrollment", version: "1" }, capabilities: { experimentalApi: true } });
14408
- const nativeVersion = version.slice("codex-cli ".length);
14414
+ const nativeVersion = version2.slice("codex-cli ".length);
14409
14415
  if (typeof initialized?.userAgent !== "string" || !(initialized.userAgent === `skills-native-hook-enrollment/${nativeVersion}` || initialized.userAgent.startsWith(`skills-native-hook-enrollment/${nativeVersion} `)))
14410
14416
  throw new Error("CODEX_HOOK_TRUST_NATIVE_VERSION_MISMATCH");
14411
14417
  child2.stdin.write(`{"method":"initialized"}
@@ -15846,7 +15852,7 @@ function canonical6(value, depth = 0, budget2 = { remaining: 65536 }) {
15846
15852
  need5(isRecord3(value));
15847
15853
  return ["object", Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, child2]) => [key, canonical6(child2, depth + 1, budget2)])];
15848
15854
  }
15849
- function normalize3(config, version = 2) {
15855
+ function normalize3(config, version2 = 2) {
15850
15856
  if (isRecord3(config.hooks)) {
15851
15857
  delete config.hooks.state;
15852
15858
  if (!Object.keys(config.hooks).length)
@@ -15864,11 +15870,11 @@ function normalize3(config, version = 2) {
15864
15870
  if (!Object.keys(skills).length)
15865
15871
  delete config.skills;
15866
15872
  }
15867
- inference(config, version);
15873
+ inference(config, version2);
15868
15874
  if (isRecord3(config.profiles)) {
15869
15875
  for (const profile of Object.values(config.profiles))
15870
15876
  if (isRecord3(profile))
15871
- inference(profile, version);
15877
+ inference(profile, version2);
15872
15878
  }
15873
15879
  }
15874
15880
  function disablesOneSkill(entry) {
@@ -15880,8 +15886,8 @@ function disablesOneSkill(entry) {
15880
15886
  const selector = ["path", "name"].filter((key) => Object.hasOwn(entry, key));
15881
15887
  return selector.length === 1 && typeof entry[selector[0]] === "string" && entry[selector[0]].length > 0;
15882
15888
  }
15883
- function inference(target, version) {
15884
- const keys = version >= 3 ? [...INFERENCE, "service_tier", "plan_mode_reasoning_effort", "personality"] : INFERENCE;
15889
+ function inference(target, version2) {
15890
+ const keys = version2 >= 3 ? [...INFERENCE, "service_tier", "plan_mode_reasoning_effort", "personality"] : INFERENCE;
15885
15891
  for (const key of keys)
15886
15892
  if (Object.hasOwn(target, key)) {
15887
15893
  const value = target[key];
@@ -15889,7 +15895,7 @@ function inference(target, version) {
15889
15895
  need5(typeof value === "string" && MODEL.test(value));
15890
15896
  else if (key === "personality")
15891
15897
  need5(typeof value === "string" && ["none", "friendly", "pragmatic"].includes(value));
15892
- else if (version >= 3 && key !== "model_verbosity") {
15898
+ else if (version2 >= 3 && key !== "model_verbosity") {
15893
15899
  need5(typeof value === "string" && value.length <= 128 && !/[\x00-\x1f\x7f]/.test(value));
15894
15900
  if (key !== "service_tier")
15895
15901
  need5(value.length > 0);
@@ -16007,7 +16013,7 @@ function projectModelAvailabilityNux(config, text2) {
16007
16013
  }
16008
16014
  return { config, numericSource: text2 };
16009
16015
  }
16010
- function settingsDigest2(text2, version = 2) {
16016
+ function settingsDigest2(text2, version2 = 2) {
16011
16017
  let config;
16012
16018
  try {
16013
16019
  config = Bun.TOML.parse(text2);
@@ -16015,10 +16021,10 @@ function settingsDigest2(text2, version = 2) {
16015
16021
  throw new Error("Invalid Codex settings witness");
16016
16022
  }
16017
16023
  need5(isRecord3(config));
16018
- const mcp = version >= 3 ? projectRegularCodexMcp(config, text2) : { config, numericSource: text2 };
16019
- const projected = version === 4 ? projectModelAvailabilityNux(mcp.config, mcp.numericSource) : mcp;
16020
- normalize3(projected.config, version);
16021
- return sha2(`hasna.skills.codex-settings.v${version}\x00${JSON.stringify([canonical6(projected.config), numericTokens2(projected.numericSource)])}`);
16024
+ const mcp = version2 >= 3 ? projectRegularCodexMcp(config, text2) : { config, numericSource: text2 };
16025
+ const projected = version2 === 4 ? projectModelAvailabilityNux(mcp.config, mcp.numericSource) : mcp;
16026
+ normalize3(projected.config, version2);
16027
+ return sha2(`hasna.skills.codex-settings.v${version2}\x00${JSON.stringify([canonical6(projected.config), numericTokens2(projected.numericSource)])}`);
16022
16028
  }
16023
16029
  function hashCodexSettingsReplacementV2(text2, budget2 = { remaining: 256 * 1024 * 1024 }) {
16024
16030
  need5(Buffer.byteLength(text2) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text2));
@@ -19197,8 +19203,8 @@ function installSkill(name, options = {}) {
19197
19203
  };
19198
19204
  }
19199
19205
  const meta = getSkill(canonicalName);
19200
- const version = readBundledSkillVersion(name);
19201
- pinProjectSkill(skillName, { version, source: meta?.source ?? "official" }, targetDir);
19206
+ const version2 = readBundledSkillVersion(name);
19207
+ pinProjectSkill(skillName, { version: version2, source: meta?.source ?? "official" }, targetDir);
19202
19208
  warnMissingDependencies(canonicalName, targetDir);
19203
19209
  return { skill: canonicalName, success: true, path: getProjectConfigPath(targetDir), mode: "pin", source: meta?.source ?? "official" };
19204
19210
  }
@@ -19884,9 +19890,9 @@ function exactProfileSelection(spec, profile) {
19884
19890
  validateResolvedProfile(profile);
19885
19891
  const at = spec.lastIndexOf("@");
19886
19892
  const slug = at > 0 ? spec.slice(0, at) : spec;
19887
- const version = at > 0 ? spec.slice(at + 1) : undefined;
19888
- const selection = profile.selections.find((entry) => (entry.slug === slug || entry.aliases?.includes(slug)) && (version === undefined || version === entry.version));
19889
- if (!selection || version === "")
19893
+ const version2 = at > 0 ? spec.slice(at + 1) : undefined;
19894
+ const selection = profile.selections.find((entry) => (entry.slug === slug || entry.aliases?.includes(slug)) && (version2 === undefined || version2 === entry.version));
19895
+ if (!selection || version2 === "")
19890
19896
  throw new SkillSelectionError("SKILL_NOT_SELECTED", "The requested exact skill version is not selected by this profile or project lock.");
19891
19897
  return selection;
19892
19898
  }
@@ -20727,8 +20733,8 @@ class Deadline {
20727
20733
  async function bundle(selection, api, deadline) {
20728
20734
  const response = await deadline.wait(api.getBundle(selection.slug, selection.version));
20729
20735
  pluginNeed(response?.ok, "Selected plugin or migrated payload bundle is unavailable");
20730
- const declared = response.headers.get("X-Skill-Bundle-Sha256"), version = response.headers.get("X-Skill-Version");
20731
- if (declared && `sha256:${declared}` !== selection.bundleDigest || version && version !== selection.version) {
20736
+ const declared = response.headers.get("X-Skill-Bundle-Sha256"), version2 = response.headers.get("X-Skill-Version");
20737
+ if (declared && `sha256:${declared}` !== selection.bundleDigest || version2 && version2 !== selection.version) {
20732
20738
  await response.body?.cancel();
20733
20739
  pluginRefusal("Selected plugin bundle identity differs from the API response");
20734
20740
  }
@@ -20899,9 +20905,9 @@ function readRegistry(path) {
20899
20905
  closeSync14(fd);
20900
20906
  }
20901
20907
  }
20902
- function nativeVersionMatches(version, receipt) {
20908
+ function nativeVersionMatches(version2, receipt) {
20903
20909
  const upstream = receipt.plan.manifest.upstream.version;
20904
- return upstream === null ? /^[a-f0-9]{12}$/.test(version) : version.startsWith(`${upstream}-`);
20910
+ return upstream === null ? /^[a-f0-9]{12}$/.test(version2) : version2.startsWith(`${upstream}-`);
20905
20911
  }
20906
20912
  function hashManagedPluginRegistry(path, managed) {
20907
20913
  validateManagedPluginWitnesses(managed);
@@ -20969,14 +20975,14 @@ function hashManagedPluginRegistry(path, managed) {
20969
20975
  } finally {
20970
20976
  directory.closeSync();
20971
20977
  }
20972
- for (const version of names.sort()) {
20973
- const files = pluginFileWitnesses(snapshotPluginTree(join32(cacheRoot, version), { nativeRuntime: `claude-${target.native.version}` }));
20978
+ for (const version2 of names.sort()) {
20979
+ const files = pluginFileWitnesses(snapshotPluginTree(join32(cacheRoot, version2), { nativeRuntime: `claude-${target.native.version}` }));
20974
20980
  verifiedBytes += files.reduce((total, file) => total + file.size, 0);
20975
20981
  pluginNeed(verifiedBytes <= 256 * 1024 * 1024, "Managed plugin verification exceeds its aggregate byte budget");
20976
20982
  const serialized = JSON.stringify(files);
20977
- const expected = currentFiles.get(join32(cacheRoot, version));
20983
+ const expected = currentFiles.get(join32(cacheRoot, version2));
20978
20984
  pluginNeed(expected === undefined || serialized === expected, "Current native cache differs from its exact registered producer receipt");
20979
- pluginNeed([...approvals.values()].some((receipt) => nativeVersionMatches(version, receipt) && JSON.stringify(receipt.plan.files) === serialized), "A retained native plugin cache version differs from every approved projection");
20985
+ pluginNeed([...approvals.values()].some((receipt) => nativeVersionMatches(version2, receipt) && JSON.stringify(receipt.plan.files) === serialized), "A retained native plugin cache version differs from every approved projection");
20980
20986
  }
20981
20987
  for (const row of rows)
20982
20988
  pluginNeed(names.includes(row.version), "Managed native plugin installation is missing");
@@ -21131,9 +21137,9 @@ function textField(value) {
21131
21137
  need7(value?.kind === "string" && value.value.length > 0 && !/[\x00-\x1f\x7f]/.test(value.value), "contains an invalid recognized field");
21132
21138
  return value.value;
21133
21139
  }
21134
- function normalizeRow(row, version = 1) {
21140
+ function normalizeRow(row, version2 = 1) {
21135
21141
  if (!exactKeys(row, ["source", "installLocation", "lastUpdated"])) {
21136
- if (version !== 2 || !exactKeys(row, ["source", "installLocation", "lastUpdated", "autoUpdate"]))
21142
+ if (version2 !== 2 || !exactKeys(row, ["source", "installLocation", "lastUpdated", "autoUpdate"]))
21137
21143
  return;
21138
21144
  const autoUpdate = field2(row, "autoUpdate");
21139
21145
  need7(autoUpdate?.kind === "literal" && (autoUpdate.value === "true" || autoUpdate.value === "false"), "contains an invalid automatic-update preference");
@@ -23367,7 +23373,7 @@ __export(exports_external, {
23367
23373
  // node_modules/zod/v4/core/index.js
23368
23374
  var exports_core2 = {};
23369
23375
  __export(exports_core2, {
23370
- version: () => version,
23376
+ version: () => version2,
23371
23377
  validateAsync: () => validateAsync,
23372
23378
  validate: () => validate,
23373
23379
  util: () => exports_util,
@@ -25044,10 +25050,10 @@ function nanoidOfLength(length) {
25044
25050
  var duration = /^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/;
25045
25051
  var extendedDuration = /^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/;
25046
25052
  var guid = /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/;
25047
- var uuid = (version) => {
25048
- if (!version)
25053
+ var uuid = (version2) => {
25054
+ if (!version2)
25049
25055
  return /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/;
25050
- return new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${version}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`);
25056
+ return new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${version2}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`);
25051
25057
  };
25052
25058
  var uuid4 = /* @__PURE__ */ uuid(4);
25053
25059
  var uuid6 = /* @__PURE__ */ uuid(6);
@@ -25713,7 +25719,7 @@ ${content.join(`
25713
25719
  }
25714
25720
 
25715
25721
  // node_modules/zod/v4/core/versions.js
25716
- var version = {
25722
+ var version2 = {
25717
25723
  major: 4,
25718
25724
  minor: 5,
25719
25725
  patch: 4
@@ -25725,7 +25731,7 @@ var $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
25725
25731
  inst ?? (inst = {});
25726
25732
  inst._zod.def = def;
25727
25733
  inst._zod.bag = inst._zod.bag || {};
25728
- inst._zod.version = version;
25734
+ inst._zod.version = version2;
25729
25735
  const defChecks = inst._zod.def.checks;
25730
25736
  const checks = inst._zod.traits.has("$ZodCheck") ? [inst, ...defChecks ?? []] : defChecks?.length ? [...defChecks] : [];
25731
25737
  for (const ch of checks) {
@@ -41472,10 +41478,10 @@ function fromJSONSchema(schema, params) {
41472
41478
  } catch {
41473
41479
  throw new Error("fromJSONSchema input is not valid JSON (possibly cyclic); use $defs/$ref for recursive schemas");
41474
41480
  }
41475
- const version2 = detectVersion(normalized, params?.defaultTarget);
41481
+ const version3 = detectVersion(normalized, params?.defaultTarget);
41476
41482
  const defs = normalized.$defs || normalized.definitions || {};
41477
41483
  const ctx = {
41478
- version: version2,
41484
+ version: version3,
41479
41485
  defs,
41480
41486
  refs: new Map,
41481
41487
  processing: new Set,
@@ -44357,8 +44363,8 @@ class RemoteSkillsClient {
44357
44363
  async downloadSkillBundle(slug2) {
44358
44364
  return this.request(`/api/v1/skills/${encodeURIComponent(slug2)}/bundle`, { method: "GET" });
44359
44365
  }
44360
- async getBundle(slug2, version2) {
44361
- const path = version2 ? `/api/v1/skills/${encodeURIComponent(slug2)}/versions/${encodeURIComponent(version2)}/bundle` : `/api/v1/skills/${encodeURIComponent(slug2)}/bundle`;
44366
+ async getBundle(slug2, version3) {
44367
+ const path = version3 ? `/api/v1/skills/${encodeURIComponent(slug2)}/versions/${encodeURIComponent(version3)}/bundle` : `/api/v1/skills/${encodeURIComponent(slug2)}/bundle`;
44362
44368
  const response = await this.request(path, { method: "GET" });
44363
44369
  if (response.status === 404)
44364
44370
  return null;
@@ -44375,13 +44381,13 @@ class RemoteSkillsClient {
44375
44381
  throw new Error(INVALID_SKILL_VERSION_RESPONSE);
44376
44382
  return body.versions.map((entry) => normalizeSkillVersion(entry, slug2));
44377
44383
  }
44378
- async getSkillVersion(slug2, version2) {
44379
- const response = await this.requestNewRoute(`/api/v1/skills/${encodeURIComponent(slug2)}/versions/${encodeURIComponent(version2)}`, undefined, { domainNotFoundCodes: ["SKILL_NOT_FOUND", "SKILL_VERSION_NOT_FOUND"] });
44384
+ async getSkillVersion(slug2, version3) {
44385
+ const response = await this.requestNewRoute(`/api/v1/skills/${encodeURIComponent(slug2)}/versions/${encodeURIComponent(version3)}`, undefined, { domainNotFoundCodes: ["SKILL_NOT_FOUND", "SKILL_VERSION_NOT_FOUND"] });
44380
44386
  if (response.status === 404)
44381
44387
  return null;
44382
44388
  if (!response.ok)
44383
44389
  throw new Error(`version request failed: ${response.status}`);
44384
- return normalizeSkillVersion(await readSkillVersionPayload(response), slug2, version2);
44390
+ return normalizeSkillVersion(await readSkillVersionPayload(response), slug2, version3);
44385
44391
  }
44386
44392
  async listPins() {
44387
44393
  const response = await this.requestNewRoute("/api/v1/pins");
@@ -44448,8 +44454,8 @@ async function readSkillVersionPayload(response) {
44448
44454
  throw new Error(INVALID_SKILL_VERSION_RESPONSE);
44449
44455
  }
44450
44456
  }
44451
- function normalizeSkillVersion(entry, slug2, version2) {
44452
- if (!isVersionRecord(entry) || typeof entry.slug !== "string" || !entry.slug.trim() || entry.slug !== slug2 || typeof entry.version !== "string" || !entry.version.trim() || version2 !== undefined && entry.version !== version2 || typeof entry.bundleSha256 !== "string" || !/^[a-f0-9]{64}$/i.test(entry.bundleSha256) || typeof entry.bundleByteSize !== "number" || !Number.isSafeInteger(entry.bundleByteSize) || entry.bundleByteSize < 0 || typeof entry.createdAt !== "string" || !entry.createdAt.trim() || entry.current !== undefined && typeof entry.current !== "boolean" || entry.storageKind !== undefined && typeof entry.storageKind !== "string" || entry.manifest !== undefined && !isVersionRecord(entry.manifest)) {
44457
+ function normalizeSkillVersion(entry, slug2, version3) {
44458
+ if (!isVersionRecord(entry) || typeof entry.slug !== "string" || !entry.slug.trim() || entry.slug !== slug2 || typeof entry.version !== "string" || !entry.version.trim() || version3 !== undefined && entry.version !== version3 || typeof entry.bundleSha256 !== "string" || !/^[a-f0-9]{64}$/i.test(entry.bundleSha256) || typeof entry.bundleByteSize !== "number" || !Number.isSafeInteger(entry.bundleByteSize) || entry.bundleByteSize < 0 || typeof entry.createdAt !== "string" || !entry.createdAt.trim() || entry.current !== undefined && typeof entry.current !== "boolean" || entry.storageKind !== undefined && typeof entry.storageKind !== "string" || entry.manifest !== undefined && !isVersionRecord(entry.manifest)) {
44453
44459
  throw new Error(INVALID_SKILL_VERSION_RESPONSE);
44454
44460
  }
44455
44461
  return entry;
@@ -45029,7 +45035,7 @@ function installVerifiedBundle(slug2, response, meta3, corpusOptions, verify, ex
45029
45035
  } catch (error61) {
45030
45036
  throw new PullSkillError(`Bundle for '${slug2}' could not be unpacked: ${error61.message}`);
45031
45037
  }
45032
- const version2 = exact?.version ?? served ?? str(meta3?.version) ?? versionFromEntries(entries) ?? "unknown";
45038
+ const version3 = exact?.version ?? served ?? str(meta3?.version) ?? versionFromEntries(entries) ?? "unknown";
45033
45039
  const sourceCommit = sourceCommitFromEntries(entries);
45034
45040
  const declaredRevision = exact ? undefined : verified.revisionId ?? meta3?.revisionId;
45035
45041
  if (declaredRevision && meta3?.revisionId && verified.revisionId && declaredRevision !== meta3.revisionId) {
@@ -45037,7 +45043,7 @@ function installVerifiedBundle(slug2, response, meta3, corpusOptions, verify, ex
45037
45043
  }
45038
45044
  const provenRevisionId = declaredRevision ? provenRevision(meta3 ?? {}, slug2, { sha256: verified.contentHash, byteSize: verified.bytes.byteLength }) : undefined;
45039
45045
  const installed = installBundleAtomically(slug2, entries, corpusOptions, {
45040
- version: version2,
45046
+ version: version3,
45041
45047
  contentHash: verified.contentHash,
45042
45048
  ...sourceCommit ? { sourceCommit } : {},
45043
45049
  ...verified.signature ? { signature: verified.signature } : {},
@@ -45048,7 +45054,7 @@ function installVerifiedBundle(slug2, response, meta3, corpusOptions, verify, ex
45048
45054
  success: true,
45049
45055
  path: installed.path,
45050
45056
  kind: meta3?.kind ?? kindFromEntries(entries),
45051
- version: version2,
45057
+ version: version3,
45052
45058
  contentHash: verified.contentHash,
45053
45059
  ...sourceCommit ? { sourceCommit } : {},
45054
45060
  ...provenRevisionId ? { revisionId: provenRevisionId } : {},
@@ -45061,9 +45067,9 @@ function versionFromEntries(entries) {
45061
45067
  if (skillJson) {
45062
45068
  try {
45063
45069
  const parsed = JSON.parse(new TextDecoder().decode(skillJson.bytes));
45064
- const version2 = str(parsed.version);
45065
- if (version2)
45066
- return version2;
45070
+ const version3 = str(parsed.version);
45071
+ if (version3)
45072
+ return version3;
45067
45073
  } catch {}
45068
45074
  }
45069
45075
  const pkg = entries.find((entry) => entry.path === "package.json");
@@ -45234,8 +45240,8 @@ function splitNameVersion(raw) {
45234
45240
  if (at <= 0)
45235
45241
  return { name: trimmed };
45236
45242
  const name = trimmed.slice(0, at);
45237
- const version2 = trimmed.slice(at + 1);
45238
- return version2 ? { name, version: version2 } : { name };
45243
+ const version3 = trimmed.slice(at + 1);
45244
+ return version3 ? { name, version: version3 } : { name };
45239
45245
  }
45240
45246
  // src/lib/recurring-surface.ts
45241
45247
  import { isAbsolute as isAbsolute24 } from "path";
@@ -7,4 +7,5 @@ export declare function detectedIntegrationAgents(options?: {
7
7
  dataDir?: string;
8
8
  env?: NodeJS.ProcessEnv;
9
9
  cwd?: string;
10
+ allowEmpty?: boolean;
10
11
  }): IntegrationAgent[];
@@ -0,0 +1,9 @@
1
+ export declare const RUNTIME_PREREQUISITES_SCHEMA = "skills.runtime-prerequisites.v1";
2
+ export declare const RUNTIME_PREREQUISITE_CODES: readonly ["RUNTIME_CONSUMER_DISCOVERY_REFUSED", "RUNTIME_PREREQUISITE_INPUT_REFUSED", "SUMI_PATH_INPUT_REFUSED", "SUMI_PATH_CONFIG_UNSUPPORTED", "SUMI_PATH_RESOLVER_UNAVAILABLE", "SUMI_PATH_RESOLVER_INVALID_RESPONSE", "SUMI_PATH_DISCOVERY_REFUSED"];
3
+ export declare function runtimePrerequisites(home: string, cwd: string): {
4
+ ok: boolean;
5
+ schema: string;
6
+ targetVersion: string;
7
+ checked: string[];
8
+ code: string | null;
9
+ };