@hasna/skills 0.10.51 → 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.51",
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) };
@@ -38561,8 +38565,193 @@ var init_codex_native_compatibility = __esm(() => {
38561
38565
  SUPPORTED_CODEX_HOOK_VERSIONS = Object.freeze(Object.keys(MEASURED_CODEX_CAPABILITIES).filter((version2) => supportsCodexNativeCapability(version2, "hooks")));
38562
38566
  });
38563
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
+
38564
38753
  // src/lib/agent-policy-limits.ts
38565
- 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";
38566
38755
  function object4(value) {
38567
38756
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
38568
38757
  }
@@ -38615,7 +38804,7 @@ function assertAgentPolicyCollections(policy) {
38615
38804
  text(control.pluginId, 1024);
38616
38805
  text(control.namespace, 64);
38617
38806
  text(control.pluginParent);
38618
- 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));
38619
38808
  if (control.remotePluginId !== undefined)
38620
38809
  requireBound(typeof control.remotePluginId === "string" && /^[A-Za-z0-9_~-]{1,1024}$/.test(control.remotePluginId));
38621
38810
  if (control.skillsOnly !== undefined)
@@ -38633,10 +38822,18 @@ function assertAgentPolicyCollections(policy) {
38633
38822
  text(control.pluginId, 1024);
38634
38823
  text(control.namespace, 64);
38635
38824
  text(control.pluginParent);
38636
- 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));
38637
38826
  ids.add(control.pluginId);
38638
38827
  }
38639
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
+ }
38640
38837
  if (bridge.disabledBuiltins !== undefined)
38641
38838
  for (const builtin of array3(bridge.disabledBuiltins, AGENT_POLICY_LIMITS.builtinNames)) {
38642
38839
  requireBound(object4(builtin));
@@ -38662,11 +38859,11 @@ function assertAgentPolicyCollections(policy) {
38662
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);
38663
38860
  for (const root of roots) {
38664
38861
  text(root);
38665
- requireBound(isAbsolute4(root) && resolve3(root) === root);
38862
+ requireBound(isAbsolute5(root) && resolve4(root) === root);
38666
38863
  }
38667
38864
  for (const parent of parents2) {
38668
38865
  text(parent);
38669
- requireBound(isAbsolute4(parent) && resolve3(parent) === parent);
38866
+ requireBound(isAbsolute5(parent) && resolve4(parent) === parent);
38670
38867
  }
38671
38868
  for (const directory of array3(proof.directories, AGENT_POLICY_LIMITS.discoveryDirectories)) {
38672
38869
  requireBound(object4(directory));
@@ -38686,7 +38883,7 @@ function assertAgentPolicyCollections(policy) {
38686
38883
  text(input2.namespace, 64);
38687
38884
  text(input2.pluginParent);
38688
38885
  text(input2.sourceRoot);
38689
- 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));
38690
38887
  ids.add(input2.pluginId);
38691
38888
  }
38692
38889
  if (proof.directories !== undefined)
@@ -38703,17 +38900,19 @@ function assertAgentPolicyCollections(policy) {
38703
38900
  text(source.path);
38704
38901
  requireBound(source.sha256 === null || typeof source.sha256 === "string" && /^[a-f0-9]{64}$/.test(source.sha256));
38705
38902
  if (source.hashMode !== undefined)
38706
- 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));
38707
38904
  if (source.hashMode === "claude-plugin-manifest-v1")
38708
- 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);
38709
38906
  if (source.hashMode === "sumi-settings-v1")
38710
- 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");
38711
38908
  if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4"))
38712
- 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");
38713
38910
  if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "claude-settings-v4"))
38714
- 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");
38715
38912
  if (source.hashMode === "claude-marketplace-registry" || source.hashMode === "claude-marketplace-registry-v2")
38716
- 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));
38717
38916
  if (source.hashMode === "claude-plugin-registry") {
38718
38917
  requireBound(agent === "claude");
38719
38918
  const managed = array3(source.managedPlugins, 64);
@@ -38728,8 +38927,8 @@ function assertAgentPolicyCollections(policy) {
38728
38927
  if (source.format !== undefined)
38729
38928
  requireBound(["json", "toml", "yaml"].includes(source.format));
38730
38929
  if (source.fields !== undefined)
38731
- for (const field of array3(source.fields, AGENT_POLICY_LIMITS.fields))
38732
- text(field, 256);
38930
+ for (const field2 of array3(source.fields, AGENT_POLICY_LIMITS.fields))
38931
+ text(field2, 256);
38733
38932
  }
38734
38933
  if (value.directories !== undefined)
38735
38934
  for (const directory of array3(value.directories, AGENT_POLICY_LIMITS.discoveryDirectories)) {
@@ -38745,6 +38944,7 @@ function assertAgentPolicyCollections(policy) {
38745
38944
  var AGENT_POLICY_LIMITS;
38746
38945
  var init_agent_policy_limits = __esm(() => {
38747
38946
  init_codex_native_compatibility();
38947
+ init_claude_marketplace_entry_witness();
38748
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 });
38749
38949
  });
38750
38950
 
@@ -43969,8 +44169,8 @@ var require_cst_visit = __commonJS((exports) => {
43969
44169
  visit2.REMOVE = REMOVE;
43970
44170
  visit2.itemAtPath = (cst, path) => {
43971
44171
  let item = cst;
43972
- for (const [field, index] of path) {
43973
- const tok = item?.[field];
44172
+ for (const [field2, index] of path) {
44173
+ const tok = item?.[field2];
43974
44174
  if (tok && "items" in tok) {
43975
44175
  item = tok.items[index];
43976
44176
  } else
@@ -43980,8 +44180,8 @@ var require_cst_visit = __commonJS((exports) => {
43980
44180
  };
43981
44181
  visit2.parentCollection = (cst, path) => {
43982
44182
  const parent = visit2.itemAtPath(cst, path.slice(0, -1));
43983
- const field = path[path.length - 1][0];
43984
- const coll = parent?.[field];
44183
+ const field2 = path[path.length - 1][0];
44184
+ const coll = parent?.[field2];
43985
44185
  if (coll && "items" in coll)
43986
44186
  return coll;
43987
44187
  throw new Error("Parent collection not found");
@@ -43990,11 +44190,11 @@ var require_cst_visit = __commonJS((exports) => {
43990
44190
  let ctrl = visitor(item, path);
43991
44191
  if (typeof ctrl === "symbol")
43992
44192
  return ctrl;
43993
- for (const field of ["key", "value"]) {
43994
- const token = item[field];
44193
+ for (const field2 of ["key", "value"]) {
44194
+ const token = item[field2];
43995
44195
  if (token && "items" in token) {
43996
44196
  for (let i = 0;i < token.items.length; ++i) {
43997
- 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);
43998
44198
  if (typeof ci === "number")
43999
44199
  i = ci - 1;
44000
44200
  else if (ci === BREAK)
@@ -44004,7 +44204,7 @@ var require_cst_visit = __commonJS((exports) => {
44004
44204
  i -= 1;
44005
44205
  }
44006
44206
  }
44007
- if (typeof ctrl === "function" && field === "key")
44207
+ if (typeof ctrl === "function" && field2 === "key")
44008
44208
  ctrl = ctrl(item, path);
44009
44209
  }
44010
44210
  }
@@ -44430,9 +44630,9 @@ var require_lexer = __commonJS((exports) => {
44430
44630
  }
44431
44631
  }
44432
44632
  *parseQuotedScalar() {
44433
- const quote = this.charAt(0);
44434
- let end = this.buffer.indexOf(quote, this.pos + 1);
44435
- if (quote === "'") {
44633
+ const quote2 = this.charAt(0);
44634
+ let end = this.buffer.indexOf(quote2, this.pos + 1);
44635
+ if (quote2 === "'") {
44436
44636
  while (end !== -1 && this.buffer[end + 1] === "'")
44437
44637
  end = this.buffer.indexOf("'", end + 2);
44438
44638
  } else {
@@ -45739,7 +45939,7 @@ var init_dist = __esm(() => {
45739
45939
  });
45740
45940
 
45741
45941
  // src/lib/agent-hermes.ts
45742
- 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";
45743
45943
  function object5(value) {
45744
45944
  return Boolean(value && typeof value === "object" && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null));
45745
45945
  }
@@ -45773,7 +45973,7 @@ function assertHermesEnvironment(home) {
45773
45973
  throw new Error(`NATIVE_SKILL_DRIFT: Hermes ${variable} requires a dedicated discovery adapter; unset it before using this adapter`);
45774
45974
  }
45775
45975
  const selected = process.env.HERMES_HOME?.trim();
45776
- if (selected && (!isAbsolute5(selected) || resolve4(selected) !== join11(resolve4(home), ".hermes")))
45976
+ if (selected && (!isAbsolute6(selected) || resolve5(selected) !== join11(resolve5(home), ".hermes")))
45777
45977
  throw new Error("NATIVE_SKILL_DRIFT: custom Hermes homes/profiles require their own reviewed bridge");
45778
45978
  if (process.env.HERMES_ENABLE_PROJECT_PLUGINS?.trim() && !["0", "false", "no", "off"].includes(process.env.HERMES_ENABLE_PROJECT_PLUGINS.trim().toLowerCase()))
45779
45979
  throw new Error("NATIVE_SKILL_DRIFT: Hermes project plugins require a dedicated discovery review");
@@ -45783,18 +45983,18 @@ var init_agent_hermes = __esm(() => {
45783
45983
  });
45784
45984
 
45785
45985
  // src/lib/agent-discovery-directories.ts
45786
- import { createHash as createHash3 } from "crypto";
45986
+ import { createHash as createHash4 } from "crypto";
45787
45987
  import { lstatSync as lstatSync6, opendirSync } from "fs";
45788
- import { dirname as dirname6, isAbsolute as isAbsolute6, join as join12, resolve as resolve5 } from "path";
45789
- 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) {
45790
45990
  if (!value)
45791
45991
  throw new Error(message);
45792
45992
  }
45793
45993
  function safe(path) {
45794
- 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");
45795
- for (let cursor = path;; cursor = dirname6(cursor)) {
45796
- need2(!lstatSync6(cursor, { throwIfNoEntry: false })?.isSymbolicLink(), "Refusing symlink native discovery directory");
45797
- 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)
45798
45998
  break;
45799
45999
  }
45800
46000
  }
@@ -45808,45 +46008,45 @@ function capture(path, budget2, excludedRoots, omittedRoots = [], rows) {
45808
46008
  const root = lstatSync6(path, { throwIfNoEntry: false });
45809
46009
  if (!root)
45810
46010
  return { path, sha256: null };
45811
- need2(root.isDirectory(), "Unsupported native discovery directory input");
45812
- const hash2 = createHash3("sha256");
46011
+ need3(root.isDirectory(), "Unsupported native discovery directory input");
46012
+ const hash2 = createHash4("sha256");
45813
46013
  function walk(current, relative3, before, depth) {
45814
- need2(depth <= 64, "Native discovery directory depth limit exceeded");
46014
+ need3(depth <= 64, "Native discovery directory depth limit exceeded");
45815
46015
  const names = [], directory = opendirSync(current);
45816
46016
  try {
45817
46017
  for (let entry = directory.readSync();entry; entry = directory.readSync()) {
45818
- 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");
45819
46019
  names.push(entry.name);
45820
46020
  }
45821
46021
  } finally {
45822
46022
  directory.closeSync();
45823
46023
  }
45824
- 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");
45825
46025
  for (const name of names.sort()) {
45826
- const child = join12(current, name), childRelative = relative3 ? `${relative3}/${name}` : name;
45827
- if (omittedRoots.includes(child))
46026
+ const child2 = join12(current, name), childRelative = relative3 ? `${relative3}/${name}` : name;
46027
+ if (omittedRoots.includes(child2))
45828
46028
  continue;
45829
- need2(child.length <= AGENT_POLICY_LIMITS.pathCharacters, "Native discovery directory path limit exceeded");
45830
- const stat = lstatSync6(child);
45831
- 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");
45832
46032
  const row = JSON.stringify([childRelative, stat.isDirectory() ? "directory" : "file"]) + `
45833
46033
  `;
45834
46034
  budget2.bytes += Buffer.byteLength(row);
45835
- 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");
45836
46036
  hash2.update(row);
45837
46037
  rows?.push(row);
45838
- if (stat.isDirectory() && !excludedRoots.includes(child))
45839
- walk(child, childRelative, stat, depth + 1);
46038
+ if (stat.isDirectory() && !excludedRoots.includes(child2))
46039
+ walk(child2, childRelative, stat, depth + 1);
45840
46040
  }
45841
- 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");
45842
46042
  }
45843
46043
  walk(path, "", root, 0);
45844
46044
  safe(path);
45845
46045
  return { path, sha256: hash2.digest("hex") };
45846
46046
  }
45847
46047
  function captureDiscoveryDirectoryProjection(paths, omittedRoots) {
45848
- need2(Array.isArray(paths) && paths.length <= AGENT_POLICY_LIMITS.discoveryDirectories && new Set(paths).size === paths.length, "Invalid projected discovery directory collection");
45849
- 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");
45850
46050
  for (const root of omittedRoots)
45851
46051
  safe(root);
45852
46052
  const budget2 = { entries: 0, bytes: 0 };
@@ -45856,65 +46056,65 @@ function captureDiscoveryDirectoryProjection(paths, omittedRoots) {
45856
46056
  });
45857
46057
  }
45858
46058
  function verifyDiscoveryDirectoryProjection(directories, omittedRoots) {
45859
- 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");
45860
46060
  let count = 0, bytes = 0;
45861
46061
  const expected = directories.map((directory) => {
45862
46062
  safe(directory.path);
45863
- need2(Array.isArray(directory.entries), "Missing reviewed directory membership inventory");
45864
- const hash2 = createHash3("sha256");
46063
+ need3(Array.isArray(directory.entries), "Missing reviewed directory membership inventory");
46064
+ const hash2 = createHash4("sha256");
45865
46065
  const kept = [];
45866
46066
  for (const row of directory.entries) {
45867
- 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");
45868
46068
  bytes += Buffer.byteLength(row);
45869
- 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");
45870
46070
  const value = JSON.parse(row);
45871
- 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) + `
45872
46072
  `, "Invalid reviewed directory member");
45873
46073
  hash2.update(row);
45874
46074
  const path = join12(directory.path, value[0]);
45875
46075
  if (!omittedRoots.some((root) => path === root || path.startsWith(root + "/")))
45876
46076
  kept.push(row);
45877
46077
  }
45878
- 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");
45879
46079
  const absent = omittedRoots.some((root) => directory.path === root || directory.path.startsWith(root + "/"));
45880
- 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") };
45881
46081
  });
45882
46082
  const current = captureDiscoveryDirectoryProjection(directories.map((item) => item.path), omittedRoots);
45883
- 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");
45884
46084
  }
45885
46085
  function captureDiscoveryDirectories(paths, excludedRoots = []) {
45886
- 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");
45887
46087
  const budget2 = { entries: 0, bytes: 0 };
45888
46088
  for (const root of excludedRoots)
45889
46089
  safe(root);
45890
46090
  return paths.map((path) => capture(path, budget2, excludedRoots));
45891
46091
  }
45892
46092
  function verifyDiscoveryDirectories(directories, excludedRoots = []) {
45893
- 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");
45894
46094
  for (const directory of directories)
45895
- 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");
45896
46096
  const current = captureDiscoveryDirectories(directories.map((directory) => directory.path), excludedRoots);
45897
46097
  for (let i = 0;i < directories.length; i++)
45898
- 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}`);
45899
46099
  }
45900
46100
  var init_agent_discovery_directories = __esm(() => {
45901
46101
  init_agent_policy_limits();
45902
46102
  });
45903
46103
 
45904
46104
  // src/lib/agent-discovery-bytes.ts
45905
- import { createHash as createHash4 } from "crypto";
46105
+ import { createHash as createHash5 } from "crypto";
45906
46106
  import { closeSync as closeSync6, constants as constants3, fstatSync as fstatSync6, lstatSync as lstatSync7, openSync as openSync6, readSync as readSync3 } from "fs";
45907
- 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";
45908
46108
  function discoveryByteBudget() {
45909
46109
  return { remaining: AGENT_POLICY_LIMITS.discoveryRawTotalBytes };
45910
46110
  }
45911
46111
  function safe2(path) {
45912
- 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"))
45913
46113
  throw new Error("Expected a canonical absolute raw discovery path");
45914
- for (let cursor = path;; cursor = dirname7(cursor)) {
46114
+ for (let cursor = path;; cursor = dirname8(cursor)) {
45915
46115
  if (lstatSync7(cursor, { throwIfNoEntry: false })?.isSymbolicLink())
45916
46116
  throw new Error("Refusing symlink raw discovery input");
45917
- if (dirname7(cursor) === cursor)
46117
+ if (dirname8(cursor) === cursor)
45918
46118
  break;
45919
46119
  }
45920
46120
  }
@@ -45933,7 +46133,7 @@ function hashRawDiscoveryFile(path, budget2, changes) {
45933
46133
  if (bytes > AGENT_POLICY_LIMITS.discoveryRawSourceBytes)
45934
46134
  throw new Error("Raw discovery file byte limit exceeded");
45935
46135
  consume(budget2, bytes);
45936
- return createHash4("sha256").update(text2).digest("hex");
46136
+ return createHash5("sha256").update(text2).digest("hex");
45937
46137
  }
45938
46138
  const initial = lstatSync7(path, { throwIfNoEntry: false });
45939
46139
  if (!initial)
@@ -45947,7 +46147,7 @@ function hashRawDiscoveryFile(path, budget2, changes) {
45947
46147
  const opened = fstatSync6(fd);
45948
46148
  if (!opened.isFile() || !same2(initial, opened))
45949
46149
  throw new Error("Raw discovery input changed during open");
45950
- const hash2 = createHash4("sha256"), buffer = Buffer.alloc(64 * 1024);
46150
+ const hash2 = createHash5("sha256"), buffer = Buffer.alloc(64 * 1024);
45951
46151
  let bytes = 0;
45952
46152
  while (true) {
45953
46153
  const count = readSync3(fd, buffer, 0, Math.min(buffer.length, AGENT_POLICY_LIMITS.discoveryRawSourceBytes - bytes + 1), null);
@@ -45973,9 +46173,9 @@ var init_agent_discovery_bytes = __esm(() => {
45973
46173
  });
45974
46174
 
45975
46175
  // src/lib/agent-discovery-path-bytes.ts
45976
- import { createHash as createHash5 } from "crypto";
46176
+ import { createHash as createHash6 } from "crypto";
45977
46177
  import { lstatSync as lstatSync8, readlinkSync } from "fs";
45978
- 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";
45979
46179
  function identity2(stat, mutable = false) {
45980
46180
  return {
45981
46181
  dev: String(stat.dev),
@@ -45986,12 +46186,12 @@ function identity2(stat, mutable = false) {
45986
46186
  ...mutable ? { size: String(stat.size), mtimeNs: String(stat.mtimeNs), ctimeNs: String(stat.ctimeNs) } : {}
45987
46187
  };
45988
46188
  }
45989
- function canonical2(path) {
45990
- 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)
45991
46191
  throw new Error("Expected a canonical absolute discovery path");
45992
46192
  }
45993
46193
  function trace(path) {
45994
- canonical2(path);
46194
+ canonical3(path);
45995
46195
  const rows = [], paths = [];
45996
46196
  let metadataBytes = 0, steps = 0, links = 0, cursor = parse7(path).root, pending = path.slice(cursor.length).split(sep4);
45997
46197
  function record4(path2, row) {
@@ -46016,7 +46216,7 @@ function trace(path) {
46016
46216
  if (!component || component === ".")
46017
46217
  continue;
46018
46218
  if (component === "..") {
46019
- cursor = dirname8(cursor);
46219
+ cursor = dirname9(cursor);
46020
46220
  continue;
46021
46221
  }
46022
46222
  const candidate = join13(cursor, component);
@@ -46036,11 +46236,11 @@ function trace(path) {
46036
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)))
46037
46237
  throw new Error("Discovery link changed during read");
46038
46238
  record4(candidate, { type: "link", target, ...identity2(stat, true) });
46039
- if (isAbsolute8(target)) {
46239
+ if (isAbsolute9(target)) {
46040
46240
  cursor = parse7(target).root;
46041
46241
  root();
46042
46242
  }
46043
- const remainder = isAbsolute8(target) ? target.slice(parse7(target).root.length) : target;
46243
+ const remainder = isAbsolute9(target) ? target.slice(parse7(target).root.length) : target;
46044
46244
  pending = [...remainder.split(sep4), ...pending];
46045
46245
  if (pending.length + steps > AGENT_POLICY_LIMITS.discoveryPathSteps)
46046
46246
  throw new Error("Discovery path step limit exceeded");
@@ -46083,7 +46283,7 @@ function hashDiscoveryPathFile(path, budget2, changes) {
46083
46283
  const after = trace(path);
46084
46284
  if (JSON.stringify(before.rows) !== JSON.stringify(after.rows) || before.file !== after.file)
46085
46285
  throw new Error("Discovery path input changed during read");
46086
- 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");
46087
46287
  }
46088
46288
  var init_agent_discovery_path_bytes = __esm(() => {
46089
46289
  init_agent_policy_limits();
@@ -46091,10 +46291,10 @@ var init_agent_discovery_path_bytes = __esm(() => {
46091
46291
  });
46092
46292
 
46093
46293
  // src/lib/claude-plugin-manifest-witness.ts
46094
- import { createHash as createHash6 } from "crypto";
46095
- function requireValue(value, reason) {
46294
+ import { createHash as createHash7 } from "crypto";
46295
+ function requireValue(value, reason2) {
46096
46296
  if (!value)
46097
- throw new Error("Claude plugin manifest " + reason);
46297
+ throw new Error("Claude plugin manifest " + reason2);
46098
46298
  }
46099
46299
  function parse8(text2) {
46100
46300
  requireValue(Buffer.byteLength(text2, "utf8") <= CLAUDE_PLUGIN_MANIFEST_LIMITS.bytes, "exceeds its byte limit");
@@ -46170,7 +46370,7 @@ function parse8(text2) {
46170
46370
  requireValue(at === text2.length && root.kind === "object", "requires a JSON object without trailing content");
46171
46371
  return root;
46172
46372
  }
46173
- function canonical3(value) {
46373
+ function canonical4(value) {
46174
46374
  if (value.kind === "string")
46175
46375
  return JSON.stringify(value.value);
46176
46376
  if (value.kind === "number")
@@ -46178,18 +46378,18 @@ function canonical3(value) {
46178
46378
  if (value.kind === "literal")
46179
46379
  return value.value;
46180
46380
  if (value.kind === "array")
46181
- return "[" + value.items.map(canonical3).join(",") + "]";
46182
- 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(",") + "}";
46183
46383
  }
46184
- function validateText(value, field) {
46185
- 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");
46186
46386
  }
46187
46387
  function validateDescriptiveFields(manifest) {
46188
46388
  const values = new Map(manifest.entries);
46189
- for (const field of ["description", "version", "homepage", "license"]) {
46190
- const value = values.get(field);
46389
+ for (const field2 of ["description", "version", "homepage", "license"]) {
46390
+ const value = values.get(field2);
46191
46391
  if (value !== undefined)
46192
- validateText(value, field);
46392
+ validateText(value, field2);
46193
46393
  }
46194
46394
  const author = values.get("author");
46195
46395
  if (author !== undefined) {
@@ -46214,10 +46414,10 @@ function hashClaudePluginManifest(text2) {
46214
46414
  const manifest = parse8(text2);
46215
46415
  validateDescriptiveFields(manifest);
46216
46416
  const discovery = { kind: "object", entries: manifest.entries.filter(([key]) => !DESCRIPTIVE_FIELDS.has(key)) };
46217
- return createHash6("sha256").update(canonical3(discovery)).digest("hex");
46417
+ return createHash7("sha256").update(canonical4(discovery)).digest("hex");
46218
46418
  }
46219
46419
  function projectReviewedClaudePluginManifest(text2, reviewedSha256) {
46220
- 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) {
46221
46421
  throw new Error("Reviewed Claude plugin manifest changed before semantic projection");
46222
46422
  }
46223
46423
  return hashClaudePluginManifest(text2);
@@ -46229,7 +46429,7 @@ var init_claude_plugin_manifest_witness = __esm(() => {
46229
46429
  });
46230
46430
 
46231
46431
  // src/lib/skill-bundle.ts
46232
- import { createHash as createHash7 } from "crypto";
46432
+ import { createHash as createHash8 } from "crypto";
46233
46433
  import { readFileSync as readFileSync9, readdirSync as readdirSync4, statSync as statSync6 } from "fs";
46234
46434
  import { join as join14, relative as relative3 } from "path";
46235
46435
  import { createGunzip } from "zlib";
@@ -46261,7 +46461,7 @@ function ownBytes(view) {
46261
46461
  return out;
46262
46462
  }
46263
46463
  function sha256Hex(bytes) {
46264
- return createHash7("sha256").update(bytes).digest("hex");
46464
+ return createHash8("sha256").update(bytes).digest("hex");
46265
46465
  }
46266
46466
  function collectSkillBundleEntries(dir) {
46267
46467
  const entries = [];
@@ -46389,12 +46589,12 @@ function inspectionLimits(options) {
46389
46589
  for (const key of Object.keys(options.limits ?? {})) {
46390
46590
  if (!Object.hasOwn(limits, key))
46391
46591
  throw new SkillBundleInspectionError("BUNDLE_LIMIT", "Unknown bundle limit");
46392
- const field = key;
46393
- const value = options.limits[field];
46394
- 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]) {
46395
46595
  throw new SkillBundleInspectionError("BUNDLE_LIMIT", "Bundle limits must be positive integers within the hard ceilings");
46396
46596
  }
46397
- limits[field] = value;
46597
+ limits[field2] = value;
46398
46598
  }
46399
46599
  return limits;
46400
46600
  }
@@ -46424,7 +46624,14 @@ async function inspectSkillBundle(bundle, options = {}) {
46424
46624
  decoder.destroy(terminalError);
46425
46625
  };
46426
46626
  const onAbort = () => stop("BUNDLE_ABORTED");
46427
- 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())));
46428
46635
  signal?.addEventListener("abort", onAbort, { once: true });
46429
46636
  let decompressedByteSize = 0;
46430
46637
  let bytesSinceYield = 0;
@@ -46439,7 +46646,7 @@ async function inspectSkillBundle(bundle, options = {}) {
46439
46646
  parser2.push(chunk);
46440
46647
  bytesSinceYield += chunk.byteLength;
46441
46648
  if (bytesSinceYield >= 256 * 1024) {
46442
- await new Promise((resolve8) => setTimeout(resolve8, 0));
46649
+ await new Promise((resolve9) => setTimeout(resolve9, 0));
46443
46650
  bytesSinceYield = 0;
46444
46651
  check2();
46445
46652
  }
@@ -46576,8 +46783,8 @@ class BoundedTarReader {
46576
46783
  }
46577
46784
  }
46578
46785
  }
46579
- function tarOctal(field) {
46580
- const text2 = new TextDecoder().decode(field);
46786
+ function tarOctal(field2) {
46787
+ const text2 = new TextDecoder().decode(field2);
46581
46788
  if (!/^[0-7]+[\0 ]*$/.test(text2))
46582
46789
  invalidBundle("Invalid tar octal field");
46583
46790
  const value = Number.parseInt(text2, 8);
@@ -46796,21 +47003,21 @@ var init_profile_limits = __esm(() => {
46796
47003
  });
46797
47004
 
46798
47005
  // src/lib/selection-cache.ts
46799
- import { createHash as createHash8, randomUUID } from "crypto";
47006
+ import { createHash as createHash9, randomUUID } from "crypto";
46800
47007
  import { spawnSync as spawnSync2 } from "child_process";
46801
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";
46802
47009
  import { hostname as hostname3 } from "os";
46803
- 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";
46804
47011
  import { isDeepStrictEqual } from "util";
46805
47012
  function selectionCacheRoot(options = {}) {
46806
- return resolve8(options.cacheDir ?? join15(getDataDirReadOnly(), "selection-cache"));
47013
+ return resolve9(options.cacheDir ?? join15(getDataDirReadOnly(), "selection-cache"));
46807
47014
  }
46808
47015
  function selectionKey(selection) {
46809
47016
  validateSelection(selection);
46810
47017
  return hash2([selection.authority, selection.workspaceId, selection.slug, selection.version, selection.bundleDigest]);
46811
47018
  }
46812
47019
  function hash2(value) {
46813
- return createHash8("sha256").update(JSON.stringify(value)).digest("hex");
47020
+ return createHash9("sha256").update(JSON.stringify(value)).digest("hex");
46814
47021
  }
46815
47022
  function validateSelection(selection) {
46816
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()) {
@@ -46850,7 +47057,7 @@ function selectionBundlePath(selection, options = {}) {
46850
47057
  return join15(selectionCacheRoot(options), "objects", hash2(selection.authority), hash2(selection.workspaceId), `${selection.bundleDigest.slice(7)}.tar.gz`);
46851
47058
  }
46852
47059
  function assertRegularPath(path, createParents = false) {
46853
- const absolute = resolve8(path);
47060
+ const absolute = resolve9(path);
46854
47061
  const root = parse9(absolute).root;
46855
47062
  let cursor = root;
46856
47063
  const segments = absolute.slice(root.length).split("/");
@@ -46907,7 +47114,7 @@ function writeSelectionJson(path, value) {
46907
47114
  }
46908
47115
  function atomicWrite(path, bytes, mode, durable = false) {
46909
47116
  assertRegularPath(path, true);
46910
- const temporary = join15(dirname9(path), `.selection-${randomUUID()}.tmp`);
47117
+ const temporary = join15(dirname10(path), `.selection-${randomUUID()}.tmp`);
46911
47118
  try {
46912
47119
  const fd = openSync7(temporary, constants4.O_WRONLY | constants4.O_CREAT | constants4.O_EXCL | constants4.O_NOFOLLOW, mode);
46913
47120
  try {
@@ -46919,7 +47126,7 @@ function atomicWrite(path, bytes, mode, durable = false) {
46919
47126
  }
46920
47127
  renameSync(temporary, path);
46921
47128
  if (durable)
46922
- syncDirectory(dirname9(path));
47129
+ syncDirectory(dirname10(path));
46923
47130
  } finally {
46924
47131
  try {
46925
47132
  unlinkSync(temporary);
@@ -46929,8 +47136,8 @@ function atomicWrite(path, bytes, mode, durable = false) {
46929
47136
  }
46930
47137
  }
46931
47138
  }
46932
- function readSelectionJson(path) {
46933
- 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));
46934
47141
  if (!bytes)
46935
47142
  return null;
46936
47143
  try {
@@ -46942,10 +47149,10 @@ function readSelectionJson(path) {
46942
47149
  async function verifiedEntries(selection, bytes, signal, deadline) {
46943
47150
  if (`sha256:${sha256Hex(bytes)}` !== selection.bundleDigest)
46944
47151
  throw new SkillSelectionError("BUNDLE_DIGEST_MISMATCH", "The skill bundle does not match its selected digest.");
46945
- const remaining = deadline === undefined ? undefined : Math.floor(deadline - performance.now());
47152
+ const remaining = deadline === undefined ? undefined : Math.ceil(deadline - performance.now());
46946
47153
  signal?.throwIfAborted();
46947
47154
  if (remaining !== undefined && remaining <= 0)
46948
- throw new SkillSelectionError("SKILLS_API_UNAVAILABLE", "Skills session authorization deadline exceeded.");
47155
+ throw new SkillBundleInspectionError("BUNDLE_TIMEOUT", "Bundle inspection deadline exceeded");
46949
47156
  const bundle = await inspectSkillBundle(bytes, { signal, ...remaining === undefined ? {} : { limits: { timeoutMs: remaining } } });
46950
47157
  return bundle.entries;
46951
47158
  }
@@ -47045,7 +47252,7 @@ function assertFreshCachedProfile(receipt, options = {}) {
47045
47252
  }
47046
47253
  }
47047
47254
  function projectSelectionLockPath(projectDir) {
47048
- return join15(resolve8(projectDir), ".skills", SELECTION_LOCK_FILE);
47255
+ return join15(resolve9(projectDir), ".skills", SELECTION_LOCK_FILE);
47049
47256
  }
47050
47257
  function readProjectSelection(projectDir) {
47051
47258
  const receipt = readSelectionJson(projectSelectionLockPath(projectDir));
@@ -47196,13 +47403,13 @@ function publishSessionLock(path, marker) {
47196
47403
  fsyncSync(fd);
47197
47404
  linkSync(stagingPath, path);
47198
47405
  published = true;
47199
- syncDirectory(dirname9(path));
47406
+ syncDirectory(dirname10(path));
47200
47407
  const staged = lstatSync9(stagingPath);
47201
47408
  if (!staged.isFile() || staged.dev !== stat.dev || staged.ino !== stat.ino) {
47202
47409
  throw new SkillSelectionError("SESSION_WRITE_LOCK_CHANGED", "The initialized lock staging inode changed before publication completed.");
47203
47410
  }
47204
47411
  unlinkSync(stagingPath);
47205
- syncDirectory(dirname9(path));
47412
+ syncDirectory(dirname10(path));
47206
47413
  handedOff = true;
47207
47414
  return { path, stagingPath, fd, dev: stat.dev, ino: stat.ino };
47208
47415
  } finally {
@@ -47247,14 +47454,14 @@ function archiveSessionLock(lock, receipt, explicitLocalHost) {
47247
47454
  writeFileSync3(guardFd, `${JSON.stringify({ schemaVersion: 1, pid: process.pid, operationId: randomUUID() })}
47248
47455
  `);
47249
47456
  fsyncSync(guardFd);
47250
- const cacheOptions = { cacheDir: dirname9(dirname9(lock.path)) };
47457
+ const cacheOptions = { cacheDir: dirname10(dirname10(lock.path)) };
47251
47458
  const current = readSessionLock(lock.marker.sessionId, cacheOptions);
47252
47459
  if (!current || current.dev !== lock.dev || current.ino !== lock.ino || current.sha256 !== lock.sha256 || current.mtimeMs !== lock.mtimeMs || !writerIsGone(current, explicitLocalHost))
47253
47460
  return null;
47254
47461
  const currentReceipt = readSkillSessionSnapshotIfExists(lock.marker.sessionId, cacheOptions);
47255
47462
  if (currentReceipt?.sha256 !== receipt?.sha256 || currentReceipt?.generation !== receipt?.generation)
47256
47463
  return null;
47257
- const directory = join15(dirname9(dirname9(lock.path)), "session-lock-recoveries", randomUUID());
47464
+ const directory = join15(dirname10(dirname10(lock.path)), "session-lock-recoveries", randomUUID());
47258
47465
  const archivePath = join15(directory, "original.write-lock");
47259
47466
  const recordPath = join15(directory, "recovery.json");
47260
47467
  assertRegularPath(archivePath, true);
@@ -47271,7 +47478,7 @@ function archiveSessionLock(lock, receipt, explicitLocalHost) {
47271
47478
  })}
47272
47479
  `));
47273
47480
  syncDirectory(directory);
47274
- syncDirectory(dirname9(directory));
47481
+ syncDirectory(dirname10(directory));
47275
47482
  const finalLock = readSessionLock(lock.marker.sessionId, cacheOptions);
47276
47483
  if (!finalLock || finalLock.dev !== lock.dev || finalLock.ino !== lock.ino || finalLock.sha256 !== lock.sha256 || readSkillSessionSnapshotIfExists(lock.marker.sessionId, cacheOptions)?.sha256 !== receipt?.sha256)
47277
47484
  return null;
@@ -47286,7 +47493,7 @@ function archiveSessionLock(lock, receipt, explicitLocalHost) {
47286
47493
  archivedPaths.push(publicationPath);
47287
47494
  }
47288
47495
  syncDirectory(directory);
47289
- syncDirectory(dirname9(lock.path));
47496
+ syncDirectory(dirname10(lock.path));
47290
47497
  for (const path of archivedPaths) {
47291
47498
  const before = lstatSync9(path, { throwIfNoEntry: false });
47292
47499
  const bytes = readRegularFile(path, SESSION_LOCK_MAX_BYTES);
@@ -47437,8 +47644,8 @@ var init_selection_cache = __esm(() => {
47437
47644
  init_profile_limits();
47438
47645
  SkillSelectionError = class SkillSelectionError extends Error {
47439
47646
  code;
47440
- constructor(code, message) {
47441
- super(message);
47647
+ constructor(code, message, options) {
47648
+ super(message, options);
47442
47649
  this.code = code;
47443
47650
  this.name = "SkillSelectionError";
47444
47651
  }
@@ -47455,7 +47662,7 @@ __export(exports_remote_files, {
47455
47662
  decodeRemoteFiles: () => decodeRemoteFiles,
47456
47663
  MAX_REMOTE_FILE_BYTES: () => MAX_REMOTE_FILE_BYTES
47457
47664
  });
47458
- import { createHash as createHash9 } from "crypto";
47665
+ import { createHash as createHash10 } from "crypto";
47459
47666
  function describeRemoteFiles(files) {
47460
47667
  if (files.length > 10)
47461
47668
  throw new Error("At most 10 input files are supported");
@@ -47472,7 +47679,7 @@ function describeRemoteFiles(files) {
47472
47679
  });
47473
47680
  }
47474
47681
  function sha256(bytes) {
47475
- return createHash9("sha256").update(bytes).digest("hex");
47682
+ return createHash10("sha256").update(bytes).digest("hex");
47476
47683
  }
47477
47684
  async function readBoundedResponse(response, maximum, signal) {
47478
47685
  if (!Number.isSafeInteger(maximum) || maximum < 0 || maximum > MAX_REMOTE_FILE_BYTES)
@@ -47548,6 +47755,10 @@ function identifier(value) {
47548
47755
  function invalid() {
47549
47756
  throw new Error("The Skills API returned an invalid profile response");
47550
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
+ }
47551
47762
  function validateSelection2(value) {
47552
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))
47553
47764
  invalid();
@@ -47595,8 +47806,8 @@ class HttpProfileClient {
47595
47806
  ...init.headers
47596
47807
  }
47597
47808
  });
47598
- } catch {
47599
- 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");
47600
47811
  }
47601
47812
  if (!response.ok) {
47602
47813
  response.body?.cancel().catch(() => {});
@@ -47613,7 +47824,9 @@ class HttpProfileClient {
47613
47824
  async read(response, limit = MAX_PROFILE_DOCUMENT_BYTES) {
47614
47825
  try {
47615
47826
  return JSON.parse(new TextDecoder().decode(await readBoundedResponse(response, limit, this.signal)));
47616
- } catch {
47827
+ } catch (error61) {
47828
+ if (this.signal?.aborted)
47829
+ throw unavailable(this.signal.reason ?? error61, "The Skills API response was cut short");
47617
47830
  invalid();
47618
47831
  }
47619
47832
  }
@@ -47703,17 +47916,17 @@ var init_profile_client = __esm(() => {
47703
47916
  });
47704
47917
 
47705
47918
  // src/lib/preparation-process.ts
47706
- 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)) {
47707
47920
  let spawnedPid;
47708
47921
  try {
47709
- spawnedPid = child.pid;
47922
+ spawnedPid = child2.pid;
47710
47923
  } catch {}
47711
47924
  const groupId = typeof spawnedPid === "number" && Number.isSafeInteger(spawnedPid) && spawnedPid > 1 ? spawnedPid : undefined;
47712
47925
  const canSignalGroup = platform !== "win32" && groupId !== undefined;
47713
47926
  const killLiveChild = () => {
47714
- if (child.exitCode === null && child.signalCode === null) {
47927
+ if (child2.exitCode === null && child2.signalCode === null) {
47715
47928
  try {
47716
- child.kill("SIGKILL");
47929
+ child2.kill("SIGKILL");
47717
47930
  } catch {}
47718
47931
  }
47719
47932
  };
@@ -47996,7 +48209,7 @@ var init_codex_native_skill_catalog = __esm(() => {
47996
48209
  });
47997
48210
 
47998
48211
  // src/lib/codex-plugin-skill-controls.ts
47999
- 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";
48000
48213
  import { lstatSync as lstatSync11, readdirSync as readdirSync6, readlinkSync as readlinkSync3, realpathSync as realpathSync3 } from "fs";
48001
48214
  function refuse() {
48002
48215
  throw new Error("CODEX_NATIVE_SKILL_IDENTITY_UNSUPPORTED: review native plugin names and hook controls");
@@ -48060,7 +48273,7 @@ function mcpControls(path, read) {
48060
48273
  function isBundledCleanupHooks(root, namespace, value) {
48061
48274
  const object7 = (v) => Boolean(v && typeof v === "object" && !Array.isArray(v));
48062
48275
  const exactKeys = (v, keys) => Object.keys(v).length === keys.length && keys.every((key) => Object.hasOwn(v, key));
48063
- if (basename5(dirname10(root)) !== namespace || basename5(dirname10(dirname10(root))) !== "openai-bundled")
48276
+ if (basename6(dirname11(root)) !== namespace || basename6(dirname11(dirname11(root))) !== "openai-bundled")
48064
48277
  return false;
48065
48278
  const server = namespace === "unified-computer-use" ? "cua_repl" : ["browser", "chrome", "chrome-dev", "chrome-internal", "computer-use"].includes(namespace) ? "node_repl" : undefined;
48066
48279
  if (!server || !object7(value) || !exactKeys(value, ["hooks"]) || !object7(value.hooks))
@@ -48094,7 +48307,7 @@ function rootControls(root, read) {
48094
48307
  }
48095
48308
  if (!manifest || typeof manifest !== "object" || Array.isArray(manifest) || !identifier2(manifest.name))
48096
48309
  refuse();
48097
- 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;
48098
48311
  if (declaredVersion === null || (declaredVersion ? declaredVersion !== cacheVersion : cacheVersion !== CODEX_DEFAULT_AGENT_PLUGIN_VERSION))
48099
48312
  refuse();
48100
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 }))
@@ -48118,13 +48331,13 @@ function rootControls(root, read) {
48118
48331
  function reviewedDisabledCodexPluginParent(cache, parent, controls, rules) {
48119
48332
  try {
48120
48333
  const parts = relative4(cache, parent).split(sep5), enrolled = controls.filter((control) => control.pluginParent === parent);
48121
- 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))
48122
48335
  return false;
48123
- for (let cursor = parent;; cursor = dirname10(cursor)) {
48336
+ for (let cursor = parent;; cursor = dirname11(cursor)) {
48124
48337
  const stat = lstatSync11(cursor, { throwIfNoEntry: false });
48125
48338
  if (stat && (!stat.isDirectory() || stat.isSymbolicLink()))
48126
48339
  return false;
48127
- if (dirname10(cursor) === cursor)
48340
+ if (dirname11(cursor) === cursor)
48128
48341
  break;
48129
48342
  }
48130
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));
@@ -48137,14 +48350,14 @@ function absentDisabledCodexPluginParent(cache, parent, controls, rules) {
48137
48350
  }
48138
48351
  function reviewedRetiredCodexRoot(cache, root, controls, rules, read, allowAbsent = false) {
48139
48352
  try {
48140
- const parent = dirname10(root), parts = relative4(cache, parent).split(sep5), enrolled = controls.filter((control) => control.pluginParent === parent);
48141
- 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))
48142
48355
  return false;
48143
- for (let cursor = root;; cursor = dirname10(cursor)) {
48356
+ for (let cursor = root;; cursor = dirname11(cursor)) {
48144
48357
  const stat = lstatSync11(cursor, { throwIfNoEntry: false });
48145
48358
  if (stat && (!stat.isDirectory() || stat.isSymbolicLink()))
48146
48359
  return false;
48147
- if (dirname10(cursor) === cursor)
48360
+ if (dirname11(cursor) === cursor)
48148
48361
  break;
48149
48362
  }
48150
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)))
@@ -48191,8 +48404,8 @@ function reviewedCodexPluginCapabilitiesUnchanged(cache, controls, read, rules)
48191
48404
  for (const name of names) {
48192
48405
  let root = join17(parent, name), stat = lstatSync11(root);
48193
48406
  if (stat.isSymbolicLink()) {
48194
- const target = resolve9(parent, readlinkSync3(root));
48195
- 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)
48196
48409
  return false;
48197
48410
  root = target;
48198
48411
  stat = lstatSync11(root);
@@ -48212,7 +48425,7 @@ function reviewedCodexPluginCapabilitiesUnchanged(cache, controls, read, rules)
48212
48425
  function sourceInputUnchanged(input2, cache, read) {
48213
48426
  try {
48214
48427
  const parts = relative4(cache, input2.pluginParent).split(sep5);
48215
- 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))
48216
48429
  return false;
48217
48430
  const path = join17(input2.sourceRoot, ".codex-plugin/plugin.json"), stat = lstatSync11(path);
48218
48431
  if (!stat.isFile() || stat.size > 1024 * 1024 || realpathSync3(path) !== path)
@@ -48250,8 +48463,8 @@ var init_codex_native_skill_policy = __esm(() => {
48250
48463
  });
48251
48464
 
48252
48465
  // src/lib/codex-settings-witness-v1.ts
48253
- import { createHash as createHash10 } from "crypto";
48254
- function need3(value) {
48466
+ import { createHash as createHash11 } from "crypto";
48467
+ function need4(value) {
48255
48468
  if (!value)
48256
48469
  throw new Error("Invalid Codex settings witness");
48257
48470
  }
@@ -48266,14 +48479,14 @@ function numericTokens(text2) {
48266
48479
  continue;
48267
48480
  }
48268
48481
  if (char === '"' || char === "'") {
48269
- 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);
48270
48483
  at += triple ? 3 : 1;
48271
48484
  while (at < text2.length) {
48272
- if (quote === '"' && text2[at] === "\\") {
48485
+ if (quote2 === '"' && text2[at] === "\\") {
48273
48486
  at += 2;
48274
48487
  continue;
48275
48488
  }
48276
- 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)) {
48277
48490
  at += triple ? 3 : 1;
48278
48491
  break;
48279
48492
  }
@@ -48294,8 +48507,8 @@ function numericTokens(text2) {
48294
48507
  }
48295
48508
  return result;
48296
48509
  }
48297
- function canonical4(value, depth = 0, budget2 = { remaining: 65536 }) {
48298
- need3(depth <= 32 && --budget2.remaining >= 0);
48510
+ function canonical5(value, depth = 0, budget2 = { remaining: 65536 }) {
48511
+ need4(depth <= 32 && --budget2.remaining >= 0);
48299
48512
  if (value === null)
48300
48513
  return ["null"];
48301
48514
  if (typeof value === "string")
@@ -48303,20 +48516,20 @@ function canonical4(value, depth = 0, budget2 = { remaining: 65536 }) {
48303
48516
  if (typeof value === "boolean")
48304
48517
  return ["boolean", value];
48305
48518
  if (typeof value === "number") {
48306
- need3(Number.isFinite(value));
48519
+ need4(Number.isFinite(value));
48307
48520
  return ["number", String(value)];
48308
48521
  }
48309
48522
  if (value instanceof Date) {
48310
- need3(Number.isFinite(value.getTime()));
48523
+ need4(Number.isFinite(value.getTime()));
48311
48524
  return ["date", value.toISOString()];
48312
48525
  }
48313
48526
  if (Array.isArray(value))
48314
- return ["array", value.map((child) => canonical4(child, depth + 1, budget2))];
48315
- need3(value && typeof value === "object");
48316
- 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)])];
48317
48530
  }
48318
48531
  function hashCodexSettingsReplacement(text2, budget2 = { remaining: 256 * 1024 * 1024 }) {
48319
- need3(Buffer.byteLength(text2) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text2));
48532
+ need4(Buffer.byteLength(text2) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text2));
48320
48533
  budget2.remaining -= Buffer.byteLength(text2);
48321
48534
  let config2;
48322
48535
  try {
@@ -48324,23 +48537,23 @@ function hashCodexSettingsReplacement(text2, budget2 = { remaining: 256 * 1024 *
48324
48537
  } catch {
48325
48538
  throw new Error("Invalid Codex settings witness");
48326
48539
  }
48327
- need3(config2 && typeof config2 === "object" && !Array.isArray(config2));
48540
+ need4(config2 && typeof config2 === "object" && !Array.isArray(config2));
48328
48541
  if (Object.hasOwn(config2, "model")) {
48329
- 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));
48330
48543
  delete config2.model;
48331
48544
  }
48332
48545
  for (const [key, values] of [["model_reasoning_effort", EFFORT], ["model_verbosity", VERBOSITY]])
48333
48546
  if (Object.hasOwn(config2, key)) {
48334
- need3(typeof config2[key] === "string" && values.has(config2[key]));
48547
+ need4(typeof config2[key] === "string" && values.has(config2[key]));
48335
48548
  delete config2[key];
48336
48549
  }
48337
- 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)])}`);
48338
48551
  }
48339
48552
  function captureCodexSettings(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
48340
48553
  const text2 = readNativeSettingsWitnessFile(path, budget2, "config.toml");
48341
48554
  return { path, hashMode: "codex-settings-v1", sha256: hashCodexSettingsReplacement(text2) };
48342
48555
  }
48343
- var sha = (text2) => createHash10("sha256").update(text2).digest("hex"), EFFORT, VERBOSITY;
48556
+ var sha = (text2) => createHash11("sha256").update(text2).digest("hex"), EFFORT, VERBOSITY;
48344
48557
  var init_codex_settings_witness_v1 = __esm(() => {
48345
48558
  init_claude_settings_witness();
48346
48559
  EFFORT = new Set(["none", "minimal", "low", "medium", "high", "xhigh"]);
@@ -48413,9 +48626,9 @@ function projectRegularCodexMcp(config2, source) {
48413
48626
  var init_codex_mcp_discovery_projection = () => {};
48414
48627
 
48415
48628
  // src/lib/codex-settings-witness.ts
48416
- import { createHash as createHash11 } from "crypto";
48629
+ import { createHash as createHash12 } from "crypto";
48417
48630
  import { isDeepStrictEqual as isDeepStrictEqual3 } from "util";
48418
- function need4(value) {
48631
+ function need5(value) {
48419
48632
  if (!value)
48420
48633
  throw new Error("Invalid Codex settings witness");
48421
48634
  }
@@ -48436,14 +48649,14 @@ function numericTokens2(text2) {
48436
48649
  continue;
48437
48650
  }
48438
48651
  if (char === '"' || char === "'") {
48439
- 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);
48440
48653
  at += triple ? 3 : 1;
48441
48654
  while (at < text2.length) {
48442
- if (quote === '"' && text2[at] === "\\") {
48655
+ if (quote2 === '"' && text2[at] === "\\") {
48443
48656
  at += 2;
48444
48657
  continue;
48445
48658
  }
48446
- 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)) {
48447
48660
  at += triple ? 3 : 1;
48448
48661
  break;
48449
48662
  }
@@ -48464,8 +48677,8 @@ function numericTokens2(text2) {
48464
48677
  }
48465
48678
  return result.sort();
48466
48679
  }
48467
- function canonical5(value, depth = 0, budget2 = { remaining: 65536 }) {
48468
- need4(depth <= 32 && --budget2.remaining >= 0);
48680
+ function canonical6(value, depth = 0, budget2 = { remaining: 65536 }) {
48681
+ need5(depth <= 32 && --budget2.remaining >= 0);
48469
48682
  if (value === null)
48470
48683
  return ["null"];
48471
48684
  if (typeof value === "string")
@@ -48473,17 +48686,17 @@ function canonical5(value, depth = 0, budget2 = { remaining: 65536 }) {
48473
48686
  if (typeof value === "boolean")
48474
48687
  return ["boolean", value];
48475
48688
  if (typeof value === "number") {
48476
- need4(Number.isFinite(value));
48689
+ need5(Number.isFinite(value));
48477
48690
  return ["number", String(value)];
48478
48691
  }
48479
48692
  if (isDate(value)) {
48480
- need4(Number.isFinite(value.getTime()));
48693
+ need5(Number.isFinite(value.getTime()));
48481
48694
  return ["date", value.toISOString()];
48482
48695
  }
48483
48696
  if (Array.isArray(value))
48484
- return ["array", value.map((child) => canonical5(child, depth + 1, budget2))];
48485
- need4(isRecord3(value));
48486
- 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)])];
48487
48700
  }
48488
48701
  function normalize2(config2, version2 = 2) {
48489
48702
  if (isRecord3(config2.hooks)) {
@@ -48525,15 +48738,15 @@ function inference(target, version2) {
48525
48738
  if (Object.hasOwn(target, key)) {
48526
48739
  const value = target[key];
48527
48740
  if (key === "model")
48528
- need4(typeof value === "string" && MODEL.test(value));
48741
+ need5(typeof value === "string" && MODEL.test(value));
48529
48742
  else if (key === "personality")
48530
- need4(typeof value === "string" && ["none", "friendly", "pragmatic"].includes(value));
48743
+ need5(typeof value === "string" && ["none", "friendly", "pragmatic"].includes(value));
48531
48744
  else if (version2 >= 3 && key !== "model_verbosity") {
48532
- 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));
48533
48746
  if (key !== "service_tier")
48534
- need4(value.length > 0);
48747
+ need5(value.length > 0);
48535
48748
  } else
48536
- 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)));
48537
48750
  delete target[key];
48538
48751
  }
48539
48752
  }
@@ -48566,14 +48779,14 @@ function projectModelAvailabilityNux(config2, text2) {
48566
48779
  continue;
48567
48780
  }
48568
48781
  if (char === '"' || char === "'") {
48569
- const quote = char;
48782
+ const quote2 = char;
48570
48783
  at++;
48571
48784
  while (at < span.length) {
48572
- if (quote === '"' && span[at] === "\\") {
48785
+ if (quote2 === '"' && span[at] === "\\") {
48573
48786
  at += 2;
48574
48787
  continue;
48575
48788
  }
48576
- if (span[at++] === quote)
48789
+ if (span[at++] === quote2)
48577
48790
  break;
48578
48791
  }
48579
48792
  continue;
@@ -48653,14 +48866,14 @@ function settingsDigest2(text2, version2 = 2) {
48653
48866
  } catch {
48654
48867
  throw new Error("Invalid Codex settings witness");
48655
48868
  }
48656
- need4(isRecord3(config2));
48869
+ need5(isRecord3(config2));
48657
48870
  const mcp = version2 >= 3 ? projectRegularCodexMcp(config2, text2) : { config: config2, numericSource: text2 };
48658
48871
  const projected = version2 === 4 ? projectModelAvailabilityNux(mcp.config, mcp.numericSource) : mcp;
48659
48872
  normalize2(projected.config, version2);
48660
- 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)])}`);
48661
48874
  }
48662
48875
  function hashCodexSettingsReplacementV2(text2, budget2 = { remaining: 256 * 1024 * 1024 }) {
48663
- need4(Buffer.byteLength(text2) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text2));
48876
+ need5(Buffer.byteLength(text2) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text2));
48664
48877
  budget2.remaining -= Buffer.byteLength(text2);
48665
48878
  return settingsDigest2(text2);
48666
48879
  }
@@ -48669,7 +48882,7 @@ function captureCodexSettingsV2(path, budget2 = { remaining: 256 * 1024 * 1024 }
48669
48882
  return { path, hashMode: "codex-settings-v2", sha256: settingsDigest2(text2) };
48670
48883
  }
48671
48884
  function hashCodexSettingsReplacementV3(text2, budget2 = { remaining: 256 * 1024 * 1024 }) {
48672
- need4(Buffer.byteLength(text2) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text2));
48885
+ need5(Buffer.byteLength(text2) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text2));
48673
48886
  budget2.remaining -= Buffer.byteLength(text2);
48674
48887
  return settingsDigest2(text2, 3);
48675
48888
  }
@@ -48677,14 +48890,14 @@ function captureCodexSettingsV3(path, budget2 = { remaining: 256 * 1024 * 1024 }
48677
48890
  return { path, hashMode: "codex-settings-v3", sha256: settingsDigest2(readNativeSettingsWitnessFile(path, budget2, "config.toml"), 3) };
48678
48891
  }
48679
48892
  function hashCodexSettingsReplacementV4(text2, budget2 = { remaining: 256 * 1024 * 1024 }) {
48680
- need4(Buffer.byteLength(text2) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text2));
48893
+ need5(Buffer.byteLength(text2) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text2));
48681
48894
  budget2.remaining -= Buffer.byteLength(text2);
48682
48895
  return settingsDigest2(text2, 4);
48683
48896
  }
48684
48897
  function captureCodexSettingsV4(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
48685
48898
  return { path, hashMode: "codex-settings-v4", sha256: settingsDigest2(readNativeSettingsWitnessFile(path, budget2, "config.toml"), 4) };
48686
48899
  }
48687
- 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;
48688
48901
  var init_codex_settings_witness = __esm(() => {
48689
48902
  init_codex_settings_witness_v1();
48690
48903
  init_codex_settings_witness_v1();
@@ -48700,8 +48913,8 @@ var init_codex_settings_witness = __esm(() => {
48700
48913
  // src/lib/managed-policy.ts
48701
48914
  import { closeSync as closeSync9, constants as constants6, fstatSync as fstatSync9, lstatSync as lstatSync12, openSync as openSync9, readSync as readSync5 } from "fs";
48702
48915
  import { join as join18 } from "path";
48703
- function refusal(reason = "is unreadable") {
48704
- 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.`);
48705
48918
  }
48706
48919
  function parseManagedSkillPolicy(text2) {
48707
48920
  if (Buffer.byteLength(text2) > AGENT_POLICY_LIMITS.bytes)
@@ -48777,7 +48990,7 @@ var init_managed_policy = __esm(() => {
48777
48990
  });
48778
48991
 
48779
48992
  // src/lib/agent-bridge.ts
48780
- import { createHash as createHash12 } from "crypto";
48993
+ import { createHash as createHash13 } from "crypto";
48781
48994
  var CLI_BRIDGE_VERSION = 1, markdown = `---
48782
48995
  name: skills-cli
48783
48996
  description: Discover, load, author, and run versioned skills through the Skills CLI when a task needs reusable instructions or an executable skill.
@@ -48793,7 +49006,7 @@ Use the Skills CLI as the skill authority for this station.
48793
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.
48794
49007
  `, CLI_BRIDGE_DIGEST, CLI_BRIDGE_FILES;
48795
49008
  var init_agent_bridge = __esm(() => {
48796
- CLI_BRIDGE_DIGEST = createHash12("sha256").update(markdown).digest("hex");
49009
+ CLI_BRIDGE_DIGEST = createHash13("sha256").update(markdown).digest("hex");
48797
49010
  CLI_BRIDGE_FILES = Object.freeze({
48798
49011
  "SKILL.md": markdown,
48799
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)}
@@ -48806,28 +49019,28 @@ var init_agent_codex = () => {};
48806
49019
 
48807
49020
  // src/lib/agent-sumi.ts
48808
49021
  import { existsSync as existsSync8, lstatSync as lstatSync13, realpathSync as realpathSync4 } from "fs";
48809
- import { join as join19, resolve as resolve10 } from "path";
49022
+ import { join as join19, resolve as resolve11 } from "path";
48810
49023
  function sumiConfigDirectory(home, env = process.env) {
48811
49024
  for (const key of ["SUMI_CONFIG", "SUMI_CONFIG_CONTENT"])
48812
49025
  if (env[key] !== undefined)
48813
49026
  throw new Error(`Sumi ${key} requires a dedicated discovery adapter; unset it before Skills integration`);
48814
49027
  const selected = (key) => env[key]?.trim() ? env[key] : undefined;
48815
- 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);
48816
49029
  const explicit = selected("SUMI_CONFIG_DIR");
48817
49030
  const xdg = selected("XDG_CONFIG_HOME");
48818
49031
  const custom2 = selected("SUMI_HOME");
48819
- 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");
48820
49033
  if (explicit || xdg || custom2)
48821
- return canonical6;
49034
+ return canonical7;
48822
49035
  const legacy = join19(home, ".config/sumi");
48823
- const a = lstatSync13(canonical6, { throwIfNoEntry: false }), b = lstatSync13(legacy, { throwIfNoEntry: false });
48824
- 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))
48825
49038
  throw new Error("Sumi config roots conflict; complete native home adoption before Skills integration");
48826
- const path = a ? canonical6 : b ? legacy : canonical6;
49039
+ const path = a ? canonical7 : b ? legacy : canonical7;
48827
49040
  if (!existsSync8(path))
48828
49041
  return path;
48829
49042
  const physical = realpathSync4(path);
48830
- if ((a?.isSymbolicLink() || b?.isSymbolicLink()) && ![canonical6, legacy].includes(physical))
49043
+ if ((a?.isSymbolicLink() || b?.isSymbolicLink()) && ![canonical7, legacy].includes(physical))
48831
49044
  throw new Error("Sumi config alias must resolve to its canonical or legacy root");
48832
49045
  return physical;
48833
49046
  }
@@ -48837,19 +49050,22 @@ function sumiConfigPath(home) {
48837
49050
  var init_agent_sumi = () => {};
48838
49051
 
48839
49052
  // src/lib/codex-hook-trust-files.ts
48840
- 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";
48841
- import { createHash as createHash13 } from "crypto";
48842
- import { dirname as dirname11 } from "path";
48843
- 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) {
48844
49057
  if (!value)
48845
49058
  throw new Error(`CODEX_HOOK_TRUST_${code}`);
48846
49059
  }
49060
+ function trustedAncestorOwner(uid) {
49061
+ return BigInt(uid) === 0n || BigInt(uid) === BigInt(process.getuid());
49062
+ }
48847
49063
  function safeParents(file2) {
48848
- for (let p = dirname11(file2);; p = dirname11(p)) {
49064
+ for (let p = dirname12(file2);; p = dirname12(p)) {
48849
49065
  const s = lstatSync14(p);
48850
- need5(s.isDirectory() && !s.isSymbolicLink(), "UNSAFE_PARENT");
48851
- need5((s.mode & 18) === 0 || s.uid === 0 && (s.mode & 512) !== 0, "UNSAFE_PARENT");
48852
- 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)
48853
49069
  break;
48854
49070
  }
48855
49071
  }
@@ -48857,12 +49073,12 @@ function snapshot(file2, privateFile = false, options = {}) {
48857
49073
  const readOnlyPackage = options.readOnlyPackage === true && !privateFile;
48858
49074
  safeParents(file2);
48859
49075
  const initial = lstatSync14(file2, { bigint: true });
48860
- 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");
48861
- 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");
48862
49078
  const fd = openSync10(file2, constants7.O_RDONLY | constants7.O_NOFOLLOW | constants7.O_NONBLOCK);
48863
49079
  try {
48864
49080
  const before = fstatSync10(fd, { bigint: true });
48865
- need5(sameStat(initial, before), "INPUT_CHANGED");
49081
+ need6(sameStat(initial, before), "INPUT_CHANGED");
48866
49082
  const bytes = Buffer.alloc(Number(before.size) + 1);
48867
49083
  let length = 0;
48868
49084
  while (length < bytes.length) {
@@ -48871,16 +49087,16 @@ function snapshot(file2, privateFile = false, options = {}) {
48871
49087
  break;
48872
49088
  length += n2;
48873
49089
  }
48874
- 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");
48875
49091
  const content = bytes.subarray(0, length), text2 = new TextDecoder("utf-8", { fatal: true }).decode(content);
48876
- 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") };
48877
49093
  } finally {
48878
49094
  closeSync10(fd);
48879
49095
  }
48880
49096
  }
48881
49097
  function unchanged2(before) {
48882
49098
  const after = snapshot(before.file, before.privateFile, before.readOnlyPackage ? { readOnlyPackage: true } : {});
48883
- 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");
48884
49100
  }
48885
49101
  var sameStat = (a, b) => ["dev", "ino", "uid", "nlink", "mode", "size", "mtimeNs", "ctimeNs"].every((key) => a[key] === b[key]);
48886
49102
  var init_codex_hook_trust_files = () => {};
@@ -49622,7 +49838,7 @@ var init_selection_resolver = __esm(() => {
49622
49838
  });
49623
49839
 
49624
49840
  // src/lib/plugin-projection.ts
49625
- import { createHash as createHash14 } from "crypto";
49841
+ import { createHash as createHash15 } from "crypto";
49626
49842
  function pluginRefusal(message) {
49627
49843
  throw new SkillSelectionError("PLUGIN_ADMISSION_REFUSED", message);
49628
49844
  }
@@ -49700,7 +49916,7 @@ function pluginFileWitnesses(entries) {
49700
49916
  return { path: item.path, mode: item.mode, size: item.bytes.byteLength, sha256: pluginHash(item.bytes) };
49701
49917
  });
49702
49918
  }
49703
- 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");
49704
49920
  var init_plugin_projection = __esm(() => {
49705
49921
  init_selection_cache();
49706
49922
  PLUGIN_PROJECTION_LIMITS = Object.freeze({ files: 1024, bytes: 64 * 1024 * 1024, fileBytes: 16 * 1024 * 1024, metadataBytes: 512 * 1024, registrations: 64, history: 128 });
@@ -49708,7 +49924,7 @@ var init_plugin_projection = __esm(() => {
49708
49924
 
49709
49925
  // src/lib/plugin-projection-store.ts
49710
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";
49711
- 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";
49712
49928
  function stat(path) {
49713
49929
  try {
49714
49930
  return lstatSync15(path, { bigint: true });
@@ -49718,8 +49934,8 @@ function stat(path) {
49718
49934
  return pluginRefusal("Cannot inspect plugin filesystem entry");
49719
49935
  }
49720
49936
  }
49721
- function canonical6(path) {
49722
- 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");
49723
49939
  }
49724
49940
  function owner(stats, system = false) {
49725
49941
  const current = uid();
@@ -49729,8 +49945,8 @@ function same3(left, right, identityOnly = false) {
49729
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");
49730
49946
  }
49731
49947
  function ancestors(path, create = false) {
49732
- canonical6(path);
49733
- const result = [], parent = dirname12(path), filesystemRoot = parse10(parent).root;
49948
+ canonical7(path);
49949
+ const result = [], parent = dirname13(path), filesystemRoot = parse10(parent).root;
49734
49950
  let current = filesystemRoot;
49735
49951
  for (const segment of ["", ...parent.slice(filesystemRoot.length).split("/").filter(Boolean)]) {
49736
49952
  if (segment)
@@ -49956,7 +50172,7 @@ var init_selected_manifest = __esm(() => {
49956
50172
  });
49957
50173
 
49958
50174
  // src/lib/plugin-admission.ts
49959
- 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";
49960
50176
  function validatePluginTarget(value) {
49961
50177
  pluginKeys(value, ["schemaVersion", "pluginId", "registrations", "native", "resolver"]);
49962
50178
  pluginNeed(value.schemaVersion === 1, "Invalid plugin admission target");
@@ -49966,7 +50182,7 @@ function validatePluginTarget(value) {
49966
50182
  for (const registration of value.registrations) {
49967
50183
  pluginKeys(registration, ["scope", "projectPath"]);
49968
50184
  pluginNeed(registration.scope === "user" || registration.scope === "project", "Unsupported plugin registration scope");
49969
- 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");
49970
50186
  const key = JSON.stringify([registration.scope, registration.projectPath]);
49971
50187
  pluginNeed(!scopes.has(key), "Duplicate plugin registration scope");
49972
50188
  scopes.add(key);
@@ -49974,7 +50190,7 @@ function validatePluginTarget(value) {
49974
50190
  for (const key of ["native", "resolver"]) {
49975
50191
  pluginKeys(value[key], key === "native" ? ["version", "executable", "digest"] : ["executable", "digest"]);
49976
50192
  pluginText(value[key].executable);
49977
- 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");
49978
50194
  pluginDigest(value[key].digest);
49979
50195
  }
49980
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)");
@@ -50113,7 +50329,7 @@ function validatePlan(value) {
50113
50329
  pluginNeed(identityDigest(plan) === plan.planDigest, "Plugin receipt immutable identity changed");
50114
50330
  }
50115
50331
  function pluginResolverCommand(binding) {
50116
- 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))}`;
50117
50333
  }
50118
50334
  function pluginBindingPath(storeRoot, id) {
50119
50335
  pluginNeed(/^[a-f0-9]{64}$/.test(id), "Invalid plugin binding identifier");
@@ -50147,7 +50363,7 @@ function readPluginAdmissionReceipt(storeRoot, id, digest) {
50147
50363
  pluginNeed(Number.isFinite(Date.parse(receipt.admittedAt)), "Invalid plugin admission time");
50148
50364
  return receipt;
50149
50365
  }
50150
- 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"';
50151
50367
  var init_plugin_admission = __esm(() => {
50152
50368
  init_profile_client();
50153
50369
  init_skill_bundle();
@@ -50160,7 +50376,7 @@ var init_plugin_admission = __esm(() => {
50160
50376
 
50161
50377
  // src/lib/plugin-discovery.ts
50162
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";
50163
- 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";
50164
50380
  function validateManagedPluginWitnesses(value) {
50165
50381
  pluginNeed(Array.isArray(value) && value.length > 0 && value.length <= PLUGIN_PROJECTION_LIMITS.registrations, "Invalid managed plugin witness collection");
50166
50382
  const seen = new Set;
@@ -50169,15 +50385,15 @@ function validateManagedPluginWitnesses(value) {
50169
50385
  pluginNeed(typeof item.bindingId === "string" && /^[a-f0-9]{64}$/.test(item.bindingId) && !seen.has(item.bindingId), "Invalid or duplicate managed plugin witness");
50170
50386
  seen.add(item.bindingId);
50171
50387
  pluginText(item.storeRoot);
50172
- 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");
50173
50389
  }
50174
50390
  }
50175
50391
  function safe3(path) {
50176
50392
  pluginText(path);
50177
- pluginNeed(isAbsolute11(path) && resolve13(path) === path, "Invalid plugin registry path");
50178
- 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)) {
50179
50395
  pluginNeed(!lstatSync16(at, { throwIfNoEntry: false })?.isSymbolicLink(), "Plugin registry path traverses a symlink");
50180
- if (at === dirname13(at))
50396
+ if (at === dirname14(at))
50181
50397
  break;
50182
50398
  }
50183
50399
  }
@@ -50227,7 +50443,7 @@ function hashManagedPluginRegistry(path, managed) {
50227
50443
  seen.add(target.pluginId);
50228
50444
  const rows = plugins[target.pluginId];
50229
50445
  pluginNeed(Array.isArray(rows) && rows.length === target.registrations.length, "Managed plugin registration membership changed");
50230
- 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);
50231
50447
  const scopes = new Set, approvals = new Map, currentFiles = new Map;
50232
50448
  plugins[target.pluginId] = rows.map((row) => {
50233
50449
  pluginNeed(pluginObject(row), "Invalid managed plugin registration");
@@ -50243,7 +50459,7 @@ function hashManagedPluginRegistry(path, managed) {
50243
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");
50244
50460
  const approval = (producer) => {
50245
50461
  pluginText(producer);
50246
- const digest = `sha256:${basename6(producer)}`;
50462
+ const digest = `sha256:${basename7(producer)}`;
50247
50463
  const receipt2 = readPluginAdmissionReceipt(witness.storeRoot, witness.bindingId, digest);
50248
50464
  pluginNeed(receipt2.materializedPath === producer, "Managed producer path is not an approved immutable projection");
50249
50465
  if (!verified.has(producer)) {
@@ -50307,37 +50523,37 @@ var init_plugin_discovery = __esm(() => {
50307
50523
  });
50308
50524
 
50309
50525
  // src/lib/claude-marketplace-registry.ts
50310
- import { createHash as createHash15 } from "crypto";
50526
+ import { createHash as createHash16 } from "crypto";
50311
50527
  import { closeSync as closeSync13, constants as constants10, fstatSync as fstatSync13, lstatSync as lstatSync17, openSync as openSync13, readSync as readSync9 } from "fs";
50312
- import { basename as basename7, dirname as dirname14, isAbsolute as isAbsolute12, resolve as resolve14 } from "path";
50313
- 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) {
50314
50530
  if (!value)
50315
- throw new Error(`Claude marketplace registry ${reason}`);
50531
+ throw new Error(`Claude marketplace registry ${reason2}`);
50316
50532
  }
50317
50533
  function absolutePath2(value) {
50318
- 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");
50319
50535
  }
50320
50536
  function parents2(path) {
50321
50537
  const result = [];
50322
- for (let at = dirname14(path);; at = dirname14(at)) {
50538
+ for (let at = dirname15(path);; at = dirname15(at)) {
50323
50539
  const stat2 = lstatSync17(at, { bigint: true });
50324
- 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");
50325
50541
  result.push([at, stat2]);
50326
- if (at === dirname14(at))
50542
+ if (at === dirname15(at))
50327
50543
  return result;
50328
50544
  }
50329
50545
  }
50330
50546
  function readRegistry2(path, budget2) {
50331
50547
  absolutePath2(path);
50332
- need6(basename7(path) === "known_marketplaces.json", "requires known_marketplaces.json");
50333
- 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");
50334
50550
  const ancestors2 = parents2(path), initial = lstatSync17(path, { bigint: true });
50335
- need6(initial.isFile() && !initial.isSymbolicLink() && initial.size <= BigInt(CLAUDE_MARKETPLACE_REGISTRY_LIMITS.bytes), "is not a bounded regular file");
50336
- 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");
50337
50553
  const fd = openSync13(path, constants10.O_RDONLY | constants10.O_NOFOLLOW | constants10.O_NONBLOCK);
50338
50554
  try {
50339
50555
  const opened = fstatSync13(fd, { bigint: true });
50340
- need6(opened.isFile() && sameFile2(initial, opened), "changed during open");
50556
+ need7(opened.isFile() && sameFile2(initial, opened), "changed during open");
50341
50557
  const bytes = Buffer.alloc(Number(opened.size) + 1);
50342
50558
  let length = 0;
50343
50559
  while (length < bytes.length) {
@@ -50347,10 +50563,10 @@ function readRegistry2(path, budget2) {
50347
50563
  length += count;
50348
50564
  }
50349
50565
  const after = fstatSync13(fd, { bigint: true }), current = lstatSync17(path, { bigint: true });
50350
- 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");
50351
50567
  for (const [ancestor, before] of ancestors2) {
50352
50568
  const now = lstatSync17(ancestor, { bigint: true });
50353
- 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");
50354
50570
  }
50355
50571
  budget2.remaining -= length;
50356
50572
  try {
@@ -50370,7 +50586,7 @@ function parse11(text2) {
50370
50586
  at++;
50371
50587
  };
50372
50588
  function string5() {
50373
- need6(text2[at] === '"', "contains invalid JSON");
50589
+ need7(text2[at] === '"', "contains invalid JSON");
50374
50590
  const start = at++;
50375
50591
  while (at < text2.length) {
50376
50592
  const character = text2[at++];
@@ -50381,7 +50597,7 @@ function parse11(text2) {
50381
50597
  } catch {
50382
50598
  throw new Error("Claude marketplace registry contains invalid JSON string");
50383
50599
  }
50384
- 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");
50385
50601
  return value2;
50386
50602
  }
50387
50603
  if (character === "\\")
@@ -50390,7 +50606,7 @@ function parse11(text2) {
50390
50606
  throw new Error("Claude marketplace registry contains an unterminated JSON string");
50391
50607
  }
50392
50608
  function value(depth) {
50393
- 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");
50394
50610
  space();
50395
50611
  const character = text2[at];
50396
50612
  if (character === '"')
@@ -50404,17 +50620,17 @@ function parse11(text2) {
50404
50620
  if (object7) {
50405
50621
  space();
50406
50622
  const key = string5();
50407
- need6(!keys.has(key), "contains a duplicate JSON key");
50623
+ need7(!keys.has(key), "contains a duplicate JSON key");
50408
50624
  keys.add(key);
50409
50625
  space();
50410
- need6(text2[at++] === ":", "contains invalid JSON");
50626
+ need7(text2[at++] === ":", "contains invalid JSON");
50411
50627
  entries.push([key, value(depth + 1)]);
50412
50628
  } else
50413
50629
  items.push(value(depth + 1));
50414
50630
  space();
50415
50631
  if (text2[at] === end)
50416
50632
  break;
50417
- need6(text2[at++] === ",", "contains invalid JSON");
50633
+ need7(text2[at++] === ",", "contains invalid JSON");
50418
50634
  }
50419
50635
  at++;
50420
50636
  return object7 ? { kind: "object", entries } : { kind: "array", items };
@@ -50426,64 +50642,64 @@ function parse11(text2) {
50426
50642
  }
50427
50643
  numberPattern.lastIndex = at;
50428
50644
  const number5 = numberPattern.exec(text2);
50429
- need6(number5, "contains invalid JSON");
50645
+ need7(number5, "contains invalid JSON");
50430
50646
  at += number5[0].length;
50431
50647
  return { kind: "number", value: number5[0] };
50432
50648
  }
50433
50649
  const root = value(0);
50434
50650
  space();
50435
- need6(at === text2.length && root.kind === "object", "requires a JSON object without trailing content");
50436
- 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");
50437
50653
  return root;
50438
50654
  }
50439
50655
  function exactKeys(value, keys) {
50440
50656
  return value?.kind === "object" && value.entries.length === keys.length && value.entries.every(([key]) => keys.includes(key));
50441
50657
  }
50442
50658
  function textField(value) {
50443
- 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");
50444
50660
  return value.value;
50445
50661
  }
50446
50662
  function normalizeRow(row, version2 = 1) {
50447
50663
  if (!exactKeys(row, ["source", "installLocation", "lastUpdated"])) {
50448
50664
  if (version2 !== 2 || !exactKeys(row, ["source", "installLocation", "lastUpdated", "autoUpdate"]))
50449
50665
  return;
50450
- const autoUpdate = field(row, "autoUpdate");
50451
- 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");
50452
50668
  }
50453
- const source = field(row, "source");
50669
+ const source = field2(row, "source");
50454
50670
  if (source?.kind !== "object")
50455
50671
  return;
50456
- const type = field(source, "source");
50672
+ const type = field2(source, "source");
50457
50673
  if (type?.kind !== "string" || !["github", "directory"].includes(type.value))
50458
50674
  return;
50459
50675
  const location = type.value === "github" ? "repo" : "path";
50460
50676
  if (!exactKeys(source, ["source", location]))
50461
50677
  return;
50462
- const sourceLocation = textField(field(source, location));
50678
+ const sourceLocation = textField(field2(source, location));
50463
50679
  if (type.value === "directory")
50464
50680
  absolutePath2(sourceLocation);
50465
- absolutePath2(textField(field(row, "installLocation")));
50466
- const updated = textField(field(row, "lastUpdated"));
50467
- 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");
50468
50684
  const millis = Date.parse(updated);
50469
- 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");
50470
50686
  row.entries = row.entries.map(([key, value]) => [key, key === "lastUpdated" ? { kind: "validated-update-time" } : value]);
50471
50687
  }
50472
50688
  function captureClaudeMarketplaceRegistry(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
50473
50689
  const value = parse11(readRegistry2(path, budget2));
50474
50690
  for (const [, row] of value.entries)
50475
50691
  normalizeRow(row);
50476
- 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");
50477
50693
  return { path, hashMode: "claude-marketplace-registry", sha256: sha2562 };
50478
50694
  }
50479
50695
  function captureClaudeMarketplaceRegistryV2(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
50480
50696
  const value = parse11(readRegistry2(path, budget2));
50481
50697
  for (const [, row] of value.entries)
50482
50698
  normalizeRow(row, 2);
50483
- 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");
50484
50700
  return { path, hashMode: "claude-marketplace-registry-v2", sha256: sha2562 };
50485
50701
  }
50486
- 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];
50487
50703
  var init_claude_marketplace_registry = __esm(() => {
50488
50704
  CLAUDE_MARKETPLACE_REGISTRY_LIMITS = Object.freeze({ bytes: 1024 * 1024, rows: 1024, depth: 32, nodes: 65536, stringCharacters: 16384, pathCharacters: 4096 });
50489
50705
  });
@@ -50502,10 +50718,10 @@ var init_codex_hook_additions_review = __esm(() => {
50502
50718
  });
50503
50719
 
50504
50720
  // src/lib/codex-hook-discovery-recovery.ts
50505
- import { createHash as createHash16 } from "crypto";
50721
+ import { createHash as createHash17 } from "crypto";
50506
50722
  function assertCodexHookDiscoveryRecovery(binding, witness) {
50507
50723
  const proof = proofs2.get(witness);
50508
- 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");
50509
50725
  unchanged2(proof.before);
50510
50726
  unchanged2(proof.current);
50511
50727
  proof.recheckAdditions();
@@ -50514,10 +50730,10 @@ function verifiesCodexHookDiscoverySource(binding, source, currentDigest, witnes
50514
50730
  if (!witness || source.path !== witness.configPath || source.hashMode !== "bytes")
50515
50731
  return false;
50516
50732
  assertCodexHookDiscoveryRecovery(binding, witness);
50517
- 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");
50518
50734
  return true;
50519
50735
  }
50520
- var sha3 = (text2) => createHash16("sha256").update(text2).digest("hex"), fields, proofs2;
50736
+ var sha3 = (text2) => createHash17("sha256").update(text2).digest("hex"), fields, proofs2;
50521
50737
  var init_codex_hook_discovery_recovery = __esm(() => {
50522
50738
  init_codex_hook_trust_files();
50523
50739
  init_codex_hook_trust_layout();
@@ -50528,10 +50744,18 @@ var init_codex_hook_discovery_recovery = __esm(() => {
50528
50744
  });
50529
50745
 
50530
50746
  // src/lib/agent-discovery.ts
50531
- import { createHash as createHash17 } from "crypto";
50747
+ import { createHash as createHash18 } from "crypto";
50532
50748
  import { lstatSync as lstatSync18, readFileSync as readFileSync15, readdirSync as readdirSync7, realpathSync as realpathSync5 } from "fs";
50533
- 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";
50534
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
+ }
50535
50759
  function parseConfig(text2, path, toml = false) {
50536
50760
  try {
50537
50761
  const value = toml ? Bun.TOML.parse(text2) : JSON.parse(text2);
@@ -50543,12 +50767,12 @@ function parseConfig(text2, path, toml = false) {
50543
50767
  }
50544
50768
  }
50545
50769
  function safe4(path) {
50546
- if (!isAbsolute13(path) || path.includes("\x00"))
50770
+ if (!isAbsolute15(path) || path.includes("\x00"))
50547
50771
  throw new Error("Expected an absolute native discovery path");
50548
- for (let cursor = path;; cursor = dirname15(cursor)) {
50772
+ for (let cursor = path;; cursor = dirname16(cursor)) {
50549
50773
  if (lstatSync18(cursor, { throwIfNoEntry: false })?.isSymbolicLink())
50550
50774
  throw new Error(`Refusing symlink native discovery input: ${cursor}`);
50551
- if (dirname15(cursor) === cursor)
50775
+ if (dirname16(cursor) === cursor)
50552
50776
  break;
50553
50777
  }
50554
50778
  }
@@ -50567,7 +50791,7 @@ function projectNativeDiscoveryFields(text2, format, fields2, path) {
50567
50791
  const object7 = format === "yaml" ? parseHermesConfig(text2) : parseConfig(text2, path, format === "toml");
50568
50792
  if (!object7 || typeof object7 !== "object" || Array.isArray(object7))
50569
50793
  throw new Error("Expected native discovery configuration object");
50570
- 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]))));
50571
50795
  }
50572
50796
  function isSupersededSettingsProjection(agent, configPath, source) {
50573
50797
  if (agent === "sumi")
@@ -50612,6 +50836,14 @@ function projected(source, changes, budget2 = discoveryByteBudget()) {
50612
50836
  throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
50613
50837
  return sha2562;
50614
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
+ }
50615
50847
  if (source.hashMode === "claude-plugin-registry") {
50616
50848
  if (source.format !== undefined || source.fields !== undefined || !source.managedPlugins || changes?.has(source.path))
50617
50849
  throw new Error("Managed plugin registry witnesses require verified native registrations");
@@ -50649,7 +50881,7 @@ function absentCodexSkillRoots(binding) {
50649
50881
  throw new Error("Invalid disabled Codex discovery proof");
50650
50882
  if (binding.method !== "reviewed" || controls.every((control) => lstatSync18(control.pluginParent, { throwIfNoEntry: false })))
50651
50883
  return [];
50652
- 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");
50653
50885
  const source = binding.sources.find((source2) => source2.path === config2 && source2.sha256 !== null && source2.format === undefined && source2.fields === undefined);
50654
50886
  if (!source || projected(source) !== source.sha256)
50655
50887
  throw new Error("Missing current disabled Codex configuration witness");
@@ -50657,7 +50889,7 @@ function absentCodexSkillRoots(binding) {
50657
50889
  return [...new Set(controls.map((control) => control.pluginParent))].filter((parent) => !codexDirectHookSelects(cache, parent) && absentDisabledCodexPluginParent(cache, parent, controls, rules));
50658
50890
  }
50659
50891
  function codexDirectHookSelects(cache, root) {
50660
- 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")) ?? "");
50661
50893
  const hooks = read(join26(codex, "hooks.json"));
50662
50894
  if (hooks !== null)
50663
50895
  hashNativeJsonControls(hooks);
@@ -50670,7 +50902,7 @@ function retiredCodexRoots(binding) {
50670
50902
  const controls = binding.codexDisabledPluginSkills;
50671
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)
50672
50904
  throw new Error("Invalid retired Codex materialization proof");
50673
- 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");
50674
50906
  const source = binding.sources.find((source2) => source2.path === config2 && source2.sha256 !== null && source2.format === undefined && source2.fields === undefined);
50675
50907
  if (!source || projected(source) !== source.sha256)
50676
50908
  throw new Error("Missing current retired Codex configuration witness");
@@ -50701,7 +50933,7 @@ function absentRetiredClaudeRoots(binding) {
50701
50933
  safe4(root);
50702
50934
  if (lstatSync18(root, { throwIfNoEntry: false }))
50703
50935
  continue;
50704
- 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");
50705
50937
  const full = (path) => binding.sources.find((item) => item.path === path && item.sha256 !== null && item.format === undefined && item.fields === undefined);
50706
50938
  const configSource = full(settings), registrySource = full(registry2);
50707
50939
  if (!configSource || !registrySource || projected(configSource) !== configSource.sha256 || projected(registrySource) !== registrySource.sha256)
@@ -50718,7 +50950,7 @@ function absentRetiredClaudeRoots(binding) {
50718
50950
  if (!Array.isArray(rows) || rows.length !== 1 || rows[0]?.scope !== "user" || typeof rows[0]?.installPath !== "string")
50719
50951
  continue;
50720
50952
  const active = rows[0].installPath;
50721
- 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)
50722
50954
  continue;
50723
50955
  const activeManifest = full(join26(active, ".claude-plugin/plugin.json"));
50724
50956
  if (!activeManifest || projected(activeManifest) !== activeManifest.sha256)
@@ -50769,7 +51001,7 @@ function verifyAgentDiscovery(binding, codexRecovery) {
50769
51001
  assertMarketplaceBinding(binding, source);
50770
51002
  if (source.hashMode === "claude-plugin-registry" && binding.agent !== "claude")
50771
51003
  throw new Error("Managed Claude registry witnesses cannot apply to another agent");
50772
- 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)))
50773
51005
  throw new Error("Invalid native discovery projection");
50774
51006
  if (source.sha256 !== null && !/^[a-f0-9]{64}$/.test(source.sha256))
50775
51007
  throw new Error("Invalid native discovery digest");
@@ -50799,13 +51031,13 @@ function codexInstallationRoots(binding) {
50799
51031
  return [];
50800
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)
50801
51033
  throw new Error("Invalid native installation input proof");
50802
- const cache = dirname15(dirname15(proof.plugins[0].pluginParent));
50803
- 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)));
50804
51036
  const configSource = binding.sources.find((source) => source.path === config2 && source.sha256 !== null && (!source.format || source.format === "toml" && source.fields?.includes("plugins")));
50805
51037
  const nativeRoots = NATIVE_SKILL_ROOTS.filter(([agent]) => agent === "codex").map(([, path]) => join26(home, path));
50806
- 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)))))
50807
51039
  throw new Error("Native installation input overlaps configuration or loading roots");
50808
- 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)))
50809
51041
  throw new Error("Missing native installation input source witness");
50810
51042
  return reviewedCodexPluginSourceRoots(cache, proof.plugins, (path) => {
50811
51043
  const text2 = read(path);
@@ -50815,16 +51047,18 @@ function codexInstallationRoots(binding) {
50815
51047
  });
50816
51048
  }
50817
51049
  function assertMarketplaceBinding(binding, source) {
50818
- 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"))))
50819
51051
  throw new Error("Claude plugin manifest witnesses require Claude plugin discovery");
50820
- 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"))
50821
51053
  throw new Error("Sumi settings witnesses require explicit reviewed Sumi configuration");
50822
- 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"))
50823
51055
  throw new Error("Codex settings witnesses require explicit reviewed Codex configuration");
50824
- 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"))
50825
51057
  throw new Error("Claude settings witnesses require explicit reviewed Claude configuration");
50826
51058
  if ((source.hashMode === "claude-marketplace-registry" || source.hashMode === "claude-marketplace-registry-v2") && (binding.agent !== "claude" || binding.method !== "reviewed"))
50827
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");
50828
51062
  }
50829
51063
  function agentDiscoveryConfigPath(home, agent) {
50830
51064
  if (agent === "sumi")
@@ -50832,10 +51066,10 @@ function agentDiscoveryConfigPath(home, agent) {
50832
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"}`);
50833
51067
  }
50834
51068
  function resolveAgentDiscovery(options) {
50835
- 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;
50836
51070
  const sources = [], roots = new Set, builtinNames = [];
50837
51071
  const witness = (path, format, fields2, hashMode) => {
50838
- 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 } : {} };
50839
51073
  source.sha256 = projected(source);
50840
51074
  sources.push(source);
50841
51075
  return read(source.path);
@@ -50857,13 +51091,13 @@ function resolveAgentDiscovery(options) {
50857
51091
  unresolved("JSONC configuration requires a supported format adapter");
50858
51092
  for (const root of [directory, join26(home, ".claude"), join26(home, ".agents")])
50859
51093
  for (const name of ["skill", "skills"])
50860
- roots.add(canonical7(join26(root, name)));
51094
+ roots.add(canonical8(join26(root, name)));
50861
51095
  if (config2.skills !== undefined && (!Array.isArray(config2.skills) || config2.skills.some((path) => typeof path !== "string")))
50862
51096
  unresolved("skills must be a string array");
50863
51097
  for (const value of config2.skills ?? []) {
50864
- 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("~/")))
50865
51099
  unresolved("remote or relative skill sources need a dedicated discovery adapter");
50866
- roots.add(canonical7(value.startsWith("~/") ? join26(home, value.slice(2)) : value));
51100
+ roots.add(canonical8(value.startsWith("~/") ? join26(home, value.slice(2)) : value));
50867
51101
  }
50868
51102
  for (const key of ["plugin", "plugins"])
50869
51103
  if (config2[key] !== undefined && !Array.isArray(config2[key]))
@@ -50902,23 +51136,23 @@ function resolveAgentDiscovery(options) {
50902
51136
  continue;
50903
51137
  if (normalized.startsWith("~") && normalized !== "~" && !normalized.startsWith("~/"))
50904
51138
  unresolved("user-specific tilde expansion requires a separate discovery adapter");
50905
- 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);
50906
51140
  safe4(path);
50907
51141
  roots.add(path);
50908
51142
  }
50909
51143
  }
50910
51144
  if (agent === "gemini") {
50911
- const executable = Bun.which("gemini");
51145
+ const executable = options.executable === undefined ? discoveryExecutable(agent) : options.executable;
50912
51146
  if (executable) {
50913
51147
  let packageRoot;
50914
- 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++) {
50915
51149
  const path = join26(directory, "package.json"), raw = read(path);
50916
51150
  if (raw !== null && parseConfig(raw, path).name === "@google/gemini-cli") {
50917
51151
  packageRoot = directory;
50918
51152
  witness(path);
50919
51153
  break;
50920
51154
  }
50921
- if (dirname15(directory) === directory)
51155
+ if (dirname16(directory) === directory)
50922
51156
  break;
50923
51157
  }
50924
51158
  if (!packageRoot)
@@ -50941,11 +51175,11 @@ function resolveAgentDiscovery(options) {
50941
51175
  if (retained.agent !== agent || retained.method !== "reviewed")
50942
51176
  unresolved("invalid retained review");
50943
51177
  verifyAgentDiscovery(retained);
50944
- 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))
50945
51179
  unresolved("retained review is missing the full agent configuration source");
50946
- 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)))
50947
51181
  unresolved("retained settings witness names another configuration source");
50948
- 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;
50949
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))
50950
51184
  unresolved("retained review is missing current runtime discovery coverage");
50951
51185
  return retained;
@@ -50957,15 +51191,15 @@ function resolveAgentDiscovery(options) {
50957
51191
  if (review.sources.some((source) => source.format !== undefined || source.fields !== undefined))
50958
51192
  throw new Error("Explicit discovery reviews require full source-file hashes");
50959
51193
  verifyAgentDiscovery(supplied);
50960
- 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)))
50961
51195
  throw new Error("Semantic settings witnesses must name the configured agent configuration source");
50962
- if (!review.sources.some((source) => source.path === canonical7(configPath)))
51196
+ if (!review.sources.some((source) => source.path === canonical8(configPath)))
50963
51197
  throw new Error("Discovery review must include the agent configuration source");
50964
- 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;
50965
51199
  const reviewedSourcesWithManifestProjection = review.sources.map((source) => {
50966
- 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")))
50967
51201
  return source;
50968
- 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");
50969
51203
  const hookStat = lstatSync18(hooksPath, { throwIfNoEntry: false });
50970
51204
  const text2 = read(source.path);
50971
51205
  if (text2 === null)
@@ -50980,13 +51214,13 @@ function resolveAgentDiscovery(options) {
50980
51214
  if (manifest.hooks !== undefined) {
50981
51215
  if (typeof manifest.hooks !== "string")
50982
51216
  throw new Error("Reviewed Claude plugin manifest has an unsupported hooks target");
50983
- const declaredHookPath = resolve15(pluginRoot, manifest.hooks);
51217
+ const declaredHookPath = resolve17(pluginRoot, manifest.hooks);
50984
51218
  if (!declaredHookPath.startsWith(pluginRoot + sep6))
50985
51219
  throw new Error("Reviewed Claude plugin hooks target escapes its root");
50986
51220
  reviewedHookPaths.add(declaredHookPath);
50987
51221
  }
50988
51222
  for (const hooksFile of reviewedHookPaths)
50989
- 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")))
50990
51224
  throw new Error("Reviewed Claude plugin manifest requires separately reviewed exact hook file sources");
50991
51225
  return { path: source.path, sha256: manifestSha256, hashMode: "claude-plugin-manifest-v1" };
50992
51226
  });
@@ -50995,7 +51229,7 @@ function resolveAgentDiscovery(options) {
50995
51229
  return { ...supplied, roots: [...new Set([...roots, ...supplied.roots])].sort(), sources: unique, ...agent === "gemini" ? { builtinNames } : {} };
50996
51230
  }
50997
51231
  function plugin(root) {
50998
- root = canonical7(root);
51232
+ root = canonical8(root);
50999
51233
  safe4(root);
51000
51234
  const manifestPath = join26(root, agent === "claude" ? ".claude-plugin/plugin.json" : ".codex-plugin/plugin.json");
51001
51235
  const raw = witness(manifestPath, undefined, undefined, agent === "claude" ? "claude-plugin-manifest-v1" : undefined);
@@ -51018,16 +51252,16 @@ function resolveAgentDiscovery(options) {
51018
51252
  if (agent === "claude")
51019
51253
  roots.add(join26(root, "skills"));
51020
51254
  for (const value of declared) {
51021
- const path = resolve15(root, value);
51255
+ const path = resolve17(root, value);
51022
51256
  if (path !== root && !path.startsWith(root + sep6))
51023
51257
  unresolved("plugin skill path escapes its root");
51024
- roots.add(path.endsWith(`${sep6}SKILL.md`) ? dirname15(path) : path);
51258
+ roots.add(path.endsWith(`${sep6}SKILL.md`) ? dirname16(path) : path);
51025
51259
  }
51026
51260
  }
51027
51261
  if (agent === "claude") {
51028
51262
  const registrations = witness(join26(home, ".claude/plugins/installed_plugins.json"));
51029
51263
  const installed = registrations === null ? {} : parseConfig(registrations, join26(home, ".claude/plugins/installed_plugins.json")).plugins;
51030
- const commands = canonical7(join26(home, ".claude/commands"));
51264
+ const commands = canonical8(join26(home, ".claude/commands"));
51031
51265
  safe4(commands);
51032
51266
  if (lstatSync18(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync7(commands).length)
51033
51267
  unresolved("legacy home command discovery requires a dedicated format adapter");
@@ -51049,7 +51283,7 @@ function resolveAgentDiscovery(options) {
51049
51283
  unresolved("unsupported plugin enablement");
51050
51284
  const split = id.lastIndexOf("@"), name = id.slice(0, split), marketplace = id.slice(split + 1);
51051
51285
  const market = config2.marketplaces?.[marketplace] ?? (marketplace === "personal" ? { source_type: "local", source: home } : undefined);
51052
- 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))
51053
51287
  unresolved("enabled plugin marketplace is not an explicit local source");
51054
51288
  const catalogText = witness(join26(market.source, ".agents/plugins/marketplace.json"));
51055
51289
  if (catalogText === null)
@@ -51057,7 +51291,7 @@ function resolveAgentDiscovery(options) {
51057
51291
  const catalog = parseConfig(catalogText, join26(market.source, ".agents/plugins/marketplace.json")), matches = Array.isArray(catalog.plugins) ? catalog.plugins.filter((item) => item.name === name) : [];
51058
51292
  if (matches.length !== 1 || matches[0]?.source?.source !== "local" || typeof matches[0]?.source?.path !== "string")
51059
51293
  unresolved("plugin catalog source is missing or ambiguous");
51060
- plugin(resolve15(market.source, matches[0].source.path));
51294
+ plugin(resolve17(market.source, matches[0].source.path));
51061
51295
  }
51062
51296
  } else if (agent === "opencode") {
51063
51297
  if (witness(join26(home, ".config/opencode/opencode.jsonc")) !== null || witness(join26(home, ".config/opencode/config.json")) !== null)
@@ -51065,7 +51299,7 @@ function resolveAgentDiscovery(options) {
51065
51299
  if ((config2.plugin?.length ?? 0) > 0 || config2.skills?.urls?.length)
51066
51300
  unresolved("external plugin or remote skill source");
51067
51301
  for (const path of config2.skills?.paths ?? []) {
51068
- if (typeof path !== "string" || !isAbsolute13(path))
51302
+ if (typeof path !== "string" || !isAbsolute15(path))
51069
51303
  unresolved("relative or malformed added skill root");
51070
51304
  roots.add(path);
51071
51305
  }
@@ -51074,7 +51308,7 @@ function resolveAgentDiscovery(options) {
51074
51308
  if (lstatSync18(localPlugins, { throwIfNoEntry: false }) && readdirSync7(localPlugins).some((name) => name !== "skills-cli.js"))
51075
51309
  unresolved("additional local plugin hooks require review");
51076
51310
  } else if (agent === "sumi") {
51077
- 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))
51078
51312
  unresolved("external or foreign local plugins require review");
51079
51313
  } else if (agent === "hermes") {
51080
51314
  for (const directory of [join26(home, ".hermes/plugins"), join26(home, ".hermes/hermes-agent")]) {
@@ -51104,9 +51338,15 @@ function resolveAgentDiscovery(options) {
51104
51338
  roots.add(join26(root, "skills"));
51105
51339
  }
51106
51340
  }
51107
- 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))) } : {} };
51108
51342
  }
51109
- 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");
51110
51350
  var init_agent_discovery = __esm(() => {
51111
51351
  init_sumi_settings_witness();
51112
51352
  init_agent_policy_limits();
@@ -51118,6 +51358,7 @@ var init_agent_discovery = __esm(() => {
51118
51358
  init_plugin_discovery();
51119
51359
  init_plugin_admission();
51120
51360
  init_claude_marketplace_registry();
51361
+ init_claude_marketplace_entry_witness();
51121
51362
  init_claude_settings_witness();
51122
51363
  init_codex_hook_discovery_recovery();
51123
51364
  init_codex_settings_witness();
@@ -51126,14 +51367,15 @@ var init_agent_discovery = __esm(() => {
51126
51367
  init_native_discovery_roots();
51127
51368
  init_codex_native_compatibility();
51128
51369
  init_agent_discovery_directories();
51370
+ DISCOVERY_RUNTIME_COMMANDS = Object.freeze({ gemini: "gemini" });
51129
51371
  });
51130
51372
 
51131
51373
  // src/lib/authoring-path.ts
51132
51374
  import { lstatSync as lstatSync19, realpathSync as realpathSync6 } from "fs";
51133
51375
  import { homedir as homedir3 } from "os";
51134
- 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";
51135
51377
  function pathParts(path) {
51136
- return resolve16(path).split(sep7).filter(Boolean);
51378
+ return resolve18(path).split(sep7).filter(Boolean);
51137
51379
  }
51138
51380
  function nativeRootMatch(path) {
51139
51381
  const parts = pathParts(path);
@@ -51147,16 +51389,16 @@ function nativeRootMatch(path) {
51147
51389
  return;
51148
51390
  }
51149
51391
  function physicalPath(path) {
51150
- let cursor = resolve16(path);
51392
+ let cursor = resolve18(path);
51151
51393
  const suffix = [];
51152
51394
  while (!lstatSync19(cursor, { throwIfNoEntry: false })) {
51153
- suffix.unshift(basename9(cursor));
51154
- const parent = dirname16(cursor);
51395
+ suffix.unshift(basename10(cursor));
51396
+ const parent = dirname17(cursor);
51155
51397
  if (parent === cursor)
51156
- return resolve16(path);
51398
+ return resolve18(path);
51157
51399
  cursor = parent;
51158
51400
  }
51159
- return resolve16(realpathSync6(cursor), ...suffix);
51401
+ return resolve18(realpathSync6(cursor), ...suffix);
51160
51402
  }
51161
51403
  function contains(root, path) {
51162
51404
  return path === root || path.startsWith(root + sep7);
@@ -51164,7 +51406,7 @@ function contains(root, path) {
51164
51406
  function configuredRoots(home, explicitHome) {
51165
51407
  const homeData = join27(home, ".hasna", "skills");
51166
51408
  const homePolicy = readManagedSkillPolicySnapshot(homeData);
51167
- const configuredPolicy = !explicitHome && resolve16(getDataDirReadOnly()) !== resolve16(homeData) ? readManagedSkillPolicySnapshot(getDataDirReadOnly()) : null;
51409
+ const configuredPolicy = !explicitHome && resolve18(getDataDirReadOnly()) !== resolve18(homeData) ? readManagedSkillPolicySnapshot(getDataDirReadOnly()) : null;
51168
51410
  const policy = homePolicy ?? configuredPolicy;
51169
51411
  const bridge = policy?.value.bridge;
51170
51412
  if (bridge && (typeof bridge.home !== "string" || physicalPath(bridge.home) !== physicalPath(home))) {
@@ -51203,22 +51445,22 @@ function configuredRoots(home, explicitHome) {
51203
51445
  function assertPortableAuthoringPath(path, options = {}) {
51204
51446
  if (typeof path !== "string" || !path || path.includes("\x00"))
51205
51447
  throw new Error("Invalid portable authoring path");
51206
- const lexical = resolve16(path);
51448
+ const lexical = resolve18(path);
51207
51449
  const physical = physicalPath(lexical);
51208
51450
  const candidates = [lexical, physical];
51209
51451
  let native = candidates.map(nativeRootMatch).find(Boolean);
51210
- const home = resolve16(options.homeDir ?? homedir3());
51452
+ const home = resolve18(options.homeDir ?? homedir3());
51211
51453
  const defaults = NATIVE_DISCOVERY_ROOTS.map((parts) => join27(home, ...parts));
51212
51454
  defaults.push(join27(home, ".codex/plugins/cache"), join27(home, ".claude/plugins/cache"), join27(home, ".claude/plugins/synced"), join27(home, ".gemini/extensions"));
51213
51455
  for (const root of defaults) {
51214
- 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)))
51215
51457
  native ??= root;
51216
51458
  }
51217
51459
  if (native) {
51218
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.`);
51219
51461
  }
51220
51462
  for (const root of configuredRoots(home, options.homeDir !== undefined)) {
51221
- 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))) {
51222
51464
  throw new Error(`Refusing portable Skills authoring below configured native discovery root: ${lexical}`);
51223
51465
  }
51224
51466
  }
@@ -51245,7 +51487,7 @@ import {
51245
51487
  statSync as statSync7,
51246
51488
  writeFileSync as writeFileSync6
51247
51489
  } from "fs";
51248
- 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";
51249
51491
  function getPortableSkillsRoot(options = {}) {
51250
51492
  return resolvePortableSkillsRoot(options, true);
51251
51493
  }
@@ -51340,20 +51582,20 @@ function scaffoldPortableSkill(name, options = {}) {
51340
51582
  return { name: skillName, path: skillPath, manifest, created: true };
51341
51583
  }
51342
51584
  function physicalImportPath(path) {
51343
- let ancestor = resolve17(path);
51585
+ let ancestor = resolve19(path);
51344
51586
  const suffix = [];
51345
51587
  while (!existsSync12(ancestor)) {
51346
- suffix.unshift(basename10(ancestor));
51347
- ancestor = dirname17(ancestor);
51588
+ suffix.unshift(basename11(ancestor));
51589
+ ancestor = dirname18(ancestor);
51348
51590
  }
51349
51591
  return join28(realpathSync7(ancestor), ...suffix);
51350
51592
  }
51351
51593
  function assertDisjointImportPaths(source, destination) {
51352
51594
  const sourcePath = realpathSync7(source);
51353
51595
  const destinationPath = physicalImportPath(destination);
51354
- const contains2 = (parent, child) => {
51355
- const path = relative5(parent, child);
51356
- 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}`);
51357
51599
  };
51358
51600
  if (contains2(sourcePath, destinationPath) || contains2(destinationPath, sourcePath)) {
51359
51601
  throw new Error("Source and destination skill directories must not overlap");
@@ -51368,8 +51610,8 @@ function portPortableSkill(sourcePath, options = {}) {
51368
51610
  const explicitName = options.name != null;
51369
51611
  const skillName = normalizeNewPortableSkillName(options.name ?? inferred.name);
51370
51612
  if (isOfficialSkillName(skillName) && !options.allowShadow) {
51371
- const sourceSlug = safeNormalizeName(basename10(absoluteSource));
51372
- 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.`;
51373
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.`);
51374
51616
  }
51375
51617
  const readOnlyDestination = join28(resolvePortableSkillsRoot(options, false), skillName);
@@ -51384,7 +51626,7 @@ function portPortableSkill(sourcePath, options = {}) {
51384
51626
  throw new Error(`Skill '${skillName}' already exists at ${destination}`);
51385
51627
  rmSync3(destination, { recursive: true, force: true });
51386
51628
  }
51387
- mkdirSync7(dirname17(destination), { recursive: true });
51629
+ mkdirSync7(dirname18(destination), { recursive: true });
51388
51630
  copySkillDirectory(absoluteSource, destination);
51389
51631
  const base = {
51390
51632
  ...inferred,
@@ -51518,7 +51760,7 @@ function safeIsDirectory(path) {
51518
51760
  }
51519
51761
  }
51520
51762
  function isSafeRelativePath2(value) {
51521
- if (!value.trim() || isAbsolute14(value))
51763
+ if (!value.trim() || isAbsolute16(value))
51522
51764
  return false;
51523
51765
  const normalized = normalize3(value).replace(/\\/g, "/");
51524
51766
  return normalized !== ".." && !normalized.startsWith("../") && !normalized.includes("/../");
@@ -52147,11 +52389,14 @@ var init_skill_context = __esm(() => {
52147
52389
  });
52148
52390
 
52149
52391
  // src/lib/session-reconciliation.ts
52150
- var SESSION_RECONCILIATION_PLAN_TTL_MS;
52392
+ var SESSION_RECONCILIATION_PLAN_TTL_MS, SESSION_RENEWAL_REFUSAL_TTL_MS, SESSION_RENEWAL_REFUSAL_MAX_BYTES;
52151
52393
  var init_session_reconciliation = __esm(() => {
52152
52394
  init_profile_client();
52395
+ init_skill_bundle();
52153
52396
  init_selection_cache();
52154
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;
52155
52400
  });
52156
52401
 
52157
52402
  // src/cli/commands/context.ts
@@ -52189,7 +52434,7 @@ var init_remote_customer_operations = __esm(() => {
52189
52434
  });
52190
52435
 
52191
52436
  // src/lib/canonical-json.ts
52192
- import { createHash as createHash18 } from "crypto";
52437
+ import { createHash as createHash19 } from "crypto";
52193
52438
  function canonicalJson2(value, maximumBytes = 2 * 1024 * 1024) {
52194
52439
  return canonicalJsonAtDepth(value, maximumBytes, 64);
52195
52440
  }
@@ -52233,7 +52478,7 @@ function canonicalJsonAtDepth(value, maximumBytes, maximumDepth) {
52233
52478
  return visit3(value, 0);
52234
52479
  }
52235
52480
  function canonicalJsonSha256(value, maximumBytes) {
52236
- return createHash18("sha256").update(canonicalJson2(value, maximumBytes)).digest("hex");
52481
+ return createHash19("sha256").update(canonicalJson2(value, maximumBytes)).digest("hex");
52237
52482
  }
52238
52483
  var init_canonical_json = () => {};
52239
52484
 
@@ -52984,13 +53229,13 @@ var init_remote_workspace_leave = __esm(() => {
52984
53229
 
52985
53230
  // src/lib/auth-store.ts
52986
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";
52987
- 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";
52988
53233
  function getAuthFilePath(env = process.env) {
52989
53234
  return skillsCredentialFilePath(env);
52990
53235
  }
52991
53236
  function getIdentityFilePath(env = process.env) {
52992
53237
  const file2 = skillsCredentialFilePath(env);
52993
- return join30(dirname18(file2), basename11(file2).replace(/^credentials/, "identity") + ".json");
53238
+ return join30(dirname19(file2), basename12(file2).replace(/^credentials/, "identity") + ".json");
52994
53239
  }
52995
53240
  function getApiUrl(action, env = process.env, options = {}) {
52996
53241
  return requireSkillsApiOrigin(action, env, options);
@@ -53072,17 +53317,17 @@ function runQuoteReceipt(value) {
53072
53317
  return value;
53073
53318
  }
53074
53319
  function parseRemoteRunQuote(value) {
53075
- const quote2 = object7(value);
53076
- runQuoteReceipt(quote2.quoteReceipt);
53077
- const pricing = object7(quote2.pricing);
53078
- 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))
53079
53324
  throw new Error("Invalid quoted skill");
53080
53325
  const costCents = creditCount(pricing.costCredits ?? pricing.costCents);
53081
53326
  if (pricing.costCredits !== undefined && pricing.costCents !== undefined && pricing.costCents !== costCents)
53082
53327
  throw new Error("Inconsistent quoted credit count");
53083
- if (quote2.availability && object7(quote2.availability).status !== "available")
53328
+ if (quote3.availability && object7(quote3.availability).status !== "available")
53084
53329
  throw new Error("This skill is unavailable for remote execution");
53085
- 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` } };
53086
53331
  }
53087
53332
  function parseRemoteCreditPacks(value) {
53088
53333
  if (!Array.isArray(value))
@@ -53174,14 +53419,14 @@ var init_remote_credit_checkout = __esm(() => {
53174
53419
  });
53175
53420
 
53176
53421
  // src/lib/remote-profile.ts
53177
- function customerNamePatch(input2, field2) {
53178
- 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))
53179
53424
  throw new Error("Provide only the requested name field.");
53180
- const value = input2[field2];
53425
+ const value = input2[field3];
53181
53426
  if (typeof value !== "string" || /[\p{Cc}\p{Cs}\u2028\u2029]/u.test(value) || !value.trim() || [...value.trim()].length > 100) {
53182
53427
  throw new Error("Use a name of 1\u2013100 characters without control characters or newlines.");
53183
53428
  }
53184
- return { [field2]: value.trim() };
53429
+ return { [field3]: value.trim() };
53185
53430
  }
53186
53431
  function isRecord5(value) {
53187
53432
  return !!value && typeof value === "object" && !Array.isArray(value);
@@ -53218,10 +53463,10 @@ async function readQuoteUnavailableCode(response) {
53218
53463
  let timer;
53219
53464
  let deadlineExceeded = false;
53220
53465
  const expired = Symbol("quote body deadline");
53221
- const deadline = new Promise((resolve18) => {
53466
+ const deadline = new Promise((resolve20) => {
53222
53467
  timer = setTimeout(() => {
53223
53468
  deadlineExceeded = true;
53224
- resolve18(expired);
53469
+ resolve20(expired);
53225
53470
  reader.cancel().catch(() => {});
53226
53471
  }, 1500);
53227
53472
  });
@@ -53504,18 +53749,18 @@ class RemoteSkillsClient {
53504
53749
  const maximum = creditCount(approval.maxCredits ?? approval.maxCostCents ?? 0);
53505
53750
  if (approval.maxCostCents !== undefined && approval.maxCostCents !== maximum)
53506
53751
  throw new Error("Credit approval fields disagree");
53507
- const quote2 = approval.quoteReceipt === undefined ? await this.quoteRun(slug2, input2, args, approval.inputFiles?.length ? approval.inputFiles : undefined) : undefined;
53508
- if (quote2 && quote2.pricing.costCents > maximum)
53509
- 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);
53510
53755
  const capabilities = await this.getCapabilities();
53511
53756
  if (!capabilities.capabilities.includes("runs.submit") || capabilities.billing?.boundedRunApproval !== true || capabilities.billing.unit !== "credits") {
53512
53757
  throw new Error("The configured server does not support bounded credit approval; refusing remote submission");
53513
53758
  }
53514
- return this.submitRun(quote2?.skill ?? slug2, input2, args, {
53759
+ return this.submitRun(quote3?.skill ?? slug2, input2, args, {
53515
53760
  ...approval,
53516
53761
  maxCredits: maximum,
53517
53762
  maxCostCents: maximum,
53518
- ...(quote2?.quoteReceipt ?? approval.quoteReceipt) === undefined ? {} : { quoteReceipt: quote2?.quoteReceipt ?? approval.quoteReceipt }
53763
+ ...(quote3?.quoteReceipt ?? approval.quoteReceipt) === undefined ? {} : { quoteReceipt: quote3?.quoteReceipt ?? approval.quoteReceipt }
53519
53764
  });
53520
53765
  }
53521
53766
  async getIdentity() {
@@ -54116,13 +54361,13 @@ class RemoteSkillsClient {
54116
54361
  return normalizeUpdatedSincePage(await response.json());
54117
54362
  }
54118
54363
  }
54119
- function requireOptionalString(record9, field2) {
54120
- if (record9[field2] === undefined)
54364
+ function requireOptionalString(record9, field3) {
54365
+ if (record9[field3] === undefined)
54121
54366
  return;
54122
- if (typeof record9[field2] !== "string") {
54123
- 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)`);
54124
54369
  }
54125
- return record9[field2];
54370
+ return record9[field3];
54126
54371
  }
54127
54372
  function isVersionRecord(value) {
54128
54373
  return value !== null && typeof value === "object" && !Array.isArray(value);
@@ -54459,7 +54704,7 @@ var init_remote_invitation_recovery = __esm(() => {
54459
54704
  });
54460
54705
 
54461
54706
  // src/lib/remote-private-publications.ts
54462
- import { createHash as createHash19 } from "crypto";
54707
+ import { createHash as createHash20 } from "crypto";
54463
54708
  function checkedPublicationDeclaration(value) {
54464
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)
54465
54710
  return bad();
@@ -54704,12 +54949,12 @@ class RemotePrivatePublicationsClient {
54704
54949
  previous = view;
54705
54950
  if (!["queued", "verifying"].includes(view.state) || Date.now() >= until)
54706
54951
  return view;
54707
- await new Promise((resolve18) => {
54952
+ await new Promise((resolve20) => {
54708
54953
  const timer = setTimeout(done, Math.min(1000, until - Date.now()));
54709
54954
  function done() {
54710
54955
  clearTimeout(timer);
54711
54956
  options.signal?.removeEventListener("abort", done);
54712
- resolve18();
54957
+ resolve20();
54713
54958
  }
54714
54959
  options.signal?.addEventListener("abort", done, { once: true });
54715
54960
  });
@@ -54720,7 +54965,7 @@ var PRIVATE_PUBLICATION_MAX_BYTES, failures2, PrivatePublicationError, bad = ()
54720
54965
  throw new PrivatePublicationError("INVALID_PUBLICATION_INPUT", "Invalid publication input or recovery data.");
54721
54966
  }, invalid4 = () => {
54722
54967
  throw new PrivatePublicationError("INVALID_PUBLICATION_RESPONSE", "The server returned an invalid publication result.");
54723
- }, 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");
54724
54969
  var init_remote_private_publications = __esm(() => {
54725
54970
  init_fleet_credentials();
54726
54971
  init_remote_workspace_selection();
@@ -55230,7 +55475,7 @@ var init_recurring_customer = __esm(() => {
55230
55475
 
55231
55476
  // src/lib/recurring-recovery.ts
55232
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";
55233
- 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";
55234
55479
  import { randomUUID as randomUUID2 } from "crypto";
55235
55480
 
55236
55481
  class RecoveryOwner {
@@ -55238,14 +55483,14 @@ class RecoveryOwner {
55238
55483
  parents = [];
55239
55484
  constructor(directory) {
55240
55485
  this.directory = directory;
55241
- if (!isAbsolute15(directory) || resolve18(directory) !== directory || realpathSync8(directory) !== directory)
55486
+ if (!isAbsolute17(directory) || resolve20(directory) !== directory || realpathSync8(directory) !== directory)
55242
55487
  invalid5();
55243
- for (let path = directory;; path = dirname19(path)) {
55488
+ for (let path = directory;; path = dirname20(path)) {
55244
55489
  const stat3 = lstatSync21(path);
55245
55490
  if (!stat3.isDirectory() || stat3.isSymbolicLink())
55246
55491
  invalid5();
55247
55492
  this.parents.push({ path, dev: stat3.dev, ino: stat3.ino });
55248
- if (path === dirname19(path))
55493
+ if (path === dirname20(path))
55249
55494
  break;
55250
55495
  }
55251
55496
  this.assert();
@@ -55373,7 +55618,7 @@ function base(customer, organizationId) {
55373
55618
  };
55374
55619
  }
55375
55620
  function create(directory, intent) {
55376
- if (!isAbsolute15(directory) || resolve18(directory) !== directory || realpathSync8(dirname19(directory)) !== dirname19(directory))
55621
+ if (!isAbsolute17(directory) || resolve20(directory) !== directory || realpathSync8(dirname20(directory)) !== dirname20(directory))
55377
55622
  invalid5();
55378
55623
  mkdirSync10(directory, { mode: 448 });
55379
55624
  const owner2 = new RecoveryOwner(directory), checked = intentSchema.parse(intent), intentSha256 = canonicalJsonSha256(checked);
@@ -55536,7 +55781,7 @@ var init_recurring_recovery = __esm(() => {
55536
55781
  });
55537
55782
 
55538
55783
  // src/lib/recurring-surface.ts
55539
- import { isAbsolute as isAbsolute16 } from "path";
55784
+ import { isAbsolute as isAbsolute18 } from "path";
55540
55785
  function recurringMcpSchema(action) {
55541
55786
  return action === "activate" ? recurringSurfaceSchemas.activate.extend({ code, confirm: exports_external.literal(true) }) : recurringSurfaceSchemas[action];
55542
55787
  }
@@ -55641,7 +55886,7 @@ var init_recurring_surface = __esm(() => {
55641
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}$/);
55642
55887
  context = { userId: uuid13.optional(), membershipId: uuid13.optional() };
55643
55888
  page2 = { limit: exports_external.number().int().min(1).max(100).optional(), cursor: exports_external.string().min(1).max(2048).optional() };
55644
- 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");
55645
55890
  email4 = exports_external.string().trim().toLowerCase().email().max(254);
55646
55891
  code = exports_external.string().regex(/^\d{6}$/);
55647
55892
  recurringSurfaceSchemas = {
@@ -57470,7 +57715,7 @@ var init_credential_state = __esm(() => {
57470
57715
  });
57471
57716
 
57472
57717
  // src/lib/run-state.ts
57473
- import { createHash as createHash20, randomBytes } from "crypto";
57718
+ import { createHash as createHash21, randomBytes } from "crypto";
57474
57719
  import { existsSync as existsSync15, mkdirSync as mkdirSync11, readFileSync as readFileSync19, readdirSync as readdirSync10, statSync as statSync9, writeFileSync as writeFileSync10 } from "fs";
57475
57720
  import { extname, join as join32, relative as relative6 } from "path";
57476
57721
  function createSkillRun(params, targetDir = process.cwd()) {
@@ -57585,7 +57830,7 @@ function collectRunArtifacts(context2) {
57585
57830
  artifacts.push({
57586
57831
  path: toProjectRelative(context2.targetDir, path),
57587
57832
  mime: mimeForPath(path),
57588
- sha256: createHash20("sha256").update(bytes).digest("hex"),
57833
+ sha256: createHash21("sha256").update(bytes).digest("hex"),
57589
57834
  sizeBytes: stat3.size
57590
57835
  });
57591
57836
  }
@@ -57831,12 +58076,12 @@ function parseExecution(value) {
57831
58076
  ].includes(v.status) || typeof v.skill !== "string" || typeof v.version !== "string" || !Array.isArray(v.artifacts))
57832
58077
  throw Error("Unsupported cloud execution response");
57833
58078
  runId(v.id);
57834
- for (const field2 of [
58079
+ for (const field3 of [
57835
58080
  "bundleDigest",
57836
58081
  "inputDigest",
57837
58082
  "runtimeImageDigest"
57838
58083
  ])
57839
- 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]))
57840
58085
  throw Error("Invalid cloud execution integrity receipt");
57841
58086
  return v;
57842
58087
  }
@@ -57861,7 +58106,7 @@ import { closeSync as closeSync16, fstatSync as fstatSync16, openSync as openSyn
57861
58106
  import { O_NOFOLLOW as O_NOFOLLOW3, O_NONBLOCK as O_NONBLOCK3, O_RDONLY as O_RDONLY3 } from "constants";
57862
58107
  import { createRequire as createRequire2 } from "module";
57863
58108
  import { hostname as osHostname2 } from "os";
57864
- import { isAbsolute as isAbsolute17, join as join33 } from "path";
58109
+ import { isAbsolute as isAbsolute19, join as join33 } from "path";
57865
58110
  import { createRequire as createRequire22 } from "module";
57866
58111
  function envToken2(name) {
57867
58112
  return name.toUpperCase().replace(/-/g, "_");
@@ -57885,7 +58130,7 @@ function homeDir2(env) {
57885
58130
  }
57886
58131
  function absoluteOverride2(env, key) {
57887
58132
  const value = env[key]?.trim();
57888
- return value && isAbsolute17(value) ? value : null;
58133
+ return value && isAbsolute19(value) ? value : null;
57889
58134
  }
57890
58135
  function hasnaHomeDir2(env) {
57891
58136
  const override = absoluteOverride2(env, HASNA_HOME_ENV_KEY2);
@@ -57931,9 +58176,9 @@ function parseEnvFile2(text3) {
57931
58176
  if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key))
57932
58177
  continue;
57933
58178
  let value = withoutExport.slice(equals + 1).trim();
57934
- const quote2 = value[0];
57935
- if (quote2 === '"' || quote2 === "'") {
57936
- if (value.length < 2 || !value.endsWith(quote2)) {
58179
+ const quote3 = value[0];
58180
+ if (quote3 === '"' || quote3 === "'") {
58181
+ if (value.length < 2 || !value.endsWith(quote3)) {
57937
58182
  unusable.add(key);
57938
58183
  continue;
57939
58184
  }
@@ -57957,8 +58202,8 @@ function configFileReadsCoherent2(before, after) {
57957
58202
  return before.dev === after.dev && before.ino === after.ino && before.size === after.size && before.mtimeMs === after.mtimeMs && before.ctimeMs === after.ctimeMs;
57958
58203
  }
57959
58204
  function readAppConfigFile2(path) {
57960
- const unsafe = (reason) => {
57961
- throw new CredentialFileUnsafeError2(path, reason);
58205
+ const unsafe = (reason2) => {
58206
+ throw new CredentialFileUnsafeError2(path, reason2);
57962
58207
  };
57963
58208
  let fd = -1;
57964
58209
  try {
@@ -58177,8 +58422,8 @@ function readKeychainItem2(name, env, kind, options) {
58177
58422
  try {
58178
58423
  result = run(["find-generic-password", "-a", account, "-s", service, "-w"]);
58179
58424
  } catch (error61) {
58180
- const reason = keychainFailureHint2(error61 instanceof Error ? error61.message : String(error61));
58181
- 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]);
58182
58427
  }
58183
58428
  if (result.status === KEYCHAIN_ITEM_NOT_FOUND_STATUS2)
58184
58429
  return null;
@@ -59022,7 +59267,7 @@ function createSecretsClientFromEnv(env = process.env, overrides = {}) {
59022
59267
  });
59023
59268
  return new SecretsClient({ ...clientOverrides, baseUrl, apiKey });
59024
59269
  }
59025
- 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;
59026
59271
  var init_sdk = __esm(() => {
59027
59272
  init_transport2 = __esm2(() => {
59028
59273
  CredentialResolutionError2 = class CredentialResolutionError3 extends Error {
@@ -59037,8 +59282,8 @@ var init_sdk = __esm(() => {
59037
59282
  };
59038
59283
  CredentialFileUnsafeError2 = class CredentialFileUnsafeError3 extends Error {
59039
59284
  path;
59040
- constructor(path, reason) {
59041
- super(`Refusing unsafe credential/config file ${path}: ${reason}.`);
59285
+ constructor(path, reason2) {
59286
+ super(`Refusing unsafe credential/config file ${path}: ${reason2}.`);
59042
59287
  this.name = "CredentialFileUnsafeError";
59043
59288
  this.path = path;
59044
59289
  }
@@ -59399,10 +59644,10 @@ __export(exports_selected_run, {
59399
59644
  prepareSelectedSecretBindings: () => prepareSelectedSecretBindings,
59400
59645
  executeSelectedLocal: () => executeSelectedLocal
59401
59646
  });
59402
- import { createHash as createHash21 } from "crypto";
59647
+ import { createHash as createHash22 } from "crypto";
59403
59648
  import { spawn } from "child_process";
59404
59649
  import { mkdirSync as mkdirSync12, mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync11, realpathSync as realpathSync10 } from "fs";
59405
- 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";
59406
59651
  import { tmpdir, hostname as stationHostname2 } from "os";
59407
59652
  async function resolveSelectedRun(spec, profileId, options = {}) {
59408
59653
  const context2 = await resolveSelectionContext(profileId, options);
@@ -59491,11 +59736,11 @@ async function executeSelectedLocal(selected, options = {}) {
59491
59736
  throw new SkillSelectionError("INVALID_BUNDLE_PATH", "The execution bundle path exceeds its limit.");
59492
59737
  });
59493
59738
  const destination = join34(runDirectory, entry.path);
59494
- mkdirSync12(dirname20(destination), { recursive: true, mode: 448 });
59739
+ mkdirSync12(dirname21(destination), { recursive: true, mode: 448 });
59495
59740
  writeFileSync11(destination, entry.bytes, { flag: "wx", mode: entry.mode & 511 });
59496
59741
  }
59497
59742
  env.SKILLS_INPUT_JSON = input2;
59498
- env.SKILLS_WORKSPACE_DIR = resolve19(options.cwd ?? process.cwd());
59743
+ env.SKILLS_WORKSPACE_DIR = resolve21(options.cwd ?? process.cwd());
59499
59744
  env.SKILLS_RUN_DIR = runDirectory;
59500
59745
  if (runtime.version) {
59501
59746
  const version2 = await subprocess([executable, ...runtimeName === "bun" ? ["--no-env-file"] : [], "--version"], runDirectory, env, "", Math.min(timeoutMs, 5000));
@@ -59525,7 +59770,7 @@ async function executeSelectedLocal(selected, options = {}) {
59525
59770
  selection: selection2,
59526
59771
  target: "local",
59527
59772
  runtime: runtimeName,
59528
- inputDigest: `sha256:${createHash21("sha256").update(input2).digest("hex")}`,
59773
+ inputDigest: `sha256:${createHash22("sha256").update(input2).digest("hex")}`,
59529
59774
  runDirectory,
59530
59775
  ...executionGrant ? { executionGrant } : {},
59531
59776
  ...bindings ? { secretBinding: { schema: bindings.schema, selection: bindings.selection, consumer: bindings.consumer, secretsAuthority: bindings.secretsAuthority, bindings: bindings.bindings } } : {},
@@ -59536,17 +59781,17 @@ async function executeSelectedLocal(selected, options = {}) {
59536
59781
  }
59537
59782
  async function subprocess(command, cwd, env, input2, timeoutMs) {
59538
59783
  return new Promise((resolveResult) => {
59539
- 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"] });
59540
59785
  let outputBytes = 0, error61, ended = false;
59541
59786
  const stdout = [], stderr = [];
59542
59787
  const kill = () => {
59543
59788
  try {
59544
- if (process.platform !== "win32" && child.pid)
59545
- process.kill(-child.pid, "SIGKILL");
59789
+ if (process.platform !== "win32" && child2.pid)
59790
+ process.kill(-child2.pid, "SIGKILL");
59546
59791
  else
59547
- child.kill("SIGKILL");
59792
+ child2.kill("SIGKILL");
59548
59793
  } catch {
59549
- child.kill("SIGKILL");
59794
+ child2.kill("SIGKILL");
59550
59795
  }
59551
59796
  };
59552
59797
  const timer = setTimeout(() => {
@@ -59562,8 +59807,8 @@ async function subprocess(command, cwd, env, input2, timeoutMs) {
59562
59807
  }
59563
59808
  target.push(chunk);
59564
59809
  };
59565
- child.stdout.on("data", capture2(stdout));
59566
- child.stderr.on("data", capture2(stderr));
59810
+ child2.stdout.on("data", capture2(stdout));
59811
+ child2.stderr.on("data", capture2(stderr));
59567
59812
  const finish = (code2) => {
59568
59813
  if (ended)
59569
59814
  return;
@@ -59571,13 +59816,13 @@ async function subprocess(command, cwd, env, input2, timeoutMs) {
59571
59816
  clearTimeout(timer);
59572
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 } : {} });
59573
59818
  };
59574
- child.on("error", () => {
59819
+ child2.on("error", () => {
59575
59820
  error61 = "LOCAL_RUNTIME_START_FAILED";
59576
59821
  finish(127);
59577
59822
  });
59578
- child.on("close", (code2) => finish(code2 ?? 1));
59579
- child.stdin.on("error", () => {});
59580
- child.stdin.end(input2);
59823
+ child2.on("close", (code2) => finish(code2 ?? 1));
59824
+ child2.stdin.on("error", () => {});
59825
+ child2.stdin.end(input2);
59581
59826
  });
59582
59827
  }
59583
59828
  var init_selected_run = __esm(() => {
@@ -60094,9 +60339,9 @@ function registerOperationTools(server) {
60094
60339
  }
60095
60340
  }, async ({ run_id, detail }) => {
60096
60341
  const { skillsCredentialOrReason: skillsCredentialOrReason2 } = await Promise.resolve().then(() => (init_fleet_credentials(), exports_fleet_credentials));
60097
- const { apiKey, apiOrigin, reason } = await skillsCredentialOrReason2();
60342
+ const { apiKey, apiOrigin, reason: reason2 } = await skillsCredentialOrReason2();
60098
60343
  if (!apiKey) {
60099
- 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"]);
60100
60345
  }
60101
60346
  const localRun = findSkillRun(run_id);
60102
60347
  const remoteRunId = localRun?.remoteRunId || run_id;
@@ -60266,14 +60511,14 @@ var init_operation_tools = __esm(() => {
60266
60511
 
60267
60512
  // src/lib/feedback.ts
60268
60513
  import { appendFileSync, existsSync as existsSync17, mkdirSync as mkdirSync13 } from "fs";
60269
- import { dirname as dirname21, join as join36 } from "path";
60514
+ import { dirname as dirname22, join as join36 } from "path";
60270
60515
  import { Database } from "bun:sqlite";
60271
60516
  function getFeedbackDbPath() {
60272
60517
  return join36(getDataDir(), "skills.db");
60273
60518
  }
60274
60519
  function getFeedbackDb() {
60275
60520
  const dbPath = getFeedbackDbPath();
60276
- const dir = dirname21(dbPath);
60521
+ const dir = dirname22(dbPath);
60277
60522
  if (!existsSync17(dir))
60278
60523
  mkdirSync13(dir, { recursive: true });
60279
60524
  const db = new Database(dbPath);
@@ -60302,7 +60547,7 @@ function saveFeedback(input2) {
60302
60547
  const category = input2.category ?? "general";
60303
60548
  if (isApiMode()) {
60304
60549
  const path = join36(getDataDir(), "feedback.jsonl");
60305
- const dir = dirname21(path);
60550
+ const dir = dirname22(path);
60306
60551
  if (!existsSync17(dir))
60307
60552
  mkdirSync13(dir, { recursive: true });
60308
60553
  appendFileSync(path, JSON.stringify({ message, category, email: input2.email ?? null, agent: input2.agent ?? null, version: input2.version ?? null, createdAt: new Date().toISOString() }) + `
@@ -60753,7 +60998,7 @@ var init_schedule_tools = __esm(() => {
60753
60998
  });
60754
60999
 
60755
61000
  // src/lib/native-storage.ts
60756
- import { createHash as createHash22, createHmac } from "crypto";
61001
+ import { createHash as createHash23, createHmac } from "crypto";
60757
61002
  import {
60758
61003
  existsSync as existsSync19,
60759
61004
  mkdirSync as mkdirSync15,
@@ -60762,7 +61007,7 @@ import {
60762
61007
  statSync as statSync11,
60763
61008
  writeFileSync as writeFileSync13
60764
61009
  } from "fs";
60765
- 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";
60766
61011
  function resolveSkillsNativeStorageConfig(env = process.env) {
60767
61012
  assertNoRetiredModeEnvVars(env, {
60768
61013
  app: SKILLS_ENV_NAMESPACE,
@@ -60830,7 +61075,7 @@ function exportSkillsLocalSnapshot(targetDir = process.cwd(), options = {}) {
60830
61075
  files.push({
60831
61076
  path: relativePath,
60832
61077
  sizeBytes: bytes.byteLength,
60833
- sha256: createHash22("sha256").update(bytes).digest("hex"),
61078
+ sha256: createHash23("sha256").update(bytes).digest("hex"),
60834
61079
  ...options.includeFileContents ? { contentBase64: Buffer.from(bytes).toString("base64") } : {}
60835
61080
  });
60836
61081
  }
@@ -61123,16 +61368,16 @@ var init_private_publication_customer = __esm(() => {
61123
61368
 
61124
61369
  // src/lib/private-publication-recovery.ts
61125
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";
61126
- 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";
61127
61372
  import { randomUUID as randomUUID3 } from "crypto";
61128
61373
  function safeDirectory(directory2) {
61129
- if (!isAbsolute18(directory2) || directory2 !== resolve20(directory2) || realpathSync11(directory2) !== directory2)
61374
+ if (!isAbsolute20(directory2) || directory2 !== resolve22(directory2) || realpathSync11(directory2) !== directory2)
61130
61375
  return fail2();
61131
- for (let path = directory2;; path = dirname23(path)) {
61376
+ for (let path = directory2;; path = dirname24(path)) {
61132
61377
  const stat3 = lstatSync22(path);
61133
61378
  if (!stat3.isDirectory() || stat3.isSymbolicLink())
61134
61379
  return fail2();
61135
- if (path === dirname23(path))
61380
+ if (path === dirname24(path))
61136
61381
  break;
61137
61382
  }
61138
61383
  const own2 = lstatSync22(directory2);
@@ -61264,11 +61509,11 @@ async function preparePrivatePublication(client, sourceDirectory, recoveryDirect
61264
61509
  phase: "prepared",
61265
61510
  intent: null
61266
61511
  };
61267
- if (!isAbsolute18(recoveryDirectory) || resolve20(recoveryDirectory) !== recoveryDirectory || realpathSync11(dirname23(recoveryDirectory)) !== dirname23(recoveryDirectory))
61512
+ if (!isAbsolute20(recoveryDirectory) || resolve22(recoveryDirectory) !== recoveryDirectory || realpathSync11(dirname24(recoveryDirectory)) !== dirname24(recoveryDirectory))
61268
61513
  return fail2();
61269
61514
  mkdirSync16(recoveryDirectory, { mode: 448 });
61270
61515
  safeDirectory(recoveryDirectory);
61271
- const parent = openSync18(dirname23(recoveryDirectory), constants14.O_RDONLY | constants14.O_NOFOLLOW);
61516
+ const parent = openSync18(dirname24(recoveryDirectory), constants14.O_RDONLY | constants14.O_NOFOLLOW);
61272
61517
  try {
61273
61518
  fsyncSync5(parent);
61274
61519
  } finally {
@@ -61365,10 +61610,10 @@ var init_private_publication_recovery = __esm(() => {
61365
61610
  });
61366
61611
 
61367
61612
  // src/mcp/private-publication-tools.ts
61368
- import { isAbsolute as isAbsolute19 } from "path";
61613
+ import { isAbsolute as isAbsolute21 } from "path";
61369
61614
  function registerPrivatePublicationTools(server) {
61370
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}$/);
61371
- 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");
61372
61617
  const verification2 = { email: exports_external.string().email().max(254), code: exports_external.string().regex(/^\d{6}$/), userId: uuid9, membershipId: uuid9, recoveryDirectory: directory2 };
61373
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.";
61374
61619
  const handler = (action) => async (value) => {
@@ -61780,8 +62025,8 @@ var WSContext = class {
61780
62025
  }
61781
62026
  url;
61782
62027
  protocol;
61783
- close(code2, reason) {
61784
- this.#init.close(code2, reason);
62028
+ close(code2, reason2) {
62029
+ this.#init.close(code2, reason2);
61785
62030
  }
61786
62031
  }, defineWebSocketHelper = (handler) => {
61787
62032
  return (...args) => {
@@ -62061,9 +62306,9 @@ var RequestError, nonJoinedHeaders, validHeaderName, isHttpWhitespace = (code2)
62061
62306
  }, normalizeAbortError = (request2, incoming) => {
62062
62307
  if (incoming.errored)
62063
62308
  return incoming.errored;
62064
- const reason = request2[abortReasonKey];
62065
- if (reason !== undefined)
62066
- 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));
62067
62312
  return /* @__PURE__ */ new Error("Client connection prematurely closed.");
62068
62313
  }, readBodyDirect = (request2) => {
62069
62314
  if (request2[bodyBufferKey])
@@ -62080,7 +62325,7 @@ var RequestError, nonJoinedHeaders, validHeaderName, isHttpWhitespace = (code2)
62080
62325
  request2[bodyBufferKey] = buffered;
62081
62326
  return Promise.resolve(buffered);
62082
62327
  }
62083
- const promise3 = new Promise((resolve21, reject) => {
62328
+ const promise3 = new Promise((resolve23, reject) => {
62084
62329
  const chunks = [];
62085
62330
  let settled = false;
62086
62331
  const finish = (callback) => {
@@ -62102,7 +62347,7 @@ var RequestError, nonJoinedHeaders, validHeaderName, isHttpWhitespace = (code2)
62102
62347
  reject(error61 ?? normalizeAbortError(request2, incoming));
62103
62348
  else {
62104
62349
  request2[bodyBufferKey] = recovered;
62105
- resolve21(recovered);
62350
+ resolve23(recovered);
62106
62351
  }
62107
62352
  });
62108
62353
  return true;
@@ -62114,7 +62359,7 @@ var RequestError, nonJoinedHeaders, validHeaderName, isHttpWhitespace = (code2)
62114
62359
  finish(() => {
62115
62360
  const buffer = chunks.length === 1 ? chunks[0] : Buffer.concat(chunks);
62116
62361
  request2[bodyBufferKey] = buffer;
62117
- resolve21(buffer);
62362
+ resolve23(buffer);
62118
62363
  });
62119
62364
  };
62120
62365
  const onError = (error61) => {
@@ -62388,7 +62633,7 @@ var RequestError, nonJoinedHeaders, validHeaderName, isHttpWhitespace = (code2)
62388
62633
  });
62389
62634
  if (!chunk) {
62390
62635
  if (i === 1) {
62391
- await new Promise((resolve21) => setTimeout(resolve21));
62636
+ await new Promise((resolve23) => setTimeout(resolve23));
62392
62637
  maxReadCount = 3;
62393
62638
  continue;
62394
62639
  }
@@ -62689,12 +62934,12 @@ var init_dist2 = __esm(() => {
62689
62934
  get headers() {
62690
62935
  return this[headersKey] ||= newHeadersFromIncoming(this[incomingKey]);
62691
62936
  },
62692
- [abortRequest](reason) {
62937
+ [abortRequest](reason2) {
62693
62938
  if (this[abortReasonKey] === undefined)
62694
- this[abortReasonKey] = reason;
62939
+ this[abortReasonKey] = reason2;
62695
62940
  const abortController = this[abortControllerKey];
62696
62941
  if (abortController && !abortController.signal.aborted)
62697
- abortController.abort(reason);
62942
+ abortController.abort(reason2);
62698
62943
  },
62699
62944
  [getAbortController]() {
62700
62945
  this[abortControllerKey] ||= new AbortController;
@@ -63018,8 +63263,8 @@ var init_dist2 = __esm(() => {
63018
63263
  ws.on("message", bufferMessage);
63019
63264
  const ctx = {
63020
63265
  binaryType: "arraybuffer",
63021
- close(code2, reason) {
63022
- ws.close(code2, reason);
63266
+ close(code2, reason2) {
63267
+ ws.close(code2, reason2);
63023
63268
  },
63024
63269
  protocol: ws.protocol,
63025
63270
  raw: ws,
@@ -63051,11 +63296,11 @@ var init_dist2 = __esm(() => {
63051
63296
  ws.on("message", (data, isBinary) => {
63052
63297
  handleMessage(data, isBinary);
63053
63298
  });
63054
- ws.on("close", (code2, reason) => {
63299
+ ws.on("close", (code2, reason2) => {
63055
63300
  try {
63056
63301
  events2?.onClose?.(new CloseEvent("close", {
63057
63302
  code: code2,
63058
- reason: reason.toString()
63303
+ reason: reason2.toString()
63059
63304
  }), ctx);
63060
63305
  } catch (e2) {
63061
63306
  (options?.onError ?? console.error)(e2);
@@ -63618,9 +63863,9 @@ data:
63618
63863
  const initRequest = messages.find((m) => isInitializeRequest(m));
63619
63864
  const clientProtocolVersion = initRequest ? initRequest.params.protocolVersion : req.headers.get("mcp-protocol-version") ?? DEFAULT_NEGOTIATED_PROTOCOL_VERSION;
63620
63865
  if (this._enableJsonResponse) {
63621
- return new Promise((resolve21) => {
63866
+ return new Promise((resolve23) => {
63622
63867
  this._streamMapping.set(streamId, {
63623
- resolveJson: resolve21,
63868
+ resolveJson: resolve23,
63624
63869
  cleanup: () => {
63625
63870
  this._streamMapping.delete(streamId);
63626
63871
  }
@@ -63989,19 +64234,19 @@ async function connectMcpForNode() {
63989
64234
  return { server: server2, transport };
63990
64235
  }
63991
64236
  function readBody(req) {
63992
- return new Promise((resolve21, reject) => {
64237
+ return new Promise((resolve23, reject) => {
63993
64238
  const chunks = [];
63994
64239
  req.on("data", (chunk) => chunks.push(Buffer.from(chunk)));
63995
64240
  req.on("end", () => {
63996
64241
  const raw = Buffer.concat(chunks).toString("utf-8");
63997
64242
  if (!raw.trim()) {
63998
- resolve21(undefined);
64243
+ resolve23(undefined);
63999
64244
  return;
64000
64245
  }
64001
64246
  try {
64002
- resolve21(JSON.parse(raw));
64247
+ resolve23(JSON.parse(raw));
64003
64248
  } catch {
64004
- resolve21(undefined);
64249
+ resolve23(undefined);
64005
64250
  }
64006
64251
  });
64007
64252
  req.on("error", reject);
@@ -64043,9 +64288,9 @@ async function startSkillsMcpHttpServer(options = {}) {
64043
64288
  }
64044
64289
  }
64045
64290
  });
64046
- await new Promise((resolve21, reject) => {
64291
+ await new Promise((resolve23, reject) => {
64047
64292
  httpServer.once("error", reject);
64048
- httpServer.listen(port, hostname4, () => resolve21());
64293
+ httpServer.listen(port, hostname4, () => resolve23());
64049
64294
  });
64050
64295
  const address = httpServer.address();
64051
64296
  const listenPort = typeof address === "object" && address ? address.port : port;