@hasna/skills 0.10.20 → 0.10.22

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/bin/mcp.js CHANGED
@@ -20019,7 +20019,7 @@ var package_default;
20019
20019
  var init_package = __esm(() => {
20020
20020
  package_default = {
20021
20021
  name: "@hasna/skills",
20022
- version: "0.10.20",
20022
+ version: "0.10.22",
20023
20023
  description: "Skills library for AI coding agents",
20024
20024
  type: "module",
20025
20025
  bin: {
@@ -38253,12 +38253,14 @@ function assertAgentPolicyCollections(policy) {
38253
38253
  }
38254
38254
  if (bridge.codexPluginSkills !== undefined)
38255
38255
  for (const control of array3(bridge.codexPluginSkills, 4096)) {
38256
- requireBound(object4(control) && Object.keys(control).every((key) => ["name", "pluginId", "namespace", "pluginParent", "manifestSha256", "appSha256"].includes(key)));
38256
+ requireBound(object4(control) && Object.keys(control).every((key) => ["name", "pluginId", "namespace", "pluginParent", "manifestSha256", "appSha256", "remotePluginId"].includes(key)));
38257
38257
  text(control.name, 129);
38258
38258
  text(control.pluginId, 1024);
38259
38259
  text(control.namespace, 64);
38260
38260
  text(control.pluginParent);
38261
38261
  requireBound(isAbsolute3(control.pluginParent) && resolve2(control.pluginParent) === control.pluginParent && /^[a-f0-9]{64}$/.test(control.manifestSha256));
38262
+ if (control.remotePluginId !== undefined)
38263
+ requireBound(typeof control.remotePluginId === "string" && /^[A-Za-z0-9_~-]{1,1024}$/.test(control.remotePluginId));
38262
38264
  if (control.appSha256 !== undefined)
38263
38265
  requireBound(typeof control.appSha256 === "string" && /^[a-f0-9]{64}$/.test(control.appSha256));
38264
38266
  }
@@ -38281,8 +38283,8 @@ function assertAgentPolicyCollections(policy) {
38281
38283
  text(source.path);
38282
38284
  requireBound(source.sha256 === null || typeof source.sha256 === "string" && /^[a-f0-9]{64}$/.test(source.sha256));
38283
38285
  if (source.hashMode !== undefined)
38284
- requireBound(["bytes", "path-bytes", "claude-plugin-registry", "claude-marketplace-registry", "claude-settings-v1", "claude-settings-v2", "claude-settings-v3", "claude-marketplace-registry-v2", "codex-settings-v1"].includes(source.hashMode) && source.format === undefined && source.fields === undefined && (source.hashMode === "bytes" || source.sha256 !== null));
38285
- if (source.hashMode === "codex-settings-v1")
38286
+ requireBound(["bytes", "path-bytes", "claude-plugin-registry", "claude-marketplace-registry", "claude-settings-v1", "claude-settings-v2", "claude-settings-v3", "claude-marketplace-registry-v2", "codex-settings-v1", "codex-settings-v2"].includes(source.hashMode) && source.format === undefined && source.fields === undefined && (source.hashMode === "bytes" || source.sha256 !== null));
38287
+ if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2")
38286
38288
  requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute3(source.path) && resolve2(source.path) === source.path && basename3(source.path) === "config.toml");
38287
38289
  if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3")
38288
38290
  requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute3(source.path) && resolve2(source.path) === source.path && basename3(source.path) === "settings.json");
@@ -47466,23 +47468,48 @@ var init_claude_settings_witness = __esm(() => {
47466
47468
  PERSISTED_EFFORT_LEVELS = new Set(["low", "medium", "high", "xhigh"]);
47467
47469
  });
47468
47470
 
47471
+ // src/lib/codex-native-compatibility.ts
47472
+ function supportsCodexNativeCapability(version2, capability) {
47473
+ return typeof version2 === "string" && Object.hasOwn(MEASURED_CODEX_CAPABILITIES, version2) && MEASURED_CODEX_CAPABILITIES[version2].includes(capability);
47474
+ }
47475
+ var MEASURED_CODEX_CAPABILITIES, SUPPORTED_CODEX_HOOK_VERSIONS;
47476
+ var init_codex_native_compatibility = __esm(() => {
47477
+ MEASURED_CODEX_CAPABILITIES = {
47478
+ "codex-cli 0.153.0": ["hooks"],
47479
+ "codex-cli 0.154.0": ["hooks"],
47480
+ "codex-cli 0.155.0": ["hooks"],
47481
+ "codex-cli 0.155.1": ["hooks"],
47482
+ "codex-cli 0.156.1": ["hooks"],
47483
+ "codex-cli 0.157.0": ["hooks"],
47484
+ "codex-cli 0.157.1": ["hooks"],
47485
+ "codex-cli 0.158.0": ["hooks"],
47486
+ "codex-cli 0.159.0": ["hooks"],
47487
+ "codex-cli 0.159.2": ["hooks", "qualified-skill-catalog"],
47488
+ "codex-cli 0.160.0": ["hooks", "qualified-skill-catalog"]
47489
+ };
47490
+ SUPPORTED_CODEX_HOOK_VERSIONS = Object.freeze(Object.keys(MEASURED_CODEX_CAPABILITIES).filter((version2) => supportsCodexNativeCapability(version2, "hooks")));
47491
+ });
47492
+
47469
47493
  // src/lib/codex-hook-rpc.ts
47470
- var init_codex_hook_rpc = () => {};
47494
+ var init_codex_hook_rpc = __esm(() => {
47495
+ init_codex_native_compatibility();
47496
+ init_codex_native_compatibility();
47497
+ });
47471
47498
 
47472
47499
  // src/lib/codex-native-skill-catalog.ts
47473
- var SUPPORTED_NAME_CONTROL_VERSIONS;
47474
47500
  var init_codex_native_skill_catalog = __esm(() => {
47475
47501
  init_codex_hook_rpc();
47476
- SUPPORTED_NAME_CONTROL_VERSIONS = new Set(["codex-cli 0.159.2"]);
47502
+ init_codex_native_compatibility();
47477
47503
  });
47478
47504
 
47479
47505
  // src/lib/codex-plugin-skill-controls.ts
47480
47506
  var init_codex_plugin_skill_controls = __esm(() => {
47481
47507
  init_claude_settings_witness();
47508
+ init_codex_native_compatibility();
47482
47509
  init_codex_native_skill_catalog();
47483
47510
  });
47484
47511
 
47485
- // src/lib/codex-settings-witness.ts
47512
+ // src/lib/codex-settings-witness-v1.ts
47486
47513
  import { createHash as createHash9 } from "crypto";
47487
47514
  function need3(value) {
47488
47515
  if (!value)
@@ -47574,12 +47601,161 @@ function captureCodexSettings(path, budget = { remaining: 256 * 1024 * 1024 }) {
47574
47601
  return { path, hashMode: "codex-settings-v1", sha256: hashCodexSettingsReplacement(text2) };
47575
47602
  }
47576
47603
  var sha = (text2) => createHash9("sha256").update(text2).digest("hex"), EFFORT, VERBOSITY;
47577
- var init_codex_settings_witness = __esm(() => {
47604
+ var init_codex_settings_witness_v1 = __esm(() => {
47578
47605
  init_claude_settings_witness();
47579
47606
  EFFORT = new Set(["none", "minimal", "low", "medium", "high", "xhigh"]);
47580
47607
  VERBOSITY = new Set(["low", "medium", "high"]);
47581
47608
  });
47582
47609
 
47610
+ // src/lib/codex-settings-witness.ts
47611
+ import { createHash as createHash10 } from "crypto";
47612
+ function need4(value) {
47613
+ if (!value)
47614
+ throw new Error("Invalid Codex settings witness");
47615
+ }
47616
+ function isRecord3(value) {
47617
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
47618
+ }
47619
+ function isDate(value) {
47620
+ return value instanceof Date;
47621
+ }
47622
+ function numericTokens2(text2) {
47623
+ const result = [];
47624
+ for (let at = 0;at < text2.length; ) {
47625
+ const char = text2[at];
47626
+ if (char === "#") {
47627
+ while (at < text2.length && text2[at] !== `
47628
+ `)
47629
+ at++;
47630
+ continue;
47631
+ }
47632
+ if (char === '"' || char === "'") {
47633
+ const quote = char, triple = text2.slice(at, at + 3) === quote.repeat(3);
47634
+ at += triple ? 3 : 1;
47635
+ while (at < text2.length) {
47636
+ if (quote === '"' && text2[at] === "\\") {
47637
+ at += 2;
47638
+ continue;
47639
+ }
47640
+ if (text2.slice(at, at + (triple ? 3 : 1)) === quote.repeat(triple ? 3 : 1)) {
47641
+ at += triple ? 3 : 1;
47642
+ break;
47643
+ }
47644
+ at++;
47645
+ }
47646
+ continue;
47647
+ }
47648
+ if (/[0-9+-]/.test(char)) {
47649
+ const start = at;
47650
+ while (at < text2.length && !/[\s,\]{}#=]/.test(text2[at]))
47651
+ at++;
47652
+ if (at > start) {
47653
+ result.push(text2.slice(start, at));
47654
+ continue;
47655
+ }
47656
+ }
47657
+ at++;
47658
+ }
47659
+ return result.sort();
47660
+ }
47661
+ function canonical4(value, depth = 0, budget = { remaining: 65536 }) {
47662
+ need4(depth <= 32 && --budget.remaining >= 0);
47663
+ if (value === null)
47664
+ return ["null"];
47665
+ if (typeof value === "string")
47666
+ return ["string", value];
47667
+ if (typeof value === "boolean")
47668
+ return ["boolean", value];
47669
+ if (typeof value === "number") {
47670
+ need4(Number.isFinite(value));
47671
+ return ["number", String(value)];
47672
+ }
47673
+ if (isDate(value)) {
47674
+ need4(Number.isFinite(value.getTime()));
47675
+ return ["date", value.toISOString()];
47676
+ }
47677
+ if (Array.isArray(value))
47678
+ return ["array", value.map((child) => canonical4(child, depth + 1, budget))];
47679
+ need4(isRecord3(value));
47680
+ return ["object", Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, child]) => [key, canonical4(child, depth + 1, budget)])];
47681
+ }
47682
+ function normalize2(config2) {
47683
+ if (isRecord3(config2.hooks)) {
47684
+ delete config2.hooks.state;
47685
+ if (!Object.keys(config2.hooks).length)
47686
+ delete config2.hooks;
47687
+ }
47688
+ if (isRecord3(config2.skills) && Array.isArray(config2.skills.config)) {
47689
+ const skills = config2.skills;
47690
+ const retained = skills.config.filter((entry) => !disablesOneSkill(entry));
47691
+ if (retained.length !== skills.config.length) {
47692
+ if (retained.length)
47693
+ skills.config = retained;
47694
+ else
47695
+ delete skills.config;
47696
+ }
47697
+ if (!Object.keys(skills).length)
47698
+ delete config2.skills;
47699
+ }
47700
+ inference(config2);
47701
+ if (isRecord3(config2.profiles)) {
47702
+ for (const profile of Object.values(config2.profiles))
47703
+ if (isRecord3(profile))
47704
+ inference(profile);
47705
+ }
47706
+ }
47707
+ function disablesOneSkill(entry) {
47708
+ if (!isRecord3(entry) || entry.enabled !== false)
47709
+ return false;
47710
+ const keys = Object.keys(entry);
47711
+ if (!keys.every((key) => key === "path" || key === "name" || key === "enabled"))
47712
+ return false;
47713
+ const selector = ["path", "name"].filter((key) => Object.hasOwn(entry, key));
47714
+ return selector.length === 1 && typeof entry[selector[0]] === "string" && entry[selector[0]].length > 0;
47715
+ }
47716
+ function inference(target) {
47717
+ for (const key of INFERENCE)
47718
+ if (Object.hasOwn(target, key)) {
47719
+ const value = target[key];
47720
+ if (key === "model")
47721
+ need4(typeof value === "string" && MODEL.test(value));
47722
+ else
47723
+ need4(typeof value === "string" && (key === "model_reasoning_effort" ? EFFORT2.has(value) : VERBOSITY2.has(value)));
47724
+ delete target[key];
47725
+ }
47726
+ }
47727
+ function settingsDigest2(text2) {
47728
+ let config2;
47729
+ try {
47730
+ config2 = Bun.TOML.parse(text2);
47731
+ } catch {
47732
+ throw new Error("Invalid Codex settings witness");
47733
+ }
47734
+ need4(isRecord3(config2));
47735
+ normalize2(config2);
47736
+ return sha2(`hasna.skills.codex-settings.v2\x00${JSON.stringify([canonical4(config2), numericTokens2(text2)])}`);
47737
+ }
47738
+ function hashCodexSettingsReplacementV2(text2, budget = { remaining: 256 * 1024 * 1024 }) {
47739
+ need4(Buffer.byteLength(text2) <= 1024 * 1024 && budget.remaining >= Buffer.byteLength(text2));
47740
+ budget.remaining -= Buffer.byteLength(text2);
47741
+ return settingsDigest2(text2);
47742
+ }
47743
+ function captureCodexSettingsV2(path, budget = { remaining: 256 * 1024 * 1024 }) {
47744
+ const text2 = readNativeSettingsWitnessFile(path, budget, "config.toml");
47745
+ return { path, hashMode: "codex-settings-v2", sha256: settingsDigest2(text2) };
47746
+ }
47747
+ var sha2 = (text2) => createHash10("sha256").update(text2).digest("hex"), EFFORT2, VERBOSITY2, MODEL, CODEX_DISCOVERY_PROJECTION_FIELDS, INFERENCE;
47748
+ var init_codex_settings_witness = __esm(() => {
47749
+ init_codex_settings_witness_v1();
47750
+ init_codex_settings_witness_v1();
47751
+ init_claude_settings_witness();
47752
+ EFFORT2 = new Set(["none", "minimal", "low", "medium", "high", "xhigh"]);
47753
+ VERBOSITY2 = new Set(["low", "medium", "high"]);
47754
+ MODEL = /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$/;
47755
+ CODEX_DISCOVERY_PROJECTION_FIELDS = ["plugins", "marketplaces", "skills"];
47756
+ INFERENCE = ["model", "model_reasoning_effort", "model_verbosity"];
47757
+ });
47758
+
47583
47759
  // src/lib/managed-policy.ts
47584
47760
  import { closeSync as closeSync9, constants as constants6, fstatSync as fstatSync9, lstatSync as lstatSync11, openSync as openSync9, readSync as readSync5 } from "fs";
47585
47761
  import { join as join16 } from "path";
@@ -47660,7 +47836,7 @@ var init_managed_policy = __esm(() => {
47660
47836
  });
47661
47837
 
47662
47838
  // src/lib/agent-bridge.ts
47663
- import { createHash as createHash10 } from "crypto";
47839
+ import { createHash as createHash11 } from "crypto";
47664
47840
  var CLI_BRIDGE_VERSION = 1, markdown = `---
47665
47841
  name: skills-cli
47666
47842
  description: Discover, load, author, and run versioned skills through the Skills CLI when a task needs reusable instructions or an executable skill.
@@ -47676,7 +47852,7 @@ Use the Skills CLI as the skill authority for this station.
47676
47852
  This bridge contains no skill payloads. Do not copy skill content into agent-native skill directories or load other native skill copies. If a Skills command refuses authority, selection, integrity, or native drift, report that refusal and use its repair guidance; do not substitute bundled or stale local content. Explicit local draft authoring remains available.
47677
47853
  `, CLI_BRIDGE_DIGEST, CLI_BRIDGE_FILES;
47678
47854
  var init_agent_bridge = __esm(() => {
47679
- CLI_BRIDGE_DIGEST = createHash10("sha256").update(markdown).digest("hex");
47855
+ CLI_BRIDGE_DIGEST = createHash11("sha256").update(markdown).digest("hex");
47680
47856
  CLI_BRIDGE_FILES = Object.freeze({
47681
47857
  "SKILL.md": markdown,
47682
47858
  ".hasna-skills.json": `${JSON.stringify({ managedBy: "@hasna/skills", kind: "cli-bridge", version: CLI_BRIDGE_VERSION, protocol: "selection-v1", contentSha256: CLI_BRIDGE_DIGEST }, null, 2)}
@@ -48370,7 +48546,7 @@ var init_selection_resolver = __esm(() => {
48370
48546
  });
48371
48547
 
48372
48548
  // src/lib/plugin-projection.ts
48373
- import { createHash as createHash11 } from "crypto";
48549
+ import { createHash as createHash12 } from "crypto";
48374
48550
  function pluginRefusal(message) {
48375
48551
  throw new SkillSelectionError("PLUGIN_ADMISSION_REFUSED", message);
48376
48552
  }
@@ -48448,7 +48624,7 @@ function pluginFileWitnesses(entries) {
48448
48624
  return { path: item.path, mode: item.mode, size: item.bytes.byteLength, sha256: pluginHash(item.bytes) };
48449
48625
  });
48450
48626
  }
48451
- var PLUGIN_PROJECTION_LIMITS, pluginHash = (bytes) => createHash11("sha256").update(bytes).digest("hex");
48627
+ var PLUGIN_PROJECTION_LIMITS, pluginHash = (bytes) => createHash12("sha256").update(bytes).digest("hex");
48452
48628
  var init_plugin_projection = __esm(() => {
48453
48629
  init_selection_cache();
48454
48630
  PLUGIN_PROJECTION_LIMITS = Object.freeze({ files: 1024, bytes: 64 * 1024 * 1024, fileBytes: 16 * 1024 * 1024, metadataBytes: 512 * 1024, registrations: 64, history: 128 });
@@ -48466,7 +48642,7 @@ function stat(path) {
48466
48642
  return pluginRefusal("Cannot inspect plugin filesystem entry");
48467
48643
  }
48468
48644
  }
48469
- function canonical4(path) {
48645
+ function canonical5(path) {
48470
48646
  pluginNeed(typeof path === "string" && path.length <= 8192 && isAbsolute9(path) && resolve9(path) === path && !/[\x00-\x1f\x7f]/.test(path), "Plugin storage paths must be canonical absolute paths");
48471
48647
  }
48472
48648
  function owner(stats, system = false) {
@@ -48477,7 +48653,7 @@ function same3(left, right, identityOnly = false) {
48477
48653
  pluginNeed(right && left.dev === right.dev && left.ino === right.ino && left.mode === right.mode && left.uid === right.uid && left.gid === right.gid && (identityOnly || left.size === right.size && left.nlink === right.nlink && left.mtimeNs === right.mtimeNs && left.ctimeNs === right.ctimeNs), "Plugin filesystem entry changed during access");
48478
48654
  }
48479
48655
  function ancestors(path, create = false) {
48480
- canonical4(path);
48656
+ canonical5(path);
48481
48657
  const result = [], parent = dirname10(path), filesystemRoot = parse9(parent).root;
48482
48658
  let current = filesystemRoot;
48483
48659
  for (const segment of ["", ...parent.slice(filesystemRoot.length).split("/").filter(Boolean)]) {
@@ -49055,21 +49231,21 @@ var init_plugin_discovery = __esm(() => {
49055
49231
  });
49056
49232
 
49057
49233
  // src/lib/claude-marketplace-registry.ts
49058
- import { createHash as createHash12 } from "crypto";
49234
+ import { createHash as createHash13 } from "crypto";
49059
49235
  import { closeSync as closeSync12, constants as constants9, fstatSync as fstatSync12, lstatSync as lstatSync14, openSync as openSync12, readSync as readSync8 } from "fs";
49060
49236
  import { basename as basename6, dirname as dirname12, isAbsolute as isAbsolute12, resolve as resolve12 } from "path";
49061
- function need4(value, reason) {
49237
+ function need5(value, reason) {
49062
49238
  if (!value)
49063
49239
  throw new Error(`Claude marketplace registry ${reason}`);
49064
49240
  }
49065
49241
  function absolutePath2(value) {
49066
- need4(typeof value === "string" && value.length > 0 && value.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.pathCharacters && !/[\x00-\x1f\x7f]/.test(value) && isAbsolute12(value) && resolve12(value) === value, "requires a normalized absolute path");
49242
+ need5(typeof value === "string" && value.length > 0 && value.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.pathCharacters && !/[\x00-\x1f\x7f]/.test(value) && isAbsolute12(value) && resolve12(value) === value, "requires a normalized absolute path");
49067
49243
  }
49068
49244
  function parents2(path) {
49069
49245
  const result = [];
49070
49246
  for (let at = dirname12(path);; at = dirname12(at)) {
49071
49247
  const stat2 = lstatSync14(at, { bigint: true });
49072
- need4(stat2.isDirectory() && !stat2.isSymbolicLink(), "path traverses a symlink or non-directory");
49248
+ need5(stat2.isDirectory() && !stat2.isSymbolicLink(), "path traverses a symlink or non-directory");
49073
49249
  result.push([at, stat2]);
49074
49250
  if (at === dirname12(at))
49075
49251
  return result;
@@ -49077,15 +49253,15 @@ function parents2(path) {
49077
49253
  }
49078
49254
  function readRegistry2(path, budget) {
49079
49255
  absolutePath2(path);
49080
- need4(basename6(path) === "known_marketplaces.json", "requires known_marketplaces.json");
49081
- need4(Number.isSafeInteger(budget.remaining) && budget.remaining >= 0, "has an invalid byte budget");
49256
+ need5(basename6(path) === "known_marketplaces.json", "requires known_marketplaces.json");
49257
+ need5(Number.isSafeInteger(budget.remaining) && budget.remaining >= 0, "has an invalid byte budget");
49082
49258
  const ancestors2 = parents2(path), initial = lstatSync14(path, { bigint: true });
49083
- need4(initial.isFile() && !initial.isSymbolicLink() && initial.size <= BigInt(CLAUDE_MARKETPLACE_REGISTRY_LIMITS.bytes), "is not a bounded regular file");
49084
- need4(initial.size <= BigInt(budget.remaining), "exceeds its aggregate byte limit");
49259
+ need5(initial.isFile() && !initial.isSymbolicLink() && initial.size <= BigInt(CLAUDE_MARKETPLACE_REGISTRY_LIMITS.bytes), "is not a bounded regular file");
49260
+ need5(initial.size <= BigInt(budget.remaining), "exceeds its aggregate byte limit");
49085
49261
  const fd = openSync12(path, constants9.O_RDONLY | constants9.O_NOFOLLOW | constants9.O_NONBLOCK);
49086
49262
  try {
49087
49263
  const opened = fstatSync12(fd, { bigint: true });
49088
- need4(opened.isFile() && sameFile2(initial, opened), "changed during open");
49264
+ need5(opened.isFile() && sameFile2(initial, opened), "changed during open");
49089
49265
  const bytes = Buffer.alloc(Number(opened.size) + 1);
49090
49266
  let length = 0;
49091
49267
  while (length < bytes.length) {
@@ -49095,10 +49271,10 @@ function readRegistry2(path, budget) {
49095
49271
  length += count;
49096
49272
  }
49097
49273
  const after = fstatSync12(fd, { bigint: true }), current = lstatSync14(path, { bigint: true });
49098
- need4(current.isFile() && sameFile2(opened, after) && sameFile2(after, current) && BigInt(length) === opened.size, "changed during read");
49274
+ need5(current.isFile() && sameFile2(opened, after) && sameFile2(after, current) && BigInt(length) === opened.size, "changed during read");
49099
49275
  for (const [ancestor, before] of ancestors2) {
49100
49276
  const now = lstatSync14(ancestor, { bigint: true });
49101
- need4(now.isDirectory() && before.dev === now.dev && before.ino === now.ino && before.mode === now.mode, "parent changed during read");
49277
+ need5(now.isDirectory() && before.dev === now.dev && before.ino === now.ino && before.mode === now.mode, "parent changed during read");
49102
49278
  }
49103
49279
  budget.remaining -= length;
49104
49280
  try {
@@ -49118,7 +49294,7 @@ function parse10(text2) {
49118
49294
  at++;
49119
49295
  };
49120
49296
  function string5() {
49121
- need4(text2[at] === '"', "contains invalid JSON");
49297
+ need5(text2[at] === '"', "contains invalid JSON");
49122
49298
  const start = at++;
49123
49299
  while (at < text2.length) {
49124
49300
  const character = text2[at++];
@@ -49129,7 +49305,7 @@ function parse10(text2) {
49129
49305
  } catch {
49130
49306
  throw new Error("Claude marketplace registry contains invalid JSON string");
49131
49307
  }
49132
- need4(value2.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.stringCharacters, "exceeds its string limit");
49308
+ need5(value2.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.stringCharacters, "exceeds its string limit");
49133
49309
  return value2;
49134
49310
  }
49135
49311
  if (character === "\\")
@@ -49138,7 +49314,7 @@ function parse10(text2) {
49138
49314
  throw new Error("Claude marketplace registry contains an unterminated JSON string");
49139
49315
  }
49140
49316
  function value(depth) {
49141
- need4(depth <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.depth && ++nodes <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.nodes, "exceeds its nesting or node limit");
49317
+ need5(depth <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.depth && ++nodes <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.nodes, "exceeds its nesting or node limit");
49142
49318
  space();
49143
49319
  const character = text2[at];
49144
49320
  if (character === '"')
@@ -49152,17 +49328,17 @@ function parse10(text2) {
49152
49328
  if (object7) {
49153
49329
  space();
49154
49330
  const key = string5();
49155
- need4(!keys.has(key), "contains a duplicate JSON key");
49331
+ need5(!keys.has(key), "contains a duplicate JSON key");
49156
49332
  keys.add(key);
49157
49333
  space();
49158
- need4(text2[at++] === ":", "contains invalid JSON");
49334
+ need5(text2[at++] === ":", "contains invalid JSON");
49159
49335
  entries.push([key, value(depth + 1)]);
49160
49336
  } else
49161
49337
  items.push(value(depth + 1));
49162
49338
  space();
49163
49339
  if (text2[at] === end)
49164
49340
  break;
49165
- need4(text2[at++] === ",", "contains invalid JSON");
49341
+ need5(text2[at++] === ",", "contains invalid JSON");
49166
49342
  }
49167
49343
  at++;
49168
49344
  return object7 ? { kind: "object", entries } : { kind: "array", items };
@@ -49174,21 +49350,21 @@ function parse10(text2) {
49174
49350
  }
49175
49351
  numberPattern.lastIndex = at;
49176
49352
  const number5 = numberPattern.exec(text2);
49177
- need4(number5, "contains invalid JSON");
49353
+ need5(number5, "contains invalid JSON");
49178
49354
  at += number5[0].length;
49179
49355
  return { kind: "number", value: number5[0] };
49180
49356
  }
49181
49357
  const root = value(0);
49182
49358
  space();
49183
- need4(at === text2.length && root.kind === "object", "requires a JSON object without trailing content");
49184
- need4(root.entries.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.rows, "exceeds its marketplace row limit");
49359
+ need5(at === text2.length && root.kind === "object", "requires a JSON object without trailing content");
49360
+ need5(root.entries.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.rows, "exceeds its marketplace row limit");
49185
49361
  return root;
49186
49362
  }
49187
49363
  function exactKeys(value, keys) {
49188
49364
  return value?.kind === "object" && value.entries.length === keys.length && value.entries.every(([key]) => keys.includes(key));
49189
49365
  }
49190
49366
  function textField(value) {
49191
- need4(value?.kind === "string" && value.value.length > 0 && !/[\x00-\x1f\x7f]/.test(value.value), "contains an invalid recognized field");
49367
+ need5(value?.kind === "string" && value.value.length > 0 && !/[\x00-\x1f\x7f]/.test(value.value), "contains an invalid recognized field");
49192
49368
  return value.value;
49193
49369
  }
49194
49370
  function normalizeRow(row, version2 = 1) {
@@ -49196,7 +49372,7 @@ function normalizeRow(row, version2 = 1) {
49196
49372
  if (version2 !== 2 || !exactKeys(row, ["source", "installLocation", "lastUpdated", "autoUpdate"]))
49197
49373
  return;
49198
49374
  const autoUpdate = field(row, "autoUpdate");
49199
- need4(autoUpdate?.kind === "literal" && (autoUpdate.value === "true" || autoUpdate.value === "false"), "contains an invalid automatic-update preference");
49375
+ need5(autoUpdate?.kind === "literal" && (autoUpdate.value === "true" || autoUpdate.value === "false"), "contains an invalid automatic-update preference");
49200
49376
  }
49201
49377
  const source = field(row, "source");
49202
49378
  if (source?.kind !== "object")
@@ -49212,23 +49388,23 @@ function normalizeRow(row, version2 = 1) {
49212
49388
  absolutePath2(sourceLocation);
49213
49389
  absolutePath2(textField(field(row, "installLocation")));
49214
49390
  const updated = textField(field(row, "lastUpdated"));
49215
- need4(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(updated), "contains an invalid recognized update timestamp");
49391
+ need5(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(updated), "contains an invalid recognized update timestamp");
49216
49392
  const millis = Date.parse(updated);
49217
- need4(Number.isFinite(millis) && new Date(millis).toISOString() === updated, "contains an invalid recognized update timestamp");
49393
+ need5(Number.isFinite(millis) && new Date(millis).toISOString() === updated, "contains an invalid recognized update timestamp");
49218
49394
  row.entries = row.entries.map(([key, value]) => [key, key === "lastUpdated" ? { kind: "validated-update-time" } : value]);
49219
49395
  }
49220
49396
  function captureClaudeMarketplaceRegistry(path, budget = { remaining: 256 * 1024 * 1024 }) {
49221
49397
  const value = parse10(readRegistry2(path, budget));
49222
49398
  for (const [, row] of value.entries)
49223
49399
  normalizeRow(row);
49224
- const sha2562 = createHash12("sha256").update("hasna.skills.claude-marketplace-registry.v1\x00").update(JSON.stringify(value)).digest("hex");
49400
+ const sha2562 = createHash13("sha256").update("hasna.skills.claude-marketplace-registry.v1\x00").update(JSON.stringify(value)).digest("hex");
49225
49401
  return { path, hashMode: "claude-marketplace-registry", sha256: sha2562 };
49226
49402
  }
49227
49403
  function captureClaudeMarketplaceRegistryV2(path, budget = { remaining: 256 * 1024 * 1024 }) {
49228
49404
  const value = parse10(readRegistry2(path, budget));
49229
49405
  for (const [, row] of value.entries)
49230
49406
  normalizeRow(row, 2);
49231
- const sha2562 = createHash12("sha256").update("hasna.skills.claude-marketplace-registry.v2\x00").update(JSON.stringify(value)).digest("hex");
49407
+ const sha2562 = createHash13("sha256").update("hasna.skills.claude-marketplace-registry.v2\x00").update(JSON.stringify(value)).digest("hex");
49232
49408
  return { path, hashMode: "claude-marketplace-registry-v2", sha256: sha2562 };
49233
49409
  }
49234
49410
  var CLAUDE_MARKETPLACE_REGISTRY_LIMITS, sameFile2 = (a, b) => a.dev === b.dev && a.ino === b.ino && a.mode === b.mode && a.uid === b.uid && a.gid === b.gid && a.nlink === b.nlink && a.size === b.size && a.mtimeNs === b.mtimeNs && a.ctimeNs === b.ctimeNs, field = (object7, key) => object7.entries.find(([name]) => name === key)?.[1];
@@ -49238,17 +49414,17 @@ var init_claude_marketplace_registry = __esm(() => {
49238
49414
 
49239
49415
  // src/lib/codex-hook-trust-files.ts
49240
49416
  import { closeSync as closeSync13, constants as constants10, fstatSync as fstatSync13, fsyncSync as fsyncSync3, lstatSync as lstatSync15, openSync as openSync13, readSync as readSync9, writeFileSync as writeFileSync5 } from "fs";
49241
- import { createHash as createHash13 } from "crypto";
49417
+ import { createHash as createHash14 } from "crypto";
49242
49418
  import { dirname as dirname13 } from "path";
49243
- function need5(value, code) {
49419
+ function need6(value, code) {
49244
49420
  if (!value)
49245
49421
  throw new Error(`CODEX_HOOK_TRUST_${code}`);
49246
49422
  }
49247
49423
  function safeParents(file2) {
49248
49424
  for (let p = dirname13(file2);; p = dirname13(p)) {
49249
49425
  const s = lstatSync15(p);
49250
- need5(s.isDirectory() && !s.isSymbolicLink(), "UNSAFE_PARENT");
49251
- need5((s.mode & 18) === 0 || s.uid === 0 && (s.mode & 512) !== 0, "UNSAFE_PARENT");
49426
+ need6(s.isDirectory() && !s.isSymbolicLink(), "UNSAFE_PARENT");
49427
+ need6((s.mode & 18) === 0 || s.uid === 0 && (s.mode & 512) !== 0, "UNSAFE_PARENT");
49252
49428
  if (dirname13(p) === p)
49253
49429
  break;
49254
49430
  }
@@ -49257,12 +49433,12 @@ function snapshot(file2, privateFile = false, options = {}) {
49257
49433
  const readOnlyPackage = options.readOnlyPackage === true && !privateFile;
49258
49434
  safeParents(file2);
49259
49435
  const initial = lstatSync15(file2, { bigint: true });
49260
- need5(initial.isFile() && initial.uid === BigInt(process.getuid()) && (initial.nlink === 1n || readOnlyPackage && initial.nlink > 1n) && (initial.mode & 0o022n) === 0n && (!privateFile || (initial.mode & 0o777n) === 0o600n), "UNSAFE_FILE");
49261
- need5(initial.size <= 8n * 1024n * 1024n, "FILE_BOUND");
49436
+ need6(initial.isFile() && initial.uid === BigInt(process.getuid()) && (initial.nlink === 1n || readOnlyPackage && initial.nlink > 1n) && (initial.mode & 0o022n) === 0n && (!privateFile || (initial.mode & 0o777n) === 0o600n), "UNSAFE_FILE");
49437
+ need6(initial.size <= 8n * 1024n * 1024n, "FILE_BOUND");
49262
49438
  const fd = openSync13(file2, constants10.O_RDONLY | constants10.O_NOFOLLOW | constants10.O_NONBLOCK);
49263
49439
  try {
49264
49440
  const before = fstatSync13(fd, { bigint: true });
49265
- need5(sameStat(initial, before), "INPUT_CHANGED");
49441
+ need6(sameStat(initial, before), "INPUT_CHANGED");
49266
49442
  const bytes = Buffer.alloc(Number(before.size) + 1);
49267
49443
  let length = 0;
49268
49444
  while (length < bytes.length) {
@@ -49271,16 +49447,16 @@ function snapshot(file2, privateFile = false, options = {}) {
49271
49447
  break;
49272
49448
  length += n2;
49273
49449
  }
49274
- need5(length === Number(before.size) && sameStat(before, fstatSync13(fd, { bigint: true })) && sameStat(before, lstatSync15(file2, { bigint: true })), "INPUT_CHANGED");
49450
+ need6(length === Number(before.size) && sameStat(before, fstatSync13(fd, { bigint: true })) && sameStat(before, lstatSync15(file2, { bigint: true })), "INPUT_CHANGED");
49275
49451
  const content = bytes.subarray(0, length), text2 = new TextDecoder("utf-8", { fatal: true }).decode(content);
49276
- return { file: file2, privateFile, readOnlyPackage, text: text2, bytes: content, stat: before, sha256: createHash13("sha256").update(content).digest("hex") };
49452
+ return { file: file2, privateFile, readOnlyPackage, text: text2, bytes: content, stat: before, sha256: createHash14("sha256").update(content).digest("hex") };
49277
49453
  } finally {
49278
49454
  closeSync13(fd);
49279
49455
  }
49280
49456
  }
49281
49457
  function unchanged2(before) {
49282
49458
  const after = snapshot(before.file, before.privateFile, before.readOnlyPackage ? { readOnlyPackage: true } : {});
49283
- need5(sameStat(before.stat, after.stat) && after.sha256 === before.sha256, "INPUT_CHANGED");
49459
+ need6(sameStat(before.stat, after.stat) && after.sha256 === before.sha256, "INPUT_CHANGED");
49284
49460
  }
49285
49461
  var sameStat = (a, b) => ["dev", "ino", "uid", "nlink", "mode", "size", "mtimeNs", "ctimeNs"].every((key) => a[key] === b[key]);
49286
49462
  var init_codex_hook_trust_files = () => {};
@@ -49299,10 +49475,10 @@ var init_codex_hook_additions_review = __esm(() => {
49299
49475
  });
49300
49476
 
49301
49477
  // src/lib/codex-hook-discovery-recovery.ts
49302
- import { createHash as createHash14 } from "crypto";
49478
+ import { createHash as createHash15 } from "crypto";
49303
49479
  function assertCodexHookDiscoveryRecovery(binding, witness) {
49304
49480
  const proof = proofs2.get(witness);
49305
- need5(!!proof && binding.agent === "codex" && witness.discoverySha256 === sha2(JSON.stringify(binding)), "RECONCILE_DISCOVERY_RECOVERY_CHANGED");
49481
+ need6(!!proof && binding.agent === "codex" && witness.discoverySha256 === sha3(JSON.stringify(binding)), "RECONCILE_DISCOVERY_RECOVERY_CHANGED");
49306
49482
  unchanged2(proof.before);
49307
49483
  unchanged2(proof.current);
49308
49484
  proof.recheckAdditions();
@@ -49311,19 +49487,21 @@ function verifiesCodexHookDiscoverySource(binding, source, currentDigest, witnes
49311
49487
  if (!witness || source.path !== witness.configPath || source.hashMode !== "bytes")
49312
49488
  return false;
49313
49489
  assertCodexHookDiscoveryRecovery(binding, witness);
49314
- need5(source.sha256 === witness.beforeSha256 && currentDigest === witness.currentSha256, "RECONCILE_DISCOVERY_RECOVERY_CHANGED");
49490
+ need6(source.sha256 === witness.beforeSha256 && currentDigest === witness.currentSha256, "RECONCILE_DISCOVERY_RECOVERY_CHANGED");
49315
49491
  return true;
49316
49492
  }
49317
- var sha2 = (text2) => createHash14("sha256").update(text2).digest("hex"), proofs2;
49493
+ var sha3 = (text2) => createHash15("sha256").update(text2).digest("hex"), fields, proofs2;
49318
49494
  var init_codex_hook_discovery_recovery = __esm(() => {
49319
49495
  init_codex_hook_trust_files();
49320
49496
  init_codex_hook_trust_layout();
49321
49497
  init_codex_hook_additions_review();
49498
+ init_codex_settings_witness();
49499
+ fields = [...CODEX_DISCOVERY_PROJECTION_FIELDS];
49322
49500
  proofs2 = new WeakMap;
49323
49501
  });
49324
49502
 
49325
49503
  // src/lib/agent-discovery.ts
49326
- import { createHash as createHash15 } from "crypto";
49504
+ import { createHash as createHash16 } from "crypto";
49327
49505
  import { lstatSync as lstatSync16, readFileSync as readFileSync15, readdirSync as readdirSync6, realpathSync as realpathSync3 } from "fs";
49328
49506
  import { basename as basename7, dirname as dirname14, isAbsolute as isAbsolute13, join as join23, resolve as resolve13, sep as sep4 } from "path";
49329
49507
  import { isDeepStrictEqual as isDeepStrictEqual2 } from "util";
@@ -49358,14 +49536,26 @@ function read(path, changes) {
49358
49536
  throw new Error(`Unsupported or oversized native discovery input: ${path}`);
49359
49537
  return readFileSync15(path, "utf8");
49360
49538
  }
49539
+ function projectNativeDiscoveryFields(text2, format, fields2, path) {
49540
+ const object7 = format === "yaml" ? parseHermesConfig(text2) : parseConfig(text2, path, format === "toml");
49541
+ if (!object7 || typeof object7 !== "object" || Array.isArray(object7))
49542
+ throw new Error("Expected native discovery configuration object");
49543
+ return digest(JSON.stringify(Object.fromEntries(fields2.map((field2) => [field2, object7[field2] ?? null]))));
49544
+ }
49545
+ function isSupersededCodexProjection(agent, configPath, source) {
49546
+ return agent === "codex" && source.path === configPath && source.format === "toml" && isDeepStrictEqual2(source.fields, [...CODEX_DISCOVERY_PROJECTION_FIELDS]);
49547
+ }
49548
+ function supersedesCodexProjection(sources, configPath) {
49549
+ return sources.some((source) => source.path === configPath && source.hashMode === "codex-settings-v2");
49550
+ }
49361
49551
  function projected(source, changes, budget = discoveryByteBudget()) {
49362
- if (source.hashMode === "codex-settings-v1") {
49552
+ if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2") {
49363
49553
  if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
49364
49554
  throw new Error("Codex settings witnesses require exact typed metadata");
49365
- const current = captureCodexSettings(source.path, budget).sha256;
49555
+ const current = (source.hashMode === "codex-settings-v2" ? captureCodexSettingsV2 : captureCodexSettings)(source.path, budget).sha256;
49366
49556
  if (current !== source.sha256)
49367
49557
  throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
49368
- return changes?.has(source.path) ? hashCodexSettingsReplacement(changes.get(source.path), budget) : current;
49558
+ return changes?.has(source.path) ? (source.hashMode === "codex-settings-v2" ? hashCodexSettingsReplacementV2 : hashCodexSettingsReplacement)(changes.get(source.path), budget) : current;
49369
49559
  }
49370
49560
  if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") {
49371
49561
  if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
@@ -49404,10 +49594,7 @@ function projected(source, changes, budget = discoveryByteBudget()) {
49404
49594
  return null;
49405
49595
  if (!source.format)
49406
49596
  return digest(text2);
49407
- const object7 = source.format === "yaml" ? parseHermesConfig(text2) : parseConfig(text2, source.path, source.format === "toml");
49408
- if (!object7 || typeof object7 !== "object" || Array.isArray(object7))
49409
- throw new Error("Expected native discovery configuration object");
49410
- return digest(JSON.stringify(Object.fromEntries((source.fields ?? []).map((field2) => [field2, object7[field2] ?? null]))));
49597
+ return projectNativeDiscoveryFields(text2, source.format, source.fields ?? [], source.path);
49411
49598
  }
49412
49599
  function verifyAgentDiscovery(binding, codexRecovery) {
49413
49600
  if (codexRecovery)
@@ -49435,7 +49622,7 @@ function verifyAgentDiscovery(binding, codexRecovery) {
49435
49622
  safe4(root);
49436
49623
  }
49437
49624
  function assertMarketplaceBinding(binding, source) {
49438
- if (source.hashMode === "codex-settings-v1" && (binding.agent !== "codex" || binding.method !== "reviewed" || basename7(source.path) !== "config.toml"))
49625
+ if ((source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2") && (binding.agent !== "codex" || binding.method !== "reviewed" || basename7(source.path) !== "config.toml"))
49439
49626
  throw new Error("Codex settings witnesses require explicit reviewed Codex configuration");
49440
49627
  if ((source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") && (binding.agent !== "claude" || binding.method !== "reviewed" || basename7(source.path) !== "settings.json"))
49441
49628
  throw new Error("Claude settings witnesses require explicit reviewed Claude configuration");
@@ -49446,10 +49633,10 @@ function agentDiscoveryConfigPath(home, agent) {
49446
49633
  return join23(home, agent === "hermes" ? ".hermes/config.yaml" : agent === "opencode" ? ".config/opencode/opencode.json" : `.${agent}/${agent === "codex" ? "config.toml" : agent === "cursor" ? "hooks.json" : "settings.json"}`);
49447
49634
  }
49448
49635
  function resolveAgentDiscovery(options) {
49449
- const canonical5 = options.canonical ?? resolve13, home = resolve13(options.home), agent = options.agent;
49636
+ const canonical6 = options.canonical ?? resolve13, home = resolve13(options.home), agent = options.agent;
49450
49637
  const sources = [], roots = new Set, builtinNames = [];
49451
- const witness = (path, format, fields) => {
49452
- const source = { path: canonical5(path), sha256: null, ...format ? { format, fields } : {} };
49638
+ const witness = (path, format, fields2) => {
49639
+ const source = { path: canonical6(path), sha256: null, ...format ? { format, fields: fields2 } : {} };
49453
49640
  source.sha256 = projected(source);
49454
49641
  sources.push(source);
49455
49642
  return read(source.path);
@@ -49457,7 +49644,7 @@ function resolveAgentDiscovery(options) {
49457
49644
  if (agent === "hermes")
49458
49645
  assertHermesEnvironment(home);
49459
49646
  const configPath = agentDiscoveryConfigPath(home, agent);
49460
- const configText = witness(configPath, agent === "hermes" ? "yaml" : agent === "codex" ? "toml" : "json", agent === "hermes" ? ["skills", "plugins", "hooks"] : agent === "claude" ? ["enabledPlugins", "extraKnownMarketplaces"] : agent === "codex" ? ["plugins", "marketplaces", "skills"] : agent === "gemini" ? ["skills", "extensions", "security"] : agent === "opencode" ? ["plugin", "skills"] : ["version"]);
49647
+ const configText = witness(configPath, agent === "hermes" ? "yaml" : agent === "codex" ? "toml" : "json", agent === "hermes" ? ["skills", "plugins", "hooks"] : agent === "claude" ? ["enabledPlugins", "extraKnownMarketplaces"] : agent === "codex" ? [...CODEX_DISCOVERY_PROJECTION_FIELDS] : agent === "gemini" ? ["skills", "extensions", "security"] : agent === "opencode" ? ["plugin", "skills"] : ["version"]);
49461
49648
  const config2 = configText === null ? {} : agent === "hermes" ? parseHermesConfig(configText) : parseConfig(configText, configPath, agent === "codex");
49462
49649
  const unresolved = (detail) => {
49463
49650
  throw new Error(`Native discovery is unresolved (${agent}: ${detail}); provide a reviewed --discovery-inputs file`);
@@ -49516,11 +49703,12 @@ function resolveAgentDiscovery(options) {
49516
49703
  if (retained.agent !== agent || retained.method !== "reviewed")
49517
49704
  unresolved("invalid retained review");
49518
49705
  verifyAgentDiscovery(retained);
49519
- if (!retained.sources.some((source) => source.path === canonical5(configPath) && source.format === undefined && source.fields === undefined))
49706
+ if (!retained.sources.some((source) => source.path === canonical6(configPath) && source.format === undefined && source.fields === undefined))
49520
49707
  unresolved("retained review is missing the full agent configuration source");
49521
- if (retained.sources.some((source) => (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "codex-settings-v1")) && source.path !== canonical5(configPath)))
49708
+ if (retained.sources.some((source) => (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2"))) && source.path !== canonical6(configPath)))
49522
49709
  unresolved("retained settings witness names another configuration source");
49523
- if (sources.some((source) => !retained.sources.some((saved) => isDeepStrictEqual2(saved, source))) || [...roots].some((root) => !retained.roots.includes(root)) || agent === "gemini" && JSON.stringify(retained.builtinNames) !== JSON.stringify(builtinNames))
49710
+ const covered = supersedesCodexProjection(retained.sources, canonical6(configPath)) ? sources.filter((source) => !isSupersededCodexProjection(agent, canonical6(configPath), source)) : sources;
49711
+ if (covered.some((source) => !retained.sources.some((saved) => isDeepStrictEqual2(saved, source))) || [...roots].some((root) => !retained.roots.includes(root)) || agent === "gemini" && JSON.stringify(retained.builtinNames) !== JSON.stringify(builtinNames))
49524
49712
  unresolved("retained review is missing current runtime discovery coverage");
49525
49713
  return retained;
49526
49714
  }
@@ -49534,14 +49722,15 @@ function resolveAgentDiscovery(options) {
49534
49722
  if (review.sources.some((source) => source.format !== undefined || source.fields !== undefined))
49535
49723
  throw new Error("Explicit discovery reviews require full source-file hashes");
49536
49724
  verifyAgentDiscovery(supplied);
49537
- if (review.sources.some((source) => (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "codex-settings-v1")) && source.path !== canonical5(configPath)))
49725
+ if (review.sources.some((source) => (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2"))) && source.path !== canonical6(configPath)))
49538
49726
  throw new Error("Semantic settings witnesses must name the configured Claude configuration source");
49539
- if (!review.sources.some((source) => source.path === canonical5(configPath)))
49727
+ if (!review.sources.some((source) => source.path === canonical6(configPath)))
49540
49728
  throw new Error("Discovery review must include the agent configuration source");
49541
- return { ...supplied, roots: [...new Set([...roots, ...supplied.roots])].sort(), sources: [...sources, ...review.sources], ...agent === "gemini" ? { builtinNames } : {} };
49729
+ const reviewedSources = supersedesCodexProjection(review.sources, canonical6(configPath)) ? sources.filter((source) => !isSupersededCodexProjection(agent, canonical6(configPath), source)) : sources;
49730
+ return { ...supplied, roots: [...new Set([...roots, ...supplied.roots])].sort(), sources: [...reviewedSources, ...review.sources], ...agent === "gemini" ? { builtinNames } : {} };
49542
49731
  }
49543
49732
  function plugin(root) {
49544
- root = canonical5(root);
49733
+ root = canonical6(root);
49545
49734
  safe4(root);
49546
49735
  const manifestPath = join23(root, agent === "claude" ? ".claude-plugin/plugin.json" : ".codex-plugin/plugin.json");
49547
49736
  const raw = witness(manifestPath);
@@ -49573,7 +49762,7 @@ function resolveAgentDiscovery(options) {
49573
49762
  if (agent === "claude") {
49574
49763
  const registrations = witness(join23(home, ".claude/plugins/installed_plugins.json"));
49575
49764
  const installed = registrations === null ? {} : parseConfig(registrations, join23(home, ".claude/plugins/installed_plugins.json")).plugins;
49576
- const commands = canonical5(join23(home, ".claude/commands"));
49765
+ const commands = canonical6(join23(home, ".claude/commands"));
49577
49766
  safe4(commands);
49578
49767
  if (lstatSync16(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync6(commands).length)
49579
49768
  unresolved("legacy home command discovery requires a dedicated format adapter");
@@ -49647,9 +49836,9 @@ function resolveAgentDiscovery(options) {
49647
49836
  roots.add(join23(root, "skills"));
49648
49837
  }
49649
49838
  }
49650
- return { agent, roots: [...roots].sort(), sources, method: "automatic", ...agent === "gemini" ? { builtinNames } : {}, ...agent === "hermes" ? { directories: captureDiscoveryDirectories([join23(home, ".hermes/plugins"), join23(home, ".hermes/hermes-agent")].map((path) => canonical5(path))) } : {} };
49839
+ return { agent, roots: [...roots].sort(), sources, method: "automatic", ...agent === "gemini" ? { builtinNames } : {}, ...agent === "hermes" ? { directories: captureDiscoveryDirectories([join23(home, ".hermes/plugins"), join23(home, ".hermes/hermes-agent")].map((path) => canonical6(path))) } : {} };
49651
49840
  }
49652
- var digest = (text2) => createHash15("sha256").update(text2).digest("hex");
49841
+ var digest = (text2) => createHash16("sha256").update(text2).digest("hex");
49653
49842
  var init_agent_discovery = __esm(() => {
49654
49843
  init_agent_policy_limits();
49655
49844
  init_agent_hermes();
@@ -49782,7 +49971,7 @@ import {
49782
49971
  statSync as statSync7,
49783
49972
  writeFileSync as writeFileSync6
49784
49973
  } from "fs";
49785
- import { basename as basename9, dirname as dirname16, isAbsolute as isAbsolute14, join as join25, normalize as normalize2, relative as relative4, resolve as resolve15, sep as sep6 } from "path";
49974
+ import { basename as basename9, dirname as dirname16, isAbsolute as isAbsolute14, join as join25, normalize as normalize3, relative as relative4, resolve as resolve15, sep as sep6 } from "path";
49786
49975
  function getPortableSkillsRoot(options = {}) {
49787
49976
  return resolvePortableSkillsRoot(options, true);
49788
49977
  }
@@ -49897,7 +50086,7 @@ function assertDisjointImportPaths(source, destination) {
49897
50086
  }
49898
50087
  }
49899
50088
  function portPortableSkill(sourcePath, options = {}) {
49900
- const absoluteSource = normalize2(sourcePath);
50089
+ const absoluteSource = normalize3(sourcePath);
49901
50090
  if (!existsSync11(absoluteSource) || !statSync7(absoluteSource).isDirectory()) {
49902
50091
  throw new Error(`Skill source directory not found: ${sourcePath}`);
49903
50092
  }
@@ -50057,7 +50246,7 @@ function safeIsDirectory(path) {
50057
50246
  function isSafeRelativePath2(value) {
50058
50247
  if (!value.trim() || isAbsolute14(value))
50059
50248
  return false;
50060
- const normalized = normalize2(value).replace(/\\/g, "/");
50249
+ const normalized = normalize3(value).replace(/\\/g, "/");
50061
50250
  return normalized !== ".." && !normalized.startsWith("../") && !normalized.includes("/../");
50062
50251
  }
50063
50252
  function add3(target, code, message) {
@@ -50726,7 +50915,7 @@ var init_remote_customer_operations = __esm(() => {
50726
50915
  });
50727
50916
 
50728
50917
  // src/lib/canonical-json.ts
50729
- import { createHash as createHash16 } from "crypto";
50918
+ import { createHash as createHash17 } from "crypto";
50730
50919
  function canonicalJson2(value, maximumBytes = 2 * 1024 * 1024) {
50731
50920
  return canonicalJsonAtDepth(value, maximumBytes, 64);
50732
50921
  }
@@ -50770,7 +50959,7 @@ function canonicalJsonAtDepth(value, maximumBytes, maximumDepth) {
50770
50959
  return visit3(value, 0);
50771
50960
  }
50772
50961
  function canonicalJsonSha256(value, maximumBytes) {
50773
- return createHash16("sha256").update(canonicalJson2(value, maximumBytes)).digest("hex");
50962
+ return createHash17("sha256").update(canonicalJson2(value, maximumBytes)).digest("hex");
50774
50963
  }
50775
50964
  var init_canonical_json = () => {};
50776
50965
 
@@ -51551,7 +51740,7 @@ var init_auth_store = __esm(() => {
51551
51740
 
51552
51741
  // src/lib/remote-run-contract.ts
51553
51742
  function normalizeRemoteSkillRunContract(payload, fallbackSkill) {
51554
- const record7 = isRecord3(payload) ? payload : {};
51743
+ const record7 = isRecord4(payload) ? payload : {};
51555
51744
  return {
51556
51745
  contractVersion: REMOTE_SKILL_RUN_CONTRACT_VERSION,
51557
51746
  ...pickString(record7, "id"),
@@ -51573,7 +51762,7 @@ function normalizeRemoteSkillRunContract(payload, fallbackSkill) {
51573
51762
  ...hasOwn(record7, "details") ? { details: record7.details } : {}
51574
51763
  };
51575
51764
  }
51576
- function isRecord3(value) {
51765
+ function isRecord4(value) {
51577
51766
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
51578
51767
  }
51579
51768
  function hasOwn(record7, key) {
@@ -51712,7 +51901,7 @@ var init_remote_credit_checkout = __esm(() => {
51712
51901
 
51713
51902
  // src/lib/remote-profile.ts
51714
51903
  function customerNamePatch(input2, field2) {
51715
- if (!isRecord4(input2) || Object.keys(input2).length !== 1 || !Object.hasOwn(input2, field2))
51904
+ if (!isRecord5(input2) || Object.keys(input2).length !== 1 || !Object.hasOwn(input2, field2))
51716
51905
  throw new Error("Provide only the requested name field.");
51717
51906
  const value = input2[field2];
51718
51907
  if (typeof value !== "string" || /[\p{Cc}\p{Cs}\u2028\u2029]/u.test(value) || !value.trim() || [...value.trim()].length > 100) {
@@ -51720,22 +51909,22 @@ function customerNamePatch(input2, field2) {
51720
51909
  }
51721
51910
  return { [field2]: value.trim() };
51722
51911
  }
51723
- function isRecord4(value) {
51912
+ function isRecord5(value) {
51724
51913
  return !!value && typeof value === "object" && !Array.isArray(value);
51725
51914
  }
51726
51915
  function string5(value) {
51727
51916
  return typeof value === "string" && value.length > 0;
51728
51917
  }
51729
51918
  function parseUpdatedProfile(value) {
51730
- const user = isRecord4(value) && value.user;
51731
- if (!isRecord4(user) || !string5(user.id) || !string5(user.email) || !(user.displayName === null || typeof user.displayName === "string") || typeof user.role !== "string" || !["owner", "admin", "member", "viewer"].includes(user.role)) {
51919
+ const user = isRecord5(value) && value.user;
51920
+ if (!isRecord5(user) || !string5(user.id) || !string5(user.email) || !(user.displayName === null || typeof user.displayName === "string") || typeof user.role !== "string" || !["owner", "admin", "member", "viewer"].includes(user.role)) {
51732
51921
  throw new Error("The server returned an invalid account profile.");
51733
51922
  }
51734
51923
  return { user: { id: user.id, email: user.email, displayName: user.displayName, role: user.role } };
51735
51924
  }
51736
51925
  function parseUpdatedWorkspace(value) {
51737
- const organization2 = isRecord4(value) && value.organization;
51738
- if (!isRecord4(organization2) || !string5(organization2.id) || !string5(organization2.slug) || !string5(organization2.name)) {
51926
+ const organization2 = isRecord5(value) && value.organization;
51927
+ if (!isRecord5(organization2) || !string5(organization2.id) || !string5(organization2.slug) || !string5(organization2.name)) {
51739
51928
  throw new Error("The server returned an invalid workspace.");
51740
51929
  }
51741
51930
  return { organization: { id: organization2.id, slug: organization2.slug, name: organization2.name } };
@@ -52996,7 +53185,7 @@ var init_remote_invitation_recovery = __esm(() => {
52996
53185
  });
52997
53186
 
52998
53187
  // src/lib/remote-private-publications.ts
52999
- import { createHash as createHash17 } from "crypto";
53188
+ import { createHash as createHash18 } from "crypto";
53000
53189
  function checkedPublicationDeclaration(value) {
53001
53190
  if (!exact(value, ["idempotencyKey", "version", "expectedCurrentVersionId", "manifestText", "archiveSha256", "archiveByteSize"]) || !publicationUuid(value.idempotencyKey) || !(value.expectedCurrentVersionId === null || publicationUuid(value.expectedCurrentVersionId)) || typeof value.version !== "string" || !value.version || value.version.length > 128 || /[\p{Cc}\p{Cs}]/u.test(value.version) || typeof value.manifestText !== "string" || Buffer.byteLength(value.manifestText) > 16384 || !hash3(value.archiveSha256) || !Number.isSafeInteger(value.archiveByteSize) || Number(value.archiveByteSize) < 1 || Number(value.archiveByteSize) > PRIVATE_PUBLICATION_MAX_BYTES)
53002
53191
  return bad();
@@ -53257,7 +53446,7 @@ var PRIVATE_PUBLICATION_MAX_BYTES, failures2, PrivatePublicationError, bad = ()
53257
53446
  throw new PrivatePublicationError("INVALID_PUBLICATION_INPUT", "Invalid publication input or recovery data.");
53258
53447
  }, invalid4 = () => {
53259
53448
  throw new PrivatePublicationError("INVALID_PUBLICATION_RESPONSE", "The server returned an invalid publication result.");
53260
- }, publicationUuid = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), hash3 = (v) => typeof v === "string" && /^[a-f0-9]{64}$/.test(v), record9 = (v) => !!v && typeof v === "object" && !Array.isArray(v), exact = (v, keys) => record9(v) && Object.keys(v).sort().join(",") === keys.sort().join(","), date6 = (v) => typeof v === "string" && /^\d{4}-\d\d-\d\dT[0-9:.]+(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(v) && Number.isFinite(Date.parse(v)), publicationSha256 = (bytes) => createHash17("sha256").update(bytes).digest("hex");
53449
+ }, publicationUuid = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), hash3 = (v) => typeof v === "string" && /^[a-f0-9]{64}$/.test(v), record9 = (v) => !!v && typeof v === "object" && !Array.isArray(v), exact = (v, keys) => record9(v) && Object.keys(v).sort().join(",") === keys.sort().join(","), date6 = (v) => typeof v === "string" && /^\d{4}-\d\d-\d\dT[0-9:.]+(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(v) && Number.isFinite(Date.parse(v)), publicationSha256 = (bytes) => createHash18("sha256").update(bytes).digest("hex");
53261
53450
  var init_remote_private_publications = __esm(() => {
53262
53451
  init_fleet_credentials();
53263
53452
  init_remote_workspace_selection();
@@ -53321,7 +53510,7 @@ async function requestAuthApi(instance, path, options) {
53321
53510
  const text3 = await res.text();
53322
53511
  const body = text3 ? parseJsonBody(text3) : {};
53323
53512
  if (!res.ok) {
53324
- const record10 = isRecord5(body) ? body : {};
53513
+ const record10 = isRecord6(body) ? body : {};
53325
53514
  const detail = typeof record10.detail === "string" ? record10.detail : undefined;
53326
53515
  const error61 = typeof record10.error === "string" ? record10.error : undefined;
53327
53516
  const code = typeof record10.code === "string" ? record10.code : undefined;
@@ -53349,7 +53538,7 @@ function condenseErrorBody(text3) {
53349
53538
  return collapsed;
53350
53539
  return `${collapsed.slice(0, MAX_ERROR_DETAIL_LENGTH - 1).trimEnd()}\u2026`;
53351
53540
  }
53352
- function isRecord5(value) {
53541
+ function isRecord6(value) {
53353
53542
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
53354
53543
  }
53355
53544
 
@@ -54035,7 +54224,7 @@ async function continueRecurringRecovery(customer, directory, options) {
54035
54224
  throw error61;
54036
54225
  }
54037
54226
  }
54038
- var uuid12, sha3, common, intentSchema, stateSchema, invalid5 = () => {
54227
+ var uuid12, sha4, common, intentSchema, stateSchema, invalid5 = () => {
54039
54228
  throw new RecurringCustomerError("RECURRING_RECOVERY_INVALID", "The original recovery directory or record is invalid or changed. Preserve it; do not create a replacement activation automatically.");
54040
54229
  };
54041
54230
  var init_recurring_recovery = __esm(() => {
@@ -54045,7 +54234,7 @@ var init_recurring_recovery = __esm(() => {
54045
54234
  init_remote_recurring();
54046
54235
  init_recurring_customer();
54047
54236
  uuid12 = exports_external.string().regex(/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/);
54048
- sha3 = exports_external.string().regex(/^[a-f0-9]{64}$/);
54237
+ sha4 = exports_external.string().regex(/^[a-f0-9]{64}$/);
54049
54238
  common = exports_external.object({
54050
54239
  contractVersion: exports_external.literal(1),
54051
54240
  apiOrigin: exports_external.string().min(1).max(4096),
@@ -54058,7 +54247,7 @@ var init_recurring_recovery = __esm(() => {
54058
54247
  common.extend({
54059
54248
  operation: exports_external.literal("activate"),
54060
54249
  draftId: uuid12,
54061
- termsSha256: sha3,
54250
+ termsSha256: sha4,
54062
54251
  approvalDeadline: exports_external.string().datetime(),
54063
54252
  approval: recurringActivationSchema
54064
54253
  }).strict(),
@@ -54066,7 +54255,7 @@ var init_recurring_recovery = __esm(() => {
54066
54255
  ]);
54067
54256
  stateSchema = exports_external.object({
54068
54257
  contractVersion: exports_external.literal(1),
54069
- intentSha256: sha3,
54258
+ intentSha256: sha4,
54070
54259
  phase: exports_external.enum(["prepared", "pending", "observed"]),
54071
54260
  consentId: uuid12.nullable()
54072
54261
  }).strict();
@@ -56007,7 +56196,7 @@ var init_credential_state = __esm(() => {
56007
56196
  });
56008
56197
 
56009
56198
  // src/lib/run-state.ts
56010
- import { createHash as createHash18, randomBytes } from "crypto";
56199
+ import { createHash as createHash19, randomBytes } from "crypto";
56011
56200
  import { existsSync as existsSync14, mkdirSync as mkdirSync11, readFileSync as readFileSync19, readdirSync as readdirSync9, statSync as statSync9, writeFileSync as writeFileSync10 } from "fs";
56012
56201
  import { extname, join as join29, relative as relative5 } from "path";
56013
56202
  function createSkillRun(params, targetDir = process.cwd()) {
@@ -56122,7 +56311,7 @@ function collectRunArtifacts(context2) {
56122
56311
  artifacts.push({
56123
56312
  path: toProjectRelative(context2.targetDir, path),
56124
56313
  mime: mimeForPath(path),
56125
- sha256: createHash18("sha256").update(bytes).digest("hex"),
56314
+ sha256: createHash19("sha256").update(bytes).digest("hex"),
56126
56315
  sizeBytes: stat3.size
56127
56316
  });
56128
56317
  }
@@ -56578,14 +56767,14 @@ function assertUsableCredential2(appName, source, value) {
56578
56767
  return;
56579
56768
  throw new CredentialResolutionError2(appName, `The credential from ${source} contains characters that cannot be sent in an HTTP header ` + `(a control character or non-ASCII byte). A file written with CR-only line endings is the usual ` + `cause. Rewrite that credential file with one LF-terminated KEY=value line. ` + `The value is not shown here, and is deliberately never logged.`, [source]);
56580
56769
  }
56581
- function sealCredential2(fields) {
56582
- const { apiKey } = fields;
56770
+ function sealCredential2(fields2) {
56771
+ const { apiKey } = fields2;
56583
56772
  const visible = {
56584
- tier: fields.tier,
56585
- source: fields.source,
56586
- deliberate: fields.deliberate,
56587
- diskCandidates: Object.freeze([...fields.diskCandidates]),
56588
- warning: fields.warning
56773
+ tier: fields2.tier,
56774
+ source: fields2.source,
56775
+ deliberate: fields2.deliberate,
56776
+ diskCandidates: Object.freeze([...fields2.diskCandidates]),
56777
+ warning: fields2.warning
56589
56778
  };
56590
56779
  const sealed = { ...visible };
56591
56780
  Object.defineProperty(sealed, "apiKey", {
@@ -56594,9 +56783,9 @@ function sealCredential2(fields) {
56594
56783
  writable: false,
56595
56784
  configurable: false
56596
56785
  });
56597
- if (fields.pointerVaultKey !== undefined) {
56786
+ if (fields2.pointerVaultKey !== undefined) {
56598
56787
  Object.defineProperty(sealed, "pointerVaultKey", {
56599
- value: fields.pointerVaultKey,
56788
+ value: fields2.pointerVaultKey,
56600
56789
  enumerable: false,
56601
56790
  writable: false,
56602
56791
  configurable: false
@@ -57936,7 +58125,7 @@ __export(exports_selected_run, {
57936
58125
  prepareSelectedSecretBindings: () => prepareSelectedSecretBindings,
57937
58126
  executeSelectedLocal: () => executeSelectedLocal
57938
58127
  });
57939
- import { createHash as createHash19 } from "crypto";
58128
+ import { createHash as createHash20 } from "crypto";
57940
58129
  import { spawn } from "child_process";
57941
58130
  import { mkdirSync as mkdirSync12, mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync11, realpathSync as realpathSync8 } from "fs";
57942
58131
  import { dirname as dirname19, join as join31, resolve as resolve17 } from "path";
@@ -58062,7 +58251,7 @@ async function executeSelectedLocal(selected, options = {}) {
58062
58251
  selection: selection2,
58063
58252
  target: "local",
58064
58253
  runtime: runtimeName,
58065
- inputDigest: `sha256:${createHash19("sha256").update(input2).digest("hex")}`,
58254
+ inputDigest: `sha256:${createHash20("sha256").update(input2).digest("hex")}`,
58066
58255
  runDirectory,
58067
58256
  ...executionGrant ? { executionGrant } : {},
58068
58257
  ...bindings ? { secretBinding: { schema: bindings.schema, selection: bindings.selection, consumer: bindings.consumer, secretsAuthority: bindings.secretsAuthority, bindings: bindings.bindings } } : {},
@@ -59061,11 +59250,11 @@ function validateCronField(expr, min, max, label) {
59061
59250
  return { valid: true };
59062
59251
  }
59063
59252
  function validateCron(expr) {
59064
- const fields = expr.trim().split(/\s+/);
59065
- if (fields.length !== 5) {
59066
- return { valid: false, error: `Expected 5 fields, got ${fields.length}. Format: "minute hour day-of-month month day-of-week"` };
59253
+ const fields2 = expr.trim().split(/\s+/);
59254
+ if (fields2.length !== 5) {
59255
+ return { valid: false, error: `Expected 5 fields, got ${fields2.length}. Format: "minute hour day-of-month month day-of-week"` };
59067
59256
  }
59068
- const [minuteF, hourF, domF, monthF, dowF] = fields;
59257
+ const [minuteF, hourF, domF, monthF, dowF] = fields2;
59069
59258
  const checks4 = [
59070
59259
  { expr: minuteF, min: 0, max: 59, label: "minute" },
59071
59260
  { expr: hourF, min: 0, max: 23, label: "hour" },
@@ -59290,7 +59479,7 @@ var init_schedule_tools = __esm(() => {
59290
59479
  });
59291
59480
 
59292
59481
  // src/lib/native-storage.ts
59293
- import { createHash as createHash20, createHmac } from "crypto";
59482
+ import { createHash as createHash21, createHmac } from "crypto";
59294
59483
  import {
59295
59484
  existsSync as existsSync18,
59296
59485
  mkdirSync as mkdirSync15,
@@ -59299,7 +59488,7 @@ import {
59299
59488
  statSync as statSync11,
59300
59489
  writeFileSync as writeFileSync13
59301
59490
  } from "fs";
59302
- import { dirname as dirname21, join as join35, normalize as normalize3, relative as relative6, sep as sep7 } from "path";
59491
+ import { dirname as dirname21, join as join35, normalize as normalize4, relative as relative6, sep as sep7 } from "path";
59303
59492
  function resolveSkillsNativeStorageConfig(env = process.env) {
59304
59493
  assertNoRetiredModeEnvVars(env, {
59305
59494
  app: SKILLS_ENV_NAMESPACE,
@@ -59367,7 +59556,7 @@ function exportSkillsLocalSnapshot(targetDir = process.cwd(), options = {}) {
59367
59556
  files.push({
59368
59557
  path: relativePath,
59369
59558
  sizeBytes: bytes.byteLength,
59370
- sha256: createHash20("sha256").update(bytes).digest("hex"),
59559
+ sha256: createHash21("sha256").update(bytes).digest("hex"),
59371
59560
  ...options.includeFileContents ? { contentBase64: Buffer.from(bytes).toString("base64") } : {}
59372
59561
  });
59373
59562
  }