@hasna/skills 0.10.50 → 0.10.52

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.50",
20022
+ version: "0.10.52",
20023
20023
  description: "Skills library for AI coding agents",
20024
20024
  type: "module",
20025
20025
  bin: {
@@ -38339,6 +38339,10 @@ function parse6(text) {
38339
38339
  need(root.entries.length <= CLAUDE_SETTINGS_WITNESS_LIMITS.rows, "exceeds its settings field limit");
38340
38340
  return root;
38341
38341
  }
38342
+ function parseNativeJsonObject(text) {
38343
+ need(typeof text === "string" && Buffer.byteLength(text) <= CLAUDE_SETTINGS_WITNESS_LIMITS.bytes, "exceeds its byte limit");
38344
+ return parse6(text);
38345
+ }
38342
38346
  function canonical(value) {
38343
38347
  if (value.kind === "object")
38344
38348
  return { kind: "object", entries: value.entries.map(([key, child]) => [key, canonical(child)]).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0) };
@@ -38538,8 +38542,216 @@ var init_sumi_settings_witness = __esm(() => {
38538
38542
  SUMI_DISCOVERY_PROJECTION_FIELDS = ["skills", "plugin", "plugins", "permissions"];
38539
38543
  });
38540
38544
 
38545
+ // src/lib/codex-native-compatibility.ts
38546
+ function supportsCodexNativeCapability(version2, capability) {
38547
+ return typeof version2 === "string" && Object.hasOwn(MEASURED_CODEX_CAPABILITIES, version2) && MEASURED_CODEX_CAPABILITIES[version2].includes(capability);
38548
+ }
38549
+ var MEASURED_CODEX_CAPABILITIES, SUPPORTED_CODEX_HOOK_VERSIONS;
38550
+ var init_codex_native_compatibility = __esm(() => {
38551
+ MEASURED_CODEX_CAPABILITIES = {
38552
+ "codex-cli 0.153.0": ["hooks"],
38553
+ "codex-cli 0.154.0": ["hooks"],
38554
+ "codex-cli 0.155.0": ["hooks"],
38555
+ "codex-cli 0.155.1": ["hooks"],
38556
+ "codex-cli 0.156.1": ["hooks"],
38557
+ "codex-cli 0.157.0": ["hooks"],
38558
+ "codex-cli 0.157.1": ["hooks"],
38559
+ "codex-cli 0.158.0": ["hooks"],
38560
+ "codex-cli 0.159.0": ["hooks"],
38561
+ "codex-cli 0.159.2": ["hooks", "qualified-skill-catalog"],
38562
+ "codex-cli 0.160.0": ["hooks", "qualified-skill-catalog", "installed-plugin-review"],
38563
+ "codex-cli 0.160.1": ["hooks", "qualified-skill-catalog", "installed-plugin-review"]
38564
+ };
38565
+ SUPPORTED_CODEX_HOOK_VERSIONS = Object.freeze(Object.keys(MEASURED_CODEX_CAPABILITIES).filter((version2) => supportsCodexNativeCapability(version2, "hooks")));
38566
+ });
38567
+
38568
+ // src/lib/claude-marketplace-entry-witness.ts
38569
+ import { createHash as createHash3 } from "crypto";
38570
+ import { basename as basename4, dirname as dirname5, isAbsolute as isAbsolute4, resolve as resolve3 } from "path";
38571
+ function need2(value, reason) {
38572
+ if (!value)
38573
+ throw new Error(`Claude marketplace entry witness ${reason}`);
38574
+ }
38575
+ function unknownKey(selector, path, key) {
38576
+ throw new Error(path === null ? `${CLAUDE_MARKETPLACE_ENTRY_HASH_MODE}: unknown top-level key ${quote(bounded(key))} in ${selector.marketplace}` : `${CLAUDE_MARKETPLACE_ENTRY_HASH_MODE}: unknown key ${quote(child(path, key))} in ${selector.marketplace}`);
38577
+ }
38578
+ function knownKeys(object4, allowed, selector, path) {
38579
+ for (const [key] of object4.entries)
38580
+ if (!allowed.has(key))
38581
+ unknownKey(selector, path, key);
38582
+ }
38583
+ function claudeMarketplaceEntrySourceValid(source) {
38584
+ const path = source?.path;
38585
+ return typeof path === "string" && path.length > 0 && path.length <= PATH_CHARACTERS && !/[\x00-\x1f\x7f]/.test(path) && isAbsolute4(path) && resolve3(path) === path && basename4(path) === "marketplace.json" && basename4(dirname5(path)) === ".claude-plugin" && typeof source.marketplace === "string" && NAME.test(source.marketplace) && !source.marketplace.includes("..") && typeof source.plugin === "string" && NAME.test(source.plugin);
38586
+ }
38587
+ function canonical2(value) {
38588
+ if (value.kind === "string")
38589
+ return JSON.stringify(value.value);
38590
+ if (value.kind === "number" || value.kind === "literal")
38591
+ return value.value;
38592
+ if (value.kind === "array")
38593
+ return "[" + value.items.map(canonical2).join(",") + "]";
38594
+ return "{" + [...value.entries].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, item]) => JSON.stringify(key) + ":" + canonical2(item)).join(",") + "}";
38595
+ }
38596
+ function validateMarketplace(root, selector) {
38597
+ knownKeys(root, MARKETPLACE_KEYS, selector, null);
38598
+ const name = field(root, "name");
38599
+ need2(isString(name) && name.value === selector.marketplace, "marketplace name does not match the reviewed binding");
38600
+ for (const key of ["$schema", "description", "version"]) {
38601
+ const value = field(root, key);
38602
+ need2(value === undefined || isString(value), `has an invalid marketplace ${key}`);
38603
+ }
38604
+ const owner = field(root, "owner");
38605
+ need2(owner === undefined || owner.kind === "object", "has an invalid marketplace owner");
38606
+ const metadata = field(root, "metadata");
38607
+ if (metadata !== undefined) {
38608
+ need2(metadata.kind === "object", "has an invalid marketplace metadata object");
38609
+ knownKeys(metadata, MARKETPLACE_METADATA_KEYS, selector, "metadata");
38610
+ for (const [key, value] of metadata.entries)
38611
+ need2(isString(value), `has an invalid marketplace metadata.${key}`);
38612
+ }
38613
+ const remove = field(root, "forceRemoveDeletedPlugins");
38614
+ need2(remove === undefined || isBoolean(remove), "has an invalid forceRemoveDeletedPlugins value");
38615
+ const cross = field(root, "allowCrossMarketplaceDependenciesOn");
38616
+ need2(cross === undefined || stringArray(cross), "has an invalid allowCrossMarketplaceDependenciesOn value");
38617
+ const renames = field(root, "renames");
38618
+ if (renames !== undefined) {
38619
+ need2(renames.kind === "object" && renames.entries.every(([, target]) => isString(target) || target.kind === "literal" && target.value === "null"), "has an invalid renames map");
38620
+ need2(!renames.entries.some(([from]) => from.toLowerCase() === selector.plugin.toLowerCase()), "plugin id is redirected by the marketplace renames map");
38621
+ }
38622
+ }
38623
+ function validateSource(source, selector, path) {
38624
+ if (isString(source)) {
38625
+ need2(source.value.length > 0, "has an empty plugin source");
38626
+ return;
38627
+ }
38628
+ need2(source?.kind === "object", "has an invalid plugin source");
38629
+ const type = field(source, "source");
38630
+ need2(isString(type) && Object.hasOwn(SOURCE_KEYS, type.value), "has an unreviewed plugin source type");
38631
+ knownKeys(source, new Set(SOURCE_KEYS[type.value]), selector, path);
38632
+ }
38633
+ function projectEntry(entry, selector) {
38634
+ const path = `plugins[${selector.plugin}]`;
38635
+ knownKeys(entry, { has: (key) => ENTRY_BOUND_KEYS.has(key) || ENTRY_OMITTED_KEYS.has(key) }, selector, path);
38636
+ const name = field(entry, "name");
38637
+ need2(isString(name) && name.value === selector.plugin, "selected entry name does not match");
38638
+ validateSource(field(entry, "source"), selector, `${path}.source`);
38639
+ for (const key of ["strict", "defaultEnabled"]) {
38640
+ const value = field(entry, key);
38641
+ need2(value === undefined || isBoolean(value), `has an invalid entry ${key}`);
38642
+ }
38643
+ const headersHelper = field(entry, "headersHelper");
38644
+ need2(headersHelper === undefined || isString(headersHelper), "has an invalid entry headersHelper");
38645
+ const experimental = field(entry, "experimental");
38646
+ if (experimental !== undefined) {
38647
+ need2(experimental.kind === "object", "has an invalid entry experimental object");
38648
+ knownKeys(experimental, EXPERIMENTAL_KEYS, selector, `${path}.experimental`);
38649
+ }
38650
+ for (const key of ["$schema", "description", "version", "homepage", "license", "category", "displayName"]) {
38651
+ const value = field(entry, key);
38652
+ need2(value === undefined || isString(value), `has an invalid entry ${key}`);
38653
+ }
38654
+ for (const [key, keys] of [["author", new Set(["name", "email", "url"])], ["repository", new Set(["type", "url", "directory"])]]) {
38655
+ const value = field(entry, key);
38656
+ if (value?.kind === "object")
38657
+ knownKeys(value, keys, selector, `${path}.${key}`);
38658
+ need2(value === undefined || isString(value) || stringObject(value), `has an invalid entry ${key}`);
38659
+ }
38660
+ for (const key of ["keywords", "tags"]) {
38661
+ const value = field(entry, key);
38662
+ need2(value === undefined || stringArray(value), `has an invalid entry ${key}`);
38663
+ }
38664
+ const metadata = field(entry, "metadata");
38665
+ need2(metadata === undefined || metadata.kind === "object", "has an invalid entry metadata object");
38666
+ return { kind: "object", entries: entry.entries.filter(([key]) => ENTRY_BOUND_KEYS.has(key)) };
38667
+ }
38668
+ function hashClaudeMarketplaceEntry(text, selector) {
38669
+ need2(selector && typeof selector.marketplace === "string" && NAME.test(selector.marketplace) && !selector.marketplace.includes("..") && typeof selector.plugin === "string" && NAME.test(selector.plugin), "requires an exact marketplace and plugin name");
38670
+ let root;
38671
+ try {
38672
+ root = parseNativeJsonObject(text);
38673
+ } catch (error61) {
38674
+ throw new Error(`Claude marketplace entry witness cannot parse marketplace.json: ${reason(error61)}`);
38675
+ }
38676
+ validateMarketplace(root, selector);
38677
+ const plugins = field(root, "plugins");
38678
+ need2(plugins?.kind === "array", "requires a plugins array");
38679
+ const entryName = (item) => {
38680
+ if (item.kind !== "object")
38681
+ return;
38682
+ const name = field(item, "name");
38683
+ return isString(name) ? name.value : undefined;
38684
+ };
38685
+ const exact = plugins.items.filter((item) => entryName(item) === selector.plugin);
38686
+ const folded = plugins.items.filter((item) => entryName(item)?.toLowerCase() === selector.plugin.toLowerCase());
38687
+ need2(exact.length > 0, "selected plugin entry is missing");
38688
+ need2(exact.length === 1 && folded.length === 1, "selected plugin entry is duplicated or ambiguous");
38689
+ const entry = projectEntry(exact[0], selector);
38690
+ const metadata = field(root, "metadata"), pluginRoot = metadata?.kind === "object" ? field(metadata, "pluginRoot") : undefined;
38691
+ const nullValue = { kind: "literal", value: "null" };
38692
+ const marketplace = { kind: "object", entries: [
38693
+ ["name", field(root, "name")],
38694
+ ["pluginRoot", pluginRoot ?? nullValue],
38695
+ ["allowCrossMarketplaceDependenciesOn", field(root, "allowCrossMarketplaceDependenciesOn") ?? nullValue]
38696
+ ] };
38697
+ const projection = { kind: "object", entries: [["marketplace", marketplace], ["plugin", entry]] };
38698
+ return createHash3("sha256").update(DOMAIN).update(canonical2(projection)).digest("hex");
38699
+ }
38700
+ function captureClaudeMarketplaceEntry(path, marketplace, plugin, budget2 = { remaining: 256 * 1024 * 1024 }) {
38701
+ need2(claudeMarketplaceEntrySourceValid({ path, marketplace, plugin }), "requires a normalized absolute .claude-plugin/marketplace.json path and exact names");
38702
+ let text;
38703
+ try {
38704
+ text = readNativeSettingsWitnessFile(path, budget2, "marketplace.json");
38705
+ } catch (error61) {
38706
+ throw new Error(`Claude marketplace entry witness cannot read marketplace.json: ${reason(error61)}`);
38707
+ }
38708
+ return { path, hashMode: CLAUDE_MARKETPLACE_ENTRY_HASH_MODE, marketplace, plugin, sha256: hashClaudeMarketplaceEntry(text, { marketplace, plugin }) };
38709
+ }
38710
+ var CLAUDE_MARKETPLACE_ENTRY_HASH_MODE = "claude-marketplace-entry-v1", DOMAIN = "hasna.skills.claude-marketplace-entry.v1\x00", PATH_CHARACTERS = 4096, NAME, bounded = (key) => key.length > 64 ? `${key.slice(0, 64)}...` : key, quote = (text) => JSON.stringify(text).replace(/[^\x20-\x7e]/g, (character) => `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`), child = (path, key) => path + (/^[A-Za-z0-9_$-]{1,64}$/.test(key) ? `.${key}` : `[${JSON.stringify(bounded(key))}]`), reason = (error61) => String(error61?.message ?? error61).replace(/^Claude settings witness /, ""), MARKETPLACE_KEYS, MARKETPLACE_METADATA_KEYS, ENTRY_BOUND_KEYS, ENTRY_OMITTED_KEYS, EXPERIMENTAL_KEYS, SOURCE_KEYS, field = (object4, key) => object4.entries.find(([name]) => name === key)?.[1], isString = (value) => value?.kind === "string", isBoolean = (value) => value?.kind === "literal" && (value.value === "true" || value.value === "false"), stringArray = (value) => value?.kind === "array" && value.items.every(isString), stringObject = (value) => value?.kind === "object" && value.entries.every(([, item]) => isString(item));
38711
+ var init_claude_marketplace_entry_witness = __esm(() => {
38712
+ init_claude_settings_witness();
38713
+ NAME = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
38714
+ MARKETPLACE_KEYS = new Set(["$schema", "name", "owner", "plugins", "description", "version", "metadata", "forceRemoveDeletedPlugins", "allowCrossMarketplaceDependenciesOn", "renames"]);
38715
+ MARKETPLACE_METADATA_KEYS = new Set(["description", "version", "pluginRoot"]);
38716
+ ENTRY_BOUND_KEYS = new Set([
38717
+ "name",
38718
+ "source",
38719
+ "strict",
38720
+ "defaultEnabled",
38721
+ "dependencies",
38722
+ "relevance",
38723
+ "headers",
38724
+ "headersHelper",
38725
+ "settings",
38726
+ "userConfig",
38727
+ "types",
38728
+ "channels",
38729
+ "skills",
38730
+ "commands",
38731
+ "agents",
38732
+ "hooks",
38733
+ "mcpServers",
38734
+ "lspServers",
38735
+ "outputStyles",
38736
+ "workflows",
38737
+ "experimental",
38738
+ "themes",
38739
+ "monitors"
38740
+ ]);
38741
+ ENTRY_OMITTED_KEYS = new Set(["$schema", "description", "version", "author", "homepage", "repository", "license", "keywords", "category", "tags", "displayName", "metadata"]);
38742
+ EXPERIMENTAL_KEYS = new Set(["themes", "monitors", "evals"]);
38743
+ SOURCE_KEYS = Object.freeze({
38744
+ github: ["source", "repo", "ref", "sha"],
38745
+ url: ["source", "url", "ref", "sha", "path"],
38746
+ "git-subdir": ["source", "url", "path", "ref", "sha"],
38747
+ npm: ["source", "package", "version", "registry"],
38748
+ archive: ["source", "url", "sha256"],
38749
+ command: ["source", "command", "timeout", "mode"]
38750
+ });
38751
+ });
38752
+
38541
38753
  // src/lib/agent-policy-limits.ts
38542
- import { basename as basename4, isAbsolute as isAbsolute4, join as join10, resolve as resolve3, sep as sep3 } from "path";
38754
+ import { basename as basename5, isAbsolute as isAbsolute5, join as join10, resolve as resolve4, sep as sep3 } from "path";
38543
38755
  function object4(value) {
38544
38756
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
38545
38757
  }
@@ -38592,7 +38804,7 @@ function assertAgentPolicyCollections(policy) {
38592
38804
  text(control.pluginId, 1024);
38593
38805
  text(control.namespace, 64);
38594
38806
  text(control.pluginParent);
38595
- requireBound(isAbsolute4(control.pluginParent) && resolve3(control.pluginParent) === control.pluginParent && /^[a-f0-9]{64}$/.test(control.manifestSha256));
38807
+ requireBound(isAbsolute5(control.pluginParent) && resolve4(control.pluginParent) === control.pluginParent && /^[a-f0-9]{64}$/.test(control.manifestSha256));
38596
38808
  if (control.remotePluginId !== undefined)
38597
38809
  requireBound(typeof control.remotePluginId === "string" && /^[A-Za-z0-9_~-]{1,1024}$/.test(control.remotePluginId));
38598
38810
  if (control.skillsOnly !== undefined)
@@ -38604,16 +38816,24 @@ function assertAgentPolicyCollections(policy) {
38604
38816
  }
38605
38817
  if (bridge.codexInactivePlugins !== undefined) {
38606
38818
  const controls = array3(bridge.codexInactivePlugins, 4096), ids = new Set;
38607
- requireBound(controls.length === 0 || object4(bridge.codexPluginSkillReview) && bridge.codexPluginSkillReview.version === "codex-cli 0.160.0" && typeof bridge.codexPluginSkillReview.catalogSha256 === "string" && /^[a-f0-9]{64}$/.test(bridge.codexPluginSkillReview.catalogSha256));
38819
+ requireBound(controls.length === 0 || object4(bridge.codexPluginSkillReview) && supportsCodexNativeCapability(bridge.codexPluginSkillReview.version, "installed-plugin-review") && typeof bridge.codexPluginSkillReview.catalogSha256 === "string" && /^[a-f0-9]{64}$/.test(bridge.codexPluginSkillReview.catalogSha256));
38608
38820
  for (const control of controls) {
38609
38821
  requireBound(object4(control) && Object.keys(control).every((key) => ["pluginId", "namespace", "pluginParent", "sourceType", "sourceSha256"].includes(key)));
38610
38822
  text(control.pluginId, 1024);
38611
38823
  text(control.namespace, 64);
38612
38824
  text(control.pluginParent);
38613
- requireBound(!ids.has(control.pluginId) && isAbsolute4(control.pluginParent) && resolve3(control.pluginParent) === control.pluginParent && ["local", "git", "npm"].includes(control.sourceType) && typeof control.sourceSha256 === "string" && /^[a-f0-9]{64}$/.test(control.sourceSha256));
38825
+ requireBound(!ids.has(control.pluginId) && isAbsolute5(control.pluginParent) && resolve4(control.pluginParent) === control.pluginParent && ["local", "git", "npm"].includes(control.sourceType) && typeof control.sourceSha256 === "string" && /^[a-f0-9]{64}$/.test(control.sourceSha256));
38614
38826
  ids.add(control.pluginId);
38615
38827
  }
38616
38828
  }
38829
+ if (bridge.discoveryExecutables !== undefined)
38830
+ for (const [agent, executable] of Object.entries(record3(bridge.discoveryExecutables, AGENT_POLICY_LIMITS.agents))) {
38831
+ requireBound(agent === "gemini" && object4(executable) && Object.keys(executable).length === 3 && executable.command === "gemini");
38832
+ for (const path of [executable.path, executable.target]) {
38833
+ text(path);
38834
+ requireBound(!/[\x00-\x1f\x7f-\x9f\u200e\u200f\u202a-\u202e\u2066-\u2069]/.test(path) && isAbsolute5(path) && resolve4(path) === path);
38835
+ }
38836
+ }
38617
38837
  if (bridge.disabledBuiltins !== undefined)
38618
38838
  for (const builtin of array3(bridge.disabledBuiltins, AGENT_POLICY_LIMITS.builtinNames)) {
38619
38839
  requireBound(object4(builtin));
@@ -38639,11 +38859,11 @@ function assertAgentPolicyCollections(policy) {
38639
38859
  requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && Object.keys(proof).every((key) => ["roots", "parents", "directories"].includes(key)) && roots.length + parents2.length > 0 && new Set(roots).size === roots.length && new Set(parents2).size === parents2.length);
38640
38860
  for (const root of roots) {
38641
38861
  text(root);
38642
- requireBound(isAbsolute4(root) && resolve3(root) === root);
38862
+ requireBound(isAbsolute5(root) && resolve4(root) === root);
38643
38863
  }
38644
38864
  for (const parent of parents2) {
38645
38865
  text(parent);
38646
- requireBound(isAbsolute4(parent) && resolve3(parent) === parent);
38866
+ requireBound(isAbsolute5(parent) && resolve4(parent) === parent);
38647
38867
  }
38648
38868
  for (const directory of array3(proof.directories, AGENT_POLICY_LIMITS.discoveryDirectories)) {
38649
38869
  requireBound(object4(directory));
@@ -38656,14 +38876,14 @@ function assertAgentPolicyCollections(policy) {
38656
38876
  }
38657
38877
  if (value.codexInstallationInputs !== undefined) {
38658
38878
  const proof = record3(value.codexInstallationInputs, 4), inputs = array3(proof.plugins, 4096), ids = new Set;
38659
- requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && proof.version === "codex-cli 0.160.0" && typeof proof.catalogSha256 === "string" && /^[a-f0-9]{64}$/.test(proof.catalogSha256) && inputs.length > 0 && object4(bridge.codexPluginSkillReview) && bridge.codexPluginSkillReview.version === proof.version && bridge.codexPluginSkillReview.catalogSha256 === proof.catalogSha256);
38879
+ requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && supportsCodexNativeCapability(proof.version, "installed-plugin-review") && typeof proof.catalogSha256 === "string" && /^[a-f0-9]{64}$/.test(proof.catalogSha256) && inputs.length > 0 && object4(bridge.codexPluginSkillReview) && bridge.codexPluginSkillReview.version === proof.version && bridge.codexPluginSkillReview.catalogSha256 === proof.catalogSha256);
38660
38880
  for (const input2 of inputs) {
38661
38881
  requireBound(object4(input2) && Object.keys(input2).every((key) => ["pluginId", "namespace", "pluginParent", "sourceRoot", "sourceSha256"].includes(key)));
38662
38882
  text(input2.pluginId, 1024);
38663
38883
  text(input2.namespace, 64);
38664
38884
  text(input2.pluginParent);
38665
38885
  text(input2.sourceRoot);
38666
- requireBound(!ids.has(input2.pluginId) && [input2.pluginParent, input2.sourceRoot].every((path) => isAbsolute4(path) && resolve3(path) === path) && typeof input2.sourceSha256 === "string" && /^[a-f0-9]{64}$/.test(input2.sourceSha256));
38886
+ requireBound(!ids.has(input2.pluginId) && [input2.pluginParent, input2.sourceRoot].every((path) => isAbsolute5(path) && resolve4(path) === path) && typeof input2.sourceSha256 === "string" && /^[a-f0-9]{64}$/.test(input2.sourceSha256));
38667
38887
  ids.add(input2.pluginId);
38668
38888
  }
38669
38889
  if (proof.directories !== undefined)
@@ -38680,17 +38900,19 @@ function assertAgentPolicyCollections(policy) {
38680
38900
  text(source.path);
38681
38901
  requireBound(source.sha256 === null || typeof source.sha256 === "string" && /^[a-f0-9]{64}$/.test(source.sha256));
38682
38902
  if (source.hashMode !== undefined)
38683
- requireBound(["bytes", "path-bytes", "claude-plugin-manifest-v1", "claude-plugin-registry", "claude-marketplace-registry", "claude-settings-v1", "claude-settings-v2", "claude-settings-v3", "claude-settings-v4", "claude-marketplace-registry-v2", "codex-settings-v1", "codex-settings-v2", "codex-settings-v3", "codex-settings-v4", "sumi-settings-v1"].includes(source.hashMode) && source.format === undefined && source.fields === undefined && (source.hashMode === "bytes" || source.sha256 !== null));
38903
+ requireBound(["bytes", "path-bytes", "claude-plugin-manifest-v1", "claude-plugin-registry", "claude-marketplace-registry", "claude-settings-v1", "claude-settings-v2", "claude-settings-v3", "claude-settings-v4", "claude-marketplace-registry-v2", "codex-settings-v1", "codex-settings-v2", "codex-settings-v3", "codex-settings-v4", "sumi-settings-v1", "claude-marketplace-entry-v1"].includes(source.hashMode) && source.format === undefined && source.fields === undefined && (source.hashMode === "bytes" || source.sha256 !== null));
38684
38904
  if (source.hashMode === "claude-plugin-manifest-v1")
38685
- requireBound(agent === "claude" && value.agent === "claude" && ["automatic", "reviewed"].includes(value.method) && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute4(source.path) && resolve3(source.path) === source.path && source.path.endsWith(join10(sep3, ".claude-plugin", "plugin.json")) && source.managedPlugins === undefined);
38905
+ requireBound(agent === "claude" && value.agent === "claude" && ["automatic", "reviewed"].includes(value.method) && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute5(source.path) && resolve4(source.path) === source.path && source.path.endsWith(join10(sep3, ".claude-plugin", "plugin.json")) && source.managedPlugins === undefined);
38686
38906
  if (source.hashMode === "sumi-settings-v1")
38687
- requireBound(agent === "sumi" && value.agent === "sumi" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute4(source.path) && resolve3(source.path) === source.path && basename4(source.path) === "sumi.json");
38907
+ requireBound(agent === "sumi" && value.agent === "sumi" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute5(source.path) && resolve4(source.path) === source.path && basename5(source.path) === "sumi.json");
38688
38908
  if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4"))
38689
- requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute4(source.path) && resolve3(source.path) === source.path && basename4(source.path) === "config.toml");
38909
+ requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute5(source.path) && resolve4(source.path) === source.path && basename5(source.path) === "config.toml");
38690
38910
  if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "claude-settings-v4"))
38691
- requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute4(source.path) && resolve3(source.path) === source.path && basename4(source.path) === "settings.json");
38911
+ requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute5(source.path) && resolve4(source.path) === source.path && basename5(source.path) === "settings.json");
38692
38912
  if (source.hashMode === "claude-marketplace-registry" || source.hashMode === "claude-marketplace-registry-v2")
38693
- requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute4(source.path) && resolve3(source.path) === source.path && basename4(source.path) === "known_marketplaces.json");
38913
+ requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute5(source.path) && resolve4(source.path) === source.path && basename5(source.path) === "known_marketplaces.json");
38914
+ if (source.hashMode === "claude-marketplace-entry-v1")
38915
+ requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && claudeMarketplaceEntrySourceValid(source));
38694
38916
  if (source.hashMode === "claude-plugin-registry") {
38695
38917
  requireBound(agent === "claude");
38696
38918
  const managed = array3(source.managedPlugins, 64);
@@ -38705,8 +38927,8 @@ function assertAgentPolicyCollections(policy) {
38705
38927
  if (source.format !== undefined)
38706
38928
  requireBound(["json", "toml", "yaml"].includes(source.format));
38707
38929
  if (source.fields !== undefined)
38708
- for (const field of array3(source.fields, AGENT_POLICY_LIMITS.fields))
38709
- text(field, 256);
38930
+ for (const field2 of array3(source.fields, AGENT_POLICY_LIMITS.fields))
38931
+ text(field2, 256);
38710
38932
  }
38711
38933
  if (value.directories !== undefined)
38712
38934
  for (const directory of array3(value.directories, AGENT_POLICY_LIMITS.discoveryDirectories)) {
@@ -38721,6 +38943,8 @@ function assertAgentPolicyCollections(policy) {
38721
38943
  }
38722
38944
  var AGENT_POLICY_LIMITS;
38723
38945
  var init_agent_policy_limits = __esm(() => {
38946
+ init_codex_native_compatibility();
38947
+ init_claude_marketplace_entry_witness();
38724
38948
  AGENT_POLICY_LIMITS = Object.freeze({ bytes: 1024 * 1024, agents: 16, discoverySources: 2048, discoveryRawSourceBytes: 64 * 1024 * 1024, discoveryRawTotalBytes: 256 * 1024 * 1024, discoveryPathLinks: 40, discoveryPathSteps: 256, discoveryPathSourceMetadataBytes: 64 * 1024, discoveryPathTotalMetadataBytes: 8 * 1024 * 1024, discoveryRoots: 512, discoveryDirectories: 64, discoveryDirectoryEntries: 20000, discoveryDirectoryBytes: 8 * 1024 * 1024, builtinNames: 2048, rootAliases: 2, fields: 64, pathCharacters: 4096 });
38725
38949
  });
38726
38950
 
@@ -43945,8 +44169,8 @@ var require_cst_visit = __commonJS((exports) => {
43945
44169
  visit2.REMOVE = REMOVE;
43946
44170
  visit2.itemAtPath = (cst, path) => {
43947
44171
  let item = cst;
43948
- for (const [field, index] of path) {
43949
- const tok = item?.[field];
44172
+ for (const [field2, index] of path) {
44173
+ const tok = item?.[field2];
43950
44174
  if (tok && "items" in tok) {
43951
44175
  item = tok.items[index];
43952
44176
  } else
@@ -43956,8 +44180,8 @@ var require_cst_visit = __commonJS((exports) => {
43956
44180
  };
43957
44181
  visit2.parentCollection = (cst, path) => {
43958
44182
  const parent = visit2.itemAtPath(cst, path.slice(0, -1));
43959
- const field = path[path.length - 1][0];
43960
- const coll = parent?.[field];
44183
+ const field2 = path[path.length - 1][0];
44184
+ const coll = parent?.[field2];
43961
44185
  if (coll && "items" in coll)
43962
44186
  return coll;
43963
44187
  throw new Error("Parent collection not found");
@@ -43966,11 +44190,11 @@ var require_cst_visit = __commonJS((exports) => {
43966
44190
  let ctrl = visitor(item, path);
43967
44191
  if (typeof ctrl === "symbol")
43968
44192
  return ctrl;
43969
- for (const field of ["key", "value"]) {
43970
- const token = item[field];
44193
+ for (const field2 of ["key", "value"]) {
44194
+ const token = item[field2];
43971
44195
  if (token && "items" in token) {
43972
44196
  for (let i = 0;i < token.items.length; ++i) {
43973
- const ci = _visit(Object.freeze(path.concat([[field, i]])), token.items[i], visitor);
44197
+ const ci = _visit(Object.freeze(path.concat([[field2, i]])), token.items[i], visitor);
43974
44198
  if (typeof ci === "number")
43975
44199
  i = ci - 1;
43976
44200
  else if (ci === BREAK)
@@ -43980,7 +44204,7 @@ var require_cst_visit = __commonJS((exports) => {
43980
44204
  i -= 1;
43981
44205
  }
43982
44206
  }
43983
- if (typeof ctrl === "function" && field === "key")
44207
+ if (typeof ctrl === "function" && field2 === "key")
43984
44208
  ctrl = ctrl(item, path);
43985
44209
  }
43986
44210
  }
@@ -44406,9 +44630,9 @@ var require_lexer = __commonJS((exports) => {
44406
44630
  }
44407
44631
  }
44408
44632
  *parseQuotedScalar() {
44409
- const quote = this.charAt(0);
44410
- let end = this.buffer.indexOf(quote, this.pos + 1);
44411
- if (quote === "'") {
44633
+ const quote2 = this.charAt(0);
44634
+ let end = this.buffer.indexOf(quote2, this.pos + 1);
44635
+ if (quote2 === "'") {
44412
44636
  while (end !== -1 && this.buffer[end + 1] === "'")
44413
44637
  end = this.buffer.indexOf("'", end + 2);
44414
44638
  } else {
@@ -45715,7 +45939,7 @@ var init_dist = __esm(() => {
45715
45939
  });
45716
45940
 
45717
45941
  // src/lib/agent-hermes.ts
45718
- import { dirname as dirname5, isAbsolute as isAbsolute5, join as join11, resolve as resolve4 } from "path";
45942
+ import { dirname as dirname6, isAbsolute as isAbsolute6, join as join11, resolve as resolve5 } from "path";
45719
45943
  function object5(value) {
45720
45944
  return Boolean(value && typeof value === "object" && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null));
45721
45945
  }
@@ -45749,7 +45973,7 @@ function assertHermesEnvironment(home) {
45749
45973
  throw new Error(`NATIVE_SKILL_DRIFT: Hermes ${variable} requires a dedicated discovery adapter; unset it before using this adapter`);
45750
45974
  }
45751
45975
  const selected = process.env.HERMES_HOME?.trim();
45752
- if (selected && (!isAbsolute5(selected) || resolve4(selected) !== join11(resolve4(home), ".hermes")))
45976
+ if (selected && (!isAbsolute6(selected) || resolve5(selected) !== join11(resolve5(home), ".hermes")))
45753
45977
  throw new Error("NATIVE_SKILL_DRIFT: custom Hermes homes/profiles require their own reviewed bridge");
45754
45978
  if (process.env.HERMES_ENABLE_PROJECT_PLUGINS?.trim() && !["0", "false", "no", "off"].includes(process.env.HERMES_ENABLE_PROJECT_PLUGINS.trim().toLowerCase()))
45755
45979
  throw new Error("NATIVE_SKILL_DRIFT: Hermes project plugins require a dedicated discovery review");
@@ -45759,18 +45983,18 @@ var init_agent_hermes = __esm(() => {
45759
45983
  });
45760
45984
 
45761
45985
  // src/lib/agent-discovery-directories.ts
45762
- import { createHash as createHash3 } from "crypto";
45986
+ import { createHash as createHash4 } from "crypto";
45763
45987
  import { lstatSync as lstatSync6, opendirSync } from "fs";
45764
- import { dirname as dirname6, isAbsolute as isAbsolute6, join as join12, resolve as resolve5 } from "path";
45765
- function need2(value, message) {
45988
+ import { dirname as dirname7, isAbsolute as isAbsolute7, join as join12, resolve as resolve6 } from "path";
45989
+ function need3(value, message) {
45766
45990
  if (!value)
45767
45991
  throw new Error(message);
45768
45992
  }
45769
45993
  function safe(path) {
45770
- need2(typeof path === "string" && path.length <= AGENT_POLICY_LIMITS.pathCharacters && isAbsolute6(path) && resolve5(path) === path && !path.includes("\x00"), "Expected a canonical absolute discovery directory path");
45771
- for (let cursor = path;; cursor = dirname6(cursor)) {
45772
- need2(!lstatSync6(cursor, { throwIfNoEntry: false })?.isSymbolicLink(), "Refusing symlink native discovery directory");
45773
- if (dirname6(cursor) === cursor)
45994
+ need3(typeof path === "string" && path.length <= AGENT_POLICY_LIMITS.pathCharacters && isAbsolute7(path) && resolve6(path) === path && !path.includes("\x00"), "Expected a canonical absolute discovery directory path");
45995
+ for (let cursor = path;; cursor = dirname7(cursor)) {
45996
+ need3(!lstatSync6(cursor, { throwIfNoEntry: false })?.isSymbolicLink(), "Refusing symlink native discovery directory");
45997
+ if (dirname7(cursor) === cursor)
45774
45998
  break;
45775
45999
  }
45776
46000
  }
@@ -45784,45 +46008,45 @@ function capture(path, budget2, excludedRoots, omittedRoots = [], rows) {
45784
46008
  const root = lstatSync6(path, { throwIfNoEntry: false });
45785
46009
  if (!root)
45786
46010
  return { path, sha256: null };
45787
- need2(root.isDirectory(), "Unsupported native discovery directory input");
45788
- const hash2 = createHash3("sha256");
46011
+ need3(root.isDirectory(), "Unsupported native discovery directory input");
46012
+ const hash2 = createHash4("sha256");
45789
46013
  function walk(current, relative3, before, depth) {
45790
- need2(depth <= 64, "Native discovery directory depth limit exceeded");
46014
+ need3(depth <= 64, "Native discovery directory depth limit exceeded");
45791
46015
  const names = [], directory = opendirSync(current);
45792
46016
  try {
45793
46017
  for (let entry = directory.readSync();entry; entry = directory.readSync()) {
45794
- need2(++budget2.entries <= AGENT_POLICY_LIMITS.discoveryDirectoryEntries, "Native discovery directory entry limit exceeded");
46018
+ need3(++budget2.entries <= AGENT_POLICY_LIMITS.discoveryDirectoryEntries, "Native discovery directory entry limit exceeded");
45795
46019
  names.push(entry.name);
45796
46020
  }
45797
46021
  } finally {
45798
46022
  directory.closeSync();
45799
46023
  }
45800
- need2(new Set(names).size === names.length, "Ambiguous native discovery directory names");
46024
+ need3(new Set(names).size === names.length, "Ambiguous native discovery directory names");
45801
46025
  for (const name of names.sort()) {
45802
- const child = join12(current, name), childRelative = relative3 ? `${relative3}/${name}` : name;
45803
- if (omittedRoots.includes(child))
46026
+ const child2 = join12(current, name), childRelative = relative3 ? `${relative3}/${name}` : name;
46027
+ if (omittedRoots.includes(child2))
45804
46028
  continue;
45805
- need2(child.length <= AGENT_POLICY_LIMITS.pathCharacters, "Native discovery directory path limit exceeded");
45806
- const stat = lstatSync6(child);
45807
- need2(stat.isFile() || stat.isDirectory(), "Refusing symlink or special native discovery directory member");
46029
+ need3(child2.length <= AGENT_POLICY_LIMITS.pathCharacters, "Native discovery directory path limit exceeded");
46030
+ const stat = lstatSync6(child2);
46031
+ need3(stat.isFile() || stat.isDirectory(), "Refusing symlink or special native discovery directory member");
45808
46032
  const row = JSON.stringify([childRelative, stat.isDirectory() ? "directory" : "file"]) + `
45809
46033
  `;
45810
46034
  budget2.bytes += Buffer.byteLength(row);
45811
- need2(budget2.bytes <= AGENT_POLICY_LIMITS.discoveryDirectoryBytes, "Native discovery directory metadata limit exceeded");
46035
+ need3(budget2.bytes <= AGENT_POLICY_LIMITS.discoveryDirectoryBytes, "Native discovery directory metadata limit exceeded");
45812
46036
  hash2.update(row);
45813
46037
  rows?.push(row);
45814
- if (stat.isDirectory() && !excludedRoots.includes(child))
45815
- walk(child, childRelative, stat, depth + 1);
46038
+ if (stat.isDirectory() && !excludedRoots.includes(child2))
46039
+ walk(child2, childRelative, stat, depth + 1);
45816
46040
  }
45817
- need2(same(before, lstatSync6(current, { throwIfNoEntry: false })), "Native discovery directory changed while reading");
46041
+ need3(same(before, lstatSync6(current, { throwIfNoEntry: false })), "Native discovery directory changed while reading");
45818
46042
  }
45819
46043
  walk(path, "", root, 0);
45820
46044
  safe(path);
45821
46045
  return { path, sha256: hash2.digest("hex") };
45822
46046
  }
45823
46047
  function captureDiscoveryDirectoryProjection(paths, omittedRoots) {
45824
- need2(Array.isArray(paths) && paths.length <= AGENT_POLICY_LIMITS.discoveryDirectories && new Set(paths).size === paths.length, "Invalid projected discovery directory collection");
45825
- need2(omittedRoots.length <= AGENT_POLICY_LIMITS.discoveryRoots && new Set(omittedRoots).size === omittedRoots.length, "Invalid inactive discovery roots");
46048
+ need3(Array.isArray(paths) && paths.length <= AGENT_POLICY_LIMITS.discoveryDirectories && new Set(paths).size === paths.length, "Invalid projected discovery directory collection");
46049
+ need3(omittedRoots.length <= AGENT_POLICY_LIMITS.discoveryRoots && new Set(omittedRoots).size === omittedRoots.length, "Invalid inactive discovery roots");
45826
46050
  for (const root of omittedRoots)
45827
46051
  safe(root);
45828
46052
  const budget2 = { entries: 0, bytes: 0 };
@@ -45832,65 +46056,65 @@ function captureDiscoveryDirectoryProjection(paths, omittedRoots) {
45832
46056
  });
45833
46057
  }
45834
46058
  function verifyDiscoveryDirectoryProjection(directories, omittedRoots) {
45835
- need2(directories.length <= AGENT_POLICY_LIMITS.discoveryDirectories, "Invalid projected discovery directory collection");
46059
+ need3(directories.length <= AGENT_POLICY_LIMITS.discoveryDirectories, "Invalid projected discovery directory collection");
45836
46060
  let count = 0, bytes = 0;
45837
46061
  const expected = directories.map((directory) => {
45838
46062
  safe(directory.path);
45839
- need2(Array.isArray(directory.entries), "Missing reviewed directory membership inventory");
45840
- const hash2 = createHash3("sha256");
46063
+ need3(Array.isArray(directory.entries), "Missing reviewed directory membership inventory");
46064
+ const hash2 = createHash4("sha256");
45841
46065
  const kept = [];
45842
46066
  for (const row of directory.entries) {
45843
- need2(typeof row === "string" && ++count <= AGENT_POLICY_LIMITS.discoveryDirectoryEntries, "Invalid reviewed directory membership rows");
46067
+ need3(typeof row === "string" && ++count <= AGENT_POLICY_LIMITS.discoveryDirectoryEntries, "Invalid reviewed directory membership rows");
45844
46068
  bytes += Buffer.byteLength(row);
45845
- need2(bytes <= AGENT_POLICY_LIMITS.discoveryDirectoryBytes, "Reviewed directory membership byte limit exceeded");
46069
+ need3(bytes <= AGENT_POLICY_LIMITS.discoveryDirectoryBytes, "Reviewed directory membership byte limit exceeded");
45846
46070
  const value = JSON.parse(row);
45847
- need2(Array.isArray(value) && value.length === 2 && typeof value[0] === "string" && value[0] && !isAbsolute6(value[0]) && !value[0].split("/").some((part) => !part || part === "." || part === "..") && ["file", "directory"].includes(value[1]) && row === JSON.stringify(value) + `
46071
+ need3(Array.isArray(value) && value.length === 2 && typeof value[0] === "string" && value[0] && !isAbsolute7(value[0]) && !value[0].split("/").some((part) => !part || part === "." || part === "..") && ["file", "directory"].includes(value[1]) && row === JSON.stringify(value) + `
45848
46072
  `, "Invalid reviewed directory member");
45849
46073
  hash2.update(row);
45850
46074
  const path = join12(directory.path, value[0]);
45851
46075
  if (!omittedRoots.some((root) => path === root || path.startsWith(root + "/")))
45852
46076
  kept.push(row);
45853
46077
  }
45854
- need2(directory.sha256 === null ? directory.entries.length === 0 : hash2.digest("hex") === directory.sha256, "Reviewed directory inventory does not match its fingerprint");
46078
+ need3(directory.sha256 === null ? directory.entries.length === 0 : hash2.digest("hex") === directory.sha256, "Reviewed directory inventory does not match its fingerprint");
45855
46079
  const absent = omittedRoots.some((root) => directory.path === root || directory.path.startsWith(root + "/"));
45856
- return { path: directory.path, sha256: absent || directory.sha256 === null ? null : createHash3("sha256").update(kept.join("")).digest("hex") };
46080
+ return { path: directory.path, sha256: absent || directory.sha256 === null ? null : createHash4("sha256").update(kept.join("")).digest("hex") };
45857
46081
  });
45858
46082
  const current = captureDiscoveryDirectoryProjection(directories.map((item) => item.path), omittedRoots);
45859
- need2(current.every((item, index) => item.sha256 === expected[index].sha256), "Native discovery directory membership changed outside retired Codex roots");
46083
+ need3(current.every((item, index) => item.sha256 === expected[index].sha256), "Native discovery directory membership changed outside retired Codex roots");
45860
46084
  }
45861
46085
  function captureDiscoveryDirectories(paths, excludedRoots = []) {
45862
- need2(Array.isArray(paths) && paths.length <= AGENT_POLICY_LIMITS.discoveryDirectories && new Set(paths).size === paths.length, "Invalid native discovery directory collection");
46086
+ need3(Array.isArray(paths) && paths.length <= AGENT_POLICY_LIMITS.discoveryDirectories && new Set(paths).size === paths.length, "Invalid native discovery directory collection");
45863
46087
  const budget2 = { entries: 0, bytes: 0 };
45864
46088
  for (const root of excludedRoots)
45865
46089
  safe(root);
45866
46090
  return paths.map((path) => capture(path, budget2, excludedRoots));
45867
46091
  }
45868
46092
  function verifyDiscoveryDirectories(directories, excludedRoots = []) {
45869
- need2(Array.isArray(directories) && directories.length <= AGENT_POLICY_LIMITS.discoveryDirectories, "Invalid native discovery directory collection");
46093
+ need3(Array.isArray(directories) && directories.length <= AGENT_POLICY_LIMITS.discoveryDirectories, "Invalid native discovery directory collection");
45870
46094
  for (const directory of directories)
45871
- need2(directory && typeof directory === "object" && (directory.sha256 === null || typeof directory.sha256 === "string" && /^[a-f0-9]{64}$/.test(directory.sha256)), "Invalid native discovery directory digest");
46095
+ need3(directory && typeof directory === "object" && (directory.sha256 === null || typeof directory.sha256 === "string" && /^[a-f0-9]{64}$/.test(directory.sha256)), "Invalid native discovery directory digest");
45872
46096
  const current = captureDiscoveryDirectories(directories.map((directory) => directory.path), excludedRoots);
45873
46097
  for (let i = 0;i < directories.length; i++)
45874
- need2(current[i].sha256 === directories[i].sha256, `Native discovery directory membership changed; run skills hook install with a fresh discovery review: ${directories[i].path}`);
46098
+ need3(current[i].sha256 === directories[i].sha256, `Native discovery directory membership changed; run skills hook install with a fresh discovery review: ${directories[i].path}`);
45875
46099
  }
45876
46100
  var init_agent_discovery_directories = __esm(() => {
45877
46101
  init_agent_policy_limits();
45878
46102
  });
45879
46103
 
45880
46104
  // src/lib/agent-discovery-bytes.ts
45881
- import { createHash as createHash4 } from "crypto";
46105
+ import { createHash as createHash5 } from "crypto";
45882
46106
  import { closeSync as closeSync6, constants as constants3, fstatSync as fstatSync6, lstatSync as lstatSync7, openSync as openSync6, readSync as readSync3 } from "fs";
45883
- import { dirname as dirname7, isAbsolute as isAbsolute7, resolve as resolve6 } from "path";
46107
+ import { dirname as dirname8, isAbsolute as isAbsolute8, resolve as resolve7 } from "path";
45884
46108
  function discoveryByteBudget() {
45885
46109
  return { remaining: AGENT_POLICY_LIMITS.discoveryRawTotalBytes };
45886
46110
  }
45887
46111
  function safe2(path) {
45888
- if (typeof path !== "string" || !isAbsolute7(path) || path !== resolve6(path) || path.length > AGENT_POLICY_LIMITS.pathCharacters || path.includes("\x00"))
46112
+ if (typeof path !== "string" || !isAbsolute8(path) || path !== resolve7(path) || path.length > AGENT_POLICY_LIMITS.pathCharacters || path.includes("\x00"))
45889
46113
  throw new Error("Expected a canonical absolute raw discovery path");
45890
- for (let cursor = path;; cursor = dirname7(cursor)) {
46114
+ for (let cursor = path;; cursor = dirname8(cursor)) {
45891
46115
  if (lstatSync7(cursor, { throwIfNoEntry: false })?.isSymbolicLink())
45892
46116
  throw new Error("Refusing symlink raw discovery input");
45893
- if (dirname7(cursor) === cursor)
46117
+ if (dirname8(cursor) === cursor)
45894
46118
  break;
45895
46119
  }
45896
46120
  }
@@ -45909,7 +46133,7 @@ function hashRawDiscoveryFile(path, budget2, changes) {
45909
46133
  if (bytes > AGENT_POLICY_LIMITS.discoveryRawSourceBytes)
45910
46134
  throw new Error("Raw discovery file byte limit exceeded");
45911
46135
  consume(budget2, bytes);
45912
- return createHash4("sha256").update(text2).digest("hex");
46136
+ return createHash5("sha256").update(text2).digest("hex");
45913
46137
  }
45914
46138
  const initial = lstatSync7(path, { throwIfNoEntry: false });
45915
46139
  if (!initial)
@@ -45923,7 +46147,7 @@ function hashRawDiscoveryFile(path, budget2, changes) {
45923
46147
  const opened = fstatSync6(fd);
45924
46148
  if (!opened.isFile() || !same2(initial, opened))
45925
46149
  throw new Error("Raw discovery input changed during open");
45926
- const hash2 = createHash4("sha256"), buffer = Buffer.alloc(64 * 1024);
46150
+ const hash2 = createHash5("sha256"), buffer = Buffer.alloc(64 * 1024);
45927
46151
  let bytes = 0;
45928
46152
  while (true) {
45929
46153
  const count = readSync3(fd, buffer, 0, Math.min(buffer.length, AGENT_POLICY_LIMITS.discoveryRawSourceBytes - bytes + 1), null);
@@ -45949,9 +46173,9 @@ var init_agent_discovery_bytes = __esm(() => {
45949
46173
  });
45950
46174
 
45951
46175
  // src/lib/agent-discovery-path-bytes.ts
45952
- import { createHash as createHash5 } from "crypto";
46176
+ import { createHash as createHash6 } from "crypto";
45953
46177
  import { lstatSync as lstatSync8, readlinkSync } from "fs";
45954
- import { dirname as dirname8, isAbsolute as isAbsolute8, join as join13, parse as parse7, resolve as resolve7, sep as sep4 } from "path";
46178
+ import { dirname as dirname9, isAbsolute as isAbsolute9, join as join13, parse as parse7, resolve as resolve8, sep as sep4 } from "path";
45955
46179
  function identity2(stat, mutable = false) {
45956
46180
  return {
45957
46181
  dev: String(stat.dev),
@@ -45962,12 +46186,12 @@ function identity2(stat, mutable = false) {
45962
46186
  ...mutable ? { size: String(stat.size), mtimeNs: String(stat.mtimeNs), ctimeNs: String(stat.ctimeNs) } : {}
45963
46187
  };
45964
46188
  }
45965
- function canonical2(path) {
45966
- if (typeof path !== "string" || !isAbsolute8(path) || path !== resolve7(path) || path.length > AGENT_POLICY_LIMITS.pathCharacters || path.includes("\x00") || Buffer.from(path).toString("utf8") !== path)
46189
+ function canonical3(path) {
46190
+ if (typeof path !== "string" || !isAbsolute9(path) || path !== resolve8(path) || path.length > AGENT_POLICY_LIMITS.pathCharacters || path.includes("\x00") || Buffer.from(path).toString("utf8") !== path)
45967
46191
  throw new Error("Expected a canonical absolute discovery path");
45968
46192
  }
45969
46193
  function trace(path) {
45970
- canonical2(path);
46194
+ canonical3(path);
45971
46195
  const rows = [], paths = [];
45972
46196
  let metadataBytes = 0, steps = 0, links = 0, cursor = parse7(path).root, pending = path.slice(cursor.length).split(sep4);
45973
46197
  function record4(path2, row) {
@@ -45992,7 +46216,7 @@ function trace(path) {
45992
46216
  if (!component || component === ".")
45993
46217
  continue;
45994
46218
  if (component === "..") {
45995
- cursor = dirname8(cursor);
46219
+ cursor = dirname9(cursor);
45996
46220
  continue;
45997
46221
  }
45998
46222
  const candidate = join13(cursor, component);
@@ -46012,11 +46236,11 @@ function trace(path) {
46012
46236
  if (!target || target.includes("\x00") || Buffer.byteLength(target) > AGENT_POLICY_LIMITS.pathCharacters || !after.isSymbolicLink() || JSON.stringify(identity2(stat, true)) !== JSON.stringify(identity2(after, true)))
46013
46237
  throw new Error("Discovery link changed during read");
46014
46238
  record4(candidate, { type: "link", target, ...identity2(stat, true) });
46015
- if (isAbsolute8(target)) {
46239
+ if (isAbsolute9(target)) {
46016
46240
  cursor = parse7(target).root;
46017
46241
  root();
46018
46242
  }
46019
- const remainder = isAbsolute8(target) ? target.slice(parse7(target).root.length) : target;
46243
+ const remainder = isAbsolute9(target) ? target.slice(parse7(target).root.length) : target;
46020
46244
  pending = [...remainder.split(sep4), ...pending];
46021
46245
  if (pending.length + steps > AGENT_POLICY_LIMITS.discoveryPathSteps)
46022
46246
  throw new Error("Discovery path step limit exceeded");
@@ -46059,7 +46283,7 @@ function hashDiscoveryPathFile(path, budget2, changes) {
46059
46283
  const after = trace(path);
46060
46284
  if (JSON.stringify(before.rows) !== JSON.stringify(after.rows) || before.file !== after.file)
46061
46285
  throw new Error("Discovery path input changed during read");
46062
- return createHash5("sha256").update(JSON.stringify({ version: 1, path, rows: before.rows, content })).digest("hex");
46286
+ return createHash6("sha256").update(JSON.stringify({ version: 1, path, rows: before.rows, content })).digest("hex");
46063
46287
  }
46064
46288
  var init_agent_discovery_path_bytes = __esm(() => {
46065
46289
  init_agent_policy_limits();
@@ -46067,10 +46291,10 @@ var init_agent_discovery_path_bytes = __esm(() => {
46067
46291
  });
46068
46292
 
46069
46293
  // src/lib/claude-plugin-manifest-witness.ts
46070
- import { createHash as createHash6 } from "crypto";
46071
- function requireValue(value, reason) {
46294
+ import { createHash as createHash7 } from "crypto";
46295
+ function requireValue(value, reason2) {
46072
46296
  if (!value)
46073
- throw new Error("Claude plugin manifest " + reason);
46297
+ throw new Error("Claude plugin manifest " + reason2);
46074
46298
  }
46075
46299
  function parse8(text2) {
46076
46300
  requireValue(Buffer.byteLength(text2, "utf8") <= CLAUDE_PLUGIN_MANIFEST_LIMITS.bytes, "exceeds its byte limit");
@@ -46146,7 +46370,7 @@ function parse8(text2) {
46146
46370
  requireValue(at === text2.length && root.kind === "object", "requires a JSON object without trailing content");
46147
46371
  return root;
46148
46372
  }
46149
- function canonical3(value) {
46373
+ function canonical4(value) {
46150
46374
  if (value.kind === "string")
46151
46375
  return JSON.stringify(value.value);
46152
46376
  if (value.kind === "number")
@@ -46154,18 +46378,18 @@ function canonical3(value) {
46154
46378
  if (value.kind === "literal")
46155
46379
  return value.value;
46156
46380
  if (value.kind === "array")
46157
- return "[" + value.items.map(canonical3).join(",") + "]";
46158
- return "{" + value.entries.map(([key, item]) => JSON.stringify(key) + ":" + canonical3(item)).join(",") + "}";
46381
+ return "[" + value.items.map(canonical4).join(",") + "]";
46382
+ return "{" + value.entries.map(([key, item]) => JSON.stringify(key) + ":" + canonical4(item)).join(",") + "}";
46159
46383
  }
46160
- function validateText(value, field) {
46161
- requireValue(value?.kind === "string" && value.value.length <= CLAUDE_PLUGIN_MANIFEST_LIMITS.stringCharacters, "has an invalid " + field + " field");
46384
+ function validateText(value, field2) {
46385
+ requireValue(value?.kind === "string" && value.value.length <= CLAUDE_PLUGIN_MANIFEST_LIMITS.stringCharacters, "has an invalid " + field2 + " field");
46162
46386
  }
46163
46387
  function validateDescriptiveFields(manifest) {
46164
46388
  const values = new Map(manifest.entries);
46165
- for (const field of ["description", "version", "homepage", "license"]) {
46166
- const value = values.get(field);
46389
+ for (const field2 of ["description", "version", "homepage", "license"]) {
46390
+ const value = values.get(field2);
46167
46391
  if (value !== undefined)
46168
- validateText(value, field);
46392
+ validateText(value, field2);
46169
46393
  }
46170
46394
  const author = values.get("author");
46171
46395
  if (author !== undefined) {
@@ -46190,10 +46414,10 @@ function hashClaudePluginManifest(text2) {
46190
46414
  const manifest = parse8(text2);
46191
46415
  validateDescriptiveFields(manifest);
46192
46416
  const discovery = { kind: "object", entries: manifest.entries.filter(([key]) => !DESCRIPTIVE_FIELDS.has(key)) };
46193
- return createHash6("sha256").update(canonical3(discovery)).digest("hex");
46417
+ return createHash7("sha256").update(canonical4(discovery)).digest("hex");
46194
46418
  }
46195
46419
  function projectReviewedClaudePluginManifest(text2, reviewedSha256) {
46196
- if (!/^[a-f0-9]{64}$/.test(reviewedSha256) || createHash6("sha256").update(text2).digest("hex") !== reviewedSha256) {
46420
+ if (!/^[a-f0-9]{64}$/.test(reviewedSha256) || createHash7("sha256").update(text2).digest("hex") !== reviewedSha256) {
46197
46421
  throw new Error("Reviewed Claude plugin manifest changed before semantic projection");
46198
46422
  }
46199
46423
  return hashClaudePluginManifest(text2);
@@ -46205,7 +46429,7 @@ var init_claude_plugin_manifest_witness = __esm(() => {
46205
46429
  });
46206
46430
 
46207
46431
  // src/lib/skill-bundle.ts
46208
- import { createHash as createHash7 } from "crypto";
46432
+ import { createHash as createHash8 } from "crypto";
46209
46433
  import { readFileSync as readFileSync9, readdirSync as readdirSync4, statSync as statSync6 } from "fs";
46210
46434
  import { join as join14, relative as relative3 } from "path";
46211
46435
  import { createGunzip } from "zlib";
@@ -46237,7 +46461,7 @@ function ownBytes(view) {
46237
46461
  return out;
46238
46462
  }
46239
46463
  function sha256Hex(bytes) {
46240
- return createHash7("sha256").update(bytes).digest("hex");
46464
+ return createHash8("sha256").update(bytes).digest("hex");
46241
46465
  }
46242
46466
  function collectSkillBundleEntries(dir) {
46243
46467
  const entries = [];
@@ -46365,12 +46589,12 @@ function inspectionLimits(options) {
46365
46589
  for (const key of Object.keys(options.limits ?? {})) {
46366
46590
  if (!Object.hasOwn(limits, key))
46367
46591
  throw new SkillBundleInspectionError("BUNDLE_LIMIT", "Unknown bundle limit");
46368
- const field = key;
46369
- const value = options.limits[field];
46370
- if (!Number.isSafeInteger(value) || value <= 0 || value > limits[field]) {
46592
+ const field2 = key;
46593
+ const value = options.limits[field2];
46594
+ if (!Number.isSafeInteger(value) || value <= 0 || value > limits[field2]) {
46371
46595
  throw new SkillBundleInspectionError("BUNDLE_LIMIT", "Bundle limits must be positive integers within the hard ceilings");
46372
46596
  }
46373
- limits[field] = value;
46597
+ limits[field2] = value;
46374
46598
  }
46375
46599
  return limits;
46376
46600
  }
@@ -46400,7 +46624,14 @@ async function inspectSkillBundle(bundle, options = {}) {
46400
46624
  decoder.destroy(terminalError);
46401
46625
  };
46402
46626
  const onAbort = () => stop("BUNDLE_ABORTED");
46403
- const timer = setTimeout(() => stop("BUNDLE_TIMEOUT"), Math.max(1, deadline - performance.now()));
46627
+ const expire = () => {
46628
+ const remaining = deadline - performance.now();
46629
+ if (remaining > 0)
46630
+ timer = setTimeout(expire, Math.max(1, Math.ceil(remaining)));
46631
+ else
46632
+ stop("BUNDLE_TIMEOUT");
46633
+ };
46634
+ let timer = setTimeout(expire, Math.max(1, Math.ceil(deadline - performance.now())));
46404
46635
  signal?.addEventListener("abort", onAbort, { once: true });
46405
46636
  let decompressedByteSize = 0;
46406
46637
  let bytesSinceYield = 0;
@@ -46415,7 +46646,7 @@ async function inspectSkillBundle(bundle, options = {}) {
46415
46646
  parser2.push(chunk);
46416
46647
  bytesSinceYield += chunk.byteLength;
46417
46648
  if (bytesSinceYield >= 256 * 1024) {
46418
- await new Promise((resolve8) => setTimeout(resolve8, 0));
46649
+ await new Promise((resolve9) => setTimeout(resolve9, 0));
46419
46650
  bytesSinceYield = 0;
46420
46651
  check2();
46421
46652
  }
@@ -46552,8 +46783,8 @@ class BoundedTarReader {
46552
46783
  }
46553
46784
  }
46554
46785
  }
46555
- function tarOctal(field) {
46556
- const text2 = new TextDecoder().decode(field);
46786
+ function tarOctal(field2) {
46787
+ const text2 = new TextDecoder().decode(field2);
46557
46788
  if (!/^[0-7]+[\0 ]*$/.test(text2))
46558
46789
  invalidBundle("Invalid tar octal field");
46559
46790
  const value = Number.parseInt(text2, 8);
@@ -46772,21 +47003,21 @@ var init_profile_limits = __esm(() => {
46772
47003
  });
46773
47004
 
46774
47005
  // src/lib/selection-cache.ts
46775
- import { createHash as createHash8, randomUUID } from "crypto";
47006
+ import { createHash as createHash9, randomUUID } from "crypto";
46776
47007
  import { spawnSync as spawnSync2 } from "child_process";
46777
47008
  import { closeSync as closeSync7, constants as constants4, fstatSync as fstatSync7, fsyncSync, linkSync, lstatSync as lstatSync9, mkdirSync as mkdirSync3, openSync as openSync7, readFileSync as readFileSync10, readlinkSync as readlinkSync2, readSync as readSync4, renameSync, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
46778
47009
  import { hostname as hostname3 } from "os";
46779
- import { dirname as dirname9, join as join15, parse as parse9, resolve as resolve8 } from "path";
47010
+ import { dirname as dirname10, join as join15, parse as parse9, resolve as resolve9 } from "path";
46780
47011
  import { isDeepStrictEqual } from "util";
46781
47012
  function selectionCacheRoot(options = {}) {
46782
- return resolve8(options.cacheDir ?? join15(getDataDirReadOnly(), "selection-cache"));
47013
+ return resolve9(options.cacheDir ?? join15(getDataDirReadOnly(), "selection-cache"));
46783
47014
  }
46784
47015
  function selectionKey(selection) {
46785
47016
  validateSelection(selection);
46786
47017
  return hash2([selection.authority, selection.workspaceId, selection.slug, selection.version, selection.bundleDigest]);
46787
47018
  }
46788
47019
  function hash2(value) {
46789
- return createHash8("sha256").update(JSON.stringify(value)).digest("hex");
47020
+ return createHash9("sha256").update(JSON.stringify(value)).digest("hex");
46790
47021
  }
46791
47022
  function validateSelection(selection) {
46792
47023
  if (!selection || !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(selection.slug) || !isValidSkillVersion(selection.version) || !/^sha256:[a-f0-9]{64}$/.test(selection.bundleDigest) || typeof selection.workspaceId !== "string" || !selection.workspaceId.trim() || selection.authorizationEpoch !== undefined && (typeof selection.authorizationEpoch !== "string" || !/^[a-f0-9]{32}$/.test(selection.authorizationEpoch)) || typeof selection.profileRevision !== "string" || !selection.profileRevision.trim()) {
@@ -46826,7 +47057,7 @@ function selectionBundlePath(selection, options = {}) {
46826
47057
  return join15(selectionCacheRoot(options), "objects", hash2(selection.authority), hash2(selection.workspaceId), `${selection.bundleDigest.slice(7)}.tar.gz`);
46827
47058
  }
46828
47059
  function assertRegularPath(path, createParents = false) {
46829
- const absolute = resolve8(path);
47060
+ const absolute = resolve9(path);
46830
47061
  const root = parse9(absolute).root;
46831
47062
  let cursor = root;
46832
47063
  const segments = absolute.slice(root.length).split("/");
@@ -46883,7 +47114,7 @@ function writeSelectionJson(path, value) {
46883
47114
  }
46884
47115
  function atomicWrite(path, bytes, mode, durable = false) {
46885
47116
  assertRegularPath(path, true);
46886
- const temporary = join15(dirname9(path), `.selection-${randomUUID()}.tmp`);
47117
+ const temporary = join15(dirname10(path), `.selection-${randomUUID()}.tmp`);
46887
47118
  try {
46888
47119
  const fd = openSync7(temporary, constants4.O_WRONLY | constants4.O_CREAT | constants4.O_EXCL | constants4.O_NOFOLLOW, mode);
46889
47120
  try {
@@ -46895,7 +47126,7 @@ function atomicWrite(path, bytes, mode, durable = false) {
46895
47126
  }
46896
47127
  renameSync(temporary, path);
46897
47128
  if (durable)
46898
- syncDirectory(dirname9(path));
47129
+ syncDirectory(dirname10(path));
46899
47130
  } finally {
46900
47131
  try {
46901
47132
  unlinkSync(temporary);
@@ -46905,8 +47136,8 @@ function atomicWrite(path, bytes, mode, durable = false) {
46905
47136
  }
46906
47137
  }
46907
47138
  }
46908
- function readSelectionJson(path) {
46909
- const bytes = readRegularFile(path, MAX_PROFILE_DOCUMENT_BYTES);
47139
+ function readSelectionJson(path, maximumBytes = MAX_PROFILE_DOCUMENT_BYTES) {
47140
+ const bytes = readRegularFile(path, Math.min(maximumBytes, MAX_PROFILE_DOCUMENT_BYTES));
46910
47141
  if (!bytes)
46911
47142
  return null;
46912
47143
  try {
@@ -46918,10 +47149,10 @@ function readSelectionJson(path) {
46918
47149
  async function verifiedEntries(selection, bytes, signal, deadline) {
46919
47150
  if (`sha256:${sha256Hex(bytes)}` !== selection.bundleDigest)
46920
47151
  throw new SkillSelectionError("BUNDLE_DIGEST_MISMATCH", "The skill bundle does not match its selected digest.");
46921
- const remaining = deadline === undefined ? undefined : Math.floor(deadline - performance.now());
47152
+ const remaining = deadline === undefined ? undefined : Math.ceil(deadline - performance.now());
46922
47153
  signal?.throwIfAborted();
46923
47154
  if (remaining !== undefined && remaining <= 0)
46924
- throw new SkillSelectionError("SKILLS_API_UNAVAILABLE", "Skills session authorization deadline exceeded.");
47155
+ throw new SkillBundleInspectionError("BUNDLE_TIMEOUT", "Bundle inspection deadline exceeded");
46925
47156
  const bundle = await inspectSkillBundle(bytes, { signal, ...remaining === undefined ? {} : { limits: { timeoutMs: remaining } } });
46926
47157
  return bundle.entries;
46927
47158
  }
@@ -47021,7 +47252,7 @@ function assertFreshCachedProfile(receipt, options = {}) {
47021
47252
  }
47022
47253
  }
47023
47254
  function projectSelectionLockPath(projectDir) {
47024
- return join15(resolve8(projectDir), ".skills", SELECTION_LOCK_FILE);
47255
+ return join15(resolve9(projectDir), ".skills", SELECTION_LOCK_FILE);
47025
47256
  }
47026
47257
  function readProjectSelection(projectDir) {
47027
47258
  const receipt = readSelectionJson(projectSelectionLockPath(projectDir));
@@ -47172,13 +47403,13 @@ function publishSessionLock(path, marker) {
47172
47403
  fsyncSync(fd);
47173
47404
  linkSync(stagingPath, path);
47174
47405
  published = true;
47175
- syncDirectory(dirname9(path));
47406
+ syncDirectory(dirname10(path));
47176
47407
  const staged = lstatSync9(stagingPath);
47177
47408
  if (!staged.isFile() || staged.dev !== stat.dev || staged.ino !== stat.ino) {
47178
47409
  throw new SkillSelectionError("SESSION_WRITE_LOCK_CHANGED", "The initialized lock staging inode changed before publication completed.");
47179
47410
  }
47180
47411
  unlinkSync(stagingPath);
47181
- syncDirectory(dirname9(path));
47412
+ syncDirectory(dirname10(path));
47182
47413
  handedOff = true;
47183
47414
  return { path, stagingPath, fd, dev: stat.dev, ino: stat.ino };
47184
47415
  } finally {
@@ -47223,14 +47454,14 @@ function archiveSessionLock(lock, receipt, explicitLocalHost) {
47223
47454
  writeFileSync3(guardFd, `${JSON.stringify({ schemaVersion: 1, pid: process.pid, operationId: randomUUID() })}
47224
47455
  `);
47225
47456
  fsyncSync(guardFd);
47226
- const cacheOptions = { cacheDir: dirname9(dirname9(lock.path)) };
47457
+ const cacheOptions = { cacheDir: dirname10(dirname10(lock.path)) };
47227
47458
  const current = readSessionLock(lock.marker.sessionId, cacheOptions);
47228
47459
  if (!current || current.dev !== lock.dev || current.ino !== lock.ino || current.sha256 !== lock.sha256 || current.mtimeMs !== lock.mtimeMs || !writerIsGone(current, explicitLocalHost))
47229
47460
  return null;
47230
47461
  const currentReceipt = readSkillSessionSnapshotIfExists(lock.marker.sessionId, cacheOptions);
47231
47462
  if (currentReceipt?.sha256 !== receipt?.sha256 || currentReceipt?.generation !== receipt?.generation)
47232
47463
  return null;
47233
- const directory = join15(dirname9(dirname9(lock.path)), "session-lock-recoveries", randomUUID());
47464
+ const directory = join15(dirname10(dirname10(lock.path)), "session-lock-recoveries", randomUUID());
47234
47465
  const archivePath = join15(directory, "original.write-lock");
47235
47466
  const recordPath = join15(directory, "recovery.json");
47236
47467
  assertRegularPath(archivePath, true);
@@ -47247,7 +47478,7 @@ function archiveSessionLock(lock, receipt, explicitLocalHost) {
47247
47478
  })}
47248
47479
  `));
47249
47480
  syncDirectory(directory);
47250
- syncDirectory(dirname9(directory));
47481
+ syncDirectory(dirname10(directory));
47251
47482
  const finalLock = readSessionLock(lock.marker.sessionId, cacheOptions);
47252
47483
  if (!finalLock || finalLock.dev !== lock.dev || finalLock.ino !== lock.ino || finalLock.sha256 !== lock.sha256 || readSkillSessionSnapshotIfExists(lock.marker.sessionId, cacheOptions)?.sha256 !== receipt?.sha256)
47253
47484
  return null;
@@ -47262,7 +47493,7 @@ function archiveSessionLock(lock, receipt, explicitLocalHost) {
47262
47493
  archivedPaths.push(publicationPath);
47263
47494
  }
47264
47495
  syncDirectory(directory);
47265
- syncDirectory(dirname9(lock.path));
47496
+ syncDirectory(dirname10(lock.path));
47266
47497
  for (const path of archivedPaths) {
47267
47498
  const before = lstatSync9(path, { throwIfNoEntry: false });
47268
47499
  const bytes = readRegularFile(path, SESSION_LOCK_MAX_BYTES);
@@ -47413,8 +47644,8 @@ var init_selection_cache = __esm(() => {
47413
47644
  init_profile_limits();
47414
47645
  SkillSelectionError = class SkillSelectionError extends Error {
47415
47646
  code;
47416
- constructor(code, message) {
47417
- super(message);
47647
+ constructor(code, message, options) {
47648
+ super(message, options);
47418
47649
  this.code = code;
47419
47650
  this.name = "SkillSelectionError";
47420
47651
  }
@@ -47431,7 +47662,7 @@ __export(exports_remote_files, {
47431
47662
  decodeRemoteFiles: () => decodeRemoteFiles,
47432
47663
  MAX_REMOTE_FILE_BYTES: () => MAX_REMOTE_FILE_BYTES
47433
47664
  });
47434
- import { createHash as createHash9 } from "crypto";
47665
+ import { createHash as createHash10 } from "crypto";
47435
47666
  function describeRemoteFiles(files) {
47436
47667
  if (files.length > 10)
47437
47668
  throw new Error("At most 10 input files are supported");
@@ -47448,7 +47679,7 @@ function describeRemoteFiles(files) {
47448
47679
  });
47449
47680
  }
47450
47681
  function sha256(bytes) {
47451
- return createHash9("sha256").update(bytes).digest("hex");
47682
+ return createHash10("sha256").update(bytes).digest("hex");
47452
47683
  }
47453
47684
  async function readBoundedResponse(response, maximum, signal) {
47454
47685
  if (!Number.isSafeInteger(maximum) || maximum < 0 || maximum > MAX_REMOTE_FILE_BYTES)
@@ -47524,6 +47755,10 @@ function identifier(value) {
47524
47755
  function invalid() {
47525
47756
  throw new Error("The Skills API returned an invalid profile response");
47526
47757
  }
47758
+ function unavailable(error61, message) {
47759
+ const name = error61?.name;
47760
+ return new SkillSelectionError("SKILLS_API_UNAVAILABLE", message, name === "AbortError" || name === "TimeoutError" ? { cause: new DOMException("The Skills API request was cut short", name) } : undefined);
47761
+ }
47527
47762
  function validateSelection2(value) {
47528
47763
  if (!object6(value) || !identifier(value.slug) || typeof value.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/.test(value.version) || value.version.includes("..") || typeof value.bundleDigest !== "string" || !/^sha256:[a-f0-9]{64}$/.test(value.bundleDigest))
47529
47764
  invalid();
@@ -47571,8 +47806,8 @@ class HttpProfileClient {
47571
47806
  ...init.headers
47572
47807
  }
47573
47808
  });
47574
- } catch {
47575
- throw new SkillSelectionError("SKILLS_API_UNAVAILABLE", "Unable to reach the configured Skills API");
47809
+ } catch (error61) {
47810
+ throw unavailable(error61, "Unable to reach the configured Skills API");
47576
47811
  }
47577
47812
  if (!response.ok) {
47578
47813
  response.body?.cancel().catch(() => {});
@@ -47589,7 +47824,9 @@ class HttpProfileClient {
47589
47824
  async read(response, limit = MAX_PROFILE_DOCUMENT_BYTES) {
47590
47825
  try {
47591
47826
  return JSON.parse(new TextDecoder().decode(await readBoundedResponse(response, limit, this.signal)));
47592
- } catch {
47827
+ } catch (error61) {
47828
+ if (this.signal?.aborted)
47829
+ throw unavailable(this.signal.reason ?? error61, "The Skills API response was cut short");
47593
47830
  invalid();
47594
47831
  }
47595
47832
  }
@@ -47679,17 +47916,17 @@ var init_profile_client = __esm(() => {
47679
47916
  });
47680
47917
 
47681
47918
  // src/lib/preparation-process.ts
47682
- function capturePreparationProcess(child, platform = process.platform, signalGroup = (pid, signal) => process.kill(pid, signal)) {
47919
+ function capturePreparationProcess(child2, platform = process.platform, signalGroup = (pid, signal) => process.kill(pid, signal)) {
47683
47920
  let spawnedPid;
47684
47921
  try {
47685
- spawnedPid = child.pid;
47922
+ spawnedPid = child2.pid;
47686
47923
  } catch {}
47687
47924
  const groupId = typeof spawnedPid === "number" && Number.isSafeInteger(spawnedPid) && spawnedPid > 1 ? spawnedPid : undefined;
47688
47925
  const canSignalGroup = platform !== "win32" && groupId !== undefined;
47689
47926
  const killLiveChild = () => {
47690
- if (child.exitCode === null && child.signalCode === null) {
47927
+ if (child2.exitCode === null && child2.signalCode === null) {
47691
47928
  try {
47692
- child.kill("SIGKILL");
47929
+ child2.kill("SIGKILL");
47693
47930
  } catch {}
47694
47931
  }
47695
47932
  };
@@ -47952,28 +48189,6 @@ function isCodexLocalStdioMcpServer(name, server) {
47952
48189
  }
47953
48190
  }
47954
48191
 
47955
- // src/lib/codex-native-compatibility.ts
47956
- function supportsCodexNativeCapability(version2, capability) {
47957
- return typeof version2 === "string" && Object.hasOwn(MEASURED_CODEX_CAPABILITIES, version2) && MEASURED_CODEX_CAPABILITIES[version2].includes(capability);
47958
- }
47959
- var MEASURED_CODEX_CAPABILITIES, SUPPORTED_CODEX_HOOK_VERSIONS;
47960
- var init_codex_native_compatibility = __esm(() => {
47961
- MEASURED_CODEX_CAPABILITIES = {
47962
- "codex-cli 0.153.0": ["hooks"],
47963
- "codex-cli 0.154.0": ["hooks"],
47964
- "codex-cli 0.155.0": ["hooks"],
47965
- "codex-cli 0.155.1": ["hooks"],
47966
- "codex-cli 0.156.1": ["hooks"],
47967
- "codex-cli 0.157.0": ["hooks"],
47968
- "codex-cli 0.157.1": ["hooks"],
47969
- "codex-cli 0.158.0": ["hooks"],
47970
- "codex-cli 0.159.0": ["hooks"],
47971
- "codex-cli 0.159.2": ["hooks", "qualified-skill-catalog"],
47972
- "codex-cli 0.160.0": ["hooks", "qualified-skill-catalog"]
47973
- };
47974
- SUPPORTED_CODEX_HOOK_VERSIONS = Object.freeze(Object.keys(MEASURED_CODEX_CAPABILITIES).filter((version2) => supportsCodexNativeCapability(version2, "hooks")));
47975
- });
47976
-
47977
48192
  // src/lib/codex-hook-rpc.ts
47978
48193
  var init_codex_hook_rpc = __esm(() => {
47979
48194
  init_codex_corpus_write();
@@ -47994,7 +48209,7 @@ var init_codex_native_skill_catalog = __esm(() => {
47994
48209
  });
47995
48210
 
47996
48211
  // src/lib/codex-plugin-skill-controls.ts
47997
- import { basename as basename5, dirname as dirname10, join as join17, relative as relative4, resolve as resolve9, sep as sep5 } from "path";
48212
+ import { basename as basename6, dirname as dirname11, join as join17, relative as relative4, resolve as resolve10, sep as sep5 } from "path";
47998
48213
  import { lstatSync as lstatSync11, readdirSync as readdirSync6, readlinkSync as readlinkSync3, realpathSync as realpathSync3 } from "fs";
47999
48214
  function refuse() {
48000
48215
  throw new Error("CODEX_NATIVE_SKILL_IDENTITY_UNSUPPORTED: review native plugin names and hook controls");
@@ -48058,7 +48273,7 @@ function mcpControls(path, read) {
48058
48273
  function isBundledCleanupHooks(root, namespace, value) {
48059
48274
  const object7 = (v) => Boolean(v && typeof v === "object" && !Array.isArray(v));
48060
48275
  const exactKeys = (v, keys) => Object.keys(v).length === keys.length && keys.every((key) => Object.hasOwn(v, key));
48061
- if (basename5(dirname10(root)) !== namespace || basename5(dirname10(dirname10(root))) !== "openai-bundled")
48276
+ if (basename6(dirname11(root)) !== namespace || basename6(dirname11(dirname11(root))) !== "openai-bundled")
48062
48277
  return false;
48063
48278
  const server = namespace === "unified-computer-use" ? "cua_repl" : ["browser", "chrome", "chrome-dev", "chrome-internal", "computer-use"].includes(namespace) ? "node_repl" : undefined;
48064
48279
  if (!server || !object7(value) || !exactKeys(value, ["hooks"]) || !object7(value.hooks))
@@ -48092,7 +48307,7 @@ function rootControls(root, read) {
48092
48307
  }
48093
48308
  if (!manifest || typeof manifest !== "object" || Array.isArray(manifest) || !identifier2(manifest.name))
48094
48309
  refuse();
48095
- const cacheVersion = basename5(root), declaredVersion = manifest.version === undefined ? "" : typeof manifest.version === "string" ? manifest.version.trim() : null;
48310
+ const cacheVersion = basename6(root), declaredVersion = manifest.version === undefined ? "" : typeof manifest.version === "string" ? manifest.version.trim() : null;
48096
48311
  if (declaredVersion === null || (declaredVersion ? declaredVersion !== cacheVersion : cacheVersion !== CODEX_DEFAULT_AGENT_PLUGIN_VERSION))
48097
48312
  refuse();
48098
48313
  if (manifest.hooks !== undefined && !isBundledCleanupHooks(root, manifest.name, manifest.hooks) || manifest.commands !== undefined || manifest.mcpServers !== undefined && manifest.mcpServers !== "./.mcp.json" || manifest.apps !== undefined && manifest.apps !== "./.app.json" || lstatSync11(join17(root, "hooks"), { throwIfNoEntry: false }))
@@ -48116,13 +48331,13 @@ function rootControls(root, read) {
48116
48331
  function reviewedDisabledCodexPluginParent(cache, parent, controls, rules) {
48117
48332
  try {
48118
48333
  const parts = relative4(cache, parent).split(sep5), enrolled = controls.filter((control) => control.pluginParent === parent);
48119
- if (resolve9(parent) !== parent || parts.length !== 2 || parts.some((part) => !identifier2(part)) || !enrolled.length || !Array.isArray(rules))
48334
+ if (resolve10(parent) !== parent || parts.length !== 2 || parts.some((part) => !identifier2(part)) || !enrolled.length || !Array.isArray(rules))
48120
48335
  return false;
48121
- for (let cursor = parent;; cursor = dirname10(cursor)) {
48336
+ for (let cursor = parent;; cursor = dirname11(cursor)) {
48122
48337
  const stat = lstatSync11(cursor, { throwIfNoEntry: false });
48123
48338
  if (stat && (!stat.isDirectory() || stat.isSymbolicLink()))
48124
48339
  return false;
48125
- if (dirname10(cursor) === cursor)
48340
+ if (dirname11(cursor) === cursor)
48126
48341
  break;
48127
48342
  }
48128
48343
  return enrolled.every((control) => control.namespace === parts[1] && control.pluginId === `${parts[1]}@${parts[0]}` && remotePluginIdentifier(control.remotePluginId) && control.skillsOnly === true && !control.appSha256 && !control.mcpSha256 && control.name.startsWith(control.namespace + ":") && /^[a-f0-9]{64}$/.test(control.manifestSha256) && rules.some((rule) => typeof rule?.name === "string" && rule.name.trim() === control.name && rule.enabled === false) && !rules.some((rule) => (typeof rule?.name === "string" && rule.name.trim() === control.name || typeof rule?.path === "string" && (rule.path === parent || rule.path.startsWith(parent + sep5))) && rule.enabled !== false));
@@ -48135,14 +48350,14 @@ function absentDisabledCodexPluginParent(cache, parent, controls, rules) {
48135
48350
  }
48136
48351
  function reviewedRetiredCodexRoot(cache, root, controls, rules, read, allowAbsent = false) {
48137
48352
  try {
48138
- const parent = dirname10(root), parts = relative4(cache, parent).split(sep5), enrolled = controls.filter((control) => control.pluginParent === parent);
48139
- if (resolve9(root) !== root || parts.length !== 2 || parts.some((part) => !identifier2(part)) || !basename5(root) || basename5(root) === "latest" || !enrolled.length || !Array.isArray(rules))
48353
+ const parent = dirname11(root), parts = relative4(cache, parent).split(sep5), enrolled = controls.filter((control) => control.pluginParent === parent);
48354
+ if (resolve10(root) !== root || parts.length !== 2 || parts.some((part) => !identifier2(part)) || !basename6(root) || basename6(root) === "latest" || !enrolled.length || !Array.isArray(rules))
48140
48355
  return false;
48141
- for (let cursor = root;; cursor = dirname10(cursor)) {
48356
+ for (let cursor = root;; cursor = dirname11(cursor)) {
48142
48357
  const stat = lstatSync11(cursor, { throwIfNoEntry: false });
48143
48358
  if (stat && (!stat.isDirectory() || stat.isSymbolicLink()))
48144
48359
  return false;
48145
- if (dirname10(cursor) === cursor)
48360
+ if (dirname11(cursor) === cursor)
48146
48361
  break;
48147
48362
  }
48148
48363
  if (!enrolled.every((control) => control.namespace === parts[1] && control.pluginId === `${parts[1]}@${parts[0]}` && remotePluginIdentifier(control.remotePluginId) && control.skillsOnly === true && !control.appSha256 && !control.mcpSha256 && control.name.startsWith(control.namespace + ":") && /^[a-f0-9]{64}$/.test(control.manifestSha256) && rules.some((rule) => typeof rule?.name === "string" && rule.name.trim() === control.name && rule.enabled === false) && !rules.some((rule) => (typeof rule?.name === "string" && rule.name.trim() === control.name || typeof rule?.path === "string" && (rule.path === parent || rule.path === root || rule.path.startsWith(root + sep5))) && rule.enabled !== false)))
@@ -48189,8 +48404,8 @@ function reviewedCodexPluginCapabilitiesUnchanged(cache, controls, read, rules)
48189
48404
  for (const name of names) {
48190
48405
  let root = join17(parent, name), stat = lstatSync11(root);
48191
48406
  if (stat.isSymbolicLink()) {
48192
- const target = resolve9(parent, readlinkSync3(root));
48193
- if (name !== "latest" || dirname10(target) !== parent || !lstatSync11(target).isDirectory() || realpathSync3(target) !== target)
48407
+ const target = resolve10(parent, readlinkSync3(root));
48408
+ if (name !== "latest" || dirname11(target) !== parent || !lstatSync11(target).isDirectory() || realpathSync3(target) !== target)
48194
48409
  return false;
48195
48410
  root = target;
48196
48411
  stat = lstatSync11(root);
@@ -48210,7 +48425,7 @@ function reviewedCodexPluginCapabilitiesUnchanged(cache, controls, read, rules)
48210
48425
  function sourceInputUnchanged(input2, cache, read) {
48211
48426
  try {
48212
48427
  const parts = relative4(cache, input2.pluginParent).split(sep5);
48213
- if (parts.length !== 2 || parts.some((part) => !identifier2(part)) || parts[1] !== input2.namespace || input2.pluginId !== `${parts[1]}@${parts[0]}` || !codexPluginSourceIsConfigControlled({ id: input2.pluginId, sourceType: "local", sourceSha256: input2.sourceSha256 }) || input2.sourceSha256 !== hashNativeJsonControls(JSON.stringify({ type: "local", path: input2.sourceRoot })) || resolve9(input2.sourceRoot) !== input2.sourceRoot || !lstatSync11(input2.sourceRoot).isDirectory() || realpathSync3(input2.sourceRoot) !== input2.sourceRoot || input2.sourceRoot === cache || input2.sourceRoot.startsWith(cache + sep5) || cache.startsWith(input2.sourceRoot + sep5))
48428
+ if (parts.length !== 2 || parts.some((part) => !identifier2(part)) || parts[1] !== input2.namespace || input2.pluginId !== `${parts[1]}@${parts[0]}` || !codexPluginSourceIsConfigControlled({ id: input2.pluginId, sourceType: "local", sourceSha256: input2.sourceSha256 }) || input2.sourceSha256 !== hashNativeJsonControls(JSON.stringify({ type: "local", path: input2.sourceRoot })) || resolve10(input2.sourceRoot) !== input2.sourceRoot || !lstatSync11(input2.sourceRoot).isDirectory() || realpathSync3(input2.sourceRoot) !== input2.sourceRoot || input2.sourceRoot === cache || input2.sourceRoot.startsWith(cache + sep5) || cache.startsWith(input2.sourceRoot + sep5))
48214
48429
  return false;
48215
48430
  const path = join17(input2.sourceRoot, ".codex-plugin/plugin.json"), stat = lstatSync11(path);
48216
48431
  if (!stat.isFile() || stat.size > 1024 * 1024 || realpathSync3(path) !== path)
@@ -48248,8 +48463,8 @@ var init_codex_native_skill_policy = __esm(() => {
48248
48463
  });
48249
48464
 
48250
48465
  // src/lib/codex-settings-witness-v1.ts
48251
- import { createHash as createHash10 } from "crypto";
48252
- function need3(value) {
48466
+ import { createHash as createHash11 } from "crypto";
48467
+ function need4(value) {
48253
48468
  if (!value)
48254
48469
  throw new Error("Invalid Codex settings witness");
48255
48470
  }
@@ -48264,14 +48479,14 @@ function numericTokens(text2) {
48264
48479
  continue;
48265
48480
  }
48266
48481
  if (char === '"' || char === "'") {
48267
- const quote = char, triple = text2.slice(at, at + 3) === quote.repeat(3);
48482
+ const quote2 = char, triple = text2.slice(at, at + 3) === quote2.repeat(3);
48268
48483
  at += triple ? 3 : 1;
48269
48484
  while (at < text2.length) {
48270
- if (quote === '"' && text2[at] === "\\") {
48485
+ if (quote2 === '"' && text2[at] === "\\") {
48271
48486
  at += 2;
48272
48487
  continue;
48273
48488
  }
48274
- if (text2.slice(at, at + (triple ? 3 : 1)) === quote.repeat(triple ? 3 : 1)) {
48489
+ if (text2.slice(at, at + (triple ? 3 : 1)) === quote2.repeat(triple ? 3 : 1)) {
48275
48490
  at += triple ? 3 : 1;
48276
48491
  break;
48277
48492
  }
@@ -48292,8 +48507,8 @@ function numericTokens(text2) {
48292
48507
  }
48293
48508
  return result;
48294
48509
  }
48295
- function canonical4(value, depth = 0, budget2 = { remaining: 65536 }) {
48296
- need3(depth <= 32 && --budget2.remaining >= 0);
48510
+ function canonical5(value, depth = 0, budget2 = { remaining: 65536 }) {
48511
+ need4(depth <= 32 && --budget2.remaining >= 0);
48297
48512
  if (value === null)
48298
48513
  return ["null"];
48299
48514
  if (typeof value === "string")
@@ -48301,20 +48516,20 @@ function canonical4(value, depth = 0, budget2 = { remaining: 65536 }) {
48301
48516
  if (typeof value === "boolean")
48302
48517
  return ["boolean", value];
48303
48518
  if (typeof value === "number") {
48304
- need3(Number.isFinite(value));
48519
+ need4(Number.isFinite(value));
48305
48520
  return ["number", String(value)];
48306
48521
  }
48307
48522
  if (value instanceof Date) {
48308
- need3(Number.isFinite(value.getTime()));
48523
+ need4(Number.isFinite(value.getTime()));
48309
48524
  return ["date", value.toISOString()];
48310
48525
  }
48311
48526
  if (Array.isArray(value))
48312
- return ["array", value.map((child) => canonical4(child, depth + 1, budget2))];
48313
- need3(value && typeof value === "object");
48314
- return ["object", Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, child]) => [key, canonical4(child, depth + 1, budget2)])];
48527
+ return ["array", value.map((child2) => canonical5(child2, depth + 1, budget2))];
48528
+ need4(value && typeof value === "object");
48529
+ return ["object", Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, child2]) => [key, canonical5(child2, depth + 1, budget2)])];
48315
48530
  }
48316
48531
  function hashCodexSettingsReplacement(text2, budget2 = { remaining: 256 * 1024 * 1024 }) {
48317
- need3(Buffer.byteLength(text2) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text2));
48532
+ need4(Buffer.byteLength(text2) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text2));
48318
48533
  budget2.remaining -= Buffer.byteLength(text2);
48319
48534
  let config2;
48320
48535
  try {
@@ -48322,23 +48537,23 @@ function hashCodexSettingsReplacement(text2, budget2 = { remaining: 256 * 1024 *
48322
48537
  } catch {
48323
48538
  throw new Error("Invalid Codex settings witness");
48324
48539
  }
48325
- need3(config2 && typeof config2 === "object" && !Array.isArray(config2));
48540
+ need4(config2 && typeof config2 === "object" && !Array.isArray(config2));
48326
48541
  if (Object.hasOwn(config2, "model")) {
48327
- need3(typeof config2.model === "string" && /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$/.test(config2.model));
48542
+ need4(typeof config2.model === "string" && /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$/.test(config2.model));
48328
48543
  delete config2.model;
48329
48544
  }
48330
48545
  for (const [key, values] of [["model_reasoning_effort", EFFORT], ["model_verbosity", VERBOSITY]])
48331
48546
  if (Object.hasOwn(config2, key)) {
48332
- need3(typeof config2[key] === "string" && values.has(config2[key]));
48547
+ need4(typeof config2[key] === "string" && values.has(config2[key]));
48333
48548
  delete config2[key];
48334
48549
  }
48335
- return sha(`hasna.skills.codex-settings.v1\x00${JSON.stringify([canonical4(config2), numericTokens(text2)])}`);
48550
+ return sha(`hasna.skills.codex-settings.v1\x00${JSON.stringify([canonical5(config2), numericTokens(text2)])}`);
48336
48551
  }
48337
48552
  function captureCodexSettings(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
48338
48553
  const text2 = readNativeSettingsWitnessFile(path, budget2, "config.toml");
48339
48554
  return { path, hashMode: "codex-settings-v1", sha256: hashCodexSettingsReplacement(text2) };
48340
48555
  }
48341
- var sha = (text2) => createHash10("sha256").update(text2).digest("hex"), EFFORT, VERBOSITY;
48556
+ var sha = (text2) => createHash11("sha256").update(text2).digest("hex"), EFFORT, VERBOSITY;
48342
48557
  var init_codex_settings_witness_v1 = __esm(() => {
48343
48558
  init_claude_settings_witness();
48344
48559
  EFFORT = new Set(["none", "minimal", "low", "medium", "high", "xhigh"]);
@@ -48411,9 +48626,9 @@ function projectRegularCodexMcp(config2, source) {
48411
48626
  var init_codex_mcp_discovery_projection = () => {};
48412
48627
 
48413
48628
  // src/lib/codex-settings-witness.ts
48414
- import { createHash as createHash11 } from "crypto";
48629
+ import { createHash as createHash12 } from "crypto";
48415
48630
  import { isDeepStrictEqual as isDeepStrictEqual3 } from "util";
48416
- function need4(value) {
48631
+ function need5(value) {
48417
48632
  if (!value)
48418
48633
  throw new Error("Invalid Codex settings witness");
48419
48634
  }
@@ -48434,14 +48649,14 @@ function numericTokens2(text2) {
48434
48649
  continue;
48435
48650
  }
48436
48651
  if (char === '"' || char === "'") {
48437
- const quote = char, triple = text2.slice(at, at + 3) === quote.repeat(3);
48652
+ const quote2 = char, triple = text2.slice(at, at + 3) === quote2.repeat(3);
48438
48653
  at += triple ? 3 : 1;
48439
48654
  while (at < text2.length) {
48440
- if (quote === '"' && text2[at] === "\\") {
48655
+ if (quote2 === '"' && text2[at] === "\\") {
48441
48656
  at += 2;
48442
48657
  continue;
48443
48658
  }
48444
- if (text2.slice(at, at + (triple ? 3 : 1)) === quote.repeat(triple ? 3 : 1)) {
48659
+ if (text2.slice(at, at + (triple ? 3 : 1)) === quote2.repeat(triple ? 3 : 1)) {
48445
48660
  at += triple ? 3 : 1;
48446
48661
  break;
48447
48662
  }
@@ -48462,8 +48677,8 @@ function numericTokens2(text2) {
48462
48677
  }
48463
48678
  return result.sort();
48464
48679
  }
48465
- function canonical5(value, depth = 0, budget2 = { remaining: 65536 }) {
48466
- need4(depth <= 32 && --budget2.remaining >= 0);
48680
+ function canonical6(value, depth = 0, budget2 = { remaining: 65536 }) {
48681
+ need5(depth <= 32 && --budget2.remaining >= 0);
48467
48682
  if (value === null)
48468
48683
  return ["null"];
48469
48684
  if (typeof value === "string")
@@ -48471,17 +48686,17 @@ function canonical5(value, depth = 0, budget2 = { remaining: 65536 }) {
48471
48686
  if (typeof value === "boolean")
48472
48687
  return ["boolean", value];
48473
48688
  if (typeof value === "number") {
48474
- need4(Number.isFinite(value));
48689
+ need5(Number.isFinite(value));
48475
48690
  return ["number", String(value)];
48476
48691
  }
48477
48692
  if (isDate(value)) {
48478
- need4(Number.isFinite(value.getTime()));
48693
+ need5(Number.isFinite(value.getTime()));
48479
48694
  return ["date", value.toISOString()];
48480
48695
  }
48481
48696
  if (Array.isArray(value))
48482
- return ["array", value.map((child) => canonical5(child, depth + 1, budget2))];
48483
- need4(isRecord3(value));
48484
- return ["object", Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, child]) => [key, canonical5(child, depth + 1, budget2)])];
48697
+ return ["array", value.map((child2) => canonical6(child2, depth + 1, budget2))];
48698
+ need5(isRecord3(value));
48699
+ return ["object", Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, child2]) => [key, canonical6(child2, depth + 1, budget2)])];
48485
48700
  }
48486
48701
  function normalize2(config2, version2 = 2) {
48487
48702
  if (isRecord3(config2.hooks)) {
@@ -48523,15 +48738,15 @@ function inference(target, version2) {
48523
48738
  if (Object.hasOwn(target, key)) {
48524
48739
  const value = target[key];
48525
48740
  if (key === "model")
48526
- need4(typeof value === "string" && MODEL.test(value));
48741
+ need5(typeof value === "string" && MODEL.test(value));
48527
48742
  else if (key === "personality")
48528
- need4(typeof value === "string" && ["none", "friendly", "pragmatic"].includes(value));
48743
+ need5(typeof value === "string" && ["none", "friendly", "pragmatic"].includes(value));
48529
48744
  else if (version2 >= 3 && key !== "model_verbosity") {
48530
- need4(typeof value === "string" && value.length <= 128 && !/[\x00-\x1f\x7f]/.test(value));
48745
+ need5(typeof value === "string" && value.length <= 128 && !/[\x00-\x1f\x7f]/.test(value));
48531
48746
  if (key !== "service_tier")
48532
- need4(value.length > 0);
48747
+ need5(value.length > 0);
48533
48748
  } else
48534
- need4(typeof value === "string" && (key === "model_reasoning_effort" ? EFFORT2.has(value) : VERBOSITY2.has(value)));
48749
+ need5(typeof value === "string" && (key === "model_reasoning_effort" ? EFFORT2.has(value) : VERBOSITY2.has(value)));
48535
48750
  delete target[key];
48536
48751
  }
48537
48752
  }
@@ -48564,14 +48779,14 @@ function projectModelAvailabilityNux(config2, text2) {
48564
48779
  continue;
48565
48780
  }
48566
48781
  if (char === '"' || char === "'") {
48567
- const quote = char;
48782
+ const quote2 = char;
48568
48783
  at++;
48569
48784
  while (at < span.length) {
48570
- if (quote === '"' && span[at] === "\\") {
48785
+ if (quote2 === '"' && span[at] === "\\") {
48571
48786
  at += 2;
48572
48787
  continue;
48573
48788
  }
48574
- if (span[at++] === quote)
48789
+ if (span[at++] === quote2)
48575
48790
  break;
48576
48791
  }
48577
48792
  continue;
@@ -48651,14 +48866,14 @@ function settingsDigest2(text2, version2 = 2) {
48651
48866
  } catch {
48652
48867
  throw new Error("Invalid Codex settings witness");
48653
48868
  }
48654
- need4(isRecord3(config2));
48869
+ need5(isRecord3(config2));
48655
48870
  const mcp = version2 >= 3 ? projectRegularCodexMcp(config2, text2) : { config: config2, numericSource: text2 };
48656
48871
  const projected = version2 === 4 ? projectModelAvailabilityNux(mcp.config, mcp.numericSource) : mcp;
48657
48872
  normalize2(projected.config, version2);
48658
- return sha2(`hasna.skills.codex-settings.v${version2}\x00${JSON.stringify([canonical5(projected.config), numericTokens2(projected.numericSource)])}`);
48873
+ return sha2(`hasna.skills.codex-settings.v${version2}\x00${JSON.stringify([canonical6(projected.config), numericTokens2(projected.numericSource)])}`);
48659
48874
  }
48660
48875
  function hashCodexSettingsReplacementV2(text2, budget2 = { remaining: 256 * 1024 * 1024 }) {
48661
- need4(Buffer.byteLength(text2) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text2));
48876
+ need5(Buffer.byteLength(text2) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text2));
48662
48877
  budget2.remaining -= Buffer.byteLength(text2);
48663
48878
  return settingsDigest2(text2);
48664
48879
  }
@@ -48667,7 +48882,7 @@ function captureCodexSettingsV2(path, budget2 = { remaining: 256 * 1024 * 1024 }
48667
48882
  return { path, hashMode: "codex-settings-v2", sha256: settingsDigest2(text2) };
48668
48883
  }
48669
48884
  function hashCodexSettingsReplacementV3(text2, budget2 = { remaining: 256 * 1024 * 1024 }) {
48670
- need4(Buffer.byteLength(text2) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text2));
48885
+ need5(Buffer.byteLength(text2) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text2));
48671
48886
  budget2.remaining -= Buffer.byteLength(text2);
48672
48887
  return settingsDigest2(text2, 3);
48673
48888
  }
@@ -48675,14 +48890,14 @@ function captureCodexSettingsV3(path, budget2 = { remaining: 256 * 1024 * 1024 }
48675
48890
  return { path, hashMode: "codex-settings-v3", sha256: settingsDigest2(readNativeSettingsWitnessFile(path, budget2, "config.toml"), 3) };
48676
48891
  }
48677
48892
  function hashCodexSettingsReplacementV4(text2, budget2 = { remaining: 256 * 1024 * 1024 }) {
48678
- need4(Buffer.byteLength(text2) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text2));
48893
+ need5(Buffer.byteLength(text2) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text2));
48679
48894
  budget2.remaining -= Buffer.byteLength(text2);
48680
48895
  return settingsDigest2(text2, 4);
48681
48896
  }
48682
48897
  function captureCodexSettingsV4(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
48683
48898
  return { path, hashMode: "codex-settings-v4", sha256: settingsDigest2(readNativeSettingsWitnessFile(path, budget2, "config.toml"), 4) };
48684
48899
  }
48685
- var sha2 = (text2) => createHash11("sha256").update(text2).digest("hex"), EFFORT2, VERBOSITY2, MODEL, CODEX_DISCOVERY_PROJECTION_FIELDS, INFERENCE;
48900
+ var sha2 = (text2) => createHash12("sha256").update(text2).digest("hex"), EFFORT2, VERBOSITY2, MODEL, CODEX_DISCOVERY_PROJECTION_FIELDS, INFERENCE;
48686
48901
  var init_codex_settings_witness = __esm(() => {
48687
48902
  init_codex_settings_witness_v1();
48688
48903
  init_codex_settings_witness_v1();
@@ -48698,8 +48913,8 @@ var init_codex_settings_witness = __esm(() => {
48698
48913
  // src/lib/managed-policy.ts
48699
48914
  import { closeSync as closeSync9, constants as constants6, fstatSync as fstatSync9, lstatSync as lstatSync12, openSync as openSync9, readSync as readSync5 } from "fs";
48700
48915
  import { join as join18 } from "path";
48701
- function refusal(reason = "is unreadable") {
48702
- return new SkillSelectionError("INVALID_AGENT_POLICY", `The Skills agent loading policy ${reason}; refusing legacy fallback.`);
48916
+ function refusal(reason2 = "is unreadable") {
48917
+ return new SkillSelectionError("INVALID_AGENT_POLICY", `The Skills agent loading policy ${reason2}; refusing legacy fallback.`);
48703
48918
  }
48704
48919
  function parseManagedSkillPolicy(text2) {
48705
48920
  if (Buffer.byteLength(text2) > AGENT_POLICY_LIMITS.bytes)
@@ -48775,7 +48990,7 @@ var init_managed_policy = __esm(() => {
48775
48990
  });
48776
48991
 
48777
48992
  // src/lib/agent-bridge.ts
48778
- import { createHash as createHash12 } from "crypto";
48993
+ import { createHash as createHash13 } from "crypto";
48779
48994
  var CLI_BRIDGE_VERSION = 1, markdown = `---
48780
48995
  name: skills-cli
48781
48996
  description: Discover, load, author, and run versioned skills through the Skills CLI when a task needs reusable instructions or an executable skill.
@@ -48791,7 +49006,7 @@ Use the Skills CLI as the skill authority for this station.
48791
49006
  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.
48792
49007
  `, CLI_BRIDGE_DIGEST, CLI_BRIDGE_FILES;
48793
49008
  var init_agent_bridge = __esm(() => {
48794
- CLI_BRIDGE_DIGEST = createHash12("sha256").update(markdown).digest("hex");
49009
+ CLI_BRIDGE_DIGEST = createHash13("sha256").update(markdown).digest("hex");
48795
49010
  CLI_BRIDGE_FILES = Object.freeze({
48796
49011
  "SKILL.md": markdown,
48797
49012
  ".hasna-skills.json": `${JSON.stringify({ managedBy: "@hasna/skills", kind: "cli-bridge", version: CLI_BRIDGE_VERSION, protocol: "selection-v1", contentSha256: CLI_BRIDGE_DIGEST }, null, 2)}
@@ -48804,28 +49019,28 @@ var init_agent_codex = () => {};
48804
49019
 
48805
49020
  // src/lib/agent-sumi.ts
48806
49021
  import { existsSync as existsSync8, lstatSync as lstatSync13, realpathSync as realpathSync4 } from "fs";
48807
- import { join as join19, resolve as resolve10 } from "path";
49022
+ import { join as join19, resolve as resolve11 } from "path";
48808
49023
  function sumiConfigDirectory(home, env = process.env) {
48809
49024
  for (const key of ["SUMI_CONFIG", "SUMI_CONFIG_CONTENT"])
48810
49025
  if (env[key] !== undefined)
48811
49026
  throw new Error(`Sumi ${key} requires a dedicated discovery adapter; unset it before Skills integration`);
48812
49027
  const selected = (key) => env[key]?.trim() ? env[key] : undefined;
48813
- const expand = (value) => resolve10(value === "~" ? home : value.startsWith("~/") ? join19(home, value.slice(2)) : value);
49028
+ const expand = (value) => resolve11(value === "~" ? home : value.startsWith("~/") ? join19(home, value.slice(2)) : value);
48814
49029
  const explicit = selected("SUMI_CONFIG_DIR");
48815
49030
  const xdg = selected("XDG_CONFIG_HOME");
48816
49031
  const custom2 = selected("SUMI_HOME");
48817
- const canonical6 = explicit ? expand(explicit) : xdg ? join19(expand(xdg), "sumi") : join19(custom2 ? expand(custom2) : join19(home, ".hasna-internal/sumi"), "config");
49032
+ const canonical7 = explicit ? expand(explicit) : xdg ? join19(expand(xdg), "sumi") : join19(custom2 ? expand(custom2) : join19(home, ".hasna-internal/sumi"), "config");
48818
49033
  if (explicit || xdg || custom2)
48819
- return canonical6;
49034
+ return canonical7;
48820
49035
  const legacy = join19(home, ".config/sumi");
48821
- const a = lstatSync13(canonical6, { throwIfNoEntry: false }), b = lstatSync13(legacy, { throwIfNoEntry: false });
48822
- if (a && b && realpathSync4(canonical6) !== realpathSync4(legacy))
49036
+ const a = lstatSync13(canonical7, { throwIfNoEntry: false }), b = lstatSync13(legacy, { throwIfNoEntry: false });
49037
+ if (a && b && realpathSync4(canonical7) !== realpathSync4(legacy))
48823
49038
  throw new Error("Sumi config roots conflict; complete native home adoption before Skills integration");
48824
- const path = a ? canonical6 : b ? legacy : canonical6;
49039
+ const path = a ? canonical7 : b ? legacy : canonical7;
48825
49040
  if (!existsSync8(path))
48826
49041
  return path;
48827
49042
  const physical = realpathSync4(path);
48828
- if ((a?.isSymbolicLink() || b?.isSymbolicLink()) && ![canonical6, legacy].includes(physical))
49043
+ if ((a?.isSymbolicLink() || b?.isSymbolicLink()) && ![canonical7, legacy].includes(physical))
48829
49044
  throw new Error("Sumi config alias must resolve to its canonical or legacy root");
48830
49045
  return physical;
48831
49046
  }
@@ -48835,19 +49050,22 @@ function sumiConfigPath(home) {
48835
49050
  var init_agent_sumi = () => {};
48836
49051
 
48837
49052
  // src/lib/codex-hook-trust-files.ts
48838
- import { closeSync as closeSync10, constants as constants7, fstatSync as fstatSync10, fsyncSync as fsyncSync2, lstatSync as lstatSync14, openSync as openSync10, readSync as readSync6, writeFileSync as writeFileSync4 } from "fs";
48839
- import { createHash as createHash13 } from "crypto";
48840
- import { dirname as dirname11 } from "path";
48841
- function need5(value, code) {
49053
+ import { closeSync as closeSync10, constants as constants7, fstatSync as fstatSync10, fsyncSync as fsyncSync2, lstatSync as lstatSync14, openSync as openSync10, readlinkSync as readlinkSync4, readSync as readSync6, writeFileSync as writeFileSync4 } from "fs";
49054
+ import { createHash as createHash14 } from "crypto";
49055
+ import { dirname as dirname12, isAbsolute as isAbsolute10, resolve as resolve12 } from "path";
49056
+ function need6(value, code) {
48842
49057
  if (!value)
48843
49058
  throw new Error(`CODEX_HOOK_TRUST_${code}`);
48844
49059
  }
49060
+ function trustedAncestorOwner(uid) {
49061
+ return BigInt(uid) === 0n || BigInt(uid) === BigInt(process.getuid());
49062
+ }
48845
49063
  function safeParents(file2) {
48846
- for (let p = dirname11(file2);; p = dirname11(p)) {
49064
+ for (let p = dirname12(file2);; p = dirname12(p)) {
48847
49065
  const s = lstatSync14(p);
48848
- need5(s.isDirectory() && !s.isSymbolicLink(), "UNSAFE_PARENT");
48849
- need5((s.mode & 18) === 0 || s.uid === 0 && (s.mode & 512) !== 0, "UNSAFE_PARENT");
48850
- if (dirname11(p) === p)
49066
+ need6(s.isDirectory() && !s.isSymbolicLink() && trustedAncestorOwner(s.uid), "UNSAFE_PARENT");
49067
+ need6((s.mode & 18) === 0 || s.uid === 0 && (s.mode & 512) !== 0, "UNSAFE_PARENT");
49068
+ if (dirname12(p) === p)
48851
49069
  break;
48852
49070
  }
48853
49071
  }
@@ -48855,12 +49073,12 @@ function snapshot(file2, privateFile = false, options = {}) {
48855
49073
  const readOnlyPackage = options.readOnlyPackage === true && !privateFile;
48856
49074
  safeParents(file2);
48857
49075
  const initial = lstatSync14(file2, { bigint: true });
48858
- 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");
48859
- need5(initial.size <= 8n * 1024n * 1024n, "FILE_BOUND");
49076
+ 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");
49077
+ need6(initial.size <= 8n * 1024n * 1024n, "FILE_BOUND");
48860
49078
  const fd = openSync10(file2, constants7.O_RDONLY | constants7.O_NOFOLLOW | constants7.O_NONBLOCK);
48861
49079
  try {
48862
49080
  const before = fstatSync10(fd, { bigint: true });
48863
- need5(sameStat(initial, before), "INPUT_CHANGED");
49081
+ need6(sameStat(initial, before), "INPUT_CHANGED");
48864
49082
  const bytes = Buffer.alloc(Number(before.size) + 1);
48865
49083
  let length = 0;
48866
49084
  while (length < bytes.length) {
@@ -48869,16 +49087,16 @@ function snapshot(file2, privateFile = false, options = {}) {
48869
49087
  break;
48870
49088
  length += n2;
48871
49089
  }
48872
- need5(length === Number(before.size) && sameStat(before, fstatSync10(fd, { bigint: true })) && sameStat(before, lstatSync14(file2, { bigint: true })), "INPUT_CHANGED");
49090
+ need6(length === Number(before.size) && sameStat(before, fstatSync10(fd, { bigint: true })) && sameStat(before, lstatSync14(file2, { bigint: true })), "INPUT_CHANGED");
48873
49091
  const content = bytes.subarray(0, length), text2 = new TextDecoder("utf-8", { fatal: true }).decode(content);
48874
- return { file: file2, privateFile, readOnlyPackage, text: text2, bytes: content, stat: before, sha256: createHash13("sha256").update(content).digest("hex") };
49092
+ return { file: file2, privateFile, readOnlyPackage, text: text2, bytes: content, stat: before, sha256: createHash14("sha256").update(content).digest("hex") };
48875
49093
  } finally {
48876
49094
  closeSync10(fd);
48877
49095
  }
48878
49096
  }
48879
49097
  function unchanged2(before) {
48880
49098
  const after = snapshot(before.file, before.privateFile, before.readOnlyPackage ? { readOnlyPackage: true } : {});
48881
- need5(sameStat(before.stat, after.stat) && after.sha256 === before.sha256, "INPUT_CHANGED");
49099
+ need6(sameStat(before.stat, after.stat) && after.sha256 === before.sha256, "INPUT_CHANGED");
48882
49100
  }
48883
49101
  var sameStat = (a, b) => ["dev", "ino", "uid", "nlink", "mode", "size", "mtimeNs", "ctimeNs"].every((key) => a[key] === b[key]);
48884
49102
  var init_codex_hook_trust_files = () => {};
@@ -49620,7 +49838,7 @@ var init_selection_resolver = __esm(() => {
49620
49838
  });
49621
49839
 
49622
49840
  // src/lib/plugin-projection.ts
49623
- import { createHash as createHash14 } from "crypto";
49841
+ import { createHash as createHash15 } from "crypto";
49624
49842
  function pluginRefusal(message) {
49625
49843
  throw new SkillSelectionError("PLUGIN_ADMISSION_REFUSED", message);
49626
49844
  }
@@ -49698,7 +49916,7 @@ function pluginFileWitnesses(entries) {
49698
49916
  return { path: item.path, mode: item.mode, size: item.bytes.byteLength, sha256: pluginHash(item.bytes) };
49699
49917
  });
49700
49918
  }
49701
- var PLUGIN_PROJECTION_LIMITS, pluginHash = (bytes) => createHash14("sha256").update(bytes).digest("hex");
49919
+ var PLUGIN_PROJECTION_LIMITS, pluginHash = (bytes) => createHash15("sha256").update(bytes).digest("hex");
49702
49920
  var init_plugin_projection = __esm(() => {
49703
49921
  init_selection_cache();
49704
49922
  PLUGIN_PROJECTION_LIMITS = Object.freeze({ files: 1024, bytes: 64 * 1024 * 1024, fileBytes: 16 * 1024 * 1024, metadataBytes: 512 * 1024, registrations: 64, history: 128 });
@@ -49706,7 +49924,7 @@ var init_plugin_projection = __esm(() => {
49706
49924
 
49707
49925
  // src/lib/plugin-projection-store.ts
49708
49926
  import { constants as constants8, closeSync as closeSync11, fchmodSync, fstatSync as fstatSync11, fsyncSync as fsyncSync3, linkSync as linkSync2, lstatSync as lstatSync15, mkdirSync as mkdirSync6, openSync as openSync11, opendirSync as opendirSync2, readSync as readSync7, renameSync as renameSync2, rmdirSync as rmdirSync2, rmSync as rmSync2, unlinkSync as unlinkSync3, writeSync as writeSync2 } from "fs";
49709
- import { dirname as dirname12, isAbsolute as isAbsolute9, join as join23, parse as parse10, resolve as resolve11 } from "path";
49927
+ import { dirname as dirname13, isAbsolute as isAbsolute11, join as join23, parse as parse10, resolve as resolve13 } from "path";
49710
49928
  function stat(path) {
49711
49929
  try {
49712
49930
  return lstatSync15(path, { bigint: true });
@@ -49716,8 +49934,8 @@ function stat(path) {
49716
49934
  return pluginRefusal("Cannot inspect plugin filesystem entry");
49717
49935
  }
49718
49936
  }
49719
- function canonical6(path) {
49720
- pluginNeed(typeof path === "string" && path.length <= 8192 && isAbsolute9(path) && resolve11(path) === path && !/[\x00-\x1f\x7f]/.test(path), "Plugin storage paths must be canonical absolute paths");
49937
+ function canonical7(path) {
49938
+ pluginNeed(typeof path === "string" && path.length <= 8192 && isAbsolute11(path) && resolve13(path) === path && !/[\x00-\x1f\x7f]/.test(path), "Plugin storage paths must be canonical absolute paths");
49721
49939
  }
49722
49940
  function owner(stats, system = false) {
49723
49941
  const current = uid();
@@ -49727,8 +49945,8 @@ function same3(left, right, identityOnly = false) {
49727
49945
  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");
49728
49946
  }
49729
49947
  function ancestors(path, create = false) {
49730
- canonical6(path);
49731
- const result = [], parent = dirname12(path), filesystemRoot = parse10(parent).root;
49948
+ canonical7(path);
49949
+ const result = [], parent = dirname13(path), filesystemRoot = parse10(parent).root;
49732
49950
  let current = filesystemRoot;
49733
49951
  for (const segment of ["", ...parent.slice(filesystemRoot.length).split("/").filter(Boolean)]) {
49734
49952
  if (segment)
@@ -49954,7 +50172,7 @@ var init_selected_manifest = __esm(() => {
49954
50172
  });
49955
50173
 
49956
50174
  // src/lib/plugin-admission.ts
49957
- import { isAbsolute as isAbsolute10, join as join24, resolve as resolve12 } from "path";
50175
+ import { isAbsolute as isAbsolute12, join as join24, resolve as resolve14 } from "path";
49958
50176
  function validatePluginTarget(value) {
49959
50177
  pluginKeys(value, ["schemaVersion", "pluginId", "registrations", "native", "resolver"]);
49960
50178
  pluginNeed(value.schemaVersion === 1, "Invalid plugin admission target");
@@ -49964,7 +50182,7 @@ function validatePluginTarget(value) {
49964
50182
  for (const registration of value.registrations) {
49965
50183
  pluginKeys(registration, ["scope", "projectPath"]);
49966
50184
  pluginNeed(registration.scope === "user" || registration.scope === "project", "Unsupported plugin registration scope");
49967
- pluginNeed(registration.scope === "user" ? registration.projectPath === null : typeof registration.projectPath === "string" && isAbsolute10(registration.projectPath) && resolve12(registration.projectPath) === registration.projectPath, "Plugin scope requires its exact project path");
50185
+ pluginNeed(registration.scope === "user" ? registration.projectPath === null : typeof registration.projectPath === "string" && isAbsolute12(registration.projectPath) && resolve14(registration.projectPath) === registration.projectPath, "Plugin scope requires its exact project path");
49968
50186
  const key = JSON.stringify([registration.scope, registration.projectPath]);
49969
50187
  pluginNeed(!scopes.has(key), "Duplicate plugin registration scope");
49970
50188
  scopes.add(key);
@@ -49972,7 +50190,7 @@ function validatePluginTarget(value) {
49972
50190
  for (const key of ["native", "resolver"]) {
49973
50191
  pluginKeys(value[key], key === "native" ? ["version", "executable", "digest"] : ["executable", "digest"]);
49974
50192
  pluginText(value[key].executable);
49975
- pluginNeed(isAbsolute10(value[key].executable) && resolve12(value[key].executable) === value[key].executable, "Plugin executable must have a canonical absolute path");
50193
+ pluginNeed(isAbsolute12(value[key].executable) && resolve14(value[key].executable) === value[key].executable, "Plugin executable must have a canonical absolute path");
49976
50194
  pluginDigest(value[key].digest);
49977
50195
  }
49978
50196
  pluginNeed(["2.1.274", "2.1.276"].includes(value.native.version), "Plugin admission requires a certified Claude command-source runtime (2.1.274 or 2.1.276)");
@@ -50111,7 +50329,7 @@ function validatePlan(value) {
50111
50329
  pluginNeed(identityDigest(plan) === plan.planDigest, "Plugin receipt immutable identity changed");
50112
50330
  }
50113
50331
  function pluginResolverCommand(binding) {
50114
- return `${quote("/bin/sh")} -eu -c ${quote(resolverGuard)} plugin-resolver ${quote(binding.target.resolver.executable)} ${quote(binding.target.resolver.digest)} ${quote(bindingId(binding))}`;
50332
+ return `${quote2("/bin/sh")} -eu -c ${quote2(resolverGuard)} plugin-resolver ${quote2(binding.target.resolver.executable)} ${quote2(binding.target.resolver.digest)} ${quote2(bindingId(binding))}`;
50115
50333
  }
50116
50334
  function pluginBindingPath(storeRoot, id) {
50117
50335
  pluginNeed(/^[a-f0-9]{64}$/.test(id), "Invalid plugin binding identifier");
@@ -50145,7 +50363,7 @@ function readPluginAdmissionReceipt(storeRoot, id, digest) {
50145
50363
  pluginNeed(Number.isFinite(Date.parse(receipt.admittedAt)), "Invalid plugin admission time");
50146
50364
  return receipt;
50147
50365
  }
50148
- var quote = (value) => `'${value.replaceAll("'", "'\\''")}'`, resolverGuard = 'exec 9<"$1"; actual=$(/usr/bin/sha256sum /proc/self/fd/9); actual=${actual%% *}; [ "sha256:$actual" = "$2" ]; exec /proc/self/fd/9 integration plugin resolve --binding "$3"';
50366
+ var quote2 = (value) => `'${value.replaceAll("'", "'\\''")}'`, resolverGuard = 'exec 9<"$1"; actual=$(/usr/bin/sha256sum /proc/self/fd/9); actual=${actual%% *}; [ "sha256:$actual" = "$2" ]; exec /proc/self/fd/9 integration plugin resolve --binding "$3"';
50149
50367
  var init_plugin_admission = __esm(() => {
50150
50368
  init_profile_client();
50151
50369
  init_skill_bundle();
@@ -50158,7 +50376,7 @@ var init_plugin_admission = __esm(() => {
50158
50376
 
50159
50377
  // src/lib/plugin-discovery.ts
50160
50378
  import { closeSync as closeSync12, constants as constants9, fstatSync as fstatSync12, lstatSync as lstatSync16, openSync as openSync12, opendirSync as opendirSync3, readSync as readSync8 } from "fs";
50161
- import { basename as basename6, dirname as dirname13, isAbsolute as isAbsolute11, join as join25, resolve as resolve13 } from "path";
50379
+ import { basename as basename7, dirname as dirname14, isAbsolute as isAbsolute13, join as join25, resolve as resolve15 } from "path";
50162
50380
  function validateManagedPluginWitnesses(value) {
50163
50381
  pluginNeed(Array.isArray(value) && value.length > 0 && value.length <= PLUGIN_PROJECTION_LIMITS.registrations, "Invalid managed plugin witness collection");
50164
50382
  const seen = new Set;
@@ -50167,15 +50385,15 @@ function validateManagedPluginWitnesses(value) {
50167
50385
  pluginNeed(typeof item.bindingId === "string" && /^[a-f0-9]{64}$/.test(item.bindingId) && !seen.has(item.bindingId), "Invalid or duplicate managed plugin witness");
50168
50386
  seen.add(item.bindingId);
50169
50387
  pluginText(item.storeRoot);
50170
- pluginNeed(isAbsolute11(item.storeRoot) && resolve13(item.storeRoot) === item.storeRoot, "Invalid plugin receipt store path");
50388
+ pluginNeed(isAbsolute13(item.storeRoot) && resolve15(item.storeRoot) === item.storeRoot, "Invalid plugin receipt store path");
50171
50389
  }
50172
50390
  }
50173
50391
  function safe3(path) {
50174
50392
  pluginText(path);
50175
- pluginNeed(isAbsolute11(path) && resolve13(path) === path, "Invalid plugin registry path");
50176
- for (let at = path;; at = dirname13(at)) {
50393
+ pluginNeed(isAbsolute13(path) && resolve15(path) === path, "Invalid plugin registry path");
50394
+ for (let at = path;; at = dirname14(at)) {
50177
50395
  pluginNeed(!lstatSync16(at, { throwIfNoEntry: false })?.isSymbolicLink(), "Plugin registry path traverses a symlink");
50178
- if (at === dirname13(at))
50396
+ if (at === dirname14(at))
50179
50397
  break;
50180
50398
  }
50181
50399
  }
@@ -50225,7 +50443,7 @@ function hashManagedPluginRegistry(path, managed) {
50225
50443
  seen.add(target.pluginId);
50226
50444
  const rows = plugins[target.pluginId];
50227
50445
  pluginNeed(Array.isArray(rows) && rows.length === target.registrations.length, "Managed plugin registration membership changed");
50228
- const [name, market] = target.pluginId.split("@"), cacheRoot = join25(dirname13(path), "cache", market, name);
50446
+ const [name, market] = target.pluginId.split("@"), cacheRoot = join25(dirname14(path), "cache", market, name);
50229
50447
  const scopes = new Set, approvals = new Map, currentFiles = new Map;
50230
50448
  plugins[target.pluginId] = rows.map((row) => {
50231
50449
  pluginNeed(pluginObject(row), "Invalid managed plugin registration");
@@ -50241,7 +50459,7 @@ function hashManagedPluginRegistry(path, managed) {
50241
50459
  pluginNeed(/^(?:[A-Za-z0-9][A-Za-z0-9._+-]*-)?[a-f0-9]{12}$/.test(row.version) && row.installPath === join25(cacheRoot, row.version), "Managed plugin cache path or version is outside its registration");
50242
50460
  const approval = (producer) => {
50243
50461
  pluginText(producer);
50244
- const digest = `sha256:${basename6(producer)}`;
50462
+ const digest = `sha256:${basename7(producer)}`;
50245
50463
  const receipt2 = readPluginAdmissionReceipt(witness.storeRoot, witness.bindingId, digest);
50246
50464
  pluginNeed(receipt2.materializedPath === producer, "Managed producer path is not an approved immutable projection");
50247
50465
  if (!verified.has(producer)) {
@@ -50305,37 +50523,37 @@ var init_plugin_discovery = __esm(() => {
50305
50523
  });
50306
50524
 
50307
50525
  // src/lib/claude-marketplace-registry.ts
50308
- import { createHash as createHash15 } from "crypto";
50526
+ import { createHash as createHash16 } from "crypto";
50309
50527
  import { closeSync as closeSync13, constants as constants10, fstatSync as fstatSync13, lstatSync as lstatSync17, openSync as openSync13, readSync as readSync9 } from "fs";
50310
- import { basename as basename7, dirname as dirname14, isAbsolute as isAbsolute12, resolve as resolve14 } from "path";
50311
- function need6(value, reason) {
50528
+ import { basename as basename8, dirname as dirname15, isAbsolute as isAbsolute14, resolve as resolve16 } from "path";
50529
+ function need7(value, reason2) {
50312
50530
  if (!value)
50313
- throw new Error(`Claude marketplace registry ${reason}`);
50531
+ throw new Error(`Claude marketplace registry ${reason2}`);
50314
50532
  }
50315
50533
  function absolutePath2(value) {
50316
- need6(typeof value === "string" && value.length > 0 && value.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.pathCharacters && !/[\x00-\x1f\x7f]/.test(value) && isAbsolute12(value) && resolve14(value) === value, "requires a normalized absolute path");
50534
+ need7(typeof value === "string" && value.length > 0 && value.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.pathCharacters && !/[\x00-\x1f\x7f]/.test(value) && isAbsolute14(value) && resolve16(value) === value, "requires a normalized absolute path");
50317
50535
  }
50318
50536
  function parents2(path) {
50319
50537
  const result = [];
50320
- for (let at = dirname14(path);; at = dirname14(at)) {
50538
+ for (let at = dirname15(path);; at = dirname15(at)) {
50321
50539
  const stat2 = lstatSync17(at, { bigint: true });
50322
- need6(stat2.isDirectory() && !stat2.isSymbolicLink(), "path traverses a symlink or non-directory");
50540
+ need7(stat2.isDirectory() && !stat2.isSymbolicLink(), "path traverses a symlink or non-directory");
50323
50541
  result.push([at, stat2]);
50324
- if (at === dirname14(at))
50542
+ if (at === dirname15(at))
50325
50543
  return result;
50326
50544
  }
50327
50545
  }
50328
50546
  function readRegistry2(path, budget2) {
50329
50547
  absolutePath2(path);
50330
- need6(basename7(path) === "known_marketplaces.json", "requires known_marketplaces.json");
50331
- need6(Number.isSafeInteger(budget2.remaining) && budget2.remaining >= 0, "has an invalid byte budget");
50548
+ need7(basename8(path) === "known_marketplaces.json", "requires known_marketplaces.json");
50549
+ need7(Number.isSafeInteger(budget2.remaining) && budget2.remaining >= 0, "has an invalid byte budget");
50332
50550
  const ancestors2 = parents2(path), initial = lstatSync17(path, { bigint: true });
50333
- need6(initial.isFile() && !initial.isSymbolicLink() && initial.size <= BigInt(CLAUDE_MARKETPLACE_REGISTRY_LIMITS.bytes), "is not a bounded regular file");
50334
- need6(initial.size <= BigInt(budget2.remaining), "exceeds its aggregate byte limit");
50551
+ need7(initial.isFile() && !initial.isSymbolicLink() && initial.size <= BigInt(CLAUDE_MARKETPLACE_REGISTRY_LIMITS.bytes), "is not a bounded regular file");
50552
+ need7(initial.size <= BigInt(budget2.remaining), "exceeds its aggregate byte limit");
50335
50553
  const fd = openSync13(path, constants10.O_RDONLY | constants10.O_NOFOLLOW | constants10.O_NONBLOCK);
50336
50554
  try {
50337
50555
  const opened = fstatSync13(fd, { bigint: true });
50338
- need6(opened.isFile() && sameFile2(initial, opened), "changed during open");
50556
+ need7(opened.isFile() && sameFile2(initial, opened), "changed during open");
50339
50557
  const bytes = Buffer.alloc(Number(opened.size) + 1);
50340
50558
  let length = 0;
50341
50559
  while (length < bytes.length) {
@@ -50345,10 +50563,10 @@ function readRegistry2(path, budget2) {
50345
50563
  length += count;
50346
50564
  }
50347
50565
  const after = fstatSync13(fd, { bigint: true }), current = lstatSync17(path, { bigint: true });
50348
- need6(current.isFile() && sameFile2(opened, after) && sameFile2(after, current) && BigInt(length) === opened.size, "changed during read");
50566
+ need7(current.isFile() && sameFile2(opened, after) && sameFile2(after, current) && BigInt(length) === opened.size, "changed during read");
50349
50567
  for (const [ancestor, before] of ancestors2) {
50350
50568
  const now = lstatSync17(ancestor, { bigint: true });
50351
- need6(now.isDirectory() && before.dev === now.dev && before.ino === now.ino && before.mode === now.mode, "parent changed during read");
50569
+ need7(now.isDirectory() && before.dev === now.dev && before.ino === now.ino && before.mode === now.mode, "parent changed during read");
50352
50570
  }
50353
50571
  budget2.remaining -= length;
50354
50572
  try {
@@ -50368,7 +50586,7 @@ function parse11(text2) {
50368
50586
  at++;
50369
50587
  };
50370
50588
  function string5() {
50371
- need6(text2[at] === '"', "contains invalid JSON");
50589
+ need7(text2[at] === '"', "contains invalid JSON");
50372
50590
  const start = at++;
50373
50591
  while (at < text2.length) {
50374
50592
  const character = text2[at++];
@@ -50379,7 +50597,7 @@ function parse11(text2) {
50379
50597
  } catch {
50380
50598
  throw new Error("Claude marketplace registry contains invalid JSON string");
50381
50599
  }
50382
- need6(value2.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.stringCharacters, "exceeds its string limit");
50600
+ need7(value2.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.stringCharacters, "exceeds its string limit");
50383
50601
  return value2;
50384
50602
  }
50385
50603
  if (character === "\\")
@@ -50388,7 +50606,7 @@ function parse11(text2) {
50388
50606
  throw new Error("Claude marketplace registry contains an unterminated JSON string");
50389
50607
  }
50390
50608
  function value(depth) {
50391
- need6(depth <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.depth && ++nodes <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.nodes, "exceeds its nesting or node limit");
50609
+ need7(depth <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.depth && ++nodes <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.nodes, "exceeds its nesting or node limit");
50392
50610
  space();
50393
50611
  const character = text2[at];
50394
50612
  if (character === '"')
@@ -50402,17 +50620,17 @@ function parse11(text2) {
50402
50620
  if (object7) {
50403
50621
  space();
50404
50622
  const key = string5();
50405
- need6(!keys.has(key), "contains a duplicate JSON key");
50623
+ need7(!keys.has(key), "contains a duplicate JSON key");
50406
50624
  keys.add(key);
50407
50625
  space();
50408
- need6(text2[at++] === ":", "contains invalid JSON");
50626
+ need7(text2[at++] === ":", "contains invalid JSON");
50409
50627
  entries.push([key, value(depth + 1)]);
50410
50628
  } else
50411
50629
  items.push(value(depth + 1));
50412
50630
  space();
50413
50631
  if (text2[at] === end)
50414
50632
  break;
50415
- need6(text2[at++] === ",", "contains invalid JSON");
50633
+ need7(text2[at++] === ",", "contains invalid JSON");
50416
50634
  }
50417
50635
  at++;
50418
50636
  return object7 ? { kind: "object", entries } : { kind: "array", items };
@@ -50424,64 +50642,64 @@ function parse11(text2) {
50424
50642
  }
50425
50643
  numberPattern.lastIndex = at;
50426
50644
  const number5 = numberPattern.exec(text2);
50427
- need6(number5, "contains invalid JSON");
50645
+ need7(number5, "contains invalid JSON");
50428
50646
  at += number5[0].length;
50429
50647
  return { kind: "number", value: number5[0] };
50430
50648
  }
50431
50649
  const root = value(0);
50432
50650
  space();
50433
- need6(at === text2.length && root.kind === "object", "requires a JSON object without trailing content");
50434
- need6(root.entries.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.rows, "exceeds its marketplace row limit");
50651
+ need7(at === text2.length && root.kind === "object", "requires a JSON object without trailing content");
50652
+ need7(root.entries.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.rows, "exceeds its marketplace row limit");
50435
50653
  return root;
50436
50654
  }
50437
50655
  function exactKeys(value, keys) {
50438
50656
  return value?.kind === "object" && value.entries.length === keys.length && value.entries.every(([key]) => keys.includes(key));
50439
50657
  }
50440
50658
  function textField(value) {
50441
- need6(value?.kind === "string" && value.value.length > 0 && !/[\x00-\x1f\x7f]/.test(value.value), "contains an invalid recognized field");
50659
+ need7(value?.kind === "string" && value.value.length > 0 && !/[\x00-\x1f\x7f]/.test(value.value), "contains an invalid recognized field");
50442
50660
  return value.value;
50443
50661
  }
50444
50662
  function normalizeRow(row, version2 = 1) {
50445
50663
  if (!exactKeys(row, ["source", "installLocation", "lastUpdated"])) {
50446
50664
  if (version2 !== 2 || !exactKeys(row, ["source", "installLocation", "lastUpdated", "autoUpdate"]))
50447
50665
  return;
50448
- const autoUpdate = field(row, "autoUpdate");
50449
- need6(autoUpdate?.kind === "literal" && (autoUpdate.value === "true" || autoUpdate.value === "false"), "contains an invalid automatic-update preference");
50666
+ const autoUpdate = field2(row, "autoUpdate");
50667
+ need7(autoUpdate?.kind === "literal" && (autoUpdate.value === "true" || autoUpdate.value === "false"), "contains an invalid automatic-update preference");
50450
50668
  }
50451
- const source = field(row, "source");
50669
+ const source = field2(row, "source");
50452
50670
  if (source?.kind !== "object")
50453
50671
  return;
50454
- const type = field(source, "source");
50672
+ const type = field2(source, "source");
50455
50673
  if (type?.kind !== "string" || !["github", "directory"].includes(type.value))
50456
50674
  return;
50457
50675
  const location = type.value === "github" ? "repo" : "path";
50458
50676
  if (!exactKeys(source, ["source", location]))
50459
50677
  return;
50460
- const sourceLocation = textField(field(source, location));
50678
+ const sourceLocation = textField(field2(source, location));
50461
50679
  if (type.value === "directory")
50462
50680
  absolutePath2(sourceLocation);
50463
- absolutePath2(textField(field(row, "installLocation")));
50464
- const updated = textField(field(row, "lastUpdated"));
50465
- need6(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(updated), "contains an invalid recognized update timestamp");
50681
+ absolutePath2(textField(field2(row, "installLocation")));
50682
+ const updated = textField(field2(row, "lastUpdated"));
50683
+ need7(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(updated), "contains an invalid recognized update timestamp");
50466
50684
  const millis = Date.parse(updated);
50467
- need6(Number.isFinite(millis) && new Date(millis).toISOString() === updated, "contains an invalid recognized update timestamp");
50685
+ need7(Number.isFinite(millis) && new Date(millis).toISOString() === updated, "contains an invalid recognized update timestamp");
50468
50686
  row.entries = row.entries.map(([key, value]) => [key, key === "lastUpdated" ? { kind: "validated-update-time" } : value]);
50469
50687
  }
50470
50688
  function captureClaudeMarketplaceRegistry(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
50471
50689
  const value = parse11(readRegistry2(path, budget2));
50472
50690
  for (const [, row] of value.entries)
50473
50691
  normalizeRow(row);
50474
- const sha2562 = createHash15("sha256").update("hasna.skills.claude-marketplace-registry.v1\x00").update(JSON.stringify(value)).digest("hex");
50692
+ const sha2562 = createHash16("sha256").update("hasna.skills.claude-marketplace-registry.v1\x00").update(JSON.stringify(value)).digest("hex");
50475
50693
  return { path, hashMode: "claude-marketplace-registry", sha256: sha2562 };
50476
50694
  }
50477
50695
  function captureClaudeMarketplaceRegistryV2(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
50478
50696
  const value = parse11(readRegistry2(path, budget2));
50479
50697
  for (const [, row] of value.entries)
50480
50698
  normalizeRow(row, 2);
50481
- const sha2562 = createHash15("sha256").update("hasna.skills.claude-marketplace-registry.v2\x00").update(JSON.stringify(value)).digest("hex");
50699
+ const sha2562 = createHash16("sha256").update("hasna.skills.claude-marketplace-registry.v2\x00").update(JSON.stringify(value)).digest("hex");
50482
50700
  return { path, hashMode: "claude-marketplace-registry-v2", sha256: sha2562 };
50483
50701
  }
50484
- 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];
50702
+ 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, field2 = (object7, key) => object7.entries.find(([name]) => name === key)?.[1];
50485
50703
  var init_claude_marketplace_registry = __esm(() => {
50486
50704
  CLAUDE_MARKETPLACE_REGISTRY_LIMITS = Object.freeze({ bytes: 1024 * 1024, rows: 1024, depth: 32, nodes: 65536, stringCharacters: 16384, pathCharacters: 4096 });
50487
50705
  });
@@ -50500,10 +50718,10 @@ var init_codex_hook_additions_review = __esm(() => {
50500
50718
  });
50501
50719
 
50502
50720
  // src/lib/codex-hook-discovery-recovery.ts
50503
- import { createHash as createHash16 } from "crypto";
50721
+ import { createHash as createHash17 } from "crypto";
50504
50722
  function assertCodexHookDiscoveryRecovery(binding, witness) {
50505
50723
  const proof = proofs2.get(witness);
50506
- need5(!!proof && binding.agent === "codex" && witness.discoverySha256 === sha3(JSON.stringify(binding)), "RECONCILE_DISCOVERY_RECOVERY_CHANGED");
50724
+ need6(!!proof && binding.agent === "codex" && witness.discoverySha256 === sha3(JSON.stringify(binding)), "RECONCILE_DISCOVERY_RECOVERY_CHANGED");
50507
50725
  unchanged2(proof.before);
50508
50726
  unchanged2(proof.current);
50509
50727
  proof.recheckAdditions();
@@ -50512,10 +50730,10 @@ function verifiesCodexHookDiscoverySource(binding, source, currentDigest, witnes
50512
50730
  if (!witness || source.path !== witness.configPath || source.hashMode !== "bytes")
50513
50731
  return false;
50514
50732
  assertCodexHookDiscoveryRecovery(binding, witness);
50515
- need5(source.sha256 === witness.beforeSha256 && currentDigest === witness.currentSha256, "RECONCILE_DISCOVERY_RECOVERY_CHANGED");
50733
+ need6(source.sha256 === witness.beforeSha256 && currentDigest === witness.currentSha256, "RECONCILE_DISCOVERY_RECOVERY_CHANGED");
50516
50734
  return true;
50517
50735
  }
50518
- var sha3 = (text2) => createHash16("sha256").update(text2).digest("hex"), fields, proofs2;
50736
+ var sha3 = (text2) => createHash17("sha256").update(text2).digest("hex"), fields, proofs2;
50519
50737
  var init_codex_hook_discovery_recovery = __esm(() => {
50520
50738
  init_codex_hook_trust_files();
50521
50739
  init_codex_hook_trust_layout();
@@ -50526,10 +50744,18 @@ var init_codex_hook_discovery_recovery = __esm(() => {
50526
50744
  });
50527
50745
 
50528
50746
  // src/lib/agent-discovery.ts
50529
- import { createHash as createHash17 } from "crypto";
50747
+ import { createHash as createHash18 } from "crypto";
50530
50748
  import { lstatSync as lstatSync18, readFileSync as readFileSync15, readdirSync as readdirSync7, realpathSync as realpathSync5 } from "fs";
50531
- import { basename as basename8, dirname as dirname15, isAbsolute as isAbsolute13, join as join26, resolve as resolve15, sep as sep6 } from "path";
50749
+ import { basename as basename9, dirname as dirname16, isAbsolute as isAbsolute15, join as join26, resolve as resolve17, sep as sep6 } from "path";
50532
50750
  import { isDeepStrictEqual as isDeepStrictEqual4 } from "util";
50751
+ function discoveryExecutable(agent) {
50752
+ const command = DISCOVERY_RUNTIME_COMMANDS[agent];
50753
+ const found = command ? Bun.which(command) : null;
50754
+ if (!command || !found)
50755
+ return null;
50756
+ const path = resolve17(found), target = realpathOrNull(path);
50757
+ return target === null ? null : { command, path, target };
50758
+ }
50533
50759
  function parseConfig(text2, path, toml = false) {
50534
50760
  try {
50535
50761
  const value = toml ? Bun.TOML.parse(text2) : JSON.parse(text2);
@@ -50541,12 +50767,12 @@ function parseConfig(text2, path, toml = false) {
50541
50767
  }
50542
50768
  }
50543
50769
  function safe4(path) {
50544
- if (!isAbsolute13(path) || path.includes("\x00"))
50770
+ if (!isAbsolute15(path) || path.includes("\x00"))
50545
50771
  throw new Error("Expected an absolute native discovery path");
50546
- for (let cursor = path;; cursor = dirname15(cursor)) {
50772
+ for (let cursor = path;; cursor = dirname16(cursor)) {
50547
50773
  if (lstatSync18(cursor, { throwIfNoEntry: false })?.isSymbolicLink())
50548
50774
  throw new Error(`Refusing symlink native discovery input: ${cursor}`);
50549
- if (dirname15(cursor) === cursor)
50775
+ if (dirname16(cursor) === cursor)
50550
50776
  break;
50551
50777
  }
50552
50778
  }
@@ -50565,7 +50791,7 @@ function projectNativeDiscoveryFields(text2, format, fields2, path) {
50565
50791
  const object7 = format === "yaml" ? parseHermesConfig(text2) : parseConfig(text2, path, format === "toml");
50566
50792
  if (!object7 || typeof object7 !== "object" || Array.isArray(object7))
50567
50793
  throw new Error("Expected native discovery configuration object");
50568
- return digest(JSON.stringify(Object.fromEntries(fields2.map((field2) => [field2, object7[field2] ?? null]))));
50794
+ return digest(JSON.stringify(Object.fromEntries(fields2.map((field3) => [field3, object7[field3] ?? null]))));
50569
50795
  }
50570
50796
  function isSupersededSettingsProjection(agent, configPath, source) {
50571
50797
  if (agent === "sumi")
@@ -50610,6 +50836,14 @@ function projected(source, changes, budget2 = discoveryByteBudget()) {
50610
50836
  throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
50611
50837
  return sha2562;
50612
50838
  }
50839
+ if (source.hashMode === "claude-marketplace-entry-v1") {
50840
+ if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256) || changes?.has(source.path) || !claudeMarketplaceEntrySourceValid(source))
50841
+ throw new Error("Claude marketplace entry witnesses require an exact reviewed entry without synthetic changes");
50842
+ const sha2562 = captureClaudeMarketplaceEntry(source.path, source.marketplace, source.plugin, budget2).sha256;
50843
+ if (sha2562 !== source.sha256)
50844
+ throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
50845
+ return sha2562;
50846
+ }
50613
50847
  if (source.hashMode === "claude-plugin-registry") {
50614
50848
  if (source.format !== undefined || source.fields !== undefined || !source.managedPlugins || changes?.has(source.path))
50615
50849
  throw new Error("Managed plugin registry witnesses require verified native registrations");
@@ -50647,7 +50881,7 @@ function absentCodexSkillRoots(binding) {
50647
50881
  throw new Error("Invalid disabled Codex discovery proof");
50648
50882
  if (binding.method !== "reviewed" || controls.every((control) => lstatSync18(control.pluginParent, { throwIfNoEntry: false })))
50649
50883
  return [];
50650
- const cache = dirname15(dirname15(controls[0].pluginParent)), config2 = join26(dirname15(dirname15(cache)), "config.toml");
50884
+ const cache = dirname16(dirname16(controls[0].pluginParent)), config2 = join26(dirname16(dirname16(cache)), "config.toml");
50651
50885
  const source = binding.sources.find((source2) => source2.path === config2 && source2.sha256 !== null && source2.format === undefined && source2.fields === undefined);
50652
50886
  if (!source || projected(source) !== source.sha256)
50653
50887
  throw new Error("Missing current disabled Codex configuration witness");
@@ -50655,7 +50889,7 @@ function absentCodexSkillRoots(binding) {
50655
50889
  return [...new Set(controls.map((control) => control.pluginParent))].filter((parent) => !codexDirectHookSelects(cache, parent) && absentDisabledCodexPluginParent(cache, parent, controls, rules));
50656
50890
  }
50657
50891
  function codexDirectHookSelects(cache, root) {
50658
- const codex = dirname15(dirname15(cache)), config2 = Bun.TOML.parse(read(join26(codex, "config.toml")) ?? "");
50892
+ const codex = dirname16(dirname16(cache)), config2 = Bun.TOML.parse(read(join26(codex, "config.toml")) ?? "");
50659
50893
  const hooks = read(join26(codex, "hooks.json"));
50660
50894
  if (hooks !== null)
50661
50895
  hashNativeJsonControls(hooks);
@@ -50668,7 +50902,7 @@ function retiredCodexRoots(binding) {
50668
50902
  const controls = binding.codexDisabledPluginSkills;
50669
50903
  if (binding.agent !== "codex" || binding.method !== "reviewed" || !Array.isArray(controls) || !controls.length || !Array.isArray(proof.roots) || proof.roots.length > AGENT_POLICY_LIMITS.discoveryRoots || new Set(proof.roots).size !== proof.roots.length || !Array.isArray(proof.directories) || proof.parents !== undefined && (!Array.isArray(proof.parents) || proof.parents.length > AGENT_POLICY_LIMITS.discoveryRoots || new Set(proof.parents).size !== proof.parents.length) || !proof.roots.length && !proof.parents?.length)
50670
50904
  throw new Error("Invalid retired Codex materialization proof");
50671
- const cache = dirname15(dirname15(controls[0].pluginParent)), config2 = join26(dirname15(dirname15(cache)), "config.toml");
50905
+ const cache = dirname16(dirname16(controls[0].pluginParent)), config2 = join26(dirname16(dirname16(cache)), "config.toml");
50672
50906
  const source = binding.sources.find((source2) => source2.path === config2 && source2.sha256 !== null && source2.format === undefined && source2.fields === undefined);
50673
50907
  if (!source || projected(source) !== source.sha256)
50674
50908
  throw new Error("Missing current retired Codex configuration witness");
@@ -50699,7 +50933,7 @@ function absentRetiredClaudeRoots(binding) {
50699
50933
  safe4(root);
50700
50934
  if (lstatSync18(root, { throwIfNoEntry: false }))
50701
50935
  continue;
50702
- const claude = dirname15(dirname15(cache)), settings = join26(claude, "settings.json"), registry2 = join26(claude, "plugins/installed_plugins.json");
50936
+ const claude = dirname16(dirname16(cache)), settings = join26(claude, "settings.json"), registry2 = join26(claude, "plugins/installed_plugins.json");
50703
50937
  const full = (path) => binding.sources.find((item) => item.path === path && item.sha256 !== null && item.format === undefined && item.fields === undefined);
50704
50938
  const configSource = full(settings), registrySource = full(registry2);
50705
50939
  if (!configSource || !registrySource || projected(configSource) !== configSource.sha256 || projected(registrySource) !== registrySource.sha256)
@@ -50716,7 +50950,7 @@ function absentRetiredClaudeRoots(binding) {
50716
50950
  if (!Array.isArray(rows) || rows.length !== 1 || rows[0]?.scope !== "user" || typeof rows[0]?.installPath !== "string")
50717
50951
  continue;
50718
50952
  const active = rows[0].installPath;
50719
- if (rows[0].version !== basename8(active) || resolve15(active) !== active || dirname15(active) !== dirname15(root) || active === root || !lstatSync18(active, { throwIfNoEntry: false })?.isDirectory() || realpathSync5(active) !== active)
50953
+ if (rows[0].version !== basename9(active) || resolve17(active) !== active || dirname16(active) !== dirname16(root) || active === root || !lstatSync18(active, { throwIfNoEntry: false })?.isDirectory() || realpathSync5(active) !== active)
50720
50954
  continue;
50721
50955
  const activeManifest = full(join26(active, ".claude-plugin/plugin.json"));
50722
50956
  if (!activeManifest || projected(activeManifest) !== activeManifest.sha256)
@@ -50767,7 +51001,7 @@ function verifyAgentDiscovery(binding, codexRecovery) {
50767
51001
  assertMarketplaceBinding(binding, source);
50768
51002
  if (source.hashMode === "claude-plugin-registry" && binding.agent !== "claude")
50769
51003
  throw new Error("Managed Claude registry witnesses cannot apply to another agent");
50770
- if (source.format !== undefined && (!["json", "toml", "yaml"].includes(source.format) || !Array.isArray(source.fields) || !source.fields.length || source.fields.length > 64 || source.fields.some((field2) => typeof field2 !== "string" || !field2)))
51004
+ if (source.format !== undefined && (!["json", "toml", "yaml"].includes(source.format) || !Array.isArray(source.fields) || !source.fields.length || source.fields.length > 64 || source.fields.some((field3) => typeof field3 !== "string" || !field3)))
50771
51005
  throw new Error("Invalid native discovery projection");
50772
51006
  if (source.sha256 !== null && !/^[a-f0-9]{64}$/.test(source.sha256))
50773
51007
  throw new Error("Invalid native discovery digest");
@@ -50795,15 +51029,15 @@ function codexInstallationRoots(binding) {
50795
51029
  const proof = binding.codexInstallationInputs;
50796
51030
  if (proof === undefined)
50797
51031
  return [];
50798
- if (binding.agent !== "codex" || binding.method !== "reviewed" || proof.version !== "codex-cli 0.160.0" || !/^[a-f0-9]{64}$/.test(proof.catalogSha256) || !Array.isArray(proof.plugins) || !proof.plugins.length)
51032
+ if (binding.agent !== "codex" || binding.method !== "reviewed" || !supportsCodexNativeCapability(proof.version, "installed-plugin-review") || !/^[a-f0-9]{64}$/.test(proof.catalogSha256) || !Array.isArray(proof.plugins) || !proof.plugins.length)
50799
51033
  throw new Error("Invalid native installation input proof");
50800
- const cache = dirname15(dirname15(proof.plugins[0].pluginParent));
50801
- const config2 = join26(dirname15(dirname15(cache)), "config.toml"), home = dirname15(dirname15(dirname15(cache)));
51034
+ const cache = dirname16(dirname16(proof.plugins[0].pluginParent));
51035
+ const config2 = join26(dirname16(dirname16(cache)), "config.toml"), home = dirname16(dirname16(dirname16(cache)));
50802
51036
  const configSource = binding.sources.find((source) => source.path === config2 && source.sha256 !== null && (!source.format || source.format === "toml" && source.fields?.includes("plugins")));
50803
51037
  const nativeRoots = NATIVE_SKILL_ROOTS.filter(([agent]) => agent === "codex").map(([, path]) => join26(home, path));
50804
- if (!configSource || proof.plugins.some((input2) => nativeRoots.some((root) => root === input2.sourceRoot || root.startsWith(input2.sourceRoot + sep6) || input2.sourceRoot.startsWith(root + sep6)) || binding.sources.some((source) => basename8(source.path) === "config.toml" && (source.path === input2.sourceRoot || source.path.startsWith(input2.sourceRoot + sep6)))))
51038
+ if (!configSource || proof.plugins.some((input2) => nativeRoots.some((root) => root === input2.sourceRoot || root.startsWith(input2.sourceRoot + sep6) || input2.sourceRoot.startsWith(root + sep6)) || binding.sources.some((source) => basename9(source.path) === "config.toml" && (source.path === input2.sourceRoot || source.path.startsWith(input2.sourceRoot + sep6)))))
50805
51039
  throw new Error("Native installation input overlaps configuration or loading roots");
50806
- if (proof.plugins.some((input2) => dirname15(dirname15(input2.pluginParent)) !== cache || !binding.sources.some((source) => source.path === join26(input2.sourceRoot, ".codex-plugin/plugin.json") && source.sha256 !== null && source.format === undefined && source.fields === undefined)))
51040
+ if (proof.plugins.some((input2) => dirname16(dirname16(input2.pluginParent)) !== cache || !binding.sources.some((source) => source.path === join26(input2.sourceRoot, ".codex-plugin/plugin.json") && source.sha256 !== null && source.format === undefined && source.fields === undefined)))
50807
51041
  throw new Error("Missing native installation input source witness");
50808
51042
  return reviewedCodexPluginSourceRoots(cache, proof.plugins, (path) => {
50809
51043
  const text2 = read(path);
@@ -50813,16 +51047,18 @@ function codexInstallationRoots(binding) {
50813
51047
  });
50814
51048
  }
50815
51049
  function assertMarketplaceBinding(binding, source) {
50816
- if (source.hashMode === "claude-plugin-manifest-v1" && (binding.agent !== "claude" || basename8(source.path) !== "plugin.json" || !source.path.endsWith(join26(sep6, ".claude-plugin", "plugin.json"))))
51050
+ if (source.hashMode === "claude-plugin-manifest-v1" && (binding.agent !== "claude" || basename9(source.path) !== "plugin.json" || !source.path.endsWith(join26(sep6, ".claude-plugin", "plugin.json"))))
50817
51051
  throw new Error("Claude plugin manifest witnesses require Claude plugin discovery");
50818
- if (source.hashMode === "sumi-settings-v1" && (binding.agent !== "sumi" || binding.method !== "reviewed" || basename8(source.path) !== "sumi.json"))
51052
+ if (source.hashMode === "sumi-settings-v1" && (binding.agent !== "sumi" || binding.method !== "reviewed" || basename9(source.path) !== "sumi.json"))
50819
51053
  throw new Error("Sumi settings witnesses require explicit reviewed Sumi configuration");
50820
- if ((source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")) && (binding.agent !== "codex" || binding.method !== "reviewed" || basename8(source.path) !== "config.toml"))
51054
+ if ((source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")) && (binding.agent !== "codex" || binding.method !== "reviewed" || basename9(source.path) !== "config.toml"))
50821
51055
  throw new Error("Codex settings witnesses require explicit reviewed Codex configuration");
50822
- if ((source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "claude-settings-v4")) && (binding.agent !== "claude" || binding.method !== "reviewed" || basename8(source.path) !== "settings.json"))
51056
+ if ((source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "claude-settings-v4")) && (binding.agent !== "claude" || binding.method !== "reviewed" || basename9(source.path) !== "settings.json"))
50823
51057
  throw new Error("Claude settings witnesses require explicit reviewed Claude configuration");
50824
51058
  if ((source.hashMode === "claude-marketplace-registry" || source.hashMode === "claude-marketplace-registry-v2") && (binding.agent !== "claude" || binding.method !== "reviewed"))
50825
51059
  throw new Error("Claude marketplace witnesses require explicit reviewed Claude discovery");
51060
+ if (source.hashMode === "claude-marketplace-entry-v1" && (binding.agent !== "claude" || binding.method !== "reviewed" || !claudeMarketplaceEntrySourceValid(source)))
51061
+ throw new Error("Claude marketplace entry witnesses require explicit reviewed Claude discovery of one named entry");
50826
51062
  }
50827
51063
  function agentDiscoveryConfigPath(home, agent) {
50828
51064
  if (agent === "sumi")
@@ -50830,10 +51066,10 @@ function agentDiscoveryConfigPath(home, agent) {
50830
51066
  return join26(home, agent === "hermes" ? ".hermes/config.yaml" : agent === "opencode" ? ".config/opencode/opencode.json" : `.${agent}/${agent === "codex" ? "config.toml" : agent === "cursor" ? "hooks.json" : "settings.json"}`);
50831
51067
  }
50832
51068
  function resolveAgentDiscovery(options) {
50833
- const canonical7 = options.canonical ?? resolve15, home = resolve15(options.home), agent = options.agent;
51069
+ const canonical8 = options.canonical ?? resolve17, home = resolve17(options.home), agent = options.agent;
50834
51070
  const sources = [], roots = new Set, builtinNames = [];
50835
51071
  const witness = (path, format, fields2, hashMode) => {
50836
- const source = { path: canonical7(path), sha256: null, ...format ? { format, fields: fields2 } : {}, ...hashMode ? { hashMode } : {} };
51072
+ const source = { path: canonical8(path), sha256: null, ...format ? { format, fields: fields2 } : {}, ...hashMode ? { hashMode } : {} };
50837
51073
  source.sha256 = projected(source);
50838
51074
  sources.push(source);
50839
51075
  return read(source.path);
@@ -50855,13 +51091,13 @@ function resolveAgentDiscovery(options) {
50855
51091
  unresolved("JSONC configuration requires a supported format adapter");
50856
51092
  for (const root of [directory, join26(home, ".claude"), join26(home, ".agents")])
50857
51093
  for (const name of ["skill", "skills"])
50858
- roots.add(canonical7(join26(root, name)));
51094
+ roots.add(canonical8(join26(root, name)));
50859
51095
  if (config2.skills !== undefined && (!Array.isArray(config2.skills) || config2.skills.some((path) => typeof path !== "string")))
50860
51096
  unresolved("skills must be a string array");
50861
51097
  for (const value of config2.skills ?? []) {
50862
- if (typeof value !== "string" || /[\0$]/.test(value) || !value || !(isAbsolute13(value) || value.startsWith("~/")))
51098
+ if (typeof value !== "string" || /[\0$]/.test(value) || !value || !(isAbsolute15(value) || value.startsWith("~/")))
50863
51099
  unresolved("remote or relative skill sources need a dedicated discovery adapter");
50864
- roots.add(canonical7(value.startsWith("~/") ? join26(home, value.slice(2)) : value));
51100
+ roots.add(canonical8(value.startsWith("~/") ? join26(home, value.slice(2)) : value));
50865
51101
  }
50866
51102
  for (const key of ["plugin", "plugins"])
50867
51103
  if (config2[key] !== undefined && !Array.isArray(config2[key]))
@@ -50900,23 +51136,23 @@ function resolveAgentDiscovery(options) {
50900
51136
  continue;
50901
51137
  if (normalized.startsWith("~") && normalized !== "~" && !normalized.startsWith("~/"))
50902
51138
  unresolved("user-specific tilde expansion requires a separate discovery adapter");
50903
- const path = normalized === "~" ? home : normalized.startsWith("~/") ? join26(home, normalized.slice(2)) : resolve15(home, ".hermes", normalized);
51139
+ const path = normalized === "~" ? home : normalized.startsWith("~/") ? join26(home, normalized.slice(2)) : resolve17(home, ".hermes", normalized);
50904
51140
  safe4(path);
50905
51141
  roots.add(path);
50906
51142
  }
50907
51143
  }
50908
51144
  if (agent === "gemini") {
50909
- const executable = Bun.which("gemini");
51145
+ const executable = options.executable === undefined ? discoveryExecutable(agent) : options.executable;
50910
51146
  if (executable) {
50911
51147
  let packageRoot;
50912
- for (let directory = dirname15(realpathSync5(executable)), depth = 0;depth < 8; directory = dirname15(directory), depth++) {
51148
+ for (let directory = dirname16(executable.target), depth = 0;depth < 8; directory = dirname16(directory), depth++) {
50913
51149
  const path = join26(directory, "package.json"), raw = read(path);
50914
51150
  if (raw !== null && parseConfig(raw, path).name === "@google/gemini-cli") {
50915
51151
  packageRoot = directory;
50916
51152
  witness(path);
50917
51153
  break;
50918
51154
  }
50919
- if (dirname15(directory) === directory)
51155
+ if (dirname16(directory) === directory)
50920
51156
  break;
50921
51157
  }
50922
51158
  if (!packageRoot)
@@ -50939,11 +51175,11 @@ function resolveAgentDiscovery(options) {
50939
51175
  if (retained.agent !== agent || retained.method !== "reviewed")
50940
51176
  unresolved("invalid retained review");
50941
51177
  verifyAgentDiscovery(retained);
50942
- if (!retained.sources.some((source) => source.path === canonical7(configPath) && source.format === undefined && source.fields === undefined))
51178
+ if (!retained.sources.some((source) => source.path === canonical8(configPath) && source.format === undefined && source.fields === undefined))
50943
51179
  unresolved("retained review is missing the full agent configuration source");
50944
- if (retained.sources.some((source) => (source.hashMode === "sumi-settings-v1" || source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "claude-settings-v4" || (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")))) && source.path !== canonical7(configPath)))
51180
+ if (retained.sources.some((source) => (source.hashMode === "sumi-settings-v1" || source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "claude-settings-v4" || (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")))) && source.path !== canonical8(configPath)))
50945
51181
  unresolved("retained settings witness names another configuration source");
50946
- const covered = supersedesSettingsProjection(agent, retained.sources, canonical7(configPath)) ? sources.filter((source) => !isSupersededSettingsProjection(agent, canonical7(configPath), source)) : sources;
51182
+ const covered = supersedesSettingsProjection(agent, retained.sources, canonical8(configPath)) ? sources.filter((source) => !isSupersededSettingsProjection(agent, canonical8(configPath), source)) : sources;
50947
51183
  if (covered.some((source) => !retained.sources.some((saved) => isDeepStrictEqual4(saved, source))) || [...roots].some((root) => !retained.roots.includes(root)) || agent === "gemini" && JSON.stringify(retained.builtinNames) !== JSON.stringify(builtinNames))
50948
51184
  unresolved("retained review is missing current runtime discovery coverage");
50949
51185
  return retained;
@@ -50955,15 +51191,15 @@ function resolveAgentDiscovery(options) {
50955
51191
  if (review.sources.some((source) => source.format !== undefined || source.fields !== undefined))
50956
51192
  throw new Error("Explicit discovery reviews require full source-file hashes");
50957
51193
  verifyAgentDiscovery(supplied);
50958
- if (review.sources.some((source) => (source.hashMode === "sumi-settings-v1" || source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "claude-settings-v4" || (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")))) && source.path !== canonical7(configPath)))
51194
+ if (review.sources.some((source) => (source.hashMode === "sumi-settings-v1" || source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "claude-settings-v4" || (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")))) && source.path !== canonical8(configPath)))
50959
51195
  throw new Error("Semantic settings witnesses must name the configured agent configuration source");
50960
- if (!review.sources.some((source) => source.path === canonical7(configPath)))
51196
+ if (!review.sources.some((source) => source.path === canonical8(configPath)))
50961
51197
  throw new Error("Discovery review must include the agent configuration source");
50962
- const reviewedSources = supersedesSettingsProjection(agent, review.sources, canonical7(configPath)) ? sources.filter((source) => !isSupersededSettingsProjection(agent, canonical7(configPath), source)) : sources;
51198
+ const reviewedSources = supersedesSettingsProjection(agent, review.sources, canonical8(configPath)) ? sources.filter((source) => !isSupersededSettingsProjection(agent, canonical8(configPath), source)) : sources;
50963
51199
  const reviewedSourcesWithManifestProjection = review.sources.map((source) => {
50964
- if (agent !== "claude" || source.sha256 === null || source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || source.hashMode !== undefined && source.hashMode !== "bytes" || basename8(source.path) !== "plugin.json" || !source.path.endsWith(join26(sep6, ".claude-plugin", "plugin.json")))
51200
+ if (agent !== "claude" || source.sha256 === null || source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || source.hashMode !== undefined && source.hashMode !== "bytes" || basename9(source.path) !== "plugin.json" || !source.path.endsWith(join26(sep6, ".claude-plugin", "plugin.json")))
50965
51201
  return source;
50966
- const pluginRoot = dirname15(dirname15(source.path)), hooksPath = join26(pluginRoot, "hooks/hooks.json");
51202
+ const pluginRoot = dirname16(dirname16(source.path)), hooksPath = join26(pluginRoot, "hooks/hooks.json");
50967
51203
  const hookStat = lstatSync18(hooksPath, { throwIfNoEntry: false });
50968
51204
  const text2 = read(source.path);
50969
51205
  if (text2 === null)
@@ -50978,13 +51214,13 @@ function resolveAgentDiscovery(options) {
50978
51214
  if (manifest.hooks !== undefined) {
50979
51215
  if (typeof manifest.hooks !== "string")
50980
51216
  throw new Error("Reviewed Claude plugin manifest has an unsupported hooks target");
50981
- const declaredHookPath = resolve15(pluginRoot, manifest.hooks);
51217
+ const declaredHookPath = resolve17(pluginRoot, manifest.hooks);
50982
51218
  if (!declaredHookPath.startsWith(pluginRoot + sep6))
50983
51219
  throw new Error("Reviewed Claude plugin hooks target escapes its root");
50984
51220
  reviewedHookPaths.add(declaredHookPath);
50985
51221
  }
50986
51222
  for (const hooksFile of reviewedHookPaths)
50987
- if (!review.sources.some((hook) => hook.path === canonical7(hooksFile) && hook.sha256 !== null && hook.format === undefined && hook.fields === undefined && hook.managedPlugins === undefined && (hook.hashMode === undefined || hook.hashMode === "bytes")))
51223
+ if (!review.sources.some((hook) => hook.path === canonical8(hooksFile) && hook.sha256 !== null && hook.format === undefined && hook.fields === undefined && hook.managedPlugins === undefined && (hook.hashMode === undefined || hook.hashMode === "bytes")))
50988
51224
  throw new Error("Reviewed Claude plugin manifest requires separately reviewed exact hook file sources");
50989
51225
  return { path: source.path, sha256: manifestSha256, hashMode: "claude-plugin-manifest-v1" };
50990
51226
  });
@@ -50993,7 +51229,7 @@ function resolveAgentDiscovery(options) {
50993
51229
  return { ...supplied, roots: [...new Set([...roots, ...supplied.roots])].sort(), sources: unique, ...agent === "gemini" ? { builtinNames } : {} };
50994
51230
  }
50995
51231
  function plugin(root) {
50996
- root = canonical7(root);
51232
+ root = canonical8(root);
50997
51233
  safe4(root);
50998
51234
  const manifestPath = join26(root, agent === "claude" ? ".claude-plugin/plugin.json" : ".codex-plugin/plugin.json");
50999
51235
  const raw = witness(manifestPath, undefined, undefined, agent === "claude" ? "claude-plugin-manifest-v1" : undefined);
@@ -51016,16 +51252,16 @@ function resolveAgentDiscovery(options) {
51016
51252
  if (agent === "claude")
51017
51253
  roots.add(join26(root, "skills"));
51018
51254
  for (const value of declared) {
51019
- const path = resolve15(root, value);
51255
+ const path = resolve17(root, value);
51020
51256
  if (path !== root && !path.startsWith(root + sep6))
51021
51257
  unresolved("plugin skill path escapes its root");
51022
- roots.add(path.endsWith(`${sep6}SKILL.md`) ? dirname15(path) : path);
51258
+ roots.add(path.endsWith(`${sep6}SKILL.md`) ? dirname16(path) : path);
51023
51259
  }
51024
51260
  }
51025
51261
  if (agent === "claude") {
51026
51262
  const registrations = witness(join26(home, ".claude/plugins/installed_plugins.json"));
51027
51263
  const installed = registrations === null ? {} : parseConfig(registrations, join26(home, ".claude/plugins/installed_plugins.json")).plugins;
51028
- const commands = canonical7(join26(home, ".claude/commands"));
51264
+ const commands = canonical8(join26(home, ".claude/commands"));
51029
51265
  safe4(commands);
51030
51266
  if (lstatSync18(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync7(commands).length)
51031
51267
  unresolved("legacy home command discovery requires a dedicated format adapter");
@@ -51047,7 +51283,7 @@ function resolveAgentDiscovery(options) {
51047
51283
  unresolved("unsupported plugin enablement");
51048
51284
  const split = id.lastIndexOf("@"), name = id.slice(0, split), marketplace = id.slice(split + 1);
51049
51285
  const market = config2.marketplaces?.[marketplace] ?? (marketplace === "personal" ? { source_type: "local", source: home } : undefined);
51050
- if (split < 1 || market?.source_type !== "local" || typeof market.source !== "string" || !isAbsolute13(market.source))
51286
+ if (split < 1 || market?.source_type !== "local" || typeof market.source !== "string" || !isAbsolute15(market.source))
51051
51287
  unresolved("enabled plugin marketplace is not an explicit local source");
51052
51288
  const catalogText = witness(join26(market.source, ".agents/plugins/marketplace.json"));
51053
51289
  if (catalogText === null)
@@ -51055,7 +51291,7 @@ function resolveAgentDiscovery(options) {
51055
51291
  const catalog = parseConfig(catalogText, join26(market.source, ".agents/plugins/marketplace.json")), matches = Array.isArray(catalog.plugins) ? catalog.plugins.filter((item) => item.name === name) : [];
51056
51292
  if (matches.length !== 1 || matches[0]?.source?.source !== "local" || typeof matches[0]?.source?.path !== "string")
51057
51293
  unresolved("plugin catalog source is missing or ambiguous");
51058
- plugin(resolve15(market.source, matches[0].source.path));
51294
+ plugin(resolve17(market.source, matches[0].source.path));
51059
51295
  }
51060
51296
  } else if (agent === "opencode") {
51061
51297
  if (witness(join26(home, ".config/opencode/opencode.jsonc")) !== null || witness(join26(home, ".config/opencode/config.json")) !== null)
@@ -51063,7 +51299,7 @@ function resolveAgentDiscovery(options) {
51063
51299
  if ((config2.plugin?.length ?? 0) > 0 || config2.skills?.urls?.length)
51064
51300
  unresolved("external plugin or remote skill source");
51065
51301
  for (const path of config2.skills?.paths ?? []) {
51066
- if (typeof path !== "string" || !isAbsolute13(path))
51302
+ if (typeof path !== "string" || !isAbsolute15(path))
51067
51303
  unresolved("relative or malformed added skill root");
51068
51304
  roots.add(path);
51069
51305
  }
@@ -51072,7 +51308,7 @@ function resolveAgentDiscovery(options) {
51072
51308
  if (lstatSync18(localPlugins, { throwIfNoEntry: false }) && readdirSync7(localPlugins).some((name) => name !== "skills-cli.js"))
51073
51309
  unresolved("additional local plugin hooks require review");
51074
51310
  } else if (agent === "sumi") {
51075
- if ((config2.plugin?.length ?? 0) > 0 || (config2.plugins?.length ?? 0) > 0 || sources.some((source) => source.path !== canonical7(configPath) && source.path !== canonical7(join26(sumiConfigDirectory(home), "sumi.jsonc")) && source.sha256 !== null))
51311
+ if ((config2.plugin?.length ?? 0) > 0 || (config2.plugins?.length ?? 0) > 0 || sources.some((source) => source.path !== canonical8(configPath) && source.path !== canonical8(join26(sumiConfigDirectory(home), "sumi.jsonc")) && source.sha256 !== null))
51076
51312
  unresolved("external or foreign local plugins require review");
51077
51313
  } else if (agent === "hermes") {
51078
51314
  for (const directory of [join26(home, ".hermes/plugins"), join26(home, ".hermes/hermes-agent")]) {
@@ -51102,9 +51338,15 @@ function resolveAgentDiscovery(options) {
51102
51338
  roots.add(join26(root, "skills"));
51103
51339
  }
51104
51340
  }
51105
- return { agent, roots: [...roots].sort(), sources, method: "automatic", ...agent === "gemini" ? { builtinNames } : {}, ...agent === "hermes" ? { directories: captureDiscoveryDirectories([join26(home, ".hermes/plugins"), join26(home, ".hermes/hermes-agent")].map((path) => canonical7(path))) } : {} };
51341
+ return { agent, roots: [...roots].sort(), sources, method: "automatic", ...agent === "gemini" ? { builtinNames } : {}, ...agent === "hermes" ? { directories: captureDiscoveryDirectories([join26(home, ".hermes/plugins"), join26(home, ".hermes/hermes-agent")].map((path) => canonical8(path))) } : {} };
51106
51342
  }
51107
- var digest = (text2) => createHash17("sha256").update(text2).digest("hex");
51343
+ var DISCOVERY_RUNTIME_COMMANDS, realpathOrNull = (path) => {
51344
+ try {
51345
+ return realpathSync5(path);
51346
+ } catch {
51347
+ return null;
51348
+ }
51349
+ }, digest = (text2) => createHash18("sha256").update(text2).digest("hex");
51108
51350
  var init_agent_discovery = __esm(() => {
51109
51351
  init_sumi_settings_witness();
51110
51352
  init_agent_policy_limits();
@@ -51116,21 +51358,24 @@ var init_agent_discovery = __esm(() => {
51116
51358
  init_plugin_discovery();
51117
51359
  init_plugin_admission();
51118
51360
  init_claude_marketplace_registry();
51361
+ init_claude_marketplace_entry_witness();
51119
51362
  init_claude_settings_witness();
51120
51363
  init_codex_hook_discovery_recovery();
51121
51364
  init_codex_settings_witness();
51122
51365
  init_codex_plugin_skill_controls();
51123
51366
  init_agent_sumi();
51124
51367
  init_native_discovery_roots();
51368
+ init_codex_native_compatibility();
51125
51369
  init_agent_discovery_directories();
51370
+ DISCOVERY_RUNTIME_COMMANDS = Object.freeze({ gemini: "gemini" });
51126
51371
  });
51127
51372
 
51128
51373
  // src/lib/authoring-path.ts
51129
51374
  import { lstatSync as lstatSync19, realpathSync as realpathSync6 } from "fs";
51130
51375
  import { homedir as homedir3 } from "os";
51131
- import { basename as basename9, dirname as dirname16, join as join27, resolve as resolve16, sep as sep7 } from "path";
51376
+ import { basename as basename10, dirname as dirname17, join as join27, resolve as resolve18, sep as sep7 } from "path";
51132
51377
  function pathParts(path) {
51133
- return resolve16(path).split(sep7).filter(Boolean);
51378
+ return resolve18(path).split(sep7).filter(Boolean);
51134
51379
  }
51135
51380
  function nativeRootMatch(path) {
51136
51381
  const parts = pathParts(path);
@@ -51144,16 +51389,16 @@ function nativeRootMatch(path) {
51144
51389
  return;
51145
51390
  }
51146
51391
  function physicalPath(path) {
51147
- let cursor = resolve16(path);
51392
+ let cursor = resolve18(path);
51148
51393
  const suffix = [];
51149
51394
  while (!lstatSync19(cursor, { throwIfNoEntry: false })) {
51150
- suffix.unshift(basename9(cursor));
51151
- const parent = dirname16(cursor);
51395
+ suffix.unshift(basename10(cursor));
51396
+ const parent = dirname17(cursor);
51152
51397
  if (parent === cursor)
51153
- return resolve16(path);
51398
+ return resolve18(path);
51154
51399
  cursor = parent;
51155
51400
  }
51156
- return resolve16(realpathSync6(cursor), ...suffix);
51401
+ return resolve18(realpathSync6(cursor), ...suffix);
51157
51402
  }
51158
51403
  function contains(root, path) {
51159
51404
  return path === root || path.startsWith(root + sep7);
@@ -51161,7 +51406,7 @@ function contains(root, path) {
51161
51406
  function configuredRoots(home, explicitHome) {
51162
51407
  const homeData = join27(home, ".hasna", "skills");
51163
51408
  const homePolicy = readManagedSkillPolicySnapshot(homeData);
51164
- const configuredPolicy = !explicitHome && resolve16(getDataDirReadOnly()) !== resolve16(homeData) ? readManagedSkillPolicySnapshot(getDataDirReadOnly()) : null;
51409
+ const configuredPolicy = !explicitHome && resolve18(getDataDirReadOnly()) !== resolve18(homeData) ? readManagedSkillPolicySnapshot(getDataDirReadOnly()) : null;
51165
51410
  const policy = homePolicy ?? configuredPolicy;
51166
51411
  const bridge = policy?.value.bridge;
51167
51412
  if (bridge && (typeof bridge.home !== "string" || physicalPath(bridge.home) !== physicalPath(home))) {
@@ -51200,22 +51445,22 @@ function configuredRoots(home, explicitHome) {
51200
51445
  function assertPortableAuthoringPath(path, options = {}) {
51201
51446
  if (typeof path !== "string" || !path || path.includes("\x00"))
51202
51447
  throw new Error("Invalid portable authoring path");
51203
- const lexical = resolve16(path);
51448
+ const lexical = resolve18(path);
51204
51449
  const physical = physicalPath(lexical);
51205
51450
  const candidates = [lexical, physical];
51206
51451
  let native = candidates.map(nativeRootMatch).find(Boolean);
51207
- const home = resolve16(options.homeDir ?? homedir3());
51452
+ const home = resolve18(options.homeDir ?? homedir3());
51208
51453
  const defaults = NATIVE_DISCOVERY_ROOTS.map((parts) => join27(home, ...parts));
51209
51454
  defaults.push(join27(home, ".codex/plugins/cache"), join27(home, ".claude/plugins/cache"), join27(home, ".claude/plugins/synced"), join27(home, ".gemini/extensions"));
51210
51455
  for (const root of defaults) {
51211
- if (candidates.some((candidate) => contains(resolve16(root), candidate) || contains(physicalPath(root), candidate)))
51456
+ if (candidates.some((candidate) => contains(resolve18(root), candidate) || contains(physicalPath(root), candidate)))
51212
51457
  native ??= root;
51213
51458
  }
51214
51459
  if (native) {
51215
51460
  throw new Error(`Refusing portable Skills authoring below native discovery root '${native}': ${lexical}. Set HASNA_SKILLS_DIR to a private authoring corpus outside native roots.`);
51216
51461
  }
51217
51462
  for (const root of configuredRoots(home, options.homeDir !== undefined)) {
51218
- if (candidates.some((candidate) => contains(resolve16(root), candidate) || contains(physicalPath(root), candidate))) {
51463
+ if (candidates.some((candidate) => contains(resolve18(root), candidate) || contains(physicalPath(root), candidate))) {
51219
51464
  throw new Error(`Refusing portable Skills authoring below configured native discovery root: ${lexical}`);
51220
51465
  }
51221
51466
  }
@@ -51242,7 +51487,7 @@ import {
51242
51487
  statSync as statSync7,
51243
51488
  writeFileSync as writeFileSync6
51244
51489
  } from "fs";
51245
- import { basename as basename10, dirname as dirname17, isAbsolute as isAbsolute14, join as join28, normalize as normalize3, relative as relative5, resolve as resolve17, sep as sep8 } from "path";
51490
+ import { basename as basename11, dirname as dirname18, isAbsolute as isAbsolute16, join as join28, normalize as normalize3, relative as relative5, resolve as resolve19, sep as sep8 } from "path";
51246
51491
  function getPortableSkillsRoot(options = {}) {
51247
51492
  return resolvePortableSkillsRoot(options, true);
51248
51493
  }
@@ -51337,20 +51582,20 @@ function scaffoldPortableSkill(name, options = {}) {
51337
51582
  return { name: skillName, path: skillPath, manifest, created: true };
51338
51583
  }
51339
51584
  function physicalImportPath(path) {
51340
- let ancestor = resolve17(path);
51585
+ let ancestor = resolve19(path);
51341
51586
  const suffix = [];
51342
51587
  while (!existsSync12(ancestor)) {
51343
- suffix.unshift(basename10(ancestor));
51344
- ancestor = dirname17(ancestor);
51588
+ suffix.unshift(basename11(ancestor));
51589
+ ancestor = dirname18(ancestor);
51345
51590
  }
51346
51591
  return join28(realpathSync7(ancestor), ...suffix);
51347
51592
  }
51348
51593
  function assertDisjointImportPaths(source, destination) {
51349
51594
  const sourcePath = realpathSync7(source);
51350
51595
  const destinationPath = physicalImportPath(destination);
51351
- const contains2 = (parent, child) => {
51352
- const path = relative5(parent, child);
51353
- return path === "" || !isAbsolute14(path) && path !== ".." && !path.startsWith(`..${sep8}`);
51596
+ const contains2 = (parent, child2) => {
51597
+ const path = relative5(parent, child2);
51598
+ return path === "" || !isAbsolute16(path) && path !== ".." && !path.startsWith(`..${sep8}`);
51354
51599
  };
51355
51600
  if (contains2(sourcePath, destinationPath) || contains2(destinationPath, sourcePath)) {
51356
51601
  throw new Error("Source and destination skill directories must not overlap");
@@ -51365,8 +51610,8 @@ function portPortableSkill(sourcePath, options = {}) {
51365
51610
  const explicitName = options.name != null;
51366
51611
  const skillName = normalizeNewPortableSkillName(options.name ?? inferred.name);
51367
51612
  if (isOfficialSkillName(skillName) && !options.allowShadow) {
51368
- const sourceSlug = safeNormalizeName(basename10(absoluteSource));
51369
- const via = explicitName ? `Name '${skillName}' matches a bundled official skill.` : `Inferred name '${skillName}'${sourceSlug && sourceSlug !== skillName ? ` (from source folder '${basename10(absoluteSource)}')` : ""} matches a bundled official skill.`;
51613
+ const sourceSlug = safeNormalizeName(basename11(absoluteSource));
51614
+ const via = explicitName ? `Name '${skillName}' matches a bundled official skill.` : `Inferred name '${skillName}'${sourceSlug && sourceSlug !== skillName ? ` (from source folder '${basename11(absoluteSource)}')` : ""} matches a bundled official skill.`;
51370
51615
  throw new Error(`${via} Importing it would shadow the official '${skillName}'. ` + `Pass --name to choose a different name, or --allow-shadow to override deliberately.`);
51371
51616
  }
51372
51617
  const readOnlyDestination = join28(resolvePortableSkillsRoot(options, false), skillName);
@@ -51381,7 +51626,7 @@ function portPortableSkill(sourcePath, options = {}) {
51381
51626
  throw new Error(`Skill '${skillName}' already exists at ${destination}`);
51382
51627
  rmSync3(destination, { recursive: true, force: true });
51383
51628
  }
51384
- mkdirSync7(dirname17(destination), { recursive: true });
51629
+ mkdirSync7(dirname18(destination), { recursive: true });
51385
51630
  copySkillDirectory(absoluteSource, destination);
51386
51631
  const base = {
51387
51632
  ...inferred,
@@ -51515,7 +51760,7 @@ function safeIsDirectory(path) {
51515
51760
  }
51516
51761
  }
51517
51762
  function isSafeRelativePath2(value) {
51518
- if (!value.trim() || isAbsolute14(value))
51763
+ if (!value.trim() || isAbsolute16(value))
51519
51764
  return false;
51520
51765
  const normalized = normalize3(value).replace(/\\/g, "/");
51521
51766
  return normalized !== ".." && !normalized.startsWith("../") && !normalized.includes("/../");
@@ -52144,11 +52389,14 @@ var init_skill_context = __esm(() => {
52144
52389
  });
52145
52390
 
52146
52391
  // src/lib/session-reconciliation.ts
52147
- var SESSION_RECONCILIATION_PLAN_TTL_MS;
52392
+ var SESSION_RECONCILIATION_PLAN_TTL_MS, SESSION_RENEWAL_REFUSAL_TTL_MS, SESSION_RENEWAL_REFUSAL_MAX_BYTES;
52148
52393
  var init_session_reconciliation = __esm(() => {
52149
52394
  init_profile_client();
52395
+ init_skill_bundle();
52150
52396
  init_selection_cache();
52151
52397
  SESSION_RECONCILIATION_PLAN_TTL_MS = 5 * 60 * 1000;
52398
+ SESSION_RENEWAL_REFUSAL_TTL_MS = 5 * 60 * 1000;
52399
+ SESSION_RENEWAL_REFUSAL_MAX_BYTES = 4 * 1024;
52152
52400
  });
52153
52401
 
52154
52402
  // src/cli/commands/context.ts
@@ -52186,7 +52434,7 @@ var init_remote_customer_operations = __esm(() => {
52186
52434
  });
52187
52435
 
52188
52436
  // src/lib/canonical-json.ts
52189
- import { createHash as createHash18 } from "crypto";
52437
+ import { createHash as createHash19 } from "crypto";
52190
52438
  function canonicalJson2(value, maximumBytes = 2 * 1024 * 1024) {
52191
52439
  return canonicalJsonAtDepth(value, maximumBytes, 64);
52192
52440
  }
@@ -52230,7 +52478,7 @@ function canonicalJsonAtDepth(value, maximumBytes, maximumDepth) {
52230
52478
  return visit3(value, 0);
52231
52479
  }
52232
52480
  function canonicalJsonSha256(value, maximumBytes) {
52233
- return createHash18("sha256").update(canonicalJson2(value, maximumBytes)).digest("hex");
52481
+ return createHash19("sha256").update(canonicalJson2(value, maximumBytes)).digest("hex");
52234
52482
  }
52235
52483
  var init_canonical_json = () => {};
52236
52484
 
@@ -52981,13 +53229,13 @@ var init_remote_workspace_leave = __esm(() => {
52981
53229
 
52982
53230
  // src/lib/auth-store.ts
52983
53231
  import { chmodSync, existsSync as existsSync14, mkdirSync as mkdirSync8, readFileSync as readFileSync17, renameSync as renameSync4, statSync as statSync8, unlinkSync as unlinkSync4, writeFileSync as writeFileSync7 } from "fs";
52984
- import { basename as basename11, dirname as dirname18, join as join30 } from "path";
53232
+ import { basename as basename12, dirname as dirname19, join as join30 } from "path";
52985
53233
  function getAuthFilePath(env = process.env) {
52986
53234
  return skillsCredentialFilePath(env);
52987
53235
  }
52988
53236
  function getIdentityFilePath(env = process.env) {
52989
53237
  const file2 = skillsCredentialFilePath(env);
52990
- return join30(dirname18(file2), basename11(file2).replace(/^credentials/, "identity") + ".json");
53238
+ return join30(dirname19(file2), basename12(file2).replace(/^credentials/, "identity") + ".json");
52991
53239
  }
52992
53240
  function getApiUrl(action, env = process.env, options = {}) {
52993
53241
  return requireSkillsApiOrigin(action, env, options);
@@ -53069,17 +53317,17 @@ function runQuoteReceipt(value) {
53069
53317
  return value;
53070
53318
  }
53071
53319
  function parseRemoteRunQuote(value) {
53072
- const quote2 = object7(value);
53073
- runQuoteReceipt(quote2.quoteReceipt);
53074
- const pricing = object7(quote2.pricing);
53075
- if (typeof quote2.skill !== "string" || !/^[a-z0-9][a-z0-9-]*$/.test(quote2.skill))
53320
+ const quote3 = object7(value);
53321
+ runQuoteReceipt(quote3.quoteReceipt);
53322
+ const pricing = object7(quote3.pricing);
53323
+ if (typeof quote3.skill !== "string" || !/^[a-z0-9][a-z0-9-]*$/.test(quote3.skill))
53076
53324
  throw new Error("Invalid quoted skill");
53077
53325
  const costCents = creditCount(pricing.costCredits ?? pricing.costCents);
53078
53326
  if (pricing.costCredits !== undefined && pricing.costCents !== undefined && pricing.costCents !== costCents)
53079
53327
  throw new Error("Inconsistent quoted credit count");
53080
- if (quote2.availability && object7(quote2.availability).status !== "available")
53328
+ if (quote3.availability && object7(quote3.availability).status !== "available")
53081
53329
  throw new Error("This skill is unavailable for remote execution");
53082
- return { ...quote2, skill: quote2.skill, pricing: { ...pricing, costCredits: costCents, costCents, formattedCost: `${costCents} credits` } };
53330
+ return { ...quote3, skill: quote3.skill, pricing: { ...pricing, costCredits: costCents, costCents, formattedCost: `${costCents} credits` } };
53083
53331
  }
53084
53332
  function parseRemoteCreditPacks(value) {
53085
53333
  if (!Array.isArray(value))
@@ -53171,14 +53419,14 @@ var init_remote_credit_checkout = __esm(() => {
53171
53419
  });
53172
53420
 
53173
53421
  // src/lib/remote-profile.ts
53174
- function customerNamePatch(input2, field2) {
53175
- if (!isRecord5(input2) || Object.keys(input2).length !== 1 || !Object.hasOwn(input2, field2))
53422
+ function customerNamePatch(input2, field3) {
53423
+ if (!isRecord5(input2) || Object.keys(input2).length !== 1 || !Object.hasOwn(input2, field3))
53176
53424
  throw new Error("Provide only the requested name field.");
53177
- const value = input2[field2];
53425
+ const value = input2[field3];
53178
53426
  if (typeof value !== "string" || /[\p{Cc}\p{Cs}\u2028\u2029]/u.test(value) || !value.trim() || [...value.trim()].length > 100) {
53179
53427
  throw new Error("Use a name of 1\u2013100 characters without control characters or newlines.");
53180
53428
  }
53181
- return { [field2]: value.trim() };
53429
+ return { [field3]: value.trim() };
53182
53430
  }
53183
53431
  function isRecord5(value) {
53184
53432
  return !!value && typeof value === "object" && !Array.isArray(value);
@@ -53215,10 +53463,10 @@ async function readQuoteUnavailableCode(response) {
53215
53463
  let timer;
53216
53464
  let deadlineExceeded = false;
53217
53465
  const expired = Symbol("quote body deadline");
53218
- const deadline = new Promise((resolve18) => {
53466
+ const deadline = new Promise((resolve20) => {
53219
53467
  timer = setTimeout(() => {
53220
53468
  deadlineExceeded = true;
53221
- resolve18(expired);
53469
+ resolve20(expired);
53222
53470
  reader.cancel().catch(() => {});
53223
53471
  }, 1500);
53224
53472
  });
@@ -53501,18 +53749,18 @@ class RemoteSkillsClient {
53501
53749
  const maximum = creditCount(approval.maxCredits ?? approval.maxCostCents ?? 0);
53502
53750
  if (approval.maxCostCents !== undefined && approval.maxCostCents !== maximum)
53503
53751
  throw new Error("Credit approval fields disagree");
53504
- const quote2 = approval.quoteReceipt === undefined ? await this.quoteRun(slug2, input2, args, approval.inputFiles?.length ? approval.inputFiles : undefined) : undefined;
53505
- if (quote2 && quote2.pricing.costCents > maximum)
53506
- throw new RemoteCreditApprovalError(quote2.pricing.costCents, maximum);
53752
+ const quote3 = approval.quoteReceipt === undefined ? await this.quoteRun(slug2, input2, args, approval.inputFiles?.length ? approval.inputFiles : undefined) : undefined;
53753
+ if (quote3 && quote3.pricing.costCents > maximum)
53754
+ throw new RemoteCreditApprovalError(quote3.pricing.costCents, maximum);
53507
53755
  const capabilities = await this.getCapabilities();
53508
53756
  if (!capabilities.capabilities.includes("runs.submit") || capabilities.billing?.boundedRunApproval !== true || capabilities.billing.unit !== "credits") {
53509
53757
  throw new Error("The configured server does not support bounded credit approval; refusing remote submission");
53510
53758
  }
53511
- return this.submitRun(quote2?.skill ?? slug2, input2, args, {
53759
+ return this.submitRun(quote3?.skill ?? slug2, input2, args, {
53512
53760
  ...approval,
53513
53761
  maxCredits: maximum,
53514
53762
  maxCostCents: maximum,
53515
- ...(quote2?.quoteReceipt ?? approval.quoteReceipt) === undefined ? {} : { quoteReceipt: quote2?.quoteReceipt ?? approval.quoteReceipt }
53763
+ ...(quote3?.quoteReceipt ?? approval.quoteReceipt) === undefined ? {} : { quoteReceipt: quote3?.quoteReceipt ?? approval.quoteReceipt }
53516
53764
  });
53517
53765
  }
53518
53766
  async getIdentity() {
@@ -54113,13 +54361,13 @@ class RemoteSkillsClient {
54113
54361
  return normalizeUpdatedSincePage(await response.json());
54114
54362
  }
54115
54363
  }
54116
- function requireOptionalString(record9, field2) {
54117
- if (record9[field2] === undefined)
54364
+ function requireOptionalString(record9, field3) {
54365
+ if (record9[field3] === undefined)
54118
54366
  return;
54119
- if (typeof record9[field2] !== "string") {
54120
- throw new Error(`Remote payload did not match the expected contract (${field2} must be a string when present)`);
54367
+ if (typeof record9[field3] !== "string") {
54368
+ throw new Error(`Remote payload did not match the expected contract (${field3} must be a string when present)`);
54121
54369
  }
54122
- return record9[field2];
54370
+ return record9[field3];
54123
54371
  }
54124
54372
  function isVersionRecord(value) {
54125
54373
  return value !== null && typeof value === "object" && !Array.isArray(value);
@@ -54456,7 +54704,7 @@ var init_remote_invitation_recovery = __esm(() => {
54456
54704
  });
54457
54705
 
54458
54706
  // src/lib/remote-private-publications.ts
54459
- import { createHash as createHash19 } from "crypto";
54707
+ import { createHash as createHash20 } from "crypto";
54460
54708
  function checkedPublicationDeclaration(value) {
54461
54709
  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)
54462
54710
  return bad();
@@ -54701,12 +54949,12 @@ class RemotePrivatePublicationsClient {
54701
54949
  previous = view;
54702
54950
  if (!["queued", "verifying"].includes(view.state) || Date.now() >= until)
54703
54951
  return view;
54704
- await new Promise((resolve18) => {
54952
+ await new Promise((resolve20) => {
54705
54953
  const timer = setTimeout(done, Math.min(1000, until - Date.now()));
54706
54954
  function done() {
54707
54955
  clearTimeout(timer);
54708
54956
  options.signal?.removeEventListener("abort", done);
54709
- resolve18();
54957
+ resolve20();
54710
54958
  }
54711
54959
  options.signal?.addEventListener("abort", done, { once: true });
54712
54960
  });
@@ -54717,7 +54965,7 @@ var PRIVATE_PUBLICATION_MAX_BYTES, failures2, PrivatePublicationError, bad = ()
54717
54965
  throw new PrivatePublicationError("INVALID_PUBLICATION_INPUT", "Invalid publication input or recovery data.");
54718
54966
  }, invalid4 = () => {
54719
54967
  throw new PrivatePublicationError("INVALID_PUBLICATION_RESPONSE", "The server returned an invalid publication result.");
54720
- }, 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), record10 = (v) => !!v && typeof v === "object" && !Array.isArray(v), exact = (v, keys) => record10(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) => createHash19("sha256").update(bytes).digest("hex");
54968
+ }, 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), record10 = (v) => !!v && typeof v === "object" && !Array.isArray(v), exact = (v, keys) => record10(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) => createHash20("sha256").update(bytes).digest("hex");
54721
54969
  var init_remote_private_publications = __esm(() => {
54722
54970
  init_fleet_credentials();
54723
54971
  init_remote_workspace_selection();
@@ -55227,7 +55475,7 @@ var init_recurring_customer = __esm(() => {
55227
55475
 
55228
55476
  // src/lib/recurring-recovery.ts
55229
55477
  import { constants as constants12, closeSync as closeSync15, fsyncSync as fsyncSync4, fstatSync as fstatSync15, lstatSync as lstatSync21, mkdirSync as mkdirSync10, openSync as openSync15, readSync as readSync10, realpathSync as realpathSync8, renameSync as renameSync6, unlinkSync as unlinkSync5, writeFileSync as writeFileSync9 } from "fs";
55230
- import { dirname as dirname19, isAbsolute as isAbsolute15, join as join31, resolve as resolve18 } from "path";
55478
+ import { dirname as dirname20, isAbsolute as isAbsolute17, join as join31, resolve as resolve20 } from "path";
55231
55479
  import { randomUUID as randomUUID2 } from "crypto";
55232
55480
 
55233
55481
  class RecoveryOwner {
@@ -55235,14 +55483,14 @@ class RecoveryOwner {
55235
55483
  parents = [];
55236
55484
  constructor(directory) {
55237
55485
  this.directory = directory;
55238
- if (!isAbsolute15(directory) || resolve18(directory) !== directory || realpathSync8(directory) !== directory)
55486
+ if (!isAbsolute17(directory) || resolve20(directory) !== directory || realpathSync8(directory) !== directory)
55239
55487
  invalid5();
55240
- for (let path = directory;; path = dirname19(path)) {
55488
+ for (let path = directory;; path = dirname20(path)) {
55241
55489
  const stat3 = lstatSync21(path);
55242
55490
  if (!stat3.isDirectory() || stat3.isSymbolicLink())
55243
55491
  invalid5();
55244
55492
  this.parents.push({ path, dev: stat3.dev, ino: stat3.ino });
55245
- if (path === dirname19(path))
55493
+ if (path === dirname20(path))
55246
55494
  break;
55247
55495
  }
55248
55496
  this.assert();
@@ -55370,7 +55618,7 @@ function base(customer, organizationId) {
55370
55618
  };
55371
55619
  }
55372
55620
  function create(directory, intent) {
55373
- if (!isAbsolute15(directory) || resolve18(directory) !== directory || realpathSync8(dirname19(directory)) !== dirname19(directory))
55621
+ if (!isAbsolute17(directory) || resolve20(directory) !== directory || realpathSync8(dirname20(directory)) !== dirname20(directory))
55374
55622
  invalid5();
55375
55623
  mkdirSync10(directory, { mode: 448 });
55376
55624
  const owner2 = new RecoveryOwner(directory), checked = intentSchema.parse(intent), intentSha256 = canonicalJsonSha256(checked);
@@ -55533,7 +55781,7 @@ var init_recurring_recovery = __esm(() => {
55533
55781
  });
55534
55782
 
55535
55783
  // src/lib/recurring-surface.ts
55536
- import { isAbsolute as isAbsolute16 } from "path";
55784
+ import { isAbsolute as isAbsolute18 } from "path";
55537
55785
  function recurringMcpSchema(action) {
55538
55786
  return action === "activate" ? recurringSurfaceSchemas.activate.extend({ code, confirm: exports_external.literal(true) }) : recurringSurfaceSchemas[action];
55539
55787
  }
@@ -55638,7 +55886,7 @@ var init_recurring_surface = __esm(() => {
55638
55886
  uuid13 = exports_external.string().regex(/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/);
55639
55887
  context = { userId: uuid13.optional(), membershipId: uuid13.optional() };
55640
55888
  page2 = { limit: exports_external.number().int().min(1).max(100).optional(), cursor: exports_external.string().min(1).max(2048).optional() };
55641
- directory = exports_external.string().max(4096).refine(isAbsolute16, "Use an absolute recovery directory");
55889
+ directory = exports_external.string().max(4096).refine(isAbsolute18, "Use an absolute recovery directory");
55642
55890
  email4 = exports_external.string().trim().toLowerCase().email().max(254);
55643
55891
  code = exports_external.string().regex(/^\d{6}$/);
55644
55892
  recurringSurfaceSchemas = {
@@ -57467,7 +57715,7 @@ var init_credential_state = __esm(() => {
57467
57715
  });
57468
57716
 
57469
57717
  // src/lib/run-state.ts
57470
- import { createHash as createHash20, randomBytes } from "crypto";
57718
+ import { createHash as createHash21, randomBytes } from "crypto";
57471
57719
  import { existsSync as existsSync15, mkdirSync as mkdirSync11, readFileSync as readFileSync19, readdirSync as readdirSync10, statSync as statSync9, writeFileSync as writeFileSync10 } from "fs";
57472
57720
  import { extname, join as join32, relative as relative6 } from "path";
57473
57721
  function createSkillRun(params, targetDir = process.cwd()) {
@@ -57582,7 +57830,7 @@ function collectRunArtifacts(context2) {
57582
57830
  artifacts.push({
57583
57831
  path: toProjectRelative(context2.targetDir, path),
57584
57832
  mime: mimeForPath(path),
57585
- sha256: createHash20("sha256").update(bytes).digest("hex"),
57833
+ sha256: createHash21("sha256").update(bytes).digest("hex"),
57586
57834
  sizeBytes: stat3.size
57587
57835
  });
57588
57836
  }
@@ -57828,12 +58076,12 @@ function parseExecution(value) {
57828
58076
  ].includes(v.status) || typeof v.skill !== "string" || typeof v.version !== "string" || !Array.isArray(v.artifacts))
57829
58077
  throw Error("Unsupported cloud execution response");
57830
58078
  runId(v.id);
57831
- for (const field2 of [
58079
+ for (const field3 of [
57832
58080
  "bundleDigest",
57833
58081
  "inputDigest",
57834
58082
  "runtimeImageDigest"
57835
58083
  ])
57836
- if (typeof v[field2] !== "string" || !/^(sha256:)?[a-f0-9]{64}$/.test(v[field2]))
58084
+ if (typeof v[field3] !== "string" || !/^(sha256:)?[a-f0-9]{64}$/.test(v[field3]))
57837
58085
  throw Error("Invalid cloud execution integrity receipt");
57838
58086
  return v;
57839
58087
  }
@@ -57858,7 +58106,7 @@ import { closeSync as closeSync16, fstatSync as fstatSync16, openSync as openSyn
57858
58106
  import { O_NOFOLLOW as O_NOFOLLOW3, O_NONBLOCK as O_NONBLOCK3, O_RDONLY as O_RDONLY3 } from "constants";
57859
58107
  import { createRequire as createRequire2 } from "module";
57860
58108
  import { hostname as osHostname2 } from "os";
57861
- import { isAbsolute as isAbsolute17, join as join33 } from "path";
58109
+ import { isAbsolute as isAbsolute19, join as join33 } from "path";
57862
58110
  import { createRequire as createRequire22 } from "module";
57863
58111
  function envToken2(name) {
57864
58112
  return name.toUpperCase().replace(/-/g, "_");
@@ -57882,7 +58130,7 @@ function homeDir2(env) {
57882
58130
  }
57883
58131
  function absoluteOverride2(env, key) {
57884
58132
  const value = env[key]?.trim();
57885
- return value && isAbsolute17(value) ? value : null;
58133
+ return value && isAbsolute19(value) ? value : null;
57886
58134
  }
57887
58135
  function hasnaHomeDir2(env) {
57888
58136
  const override = absoluteOverride2(env, HASNA_HOME_ENV_KEY2);
@@ -57928,9 +58176,9 @@ function parseEnvFile2(text3) {
57928
58176
  if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key))
57929
58177
  continue;
57930
58178
  let value = withoutExport.slice(equals + 1).trim();
57931
- const quote2 = value[0];
57932
- if (quote2 === '"' || quote2 === "'") {
57933
- if (value.length < 2 || !value.endsWith(quote2)) {
58179
+ const quote3 = value[0];
58180
+ if (quote3 === '"' || quote3 === "'") {
58181
+ if (value.length < 2 || !value.endsWith(quote3)) {
57934
58182
  unusable.add(key);
57935
58183
  continue;
57936
58184
  }
@@ -57954,8 +58202,8 @@ function configFileReadsCoherent2(before, after) {
57954
58202
  return before.dev === after.dev && before.ino === after.ino && before.size === after.size && before.mtimeMs === after.mtimeMs && before.ctimeMs === after.ctimeMs;
57955
58203
  }
57956
58204
  function readAppConfigFile2(path) {
57957
- const unsafe = (reason) => {
57958
- throw new CredentialFileUnsafeError2(path, reason);
58205
+ const unsafe = (reason2) => {
58206
+ throw new CredentialFileUnsafeError2(path, reason2);
57959
58207
  };
57960
58208
  let fd = -1;
57961
58209
  try {
@@ -58174,8 +58422,8 @@ function readKeychainItem2(name, env, kind, options) {
58174
58422
  try {
58175
58423
  result = run(["find-generic-password", "-a", account, "-s", service, "-w"]);
58176
58424
  } catch (error61) {
58177
- const reason = keychainFailureHint2(error61 instanceof Error ? error61.message : String(error61));
58178
- throw new CredentialResolutionError2(name, `The Keychain lookup for ${source} could not run${reason}. A Keychain failure is never resolved ` + `around: fix the keychain, or delete the item to fall through to the credential on disk.`, [source]);
58425
+ const reason2 = keychainFailureHint2(error61 instanceof Error ? error61.message : String(error61));
58426
+ throw new CredentialResolutionError2(name, `The Keychain lookup for ${source} could not run${reason2}. A Keychain failure is never resolved ` + `around: fix the keychain, or delete the item to fall through to the credential on disk.`, [source]);
58179
58427
  }
58180
58428
  if (result.status === KEYCHAIN_ITEM_NOT_FOUND_STATUS2)
58181
58429
  return null;
@@ -59019,7 +59267,7 @@ function createSecretsClientFromEnv(env = process.env, overrides = {}) {
59019
59267
  });
59020
59268
  return new SecretsClient({ ...clientOverrides, baseUrl, apiKey });
59021
59269
  }
59022
- var __esm2 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), CREDENTIAL_PROFILE_ENV_KEY2 = "HASNA_PROFILE", CredentialResolutionError2, CredentialFileUnsafeError2, HASNA_HOME_ENV_KEY2 = "HASNA_HOME", HASNA_CONFIG_HOME_ENV_KEY2 = "HASNA_CONFIG_HOME", KEYCHAIN_STATION_ENV_KEY2 = "HASNA_STATION", HASNA_HOME_DIR2 = ".hasna", CONFIG_SUBDIR2 = "config", CREDENTIALS_FILE2 = "credentials", KEYCHAIN_SECURITY_BIN2 = "/usr/bin/security", KEYCHAIN_SERVICE_PREFIX2 = "hasna.credentials", KEYCHAIN_ITEM_NOT_FOUND_STATUS2 = 44, KEYCHAIN_SPAWN_TIMEOUT_MS2 = 1e4, MAX_CREDENTIAL_FILE_BYTES2, SAFE_APP_SLUG2, SAFE_PROFILE2, ILLEGAL_IN_HEADER_VALUE2, VAULT_POINTER_SHAPE2, CREDENTIAL_SHAPED_KEY2, INSPECT_CUSTOM2, CREDENTIAL_SEAL2, CALLER_SUPPLIED_CREDENTIAL_PROVIDER_SOURCE = "caller-supplied CredentialProvider", AMBIENT_ENVIRONMENT2, SECRETS_PACKAGE_SPECIFIER, requireSecretsSdk2, DEFAULT_FLEET_GATEWAY_ORIGIN2 = "https://api.hasna.com", DEFAULT_AUTHORITY_SOURCE = "default", ASCII_CONTROL_PATTERN2, DNS_LABEL_PATTERN2, ClientTransportConfigurationError2, HasnaHttpError, DEFAULT_RETRY_STATUSES, IDEMPOTENT_METHODS2, AUTHORITY_OVERRIDE_HEADERS2, defaultSleep = (ms) => new Promise((resolve19) => setTimeout(resolve19, ms)), init_transport2, MAX_CREDENTIAL_FILE_BYTES22, INSPECT_CUSTOM22, CREDENTIAL_SEAL22, AMBIENT_ENVIRONMENT22, SECRETS_PACKAGE_SPECIFIER2, requireSecretsSdk22, IDEMPOTENT_METHODS22, AUTHORITY_OVERRIDE_HEADERS22, init_storage, PATHS_RESOLVER_APP_SLUG_RE2, SQLITE_SIDECAR_FILES, LEGACY_SERVICE_FILES, init_data_dir, SecretsTestIsolationError, TEST_ENTRYPOINT_RE, init_test_isolation, init_client, ApiError;
59270
+ var __esm2 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), CREDENTIAL_PROFILE_ENV_KEY2 = "HASNA_PROFILE", CredentialResolutionError2, CredentialFileUnsafeError2, HASNA_HOME_ENV_KEY2 = "HASNA_HOME", HASNA_CONFIG_HOME_ENV_KEY2 = "HASNA_CONFIG_HOME", KEYCHAIN_STATION_ENV_KEY2 = "HASNA_STATION", HASNA_HOME_DIR2 = ".hasna", CONFIG_SUBDIR2 = "config", CREDENTIALS_FILE2 = "credentials", KEYCHAIN_SECURITY_BIN2 = "/usr/bin/security", KEYCHAIN_SERVICE_PREFIX2 = "hasna.credentials", KEYCHAIN_ITEM_NOT_FOUND_STATUS2 = 44, KEYCHAIN_SPAWN_TIMEOUT_MS2 = 1e4, MAX_CREDENTIAL_FILE_BYTES2, SAFE_APP_SLUG2, SAFE_PROFILE2, ILLEGAL_IN_HEADER_VALUE2, VAULT_POINTER_SHAPE2, CREDENTIAL_SHAPED_KEY2, INSPECT_CUSTOM2, CREDENTIAL_SEAL2, CALLER_SUPPLIED_CREDENTIAL_PROVIDER_SOURCE = "caller-supplied CredentialProvider", AMBIENT_ENVIRONMENT2, SECRETS_PACKAGE_SPECIFIER, requireSecretsSdk2, DEFAULT_FLEET_GATEWAY_ORIGIN2 = "https://api.hasna.com", DEFAULT_AUTHORITY_SOURCE = "default", ASCII_CONTROL_PATTERN2, DNS_LABEL_PATTERN2, ClientTransportConfigurationError2, HasnaHttpError, DEFAULT_RETRY_STATUSES, IDEMPOTENT_METHODS2, AUTHORITY_OVERRIDE_HEADERS2, defaultSleep = (ms) => new Promise((resolve21) => setTimeout(resolve21, ms)), init_transport2, MAX_CREDENTIAL_FILE_BYTES22, INSPECT_CUSTOM22, CREDENTIAL_SEAL22, AMBIENT_ENVIRONMENT22, SECRETS_PACKAGE_SPECIFIER2, requireSecretsSdk22, IDEMPOTENT_METHODS22, AUTHORITY_OVERRIDE_HEADERS22, init_storage, PATHS_RESOLVER_APP_SLUG_RE2, SQLITE_SIDECAR_FILES, LEGACY_SERVICE_FILES, init_data_dir, SecretsTestIsolationError, TEST_ENTRYPOINT_RE, init_test_isolation, init_client, ApiError;
59023
59271
  var init_sdk = __esm(() => {
59024
59272
  init_transport2 = __esm2(() => {
59025
59273
  CredentialResolutionError2 = class CredentialResolutionError3 extends Error {
@@ -59034,8 +59282,8 @@ var init_sdk = __esm(() => {
59034
59282
  };
59035
59283
  CredentialFileUnsafeError2 = class CredentialFileUnsafeError3 extends Error {
59036
59284
  path;
59037
- constructor(path, reason) {
59038
- super(`Refusing unsafe credential/config file ${path}: ${reason}.`);
59285
+ constructor(path, reason2) {
59286
+ super(`Refusing unsafe credential/config file ${path}: ${reason2}.`);
59039
59287
  this.name = "CredentialFileUnsafeError";
59040
59288
  this.path = path;
59041
59289
  }
@@ -59396,10 +59644,10 @@ __export(exports_selected_run, {
59396
59644
  prepareSelectedSecretBindings: () => prepareSelectedSecretBindings,
59397
59645
  executeSelectedLocal: () => executeSelectedLocal
59398
59646
  });
59399
- import { createHash as createHash21 } from "crypto";
59647
+ import { createHash as createHash22 } from "crypto";
59400
59648
  import { spawn } from "child_process";
59401
59649
  import { mkdirSync as mkdirSync12, mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync11, realpathSync as realpathSync10 } from "fs";
59402
- import { dirname as dirname20, join as join34, resolve as resolve19 } from "path";
59650
+ import { dirname as dirname21, join as join34, resolve as resolve21 } from "path";
59403
59651
  import { tmpdir, hostname as stationHostname2 } from "os";
59404
59652
  async function resolveSelectedRun(spec, profileId, options = {}) {
59405
59653
  const context2 = await resolveSelectionContext(profileId, options);
@@ -59488,11 +59736,11 @@ async function executeSelectedLocal(selected, options = {}) {
59488
59736
  throw new SkillSelectionError("INVALID_BUNDLE_PATH", "The execution bundle path exceeds its limit.");
59489
59737
  });
59490
59738
  const destination = join34(runDirectory, entry.path);
59491
- mkdirSync12(dirname20(destination), { recursive: true, mode: 448 });
59739
+ mkdirSync12(dirname21(destination), { recursive: true, mode: 448 });
59492
59740
  writeFileSync11(destination, entry.bytes, { flag: "wx", mode: entry.mode & 511 });
59493
59741
  }
59494
59742
  env.SKILLS_INPUT_JSON = input2;
59495
- env.SKILLS_WORKSPACE_DIR = resolve19(options.cwd ?? process.cwd());
59743
+ env.SKILLS_WORKSPACE_DIR = resolve21(options.cwd ?? process.cwd());
59496
59744
  env.SKILLS_RUN_DIR = runDirectory;
59497
59745
  if (runtime.version) {
59498
59746
  const version2 = await subprocess([executable, ...runtimeName === "bun" ? ["--no-env-file"] : [], "--version"], runDirectory, env, "", Math.min(timeoutMs, 5000));
@@ -59522,7 +59770,7 @@ async function executeSelectedLocal(selected, options = {}) {
59522
59770
  selection: selection2,
59523
59771
  target: "local",
59524
59772
  runtime: runtimeName,
59525
- inputDigest: `sha256:${createHash21("sha256").update(input2).digest("hex")}`,
59773
+ inputDigest: `sha256:${createHash22("sha256").update(input2).digest("hex")}`,
59526
59774
  runDirectory,
59527
59775
  ...executionGrant ? { executionGrant } : {},
59528
59776
  ...bindings ? { secretBinding: { schema: bindings.schema, selection: bindings.selection, consumer: bindings.consumer, secretsAuthority: bindings.secretsAuthority, bindings: bindings.bindings } } : {},
@@ -59533,17 +59781,17 @@ async function executeSelectedLocal(selected, options = {}) {
59533
59781
  }
59534
59782
  async function subprocess(command, cwd, env, input2, timeoutMs) {
59535
59783
  return new Promise((resolveResult) => {
59536
- const child = spawn(command[0], command.slice(1), { cwd, env, shell: false, detached: process.platform !== "win32", stdio: ["pipe", "pipe", "pipe"] });
59784
+ const child2 = spawn(command[0], command.slice(1), { cwd, env, shell: false, detached: process.platform !== "win32", stdio: ["pipe", "pipe", "pipe"] });
59537
59785
  let outputBytes = 0, error61, ended = false;
59538
59786
  const stdout = [], stderr = [];
59539
59787
  const kill = () => {
59540
59788
  try {
59541
- if (process.platform !== "win32" && child.pid)
59542
- process.kill(-child.pid, "SIGKILL");
59789
+ if (process.platform !== "win32" && child2.pid)
59790
+ process.kill(-child2.pid, "SIGKILL");
59543
59791
  else
59544
- child.kill("SIGKILL");
59792
+ child2.kill("SIGKILL");
59545
59793
  } catch {
59546
- child.kill("SIGKILL");
59794
+ child2.kill("SIGKILL");
59547
59795
  }
59548
59796
  };
59549
59797
  const timer = setTimeout(() => {
@@ -59559,8 +59807,8 @@ async function subprocess(command, cwd, env, input2, timeoutMs) {
59559
59807
  }
59560
59808
  target.push(chunk);
59561
59809
  };
59562
- child.stdout.on("data", capture2(stdout));
59563
- child.stderr.on("data", capture2(stderr));
59810
+ child2.stdout.on("data", capture2(stdout));
59811
+ child2.stderr.on("data", capture2(stderr));
59564
59812
  const finish = (code2) => {
59565
59813
  if (ended)
59566
59814
  return;
@@ -59568,13 +59816,13 @@ async function subprocess(command, cwd, env, input2, timeoutMs) {
59568
59816
  clearTimeout(timer);
59569
59817
  resolveResult({ exitCode: error61 === "LOCAL_RUN_TIMEOUT" ? 124 : error61 ? 1 : code2, stdout: Buffer.concat(stdout).toString("utf8"), stderr: Buffer.concat(stderr).toString("utf8"), ...error61 ? { error: error61 } : {} });
59570
59818
  };
59571
- child.on("error", () => {
59819
+ child2.on("error", () => {
59572
59820
  error61 = "LOCAL_RUNTIME_START_FAILED";
59573
59821
  finish(127);
59574
59822
  });
59575
- child.on("close", (code2) => finish(code2 ?? 1));
59576
- child.stdin.on("error", () => {});
59577
- child.stdin.end(input2);
59823
+ child2.on("close", (code2) => finish(code2 ?? 1));
59824
+ child2.stdin.on("error", () => {});
59825
+ child2.stdin.end(input2);
59578
59826
  });
59579
59827
  }
59580
59828
  var init_selected_run = __esm(() => {
@@ -60091,9 +60339,9 @@ function registerOperationTools(server) {
60091
60339
  }
60092
60340
  }, async ({ run_id, detail }) => {
60093
60341
  const { skillsCredentialOrReason: skillsCredentialOrReason2 } = await Promise.resolve().then(() => (init_fleet_credentials(), exports_fleet_credentials));
60094
- const { apiKey, apiOrigin, reason } = await skillsCredentialOrReason2();
60342
+ const { apiKey, apiOrigin, reason: reason2 } = await skillsCredentialOrReason2();
60095
60343
  if (!apiKey) {
60096
- return mcpError("AUTH_REQUIRED", reason ?? "Remote run status requires API access. Run: skills auth login", ["skills auth login"]);
60344
+ return mcpError("AUTH_REQUIRED", reason2 ?? "Remote run status requires API access. Run: skills auth login", ["skills auth login"]);
60097
60345
  }
60098
60346
  const localRun = findSkillRun(run_id);
60099
60347
  const remoteRunId = localRun?.remoteRunId || run_id;
@@ -60263,14 +60511,14 @@ var init_operation_tools = __esm(() => {
60263
60511
 
60264
60512
  // src/lib/feedback.ts
60265
60513
  import { appendFileSync, existsSync as existsSync17, mkdirSync as mkdirSync13 } from "fs";
60266
- import { dirname as dirname21, join as join36 } from "path";
60514
+ import { dirname as dirname22, join as join36 } from "path";
60267
60515
  import { Database } from "bun:sqlite";
60268
60516
  function getFeedbackDbPath() {
60269
60517
  return join36(getDataDir(), "skills.db");
60270
60518
  }
60271
60519
  function getFeedbackDb() {
60272
60520
  const dbPath = getFeedbackDbPath();
60273
- const dir = dirname21(dbPath);
60521
+ const dir = dirname22(dbPath);
60274
60522
  if (!existsSync17(dir))
60275
60523
  mkdirSync13(dir, { recursive: true });
60276
60524
  const db = new Database(dbPath);
@@ -60299,7 +60547,7 @@ function saveFeedback(input2) {
60299
60547
  const category = input2.category ?? "general";
60300
60548
  if (isApiMode()) {
60301
60549
  const path = join36(getDataDir(), "feedback.jsonl");
60302
- const dir = dirname21(path);
60550
+ const dir = dirname22(path);
60303
60551
  if (!existsSync17(dir))
60304
60552
  mkdirSync13(dir, { recursive: true });
60305
60553
  appendFileSync(path, JSON.stringify({ message, category, email: input2.email ?? null, agent: input2.agent ?? null, version: input2.version ?? null, createdAt: new Date().toISOString() }) + `
@@ -60750,7 +60998,7 @@ var init_schedule_tools = __esm(() => {
60750
60998
  });
60751
60999
 
60752
61000
  // src/lib/native-storage.ts
60753
- import { createHash as createHash22, createHmac } from "crypto";
61001
+ import { createHash as createHash23, createHmac } from "crypto";
60754
61002
  import {
60755
61003
  existsSync as existsSync19,
60756
61004
  mkdirSync as mkdirSync15,
@@ -60759,7 +61007,7 @@ import {
60759
61007
  statSync as statSync11,
60760
61008
  writeFileSync as writeFileSync13
60761
61009
  } from "fs";
60762
- import { dirname as dirname22, join as join38, normalize as normalize4, relative as relative7, sep as sep9 } from "path";
61010
+ import { dirname as dirname23, join as join38, normalize as normalize4, relative as relative7, sep as sep9 } from "path";
60763
61011
  function resolveSkillsNativeStorageConfig(env = process.env) {
60764
61012
  assertNoRetiredModeEnvVars(env, {
60765
61013
  app: SKILLS_ENV_NAMESPACE,
@@ -60827,7 +61075,7 @@ function exportSkillsLocalSnapshot(targetDir = process.cwd(), options = {}) {
60827
61075
  files.push({
60828
61076
  path: relativePath,
60829
61077
  sizeBytes: bytes.byteLength,
60830
- sha256: createHash22("sha256").update(bytes).digest("hex"),
61078
+ sha256: createHash23("sha256").update(bytes).digest("hex"),
60831
61079
  ...options.includeFileContents ? { contentBase64: Buffer.from(bytes).toString("base64") } : {}
60832
61080
  });
60833
61081
  }
@@ -61120,16 +61368,16 @@ var init_private_publication_customer = __esm(() => {
61120
61368
 
61121
61369
  // src/lib/private-publication-recovery.ts
61122
61370
  import { constants as constants14, closeSync as closeSync18, fsyncSync as fsyncSync5, fstatSync as fstatSync18, lstatSync as lstatSync22, mkdirSync as mkdirSync16, openSync as openSync18, readSync as readSync12, realpathSync as realpathSync11, renameSync as renameSync7, unlinkSync as unlinkSync6, writeFileSync as writeFileSync14 } from "fs";
61123
- import { dirname as dirname23, isAbsolute as isAbsolute18, join as join39, resolve as resolve20 } from "path";
61371
+ import { dirname as dirname24, isAbsolute as isAbsolute20, join as join39, resolve as resolve22 } from "path";
61124
61372
  import { randomUUID as randomUUID3 } from "crypto";
61125
61373
  function safeDirectory(directory2) {
61126
- if (!isAbsolute18(directory2) || directory2 !== resolve20(directory2) || realpathSync11(directory2) !== directory2)
61374
+ if (!isAbsolute20(directory2) || directory2 !== resolve22(directory2) || realpathSync11(directory2) !== directory2)
61127
61375
  return fail2();
61128
- for (let path = directory2;; path = dirname23(path)) {
61376
+ for (let path = directory2;; path = dirname24(path)) {
61129
61377
  const stat3 = lstatSync22(path);
61130
61378
  if (!stat3.isDirectory() || stat3.isSymbolicLink())
61131
61379
  return fail2();
61132
- if (path === dirname23(path))
61380
+ if (path === dirname24(path))
61133
61381
  break;
61134
61382
  }
61135
61383
  const own2 = lstatSync22(directory2);
@@ -61261,11 +61509,11 @@ async function preparePrivatePublication(client, sourceDirectory, recoveryDirect
61261
61509
  phase: "prepared",
61262
61510
  intent: null
61263
61511
  };
61264
- if (!isAbsolute18(recoveryDirectory) || resolve20(recoveryDirectory) !== recoveryDirectory || realpathSync11(dirname23(recoveryDirectory)) !== dirname23(recoveryDirectory))
61512
+ if (!isAbsolute20(recoveryDirectory) || resolve22(recoveryDirectory) !== recoveryDirectory || realpathSync11(dirname24(recoveryDirectory)) !== dirname24(recoveryDirectory))
61265
61513
  return fail2();
61266
61514
  mkdirSync16(recoveryDirectory, { mode: 448 });
61267
61515
  safeDirectory(recoveryDirectory);
61268
- const parent = openSync18(dirname23(recoveryDirectory), constants14.O_RDONLY | constants14.O_NOFOLLOW);
61516
+ const parent = openSync18(dirname24(recoveryDirectory), constants14.O_RDONLY | constants14.O_NOFOLLOW);
61269
61517
  try {
61270
61518
  fsyncSync5(parent);
61271
61519
  } finally {
@@ -61362,10 +61610,10 @@ var init_private_publication_recovery = __esm(() => {
61362
61610
  });
61363
61611
 
61364
61612
  // src/mcp/private-publication-tools.ts
61365
- import { isAbsolute as isAbsolute19 } from "path";
61613
+ import { isAbsolute as isAbsolute21 } from "path";
61366
61614
  function registerPrivatePublicationTools(server) {
61367
61615
  const uuid9 = exports_external.string().regex(/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/);
61368
- const directory2 = exports_external.string().max(4096).refine(isAbsolute19, "Use an absolute local directory");
61616
+ const directory2 = exports_external.string().max(4096).refine(isAbsolute21, "Use an absolute local directory");
61369
61617
  const verification2 = { email: exports_external.string().email().max(254), code: exports_external.string().regex(/^\d{6}$/), userId: uuid9, membershipId: uuid9, recoveryDirectory: directory2 };
61370
61618
  const description = "Manage a private source publication using fresh workspace-bound verification and a host-local recovery directory. Publishing requires explicit UUID current-version comparison and upload consent. Resume reuses immutable saved bytes and intent; an uncertain PUT is finalized for server verification, never uploaded twice. Sessions and signed URLs are not returned or persisted. Private execution is unavailable. Host request history may contain the supplied verification code.";
61371
61619
  const handler = (action) => async (value) => {
@@ -61777,8 +62025,8 @@ var WSContext = class {
61777
62025
  }
61778
62026
  url;
61779
62027
  protocol;
61780
- close(code2, reason) {
61781
- this.#init.close(code2, reason);
62028
+ close(code2, reason2) {
62029
+ this.#init.close(code2, reason2);
61782
62030
  }
61783
62031
  }, defineWebSocketHelper = (handler) => {
61784
62032
  return (...args) => {
@@ -62058,9 +62306,9 @@ var RequestError, nonJoinedHeaders, validHeaderName, isHttpWhitespace = (code2)
62058
62306
  }, normalizeAbortError = (request2, incoming) => {
62059
62307
  if (incoming.errored)
62060
62308
  return incoming.errored;
62061
- const reason = request2[abortReasonKey];
62062
- if (reason !== undefined)
62063
- return reason instanceof Error ? reason : new Error(String(reason));
62309
+ const reason2 = request2[abortReasonKey];
62310
+ if (reason2 !== undefined)
62311
+ return reason2 instanceof Error ? reason2 : new Error(String(reason2));
62064
62312
  return /* @__PURE__ */ new Error("Client connection prematurely closed.");
62065
62313
  }, readBodyDirect = (request2) => {
62066
62314
  if (request2[bodyBufferKey])
@@ -62077,7 +62325,7 @@ var RequestError, nonJoinedHeaders, validHeaderName, isHttpWhitespace = (code2)
62077
62325
  request2[bodyBufferKey] = buffered;
62078
62326
  return Promise.resolve(buffered);
62079
62327
  }
62080
- const promise3 = new Promise((resolve21, reject) => {
62328
+ const promise3 = new Promise((resolve23, reject) => {
62081
62329
  const chunks = [];
62082
62330
  let settled = false;
62083
62331
  const finish = (callback) => {
@@ -62099,7 +62347,7 @@ var RequestError, nonJoinedHeaders, validHeaderName, isHttpWhitespace = (code2)
62099
62347
  reject(error61 ?? normalizeAbortError(request2, incoming));
62100
62348
  else {
62101
62349
  request2[bodyBufferKey] = recovered;
62102
- resolve21(recovered);
62350
+ resolve23(recovered);
62103
62351
  }
62104
62352
  });
62105
62353
  return true;
@@ -62111,7 +62359,7 @@ var RequestError, nonJoinedHeaders, validHeaderName, isHttpWhitespace = (code2)
62111
62359
  finish(() => {
62112
62360
  const buffer = chunks.length === 1 ? chunks[0] : Buffer.concat(chunks);
62113
62361
  request2[bodyBufferKey] = buffer;
62114
- resolve21(buffer);
62362
+ resolve23(buffer);
62115
62363
  });
62116
62364
  };
62117
62365
  const onError = (error61) => {
@@ -62385,7 +62633,7 @@ var RequestError, nonJoinedHeaders, validHeaderName, isHttpWhitespace = (code2)
62385
62633
  });
62386
62634
  if (!chunk) {
62387
62635
  if (i === 1) {
62388
- await new Promise((resolve21) => setTimeout(resolve21));
62636
+ await new Promise((resolve23) => setTimeout(resolve23));
62389
62637
  maxReadCount = 3;
62390
62638
  continue;
62391
62639
  }
@@ -62686,12 +62934,12 @@ var init_dist2 = __esm(() => {
62686
62934
  get headers() {
62687
62935
  return this[headersKey] ||= newHeadersFromIncoming(this[incomingKey]);
62688
62936
  },
62689
- [abortRequest](reason) {
62937
+ [abortRequest](reason2) {
62690
62938
  if (this[abortReasonKey] === undefined)
62691
- this[abortReasonKey] = reason;
62939
+ this[abortReasonKey] = reason2;
62692
62940
  const abortController = this[abortControllerKey];
62693
62941
  if (abortController && !abortController.signal.aborted)
62694
- abortController.abort(reason);
62942
+ abortController.abort(reason2);
62695
62943
  },
62696
62944
  [getAbortController]() {
62697
62945
  this[abortControllerKey] ||= new AbortController;
@@ -63015,8 +63263,8 @@ var init_dist2 = __esm(() => {
63015
63263
  ws.on("message", bufferMessage);
63016
63264
  const ctx = {
63017
63265
  binaryType: "arraybuffer",
63018
- close(code2, reason) {
63019
- ws.close(code2, reason);
63266
+ close(code2, reason2) {
63267
+ ws.close(code2, reason2);
63020
63268
  },
63021
63269
  protocol: ws.protocol,
63022
63270
  raw: ws,
@@ -63048,11 +63296,11 @@ var init_dist2 = __esm(() => {
63048
63296
  ws.on("message", (data, isBinary) => {
63049
63297
  handleMessage(data, isBinary);
63050
63298
  });
63051
- ws.on("close", (code2, reason) => {
63299
+ ws.on("close", (code2, reason2) => {
63052
63300
  try {
63053
63301
  events2?.onClose?.(new CloseEvent("close", {
63054
63302
  code: code2,
63055
- reason: reason.toString()
63303
+ reason: reason2.toString()
63056
63304
  }), ctx);
63057
63305
  } catch (e2) {
63058
63306
  (options?.onError ?? console.error)(e2);
@@ -63615,9 +63863,9 @@ data:
63615
63863
  const initRequest = messages.find((m) => isInitializeRequest(m));
63616
63864
  const clientProtocolVersion = initRequest ? initRequest.params.protocolVersion : req.headers.get("mcp-protocol-version") ?? DEFAULT_NEGOTIATED_PROTOCOL_VERSION;
63617
63865
  if (this._enableJsonResponse) {
63618
- return new Promise((resolve21) => {
63866
+ return new Promise((resolve23) => {
63619
63867
  this._streamMapping.set(streamId, {
63620
- resolveJson: resolve21,
63868
+ resolveJson: resolve23,
63621
63869
  cleanup: () => {
63622
63870
  this._streamMapping.delete(streamId);
63623
63871
  }
@@ -63986,19 +64234,19 @@ async function connectMcpForNode() {
63986
64234
  return { server: server2, transport };
63987
64235
  }
63988
64236
  function readBody(req) {
63989
- return new Promise((resolve21, reject) => {
64237
+ return new Promise((resolve23, reject) => {
63990
64238
  const chunks = [];
63991
64239
  req.on("data", (chunk) => chunks.push(Buffer.from(chunk)));
63992
64240
  req.on("end", () => {
63993
64241
  const raw = Buffer.concat(chunks).toString("utf-8");
63994
64242
  if (!raw.trim()) {
63995
- resolve21(undefined);
64243
+ resolve23(undefined);
63996
64244
  return;
63997
64245
  }
63998
64246
  try {
63999
- resolve21(JSON.parse(raw));
64247
+ resolve23(JSON.parse(raw));
64000
64248
  } catch {
64001
- resolve21(undefined);
64249
+ resolve23(undefined);
64002
64250
  }
64003
64251
  });
64004
64252
  req.on("error", reject);
@@ -64040,9 +64288,9 @@ async function startSkillsMcpHttpServer(options = {}) {
64040
64288
  }
64041
64289
  }
64042
64290
  });
64043
- await new Promise((resolve21, reject) => {
64291
+ await new Promise((resolve23, reject) => {
64044
64292
  httpServer.once("error", reject);
64045
- httpServer.listen(port, hostname4, () => resolve21());
64293
+ httpServer.listen(port, hostname4, () => resolve23());
64046
64294
  });
64047
64295
  const address = httpServer.address();
64048
64296
  const listenPort = typeof address === "object" && address ? address.port : port;