@hasna/skills 0.10.62 → 0.10.63

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
@@ -23,7 +23,7 @@ var package_default;
23
23
  var init_package = __esm(() => {
24
24
  package_default = {
25
25
  name: "@hasna/skills",
26
- version: "0.10.62",
26
+ version: "0.10.63",
27
27
  description: "Skills library for AI coding agents",
28
28
  type: "module",
29
29
  bin: {
@@ -23119,6 +23119,15 @@ function assertAgentPolicyCollections(policy) {
23119
23119
  }
23120
23120
  } else
23121
23121
  requireBound(source.managedPlugins === undefined);
23122
+ if (source.reviewArtifact !== undefined) {
23123
+ const artifact = source.reviewArtifact;
23124
+ requireBound(agent === "codex" && value.method === "reviewed" && source.hashMode === "bytes" && object2(artifact) && Object.keys(artifact).length === 6 && Object.keys(artifact).every((key) => ["version", "kind", "storeRoot", "originalPath", "sha256", "catalogSha256"].includes(key)) && artifact.version === 1 && artifact.kind === "codex-native-catalog" && artifact.sha256 === source.sha256 && /^[a-f0-9]{64}$/.test(artifact.catalogSha256));
23125
+ for (const path of [artifact.storeRoot, artifact.originalPath]) {
23126
+ text(path);
23127
+ requireBound(isAbsolute5(path) && resolve4(path) === path);
23128
+ }
23129
+ requireBound(source.path === join10(artifact.storeRoot, "agent-discovery", "artifacts", artifact.sha256, "catalog.json"));
23130
+ }
23122
23131
  if (source.format !== undefined)
23123
23132
  requireBound(["json", "toml", "yaml"].includes(source.format));
23124
23133
  if (source.fields !== undefined)
@@ -32722,11 +32731,55 @@ var init_codex_hook_rpc = __esm(() => {
32722
32731
  });
32723
32732
 
32724
32733
  // src/lib/codex-native-skill-catalog.ts
32734
+ import { isAbsolute as isAbsolute10, normalize as normalize2 } from "path";
32725
32735
  function codexPluginSourceIsConfigControlled(plugin) {
32726
32736
  const remoteRealms = ["openai-curated-remote", "created-by-me-remote", "workspace-directory", "workspace-shared-with-me", "workspace-shared-with-me-private", "workspace-shared-with-me-unlisted"];
32727
32737
  return Boolean(plugin.sourceType && ["local", "git", "npm"].includes(plugin.sourceType) && plugin.sourceSha256 && /^[a-f0-9]{64}$/.test(plugin.sourceSha256) && !plugin.remotePluginId && !remoteRealms.includes(plugin.id.slice(plugin.id.lastIndexOf("@") + 1)));
32728
32738
  }
32729
- var remotePluginIdentifier = (value) => typeof value === "string" && /^[A-Za-z0-9_~-]{1,1024}$/.test(value);
32739
+ function refuse() {
32740
+ throw new Error("CODEX_NATIVE_SKILL_CATALOG_INVALID");
32741
+ }
32742
+ function projectCodexNativeSkillCatalog(response, cwd) {
32743
+ if (!absolutePath2(cwd) || !object5(response) || !Array.isArray(response.data) || response.data.length !== 1)
32744
+ refuse();
32745
+ const entry = response.data[0];
32746
+ if (!object5(entry) || entry.cwd !== cwd || !Array.isArray(entry.errors) || entry.errors.length !== 0 || !Array.isArray(entry.skills) || entry.skills.length > MAX_SKILLS)
32747
+ refuse();
32748
+ const paths = new Set;
32749
+ return entry.skills.map((value) => {
32750
+ if (!object5(value) || !scalar(value.name, MAX_NAME_BYTES) || !absolutePath2(value.path) || typeof value.enabled !== "boolean" || value.pluginId !== undefined && value.pluginId !== null && !scalar(value.pluginId, MAX_NAME_BYTES))
32751
+ refuse();
32752
+ if (paths.has(value.path))
32753
+ refuse();
32754
+ paths.add(value.path);
32755
+ return { name: value.name, path: value.path, enabled: value.enabled, pluginId: value.pluginId ?? null };
32756
+ });
32757
+ }
32758
+ function projectCodexInstalledPluginEntries(value) {
32759
+ if (!Array.isArray(value) || value.length > MAX_SKILLS)
32760
+ refuse();
32761
+ const ids = new Set;
32762
+ return value.map((item) => {
32763
+ if (!object5(item) || !scalar(item.id, MAX_PLUGIN_ID_BYTES) || !scalar(item.name, MAX_NAME_BYTES) || typeof item.installed !== "boolean" || typeof item.enabled !== "boolean" || item.localVersion !== null && !scalar(item.localVersion, MAX_NAME_BYTES) || item.remotePluginId !== undefined && item.remotePluginId !== null && !remotePluginIdentifier(item.remotePluginId) || item.sourceType !== undefined && !["remote", "local", "git", "npm"].includes(item.sourceType) || (["local", "git", "npm"].includes(item.sourceType) ? typeof item.sourceSha256 !== "string" || !/^[a-f0-9]{64}$/.test(item.sourceSha256) : item.sourceSha256 !== undefined) || (item.sourceType === "local" ? !absolutePath2(item.sourcePath) || normalize2(item.sourcePath) !== item.sourcePath || item.sourceSha256 !== hashNativeJsonControls(JSON.stringify({ type: "local", path: item.sourcePath })) : item.sourcePath !== undefined))
32764
+ refuse();
32765
+ const at = item.id.lastIndexOf("@");
32766
+ if (at < 1 || item.id.slice(0, at) !== item.name || at === item.id.length - 1 || ids.has(item.id))
32767
+ refuse();
32768
+ ids.add(item.id);
32769
+ return {
32770
+ id: item.id,
32771
+ name: item.name,
32772
+ installed: item.installed,
32773
+ enabled: item.enabled,
32774
+ localVersion: item.localVersion ?? null,
32775
+ ...item.sourceType === undefined ? {} : { sourceType: item.sourceType },
32776
+ ...item.sourceSha256 === undefined ? {} : { sourceSha256: item.sourceSha256 },
32777
+ ...item.sourcePath === undefined ? {} : { sourcePath: item.sourcePath },
32778
+ ...item.remotePluginId == null ? {} : { remotePluginId: item.remotePluginId }
32779
+ };
32780
+ });
32781
+ }
32782
+ var MAX_SKILLS = 4096, MAX_NAME_BYTES = 1024, MAX_PATH_BYTES = 16384, MAX_PLUGIN_ID_BYTES = 1024, object5 = (value) => value !== null && typeof value === "object" && !Array.isArray(value), scalar = (value, max) => typeof value === "string" && value.length > 0 && value.trim() === value && Buffer.byteLength(value, "utf8") <= max && !/[\u0000-\u001f\u007f]/u.test(value), remotePluginIdentifier = (value) => typeof value === "string" && /^[A-Za-z0-9_~-]{1,1024}$/.test(value), absolutePath2 = (value) => scalar(value, MAX_PATH_BYTES) && isAbsolute10(value);
32730
32783
  var init_codex_native_skill_catalog = __esm(() => {
32731
32784
  init_codex_hook_rpc();
32732
32785
  init_codex_native_compatibility();
@@ -32736,7 +32789,7 @@ var init_codex_native_skill_catalog = __esm(() => {
32736
32789
  // src/lib/codex-plugin-skill-controls.ts
32737
32790
  import { basename as basename6, dirname as dirname12, join as join18, relative as relative5, resolve as resolve11, sep as sep6 } from "path";
32738
32791
  import { lstatSync as lstatSync12, readdirSync as readdirSync6, readlinkSync as readlinkSync3, realpathSync as realpathSync4 } from "fs";
32739
- function refuse() {
32792
+ function refuse2() {
32740
32793
  throw new Error("CODEX_NATIVE_SKILL_IDENTITY_UNSUPPORTED: review native plugin names and hook controls");
32741
32794
  }
32742
32795
  function remoteInstallationMatches(parent, remotePluginId, read) {
@@ -32761,17 +32814,17 @@ function appControls(path, read) {
32761
32814
  sha2562 = hashNativeJsonControls(text2);
32762
32815
  value = JSON.parse(text2);
32763
32816
  } catch {
32764
- refuse();
32817
+ refuse2();
32765
32818
  }
32766
- const object5 = (v) => Boolean(v && typeof v === "object" && !Array.isArray(v));
32767
- if (!object5(value) || Object.keys(value).length !== 1 || !object5(value.apps))
32768
- refuse();
32819
+ const object6 = (v) => Boolean(v && typeof v === "object" && !Array.isArray(v));
32820
+ if (!object6(value) || Object.keys(value).length !== 1 || !object6(value.apps))
32821
+ refuse2();
32769
32822
  const apps = Object.entries(value.apps);
32770
32823
  if (!apps.length || apps.length > 256)
32771
- refuse();
32824
+ refuse2();
32772
32825
  for (const [name, entry] of apps) {
32773
- if (!identifier2(name) || !object5(entry) || !Object.keys(entry).every((key) => ["id", "category", "required"].includes(key)) || typeof entry.id !== "string" || !/^[A-Za-z0-9_-]{1,256}$/.test(entry.id) || entry.category !== undefined && (typeof entry.category !== "string" || !entry.category.trim() || entry.category.length > 256 || /[\x00-\x1f\x7f]/.test(entry.category)) || entry.required !== undefined && typeof entry.required !== "boolean")
32774
- refuse();
32826
+ if (!identifier2(name) || !object6(entry) || !Object.keys(entry).every((key) => ["id", "category", "required"].includes(key)) || typeof entry.id !== "string" || !/^[A-Za-z0-9_-]{1,256}$/.test(entry.id) || entry.category !== undefined && (typeof entry.category !== "string" || !entry.category.trim() || entry.category.length > 256 || /[\x00-\x1f\x7f]/.test(entry.category)) || entry.required !== undefined && typeof entry.required !== "boolean")
32827
+ refuse2();
32775
32828
  }
32776
32829
  return sha2562;
32777
32830
  }
@@ -32782,26 +32835,26 @@ function mcpControls(path, read) {
32782
32835
  sha2562 = hashNativeJsonControls(text2);
32783
32836
  value = JSON.parse(text2);
32784
32837
  } catch {
32785
- refuse();
32838
+ refuse2();
32786
32839
  }
32787
- const object5 = (v) => Boolean(v && typeof v === "object" && !Array.isArray(v));
32788
- if (!object5(value) || Object.keys(value).length !== 1 || !object5(value.mcpServers))
32789
- refuse();
32840
+ const object6 = (v) => Boolean(v && typeof v === "object" && !Array.isArray(v));
32841
+ if (!object6(value) || Object.keys(value).length !== 1 || !object6(value.mcpServers))
32842
+ refuse2();
32790
32843
  const servers = Object.entries(value.mcpServers);
32791
32844
  if (!servers.length || servers.length > 256)
32792
- refuse();
32845
+ refuse2();
32793
32846
  for (const [name, server] of servers)
32794
32847
  if (!isCodexLocalStdioMcpServer(name, server))
32795
- refuse();
32848
+ refuse2();
32796
32849
  return sha2562;
32797
32850
  }
32798
32851
  function isBundledCleanupHooks(root, namespace, value) {
32799
- const object5 = (v) => Boolean(v && typeof v === "object" && !Array.isArray(v));
32852
+ const object6 = (v) => Boolean(v && typeof v === "object" && !Array.isArray(v));
32800
32853
  const exactKeys = (v, keys) => Object.keys(v).length === keys.length && keys.every((key) => Object.hasOwn(v, key));
32801
32854
  if (basename6(dirname12(root)) !== namespace || basename6(dirname12(dirname12(root))) !== "openai-bundled")
32802
32855
  return false;
32803
32856
  const server = namespace === "unified-computer-use" ? "cua_repl" : ["browser", "chrome", "chrome-dev", "chrome-internal", "computer-use"].includes(namespace) ? "node_repl" : undefined;
32804
- if (!server || !object5(value) || !exactKeys(value, ["hooks"]) || !object5(value.hooks))
32857
+ if (!server || !object6(value) || !exactKeys(value, ["hooks"]) || !object6(value.hooks))
32805
32858
  return false;
32806
32859
  const events = Object.entries(value.hooks);
32807
32860
  if (!events.length || events.length > 3)
@@ -32810,10 +32863,10 @@ function isBundledCleanupHooks(root, namespace, value) {
32810
32863
  if (!["Interrupt", "SubagentStop", "Stop"].includes(event) || !Array.isArray(groups) || groups.length !== 1)
32811
32864
  return false;
32812
32865
  const group = groups[0];
32813
- if (!object5(group) || !exactKeys(group, ["hooks"]) || !Array.isArray(group.hooks) || group.hooks.length !== 1)
32866
+ if (!object6(group) || !exactKeys(group, ["hooks"]) || !Array.isArray(group.hooks) || group.hooks.length !== 1)
32814
32867
  return false;
32815
32868
  const handler = group.hooks[0];
32816
- if (!object5(handler) || !exactKeys(handler, ["type", "server", "tool", "input"]) || handler.type !== "mcp_tool" || handler.server !== server || handler.tool !== "turn_ended" || !object5(handler.input) || !exactKeys(handler.input, ["hook_event_name", "session_id", "turn_id"]) || handler.input.hook_event_name !== "${hook_event_name}" || handler.input.turn_id !== "${turn_id}" || handler.input.session_id !== (event === "SubagentStop" ? "${agent_id}" : "${session_id}"))
32869
+ if (!object6(handler) || !exactKeys(handler, ["type", "server", "tool", "input"]) || handler.type !== "mcp_tool" || handler.server !== server || handler.tool !== "turn_ended" || !object6(handler.input) || !exactKeys(handler.input, ["hook_event_name", "session_id", "turn_id"]) || handler.input.hook_event_name !== "${hook_event_name}" || handler.input.turn_id !== "${turn_id}" || handler.input.session_id !== (event === "SubagentStop" ? "${agent_id}" : "${session_id}"))
32817
32870
  return false;
32818
32871
  }
32819
32872
  return true;
@@ -32821,35 +32874,35 @@ function isBundledCleanupHooks(root, namespace, value) {
32821
32874
  function rootControls(root, read) {
32822
32875
  const manifestPath = join18(root, ".codex-plugin/plugin.json"), manifestFile = lstatSync12(manifestPath, { throwIfNoEntry: false });
32823
32876
  if (!lstatSync12(join18(root, ".codex-plugin"), { throwIfNoEntry: false })?.isDirectory() || !manifestFile?.isFile() || manifestFile.size > 1024 * 1024)
32824
- refuse();
32877
+ refuse2();
32825
32878
  let manifest, manifestSha256;
32826
32879
  try {
32827
32880
  const text2 = read(manifestPath);
32828
32881
  manifestSha256 = hashNativeJsonControls(text2, "version");
32829
32882
  manifest = JSON.parse(text2);
32830
32883
  } catch {
32831
- refuse();
32884
+ refuse2();
32832
32885
  }
32833
32886
  if (!manifest || typeof manifest !== "object" || Array.isArray(manifest) || !identifier2(manifest.name))
32834
- refuse();
32887
+ refuse2();
32835
32888
  const cacheVersion = basename6(root), declaredVersion = manifest.version === undefined ? "" : typeof manifest.version === "string" ? manifest.version.trim() : null;
32836
32889
  if (declaredVersion === null || (declaredVersion ? declaredVersion !== cacheVersion : cacheVersion !== CODEX_DEFAULT_AGENT_PLUGIN_VERSION))
32837
- refuse();
32890
+ refuse2();
32838
32891
  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" || lstatSync12(join18(root, "hooks"), { throwIfNoEntry: false }))
32839
- refuse();
32892
+ refuse2();
32840
32893
  const mcp = join18(root, ".mcp.json"), mcpPresent = lstatSync12(mcp, { throwIfNoEntry: false });
32841
32894
  if (manifest.hooks !== undefined && (manifest.mcpServers !== undefined || mcpPresent))
32842
- refuse();
32895
+ refuse2();
32843
32896
  if (mcpPresent && (!mcpPresent.isFile() || mcpPresent.isSymbolicLink() || mcpPresent.size > 1024 * 1024 || realpathSync4(mcp) !== mcp))
32844
- refuse();
32897
+ refuse2();
32845
32898
  if (Boolean(mcpPresent) !== (manifest.mcpServers !== undefined))
32846
- refuse();
32899
+ refuse2();
32847
32900
  const mcpSha256 = mcpPresent ? mcpControls(mcp, read) : undefined;
32848
32901
  const app = join18(root, ".app.json"), present = lstatSync12(app, { throwIfNoEntry: false });
32849
32902
  if (present && (!present.isFile() || present.isSymbolicLink() || present.size > 1024 * 1024))
32850
- refuse();
32903
+ refuse2();
32851
32904
  if (manifest.apps !== undefined && !present)
32852
- refuse();
32905
+ refuse2();
32853
32906
  const appSha256 = present ? appControls(app, read) : undefined;
32854
32907
  return { namespace: manifest.name, manifestSha256, ...appSha256 ? { appSha256 } : {}, ...mcpSha256 ? { mcpSha256 } : {} };
32855
32908
  }
@@ -32965,10 +33018,10 @@ function sourceInputUnchanged(input2, cache, read) {
32965
33018
  }
32966
33019
  function reviewedCodexPluginSourceRoots(cache, inputs, read) {
32967
33020
  if (!Array.isArray(inputs) || inputs.length > 4096 || new Set(inputs.map((input2) => input2.pluginId)).size !== inputs.length || new Set(inputs.map((input2) => input2.sourceRoot)).size !== inputs.length || inputs.some((input2) => !sourceInputUnchanged(input2, cache, read)))
32968
- refuse();
33021
+ refuse2();
32969
33022
  const roots = inputs.map((input2) => input2.sourceRoot);
32970
33023
  if (roots.some((root) => roots.some((other) => root !== other && root.startsWith(other + sep6))))
32971
- refuse();
33024
+ refuse2();
32972
33025
  return roots;
32973
33026
  }
32974
33027
  var identifier2 = (v) => typeof v === "string" && /^[A-Za-z0-9_-]{1,64}$/.test(v), CODEX_DEFAULT_AGENT_PLUGIN_VERSION = "1.0.0";
@@ -33223,7 +33276,7 @@ function canonical6(value, depth = 0, budget2 = { remaining: 65536 }) {
33223
33276
  need5(isRecord3(value));
33224
33277
  return ["object", Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, child2]) => [key, canonical6(child2, depth + 1, budget2)])];
33225
33278
  }
33226
- function normalize2(config2, version2 = 2) {
33279
+ function normalize3(config2, version2 = 2) {
33227
33280
  if (isRecord3(config2.hooks)) {
33228
33281
  delete config2.hooks.state;
33229
33282
  if (!Object.keys(config2.hooks).length)
@@ -33394,7 +33447,7 @@ function settingsDigest2(text2, version2 = 2) {
33394
33447
  need5(isRecord3(config2));
33395
33448
  const mcp = version2 >= 3 ? projectRegularCodexMcp(config2, text2) : { config: config2, numericSource: text2 };
33396
33449
  const projected = version2 === 4 ? projectModelAvailabilityNux(mcp.config, mcp.numericSource) : mcp;
33397
- normalize2(projected.config, version2);
33450
+ normalize3(projected.config, version2);
33398
33451
  return sha2(`hasna.skills.codex-settings.v${version2}\x00${JSON.stringify([canonical6(projected.config), numericTokens2(projected.numericSource)])}`);
33399
33452
  }
33400
33453
  function hashCodexSettingsReplacementV2(text2, budget2 = { remaining: 256 * 1024 * 1024 }) {
@@ -33545,15 +33598,15 @@ var init_agent_codex = () => {};
33545
33598
  // src/lib/agent-sumi.ts
33546
33599
  import { spawnSync as spawnSync4 } from "child_process";
33547
33600
  import { accessSync, constants as constants8, existsSync as existsSync8, lstatSync as lstatSync14, realpathSync as realpathSync5, statSync as statSync7 } from "fs";
33548
- import { delimiter, isAbsolute as isAbsolute10, join as join20, resolve as resolve12 } from "path";
33601
+ import { delimiter, isAbsolute as isAbsolute11, join as join20, resolve as resolve12 } from "path";
33549
33602
  function recordWithKeys(value, keys) {
33550
33603
  return value !== null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
33551
33604
  }
33552
- function absolutePath2(value) {
33553
- return typeof value === "string" && value.length > 0 && value.length <= 32768 && !/[\x00-\x1f\x7f]/.test(value) && isAbsolute10(value) && resolve12(value) === value;
33605
+ function absolutePath3(value) {
33606
+ return typeof value === "string" && value.length > 0 && value.length <= 32768 && !/[\x00-\x1f\x7f]/.test(value) && isAbsolute11(value) && resolve12(value) === value;
33554
33607
  }
33555
33608
  function absoluteInput(value) {
33556
- return value.length > 0 && value.length <= 32768 && !/[\x00-\x1f\x7f]/.test(value) && isAbsolute10(value);
33609
+ return value.length > 0 && value.length <= 32768 && !/[\x00-\x1f\x7f]/.test(value) && isAbsolute11(value);
33557
33610
  }
33558
33611
  function resolveSumiPathsCommand(pathValue) {
33559
33612
  if (!pathValue)
@@ -33578,18 +33631,18 @@ function validPathPlan(value, home, cwd) {
33578
33631
  if (!recordWithKeys(value.roots, SUMI_PATH_KEYS) || !recordWithKeys(value.legacyRoots, SUMI_PATH_KEYS))
33579
33632
  return false;
33580
33633
  for (const key of SUMI_PATH_KEYS) {
33581
- if (!absolutePath2(value.roots[key]))
33634
+ if (!absolutePath3(value.roots[key]))
33582
33635
  return false;
33583
- if (value.legacyRoots[key] !== null && !absolutePath2(value.legacyRoots[key]))
33636
+ if (value.legacyRoots[key] !== null && !absolutePath3(value.legacyRoots[key]))
33584
33637
  return false;
33585
33638
  }
33586
33639
  if (!recordWithKeys(value.configFiles, ["canonical", "legacy"]) || !recordWithKeys(value.skillRoots, ["canonical", "legacy"]))
33587
33640
  return false;
33588
- if (!absolutePath2(value.configFiles.canonical) || !absolutePath2(value.skillRoots.canonical))
33641
+ if (!absolutePath3(value.configFiles.canonical) || !absolutePath3(value.skillRoots.canonical))
33589
33642
  return false;
33590
- if (value.configFiles.legacy !== null && !absolutePath2(value.configFiles.legacy))
33643
+ if (value.configFiles.legacy !== null && !absolutePath3(value.configFiles.legacy))
33591
33644
  return false;
33592
- if (value.skillRoots.legacy !== null && !absolutePath2(value.skillRoots.legacy))
33645
+ if (value.skillRoots.legacy !== null && !absolutePath3(value.skillRoots.legacy))
33593
33646
  return false;
33594
33647
  const configRoot = value.roots.config;
33595
33648
  const legacyConfigRoot = value.legacyRoots.config;
@@ -33609,7 +33662,7 @@ function sumiPathPlan(home, cwd = process.cwd(), env = process.env) {
33609
33662
  throw new SumiPathResolverError("SUMI_PATH_INPUT_REFUSED");
33610
33663
  const runtimePath = process.env.PATH ?? "";
33611
33664
  const executable = resolveSumiPathsCommand(runtimePath);
33612
- if (!executable || !isAbsolute10(executable))
33665
+ if (!executable || !isAbsolute11(executable))
33613
33666
  throw new SumiPathResolverError("SUMI_PATH_RESOLVER_UNAVAILABLE");
33614
33667
  const childEnv = { PATH: runtimePath };
33615
33668
  for (const key of SUMI_PATH_SELECTORS)
@@ -33685,7 +33738,7 @@ var init_agent_sumi = __esm(() => {
33685
33738
  // src/lib/codex-hook-trust-files.ts
33686
33739
  import { closeSync as closeSync11, constants as constants9, fstatSync as fstatSync11, fsyncSync as fsyncSync2, lstatSync as lstatSync15, openSync as openSync11, readlinkSync as readlinkSync4, readSync as readSync6, writeFileSync as writeFileSync4 } from "fs";
33687
33740
  import { createHash as createHash15 } from "crypto";
33688
- import { dirname as dirname13, isAbsolute as isAbsolute11, resolve as resolve13 } from "path";
33741
+ import { dirname as dirname13, isAbsolute as isAbsolute12, resolve as resolve13 } from "path";
33689
33742
  function need6(value, code) {
33690
33743
  if (!value)
33691
33744
  throw new Error(`CODEX_HOOK_TRUST_${code}`);
@@ -33785,6 +33838,96 @@ var init_runtime_launcher = __esm(() => {
33785
33838
  PINNED_LAUNCHER_MAX_BYTES = 16 * 1024;
33786
33839
  });
33787
33840
 
33841
+ // src/lib/retained-review-artifacts.ts
33842
+ import { createHash as createHash16 } from "crypto";
33843
+ import { constants as constants10, closeSync as closeSync12, fstatSync as fstatSync12, fsyncSync as fsyncSync3, lstatSync as lstatSync16, mkdirSync as mkdirSync5, openSync as openSync12, readSync as readSync7, writeSync as writeSync2 } from "fs";
33844
+ import { dirname as dirname14, isAbsolute as isAbsolute13, join as join21, resolve as resolve14, sep as sep7 } from "path";
33845
+ function keys(value, names) {
33846
+ return Boolean(value && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === names.length && names.every((name) => Object.hasOwn(value, name)));
33847
+ }
33848
+ function safe3(path) {
33849
+ need7(typeof path === "string" && path.length <= AGENT_POLICY_LIMITS.pathCharacters && isAbsolute13(path) && resolve14(path) === path && !/[\x00-\x1f\x7f]/.test(path));
33850
+ for (let cursor = path;; cursor = dirname14(cursor)) {
33851
+ const stat = lstatSync16(cursor, { throwIfNoEntry: false });
33852
+ need7(!stat?.isSymbolicLink());
33853
+ if (cursor !== path && stat)
33854
+ need7(stat.isDirectory());
33855
+ if (dirname14(cursor) === cursor)
33856
+ break;
33857
+ }
33858
+ }
33859
+ function readExact(path) {
33860
+ safe3(path);
33861
+ const before = lstatSync16(path, { throwIfNoEntry: false });
33862
+ need7(before?.isFile() && before.nlink === 1 && before.size <= AGENT_POLICY_LIMITS.discoveryRawSourceBytes && (before.mode & 63) === 0 && (process.getuid === undefined || before.uid === process.getuid()));
33863
+ const fd = openSync12(path, constants10.O_RDONLY | constants10.O_NOFOLLOW | constants10.O_NONBLOCK);
33864
+ try {
33865
+ const opened = fstatSync12(fd);
33866
+ need7(opened.dev === before.dev && opened.ino === before.ino && opened.size === before.size && opened.mode === before.mode && opened.uid === before.uid && opened.nlink === 1);
33867
+ const bytes = Buffer.alloc(opened.size);
33868
+ let offset = 0;
33869
+ while (offset < bytes.length) {
33870
+ const count = readSync7(fd, bytes, offset, bytes.length - offset, null);
33871
+ need7(count > 0);
33872
+ offset += count;
33873
+ }
33874
+ need7(readSync7(fd, Buffer.alloc(1), 0, 1, null) === 0);
33875
+ const after = fstatSync12(fd), current = lstatSync16(path, { throwIfNoEntry: false });
33876
+ safe3(path);
33877
+ need7(current && opened.dev === current.dev && opened.ino === current.ino && opened.mode === current.mode && opened.uid === current.uid && opened.size === current.size && opened.mtimeMs === current.mtimeMs && opened.ctimeMs === current.ctimeMs && current.nlink === 1 && opened.mode === after.mode && opened.uid === after.uid && after.nlink === 1 && opened.size === after.size && opened.mtimeMs === after.mtimeMs && opened.ctimeMs === after.ctimeMs);
33878
+ const text2 = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes);
33879
+ need7(Buffer.from(text2).equals(bytes));
33880
+ return text2;
33881
+ } finally {
33882
+ closeSync12(fd);
33883
+ }
33884
+ }
33885
+ function catalogDigest(text2) {
33886
+ let catalog;
33887
+ try {
33888
+ catalog = JSON.parse(text2);
33889
+ } catch {
33890
+ return refuse3();
33891
+ }
33892
+ need7(catalog && typeof catalog === "object" && !Array.isArray(catalog) && Object.keys(catalog).every((key) => ["version", "cwd", "skills", "plugins"].includes(key)) && typeof catalog.version === "string" && supportsCodexNativeCapability(catalog.version, "installed-plugin-review"));
33893
+ const skills = projectCodexNativeSkillCatalog({ data: [{ cwd: catalog.cwd, errors: [], skills: catalog.skills }] }, catalog.cwd);
33894
+ const plugins = catalog.plugins === undefined ? undefined : projectCodexInstalledPluginEntries(catalog.plugins);
33895
+ return sha3(JSON.stringify({ version: catalog.version, cwd: catalog.cwd, skills, ...plugins === undefined ? {} : { plugins } }));
33896
+ }
33897
+ function retainedArtifactPath(metadata) {
33898
+ return join21(metadata.storeRoot, "agent-discovery", "artifacts", metadata.sha256, "catalog.json");
33899
+ }
33900
+ function validRetainedArtifact(value) {
33901
+ return keys(value, ["version", "kind", "storeRoot", "originalPath", "sha256", "catalogSha256"]) && value.version === 1 && value.kind === "codex-native-catalog" && hex3(value.sha256) && hex3(value.catalogSha256) && [value.storeRoot, value.originalPath].every((path) => typeof path === "string" && isAbsolute13(path) && resolve14(path) === path && path.length <= AGENT_POLICY_LIMITS.pathCharacters && !/[\x00-\x1f\x7f]/.test(path));
33902
+ }
33903
+ function privateStore(storeRoot) {
33904
+ safe3(storeRoot);
33905
+ const stat = lstatSync16(storeRoot, { throwIfNoEntry: false });
33906
+ need7(!stat || stat.isDirectory() && (stat.mode & 18) === 0 && (process.getuid === undefined || stat.uid === process.getuid()));
33907
+ }
33908
+ function verifyRetainedReviewArtifact(source, storeRoot) {
33909
+ const artifact = source.reviewArtifact;
33910
+ need7(validRetainedArtifact(artifact) && source.hashMode === "bytes" && source.sha256 === artifact.sha256 && source.format === undefined && source.fields === undefined && source.managedPlugins === undefined && source.path === retainedArtifactPath(artifact) && (storeRoot === undefined || artifact.storeRoot === resolve14(storeRoot)));
33911
+ privateStore(artifact.storeRoot);
33912
+ const text2 = readExact(source.path);
33913
+ need7(sha3(text2) === artifact.sha256 && catalogDigest(text2) === artifact.catalogSha256);
33914
+ for (let parent = dirname14(source.path);parent !== artifact.storeRoot; parent = dirname14(parent)) {
33915
+ const stat = lstatSync16(parent);
33916
+ need7(stat.isDirectory() && (stat.mode & 63) === 0 && (process.getuid === undefined || stat.uid === process.getuid()));
33917
+ }
33918
+ }
33919
+ var sha3 = (bytes) => createHash16("sha256").update(bytes).digest("hex"), hex3 = (value) => typeof value === "string" && /^[a-f0-9]{64}$/.test(value), refuse3 = () => {
33920
+ throw new Error("REVIEW_ARTIFACT_INVALID");
33921
+ }, need7 = (condition) => {
33922
+ if (!condition)
33923
+ refuse3();
33924
+ };
33925
+ var init_retained_review_artifacts = __esm(() => {
33926
+ init_agent_policy_limits();
33927
+ init_codex_native_skill_catalog();
33928
+ init_codex_native_compatibility();
33929
+ });
33930
+
33788
33931
  // src/lib/agent-integration.ts
33789
33932
  var init_agent_integration = __esm(() => {
33790
33933
  init_sumi_settings_witness();
@@ -33806,6 +33949,7 @@ var init_agent_integration = __esm(() => {
33806
33949
  init_claude_settings_witness();
33807
33950
  init_codex_hook_trust_files();
33808
33951
  init_runtime_launcher();
33952
+ init_retained_review_artifacts();
33809
33953
  });
33810
33954
 
33811
33955
  // src/lib/home-migration.ts
@@ -33842,13 +33986,13 @@ var init_skill_aliases = __esm(() => {
33842
33986
  });
33843
33987
 
33844
33988
  // src/lib/project-state.ts
33845
- import { existsSync as existsSync9, mkdirSync as mkdirSync5, readFileSync as readFileSync13, writeFileSync as writeFileSync5 } from "fs";
33846
- import { join as join21 } from "path";
33989
+ import { existsSync as existsSync9, mkdirSync as mkdirSync6, readFileSync as readFileSync13, writeFileSync as writeFileSync5 } from "fs";
33990
+ import { join as join22 } from "path";
33847
33991
  function getProjectStateDir(targetDir = process.cwd()) {
33848
- return join21(targetDir, SKILLS_PROJECT_DIR);
33992
+ return join22(targetDir, SKILLS_PROJECT_DIR);
33849
33993
  }
33850
33994
  function getProjectConfigPath(targetDir = process.cwd()) {
33851
- return join21(getProjectStateDir(targetDir), PROJECT_CONFIG_FILE);
33995
+ return join22(getProjectStateDir(targetDir), PROJECT_CONFIG_FILE);
33852
33996
  }
33853
33997
  function loadProjectConfig(targetDir = process.cwd()) {
33854
33998
  const path = getProjectConfigPath(targetDir);
@@ -33876,7 +34020,7 @@ function ensureProjectConfig(targetDir = process.cwd()) {
33876
34020
  }
33877
34021
  function saveProjectConfig(config2, targetDir = process.cwd()) {
33878
34022
  const dir = getProjectStateDir(targetDir);
33879
- mkdirSync5(dir, { recursive: true });
34023
+ mkdirSync6(dir, { recursive: true });
33880
34024
  const normalized = normalizeProjectConfig({ ...config2, updatedAt: new Date().toISOString() });
33881
34025
  writeFileSync5(getProjectConfigPath(targetDir), JSON.stringify(normalized, null, 2) + `
33882
34026
  `);
@@ -33964,7 +34108,7 @@ var init_project_state = __esm(() => {
33964
34108
 
33965
34109
  // src/lib/installer.ts
33966
34110
  import { existsSync as existsSync10, readFileSync as readFileSync14, rmSync } from "fs";
33967
- import { join as join22 } from "path";
34111
+ import { join as join23 } from "path";
33968
34112
  import { homedir as homedir2 } from "os";
33969
34113
  function getSkillPath(name) {
33970
34114
  const skillName = normalizeSkillName(getCanonicalSkillName(name));
@@ -33974,7 +34118,7 @@ function getSkillPath(name) {
33974
34118
  const extensionPath = findExtensionSkillPath(skillName);
33975
34119
  if (extensionPath)
33976
34120
  return extensionPath;
33977
- return join22(getPortableSkillsRoot(), skillName);
34121
+ return join23(getPortableSkillsRoot(), skillName);
33978
34122
  }
33979
34123
  function getCanonicalSkillName(name) {
33980
34124
  return getSkill(name)?.name ?? resolveSkillAlias(normalizeSkillSlug(name));
@@ -34028,11 +34172,11 @@ function getAgentSkillsDir(agent, scope = "global", projectDir) {
34028
34172
  const base = projectDir || process.cwd();
34029
34173
  switch (agent) {
34030
34174
  case "pi":
34031
- return scope === "project" ? join22(base, ".pi", "skills") : join22(homedir2(), ".pi", "agent", "skills");
34175
+ return scope === "project" ? join23(base, ".pi", "skills") : join23(homedir2(), ".pi", "agent", "skills");
34032
34176
  case "opencode":
34033
- return scope === "project" ? join22(base, ".opencode", "skills") : join22(homedir2(), ".config", "opencode", "skills");
34177
+ return scope === "project" ? join23(base, ".opencode", "skills") : join23(homedir2(), ".config", "opencode", "skills");
34034
34178
  default:
34035
- return scope === "project" ? join22(base, `.${agent}`, "skills") : join22(homedir2(), `.${agent}`, "skills");
34179
+ return scope === "project" ? join23(base, `.${agent}`, "skills") : join23(homedir2(), `.${agent}`, "skills");
34036
34180
  }
34037
34181
  }
34038
34182
  function warnMissingDependencies(name, targetDir) {
@@ -34047,7 +34191,7 @@ function warnMissingDependencies(name, targetDir) {
34047
34191
  }
34048
34192
  }
34049
34193
  function readBundledSkillVersion(name) {
34050
- const pkgPath = join22(getSkillPath(name), "package.json");
34194
+ const pkgPath = join23(getSkillPath(name), "package.json");
34051
34195
  if (!existsSync10(pkgPath))
34052
34196
  return "unknown";
34053
34197
  try {
@@ -34117,11 +34261,11 @@ var init_skill_doc_file = __esm(() => {
34117
34261
 
34118
34262
  // src/lib/skillinfo.ts
34119
34263
  import { existsSync as existsSync11, readFileSync as readFileSync15 } from "fs";
34120
- import { join as join23 } from "path";
34264
+ import { join as join24 } from "path";
34121
34265
  function isInstructionSkillDir(skillPath, meta3) {
34122
34266
  if (meta3?.kind === "instruction")
34123
34267
  return true;
34124
- const skillMdPath = join23(skillPath, "SKILL.md");
34268
+ const skillMdPath = join24(skillPath, "SKILL.md");
34125
34269
  if (!existsSync11(skillMdPath))
34126
34270
  return false;
34127
34271
  try {
@@ -34135,9 +34279,9 @@ function getSkillDocs(name) {
34135
34279
  if (!existsSync11(skillPath))
34136
34280
  return null;
34137
34281
  return {
34138
- skillMd: readIfExists(join23(skillPath, "SKILL.md")),
34139
- readme: readIfExists(join23(skillPath, "README.md")),
34140
- claudeMd: readIfExists(join23(skillPath, "CLAUDE.md"))
34282
+ skillMd: readIfExists(join24(skillPath, "SKILL.md")),
34283
+ readme: readIfExists(join24(skillPath, "README.md")),
34284
+ claudeMd: readIfExists(join24(skillPath, "CLAUDE.md"))
34141
34285
  };
34142
34286
  }
34143
34287
  function getSkillBestDoc(name, file2) {
@@ -34153,14 +34297,14 @@ function getSkillRequirements(name) {
34153
34297
  return null;
34154
34298
  const texts = [];
34155
34299
  for (const file2 of ["SKILL.md", "README.md", "CLAUDE.md", ".env.example", ".env.local.example"]) {
34156
- const content = readIfExists(join23(skillPath, file2));
34300
+ const content = readIfExists(join24(skillPath, file2));
34157
34301
  if (content)
34158
34302
  texts.push(content);
34159
34303
  }
34160
34304
  const meta3 = getSkill(name);
34161
34305
  let dependencies = {};
34162
34306
  try {
34163
- dependencies = JSON.parse(readFileSync15(join23(skillPath, "package.json"), "utf8")).dependencies || {};
34307
+ dependencies = JSON.parse(readFileSync15(join24(skillPath, "package.json"), "utf8")).dependencies || {};
34164
34308
  } catch {}
34165
34309
  return getSkillRequirementsFromContent(name, texts, dependencies, meta3);
34166
34310
  }
@@ -34222,7 +34366,7 @@ async function runSkill(name, args, options = {}) {
34222
34366
  error: `Skill '${name}' is an instruction skill (kind: instruction) and is not runnable. Instruction skills are consumed by coding agents via SKILL.md, not executed with 'skills run'.`
34223
34367
  };
34224
34368
  }
34225
- const pkgPath = join23(skillPath, "package.json");
34369
+ const pkgPath = join24(skillPath, "package.json");
34226
34370
  if (!existsSync11(pkgPath)) {
34227
34371
  return { exitCode: 1, error: `No package.json in skill '${name}'` };
34228
34372
  }
@@ -34242,12 +34386,12 @@ async function runSkill(name, args, options = {}) {
34242
34386
  } catch {
34243
34387
  return { exitCode: 1, error: `Failed to parse package.json for skill '${name}'` };
34244
34388
  }
34245
- const entryPath = join23(skillPath, entryPoint2);
34389
+ const entryPath = join24(skillPath, entryPoint2);
34246
34390
  if (!existsSync11(entryPath)) {
34247
34391
  return { exitCode: 1, error: `Entry point '${entryPoint2}' not found in skill '${name}'` };
34248
34392
  }
34249
34393
  const env = { ...process.env, ...options.env };
34250
- if (!existsSync11(join23(skillPath, "node_modules")) || hasDependencyPreparationMarker(skillPath)) {
34394
+ if (!existsSync11(join24(skillPath, "node_modules")) || hasDependencyPreparationMarker(skillPath)) {
34251
34395
  const failure = await prepareSkillDependencies(skillPath, env, options.preparationTimeoutMs);
34252
34396
  if (failure)
34253
34397
  return failure;
@@ -34273,7 +34417,7 @@ async function runSkill(name, args, options = {}) {
34273
34417
  function detectProjectSkills(cwd = process.cwd()) {
34274
34418
  let pkg;
34275
34419
  try {
34276
- pkg = JSON.parse(readFileSync15(join23(cwd, "package.json"), "utf8"));
34420
+ pkg = JSON.parse(readFileSync15(join24(cwd, "package.json"), "utf8"));
34277
34421
  } catch {
34278
34422
  return { detected: [], recommended: [] };
34279
34423
  }
@@ -34478,7 +34622,7 @@ var init_selection_resolver = __esm(() => {
34478
34622
  });
34479
34623
 
34480
34624
  // src/lib/plugin-projection.ts
34481
- import { createHash as createHash16 } from "crypto";
34625
+ import { createHash as createHash17 } from "crypto";
34482
34626
  function pluginRefusal(message) {
34483
34627
  throw new SkillSelectionError("PLUGIN_ADMISSION_REFUSED", message);
34484
34628
  }
@@ -34489,8 +34633,8 @@ function pluginNeed(value, message) {
34489
34633
  function pluginObject(value) {
34490
34634
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
34491
34635
  }
34492
- function pluginKeys(value, keys) {
34493
- pluginNeed(pluginObject(value) && Object.keys(value).every((key) => keys.includes(key)), "Unsupported plugin contract fields");
34636
+ function pluginKeys(value, keys2) {
34637
+ pluginNeed(pluginObject(value) && Object.keys(value).every((key) => keys2.includes(key)), "Unsupported plugin contract fields");
34494
34638
  }
34495
34639
  function pluginText(value, limit = 4096) {
34496
34640
  pluginNeed(typeof value === "string" && value.length > 0 && value.length <= limit && !/[\x00-\x1f\x7f]/.test(value), "Invalid plugin contract text");
@@ -34556,18 +34700,18 @@ function pluginFileWitnesses(entries) {
34556
34700
  return { path: item.path, mode: item.mode, size: item.bytes.byteLength, sha256: pluginHash(item.bytes) };
34557
34701
  });
34558
34702
  }
34559
- var PLUGIN_PROJECTION_LIMITS, pluginHash = (bytes) => createHash16("sha256").update(bytes).digest("hex");
34703
+ var PLUGIN_PROJECTION_LIMITS, pluginHash = (bytes) => createHash17("sha256").update(bytes).digest("hex");
34560
34704
  var init_plugin_projection = __esm(() => {
34561
34705
  init_selection_cache();
34562
34706
  PLUGIN_PROJECTION_LIMITS = Object.freeze({ files: 1024, bytes: 64 * 1024 * 1024, fileBytes: 16 * 1024 * 1024, metadataBytes: 512 * 1024, registrations: 64, history: 128 });
34563
34707
  });
34564
34708
 
34565
34709
  // src/lib/plugin-projection-store.ts
34566
- import { constants as constants10, closeSync as closeSync12, fchmodSync, fstatSync as fstatSync12, fsyncSync as fsyncSync3, linkSync as linkSync2, lstatSync as lstatSync16, mkdirSync as mkdirSync6, openSync as openSync12, opendirSync as opendirSync2, readSync as readSync7, renameSync as renameSync2, rmdirSync as rmdirSync2, rmSync as rmSync2, unlinkSync as unlinkSync3, writeSync as writeSync2 } from "fs";
34567
- import { dirname as dirname14, isAbsolute as isAbsolute12, join as join24, parse as parse10, resolve as resolve14 } from "path";
34710
+ import { constants as constants11, closeSync as closeSync13, fchmodSync, fstatSync as fstatSync13, fsyncSync as fsyncSync4, linkSync as linkSync2, lstatSync as lstatSync17, mkdirSync as mkdirSync7, openSync as openSync13, opendirSync as opendirSync2, readSync as readSync8, renameSync as renameSync2, rmdirSync as rmdirSync2, rmSync as rmSync2, unlinkSync as unlinkSync3, writeSync as writeSync3 } from "fs";
34711
+ import { dirname as dirname15, isAbsolute as isAbsolute14, join as join25, parse as parse10, resolve as resolve15 } from "path";
34568
34712
  function stat(path) {
34569
34713
  try {
34570
- return lstatSync16(path, { bigint: true });
34714
+ return lstatSync17(path, { bigint: true });
34571
34715
  } catch (error61) {
34572
34716
  if (missing(error61))
34573
34717
  return null;
@@ -34575,7 +34719,7 @@ function stat(path) {
34575
34719
  }
34576
34720
  }
34577
34721
  function canonical7(path) {
34578
- pluginNeed(typeof path === "string" && path.length <= 8192 && isAbsolute12(path) && resolve14(path) === path && !/[\x00-\x1f\x7f]/.test(path), "Plugin storage paths must be canonical absolute paths");
34722
+ pluginNeed(typeof path === "string" && path.length <= 8192 && isAbsolute14(path) && resolve15(path) === path && !/[\x00-\x1f\x7f]/.test(path), "Plugin storage paths must be canonical absolute paths");
34579
34723
  }
34580
34724
  function owner(stats, system = false) {
34581
34725
  const current = uid();
@@ -34586,15 +34730,15 @@ function same3(left, right, identityOnly = false) {
34586
34730
  }
34587
34731
  function ancestors(path, create = false) {
34588
34732
  canonical7(path);
34589
- const result = [], parent = dirname14(path), filesystemRoot = parse10(parent).root;
34733
+ const result = [], parent = dirname15(path), filesystemRoot = parse10(parent).root;
34590
34734
  let current = filesystemRoot;
34591
34735
  for (const segment of ["", ...parent.slice(filesystemRoot.length).split("/").filter(Boolean)]) {
34592
34736
  if (segment)
34593
- current = join24(current, segment);
34737
+ current = join25(current, segment);
34594
34738
  let currentStat = stat(current);
34595
34739
  if (!currentStat && create) {
34596
34740
  try {
34597
- mkdirSync6(current, { mode: 448 });
34741
+ mkdirSync7(current, { mode: 448 });
34598
34742
  } catch (error61) {
34599
34743
  if (!(error61 && typeof error61 === "object" && ("code" in error61) && error61.code === "EEXIST"))
34600
34744
  pluginRefusal("Cannot create private plugin storage directory");
@@ -34636,19 +34780,19 @@ function readBytes(path, maximum, kind) {
34636
34780
  fileShape(before, maximum, kind);
34637
34781
  let fd;
34638
34782
  try {
34639
- fd = openSync12(path, READ_FLAGS);
34640
- const opened = fstatSync12(fd, { bigint: true });
34783
+ fd = openSync13(path, READ_FLAGS);
34784
+ const opened = fstatSync13(fd, { bigint: true });
34641
34785
  same3(before, opened);
34642
34786
  fileShape(opened, maximum, kind);
34643
34787
  const bytes = new Uint8Array(Number(opened.size));
34644
34788
  let offset = 0;
34645
34789
  while (offset < bytes.byteLength) {
34646
- const count = readSync7(fd, bytes, offset, bytes.byteLength - offset, null);
34790
+ const count = readSync8(fd, bytes, offset, bytes.byteLength - offset, null);
34647
34791
  pluginNeed(count > 0, "Plugin file changed while being read");
34648
34792
  offset += count;
34649
34793
  }
34650
- pluginNeed(readSync7(fd, new Uint8Array(1), 0, 1, null) === 0, "Plugin file grew while being read");
34651
- same3(opened, fstatSync12(fd, { bigint: true }));
34794
+ pluginNeed(readSync8(fd, new Uint8Array(1), 0, 1, null) === 0, "Plugin file grew while being read");
34795
+ same3(opened, fstatSync13(fd, { bigint: true }));
34652
34796
  same3(opened, stat(path));
34653
34797
  verifyAncestors(chain);
34654
34798
  return bytes;
@@ -34658,7 +34802,7 @@ function readBytes(path, maximum, kind) {
34658
34802
  return pluginRefusal("Cannot safely read plugin file");
34659
34803
  } finally {
34660
34804
  if (fd !== undefined)
34661
- closeSync12(fd);
34805
+ closeSync13(fd);
34662
34806
  }
34663
34807
  }
34664
34808
  function exactPaths(entries) {
@@ -34698,7 +34842,7 @@ function snapshotPluginTree(root, options = {}) {
34698
34842
  pluginNeed(++visited <= PLUGIN_PROJECTION_LIMITS.files * 50, "Plugin tree membership exceeds its limit");
34699
34843
  const path = relative6 ? `${relative6}/${name}` : name;
34700
34844
  pluginNeed(new TextEncoder().encode(path).byteLength <= 100 && !/[\\:\x00-\x1f\x7f]/u.test(path), "Plugin entry path exceeds its limit or is unsafe");
34701
- const absolute = join24(directory, name), entryStat = stat(absolute);
34845
+ const absolute = join25(directory, name), entryStat = stat(absolute);
34702
34846
  pluginNeed(entryStat, "Plugin tree member disappeared");
34703
34847
  if (relative6 === "" && name === ".orphaned_at" && (options.nativeRuntime === "claude-2.1.274" || options.nativeRuntime === "claude-2.1.276")) {
34704
34848
  const bytes2 = readBytes(absolute, 32, "native-pin");
@@ -34715,7 +34859,7 @@ function snapshotPluginTree(root, options = {}) {
34715
34859
  directories.push({ path: absolute, stat: entryStat, names: pins });
34716
34860
  for (const pin of pins) {
34717
34861
  pluginNeed(/^[1-9][0-9]{0,9}$/.test(pin) && Number(pin) <= 2147483647, "Unrecognized native plugin pin name");
34718
- const pinPath = join24(absolute, pin), pinStat = stat(pinPath);
34862
+ const pinPath = join25(absolute, pin), pinStat = stat(pinPath);
34719
34863
  pluginNeed(pinStat, "Native plugin pin disappeared");
34720
34864
  const bytes2 = readBytes(pinPath, 4096, "native-pin");
34721
34865
  let value;
@@ -34781,8 +34925,8 @@ function readPluginJson(path) {
34781
34925
  var READ_FLAGS, WRITE_FLAGS, uid = () => typeof process.getuid === "function" ? BigInt(process.getuid()) : undefined, missing = (error61) => Boolean(error61 && typeof error61 === "object" && "code" in error61 && error61.code === "ENOENT");
34782
34926
  var init_plugin_projection_store = __esm(() => {
34783
34927
  init_plugin_projection();
34784
- READ_FLAGS = constants10.O_RDONLY | constants10.O_NOFOLLOW | constants10.O_NONBLOCK;
34785
- WRITE_FLAGS = constants10.O_WRONLY | constants10.O_CREAT | constants10.O_EXCL | constants10.O_NOFOLLOW | constants10.O_NONBLOCK;
34928
+ READ_FLAGS = constants11.O_RDONLY | constants11.O_NOFOLLOW | constants11.O_NONBLOCK;
34929
+ WRITE_FLAGS = constants11.O_WRONLY | constants11.O_CREAT | constants11.O_EXCL | constants11.O_NOFOLLOW | constants11.O_NONBLOCK;
34786
34930
  });
34787
34931
 
34788
34932
  // src/lib/selected-manifest.ts
@@ -34812,7 +34956,7 @@ var init_selected_manifest = __esm(() => {
34812
34956
  });
34813
34957
 
34814
34958
  // src/lib/plugin-admission.ts
34815
- import { isAbsolute as isAbsolute13, join as join25, resolve as resolve15 } from "path";
34959
+ import { isAbsolute as isAbsolute15, join as join26, resolve as resolve16 } from "path";
34816
34960
  function validatePluginTarget(value) {
34817
34961
  pluginKeys(value, ["schemaVersion", "pluginId", "registrations", "native", "resolver"]);
34818
34962
  pluginNeed(value.schemaVersion === 1, "Invalid plugin admission target");
@@ -34822,7 +34966,7 @@ function validatePluginTarget(value) {
34822
34966
  for (const registration of value.registrations) {
34823
34967
  pluginKeys(registration, ["scope", "projectPath"]);
34824
34968
  pluginNeed(registration.scope === "user" || registration.scope === "project", "Unsupported plugin registration scope");
34825
- pluginNeed(registration.scope === "user" ? registration.projectPath === null : typeof registration.projectPath === "string" && isAbsolute13(registration.projectPath) && resolve15(registration.projectPath) === registration.projectPath, "Plugin scope requires its exact project path");
34969
+ pluginNeed(registration.scope === "user" ? registration.projectPath === null : typeof registration.projectPath === "string" && isAbsolute15(registration.projectPath) && resolve16(registration.projectPath) === registration.projectPath, "Plugin scope requires its exact project path");
34826
34970
  const key = JSON.stringify([registration.scope, registration.projectPath]);
34827
34971
  pluginNeed(!scopes.has(key), "Duplicate plugin registration scope");
34828
34972
  scopes.add(key);
@@ -34830,7 +34974,7 @@ function validatePluginTarget(value) {
34830
34974
  for (const key of ["native", "resolver"]) {
34831
34975
  pluginKeys(value[key], key === "native" ? ["version", "executable", "digest"] : ["executable", "digest"]);
34832
34976
  pluginText(value[key].executable);
34833
- pluginNeed(isAbsolute13(value[key].executable) && resolve15(value[key].executable) === value[key].executable, "Plugin executable must have a canonical absolute path");
34977
+ pluginNeed(isAbsolute15(value[key].executable) && resolve16(value[key].executable) === value[key].executable, "Plugin executable must have a canonical absolute path");
34834
34978
  pluginDigest(value[key].digest);
34835
34979
  }
34836
34980
  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)");
@@ -34973,12 +35117,12 @@ function pluginResolverCommand(binding) {
34973
35117
  }
34974
35118
  function pluginBindingPath(storeRoot, id) {
34975
35119
  pluginNeed(/^[a-f0-9]{64}$/.test(id), "Invalid plugin binding identifier");
34976
- return join25(storeRoot, "bindings", `${id}.json`);
35120
+ return join26(storeRoot, "bindings", `${id}.json`);
34977
35121
  }
34978
35122
  function pluginReceiptPath(storeRoot, id, digest) {
34979
35123
  pluginNeed(/^[a-f0-9]{64}$/.test(id), "Invalid plugin binding identifier");
34980
35124
  pluginDigest(digest);
34981
- return join25(storeRoot, "receipts", id, `${digest.slice(7)}.json`);
35125
+ return join26(storeRoot, "receipts", id, `${digest.slice(7)}.json`);
34982
35126
  }
34983
35127
  function readPluginBinding(storeRoot, id) {
34984
35128
  const value = readPluginJson(pluginBindingPath(storeRoot, id));
@@ -34998,7 +35142,7 @@ function readPluginAdmissionReceipt(storeRoot, id, digest) {
34998
35142
  pluginNeed(receipt.plan.bindingId === id && receipt.plan.planDigest === digest, "Plugin receipt identity differs from its filename");
34999
35143
  const binding = readPluginBinding(storeRoot, id);
35000
35144
  pluginNeed(canonicalJson(binding) === canonicalJson(receipt.plan.binding) && receipt.plan.sourceCommand === pluginResolverCommand(binding), "Plugin receipt binding changed");
35001
- pluginNeed(receipt.materializedPath === join25(storeRoot, "objects", id, digest.slice(7)), "Plugin receipt points outside its immutable materialization");
35145
+ pluginNeed(receipt.materializedPath === join26(storeRoot, "objects", id, digest.slice(7)), "Plugin receipt points outside its immutable materialization");
35002
35146
  pluginText(receipt.admittedAt, 64);
35003
35147
  pluginNeed(Number.isFinite(Date.parse(receipt.admittedAt)), "Invalid plugin admission time");
35004
35148
  return receipt;
@@ -35015,8 +35159,8 @@ var init_plugin_admission = __esm(() => {
35015
35159
  });
35016
35160
 
35017
35161
  // src/lib/plugin-discovery.ts
35018
- import { closeSync as closeSync13, constants as constants11, fstatSync as fstatSync13, lstatSync as lstatSync17, openSync as openSync13, opendirSync as opendirSync3, readSync as readSync8 } from "fs";
35019
- import { basename as basename7, dirname as dirname15, isAbsolute as isAbsolute14, join as join26, resolve as resolve16 } from "path";
35162
+ import { closeSync as closeSync14, constants as constants12, fstatSync as fstatSync14, lstatSync as lstatSync18, openSync as openSync14, opendirSync as opendirSync3, readSync as readSync9 } from "fs";
35163
+ import { basename as basename7, dirname as dirname16, isAbsolute as isAbsolute16, join as join27, resolve as resolve17 } from "path";
35020
35164
  function validateManagedPluginWitnesses(value) {
35021
35165
  pluginNeed(Array.isArray(value) && value.length > 0 && value.length <= PLUGIN_PROJECTION_LIMITS.registrations, "Invalid managed plugin witness collection");
35022
35166
  const seen = new Set;
@@ -35025,36 +35169,36 @@ function validateManagedPluginWitnesses(value) {
35025
35169
  pluginNeed(typeof item.bindingId === "string" && /^[a-f0-9]{64}$/.test(item.bindingId) && !seen.has(item.bindingId), "Invalid or duplicate managed plugin witness");
35026
35170
  seen.add(item.bindingId);
35027
35171
  pluginText(item.storeRoot);
35028
- pluginNeed(isAbsolute14(item.storeRoot) && resolve16(item.storeRoot) === item.storeRoot, "Invalid plugin receipt store path");
35172
+ pluginNeed(isAbsolute16(item.storeRoot) && resolve17(item.storeRoot) === item.storeRoot, "Invalid plugin receipt store path");
35029
35173
  }
35030
35174
  }
35031
- function safe3(path) {
35175
+ function safe4(path) {
35032
35176
  pluginText(path);
35033
- pluginNeed(isAbsolute14(path) && resolve16(path) === path, "Invalid plugin registry path");
35034
- for (let at = path;; at = dirname15(at)) {
35035
- pluginNeed(!lstatSync17(at, { throwIfNoEntry: false })?.isSymbolicLink(), "Plugin registry path traverses a symlink");
35036
- if (at === dirname15(at))
35177
+ pluginNeed(isAbsolute16(path) && resolve17(path) === path, "Invalid plugin registry path");
35178
+ for (let at = path;; at = dirname16(at)) {
35179
+ pluginNeed(!lstatSync18(at, { throwIfNoEntry: false })?.isSymbolicLink(), "Plugin registry path traverses a symlink");
35180
+ if (at === dirname16(at))
35037
35181
  break;
35038
35182
  }
35039
35183
  }
35040
35184
  function readRegistry(path) {
35041
- safe3(path);
35042
- const initial = lstatSync17(path);
35185
+ safe4(path);
35186
+ const initial = lstatSync18(path);
35043
35187
  pluginNeed(initial.isFile() && initial.size <= 1024 * 1024, "Plugin registry is not a bounded regular file");
35044
- const fd = openSync13(path, constants11.O_RDONLY | constants11.O_NOFOLLOW | constants11.O_NONBLOCK);
35188
+ const fd = openSync14(path, constants12.O_RDONLY | constants12.O_NOFOLLOW | constants12.O_NONBLOCK);
35045
35189
  try {
35046
- const opened = fstatSync13(fd);
35190
+ const opened = fstatSync14(fd);
35047
35191
  pluginNeed(opened.isFile() && opened.ino === initial.ino && opened.dev === initial.dev, "Plugin registry changed during open");
35048
35192
  const bytes = Buffer.alloc(1024 * 1024 + 1);
35049
35193
  let length = 0;
35050
35194
  while (length < bytes.length) {
35051
- const count = readSync8(fd, bytes, length, bytes.length - length, null);
35195
+ const count = readSync9(fd, bytes, length, bytes.length - length, null);
35052
35196
  if (!count)
35053
35197
  break;
35054
35198
  length += count;
35055
35199
  }
35056
- const after = fstatSync13(fd), current = lstatSync17(path);
35057
- safe3(path);
35200
+ const after = fstatSync14(fd), current = lstatSync18(path);
35201
+ safe4(path);
35058
35202
  pluginNeed(length <= 1024 * 1024 && length === opened.size && after.size === opened.size && after.mtimeMs === opened.mtimeMs && after.ctimeMs === opened.ctimeMs && current.dev === opened.dev && current.ino === opened.ino && current.mtimeMs === opened.mtimeMs && current.ctimeMs === opened.ctimeMs, "Plugin registry changed during read");
35059
35203
  let value;
35060
35204
  try {
@@ -35065,7 +35209,7 @@ function readRegistry(path) {
35065
35209
  pluginNeed(pluginObject(value) && value.version === 2 && pluginObject(value.plugins), "Unsupported native plugin registry schema");
35066
35210
  return { value, rawDigest: pluginHash(bytes.subarray(0, length)) };
35067
35211
  } finally {
35068
- closeSync13(fd);
35212
+ closeSync14(fd);
35069
35213
  }
35070
35214
  }
35071
35215
  function nativeVersionMatches(version2, receipt) {
@@ -35083,7 +35227,7 @@ function hashManagedPluginRegistry(path, managed) {
35083
35227
  seen.add(target.pluginId);
35084
35228
  const rows = plugins[target.pluginId];
35085
35229
  pluginNeed(Array.isArray(rows) && rows.length === target.registrations.length, "Managed plugin registration membership changed");
35086
- const [name, market] = target.pluginId.split("@"), cacheRoot = join26(dirname15(path), "cache", market, name);
35230
+ const [name, market] = target.pluginId.split("@"), cacheRoot = join27(dirname16(path), "cache", market, name);
35087
35231
  const scopes = new Set, approvals = new Map, currentFiles = new Map;
35088
35232
  plugins[target.pluginId] = rows.map((row) => {
35089
35233
  pluginNeed(pluginObject(row), "Invalid managed plugin registration");
@@ -35096,7 +35240,7 @@ function hashManagedPluginRegistry(path, managed) {
35096
35240
  pluginText(row.sourceProducerPath);
35097
35241
  pluginText(row.lastUpdated, 64);
35098
35242
  pluginNeed(Number.isFinite(Date.parse(row.lastUpdated)), "Invalid managed plugin update timestamp");
35099
- pluginNeed(/^(?:[A-Za-z0-9][A-Za-z0-9._+-]*-)?[a-f0-9]{12}$/.test(row.version) && row.installPath === join26(cacheRoot, row.version), "Managed plugin cache path or version is outside its registration");
35243
+ pluginNeed(/^(?:[A-Za-z0-9][A-Za-z0-9._+-]*-)?[a-f0-9]{12}$/.test(row.version) && row.installPath === join27(cacheRoot, row.version), "Managed plugin cache path or version is outside its registration");
35100
35244
  const approval = (producer) => {
35101
35245
  pluginText(producer);
35102
35246
  const digest = `sha256:${basename7(producer)}`;
@@ -35125,8 +35269,8 @@ function hashManagedPluginRegistry(path, managed) {
35125
35269
  }
35126
35270
  return Object.fromEntries(Object.entries(row).filter(([key]) => !["version", "installPath", "sourceProducerPath", "previousProducerPaths", "lastUpdated"].includes(key)));
35127
35271
  });
35128
- safe3(cacheRoot);
35129
- const before = lstatSync17(cacheRoot);
35272
+ safe4(cacheRoot);
35273
+ const before = lstatSync18(cacheRoot);
35130
35274
  pluginNeed(before.isDirectory(), "Invalid managed plugin cache root");
35131
35275
  const directory = opendirSync3(cacheRoot), names = [];
35132
35276
  try {
@@ -35139,18 +35283,18 @@ function hashManagedPluginRegistry(path, managed) {
35139
35283
  directory.closeSync();
35140
35284
  }
35141
35285
  for (const version2 of names.sort()) {
35142
- const files = pluginFileWitnesses(snapshotPluginTree(join26(cacheRoot, version2), { nativeRuntime: `claude-${target.native.version}` }));
35286
+ const files = pluginFileWitnesses(snapshotPluginTree(join27(cacheRoot, version2), { nativeRuntime: `claude-${target.native.version}` }));
35143
35287
  verifiedBytes += files.reduce((total, file2) => total + file2.size, 0);
35144
35288
  pluginNeed(verifiedBytes <= 256 * 1024 * 1024, "Managed plugin verification exceeds its aggregate byte budget");
35145
35289
  const serialized = JSON.stringify(files);
35146
- const expected = currentFiles.get(join26(cacheRoot, version2));
35290
+ const expected = currentFiles.get(join27(cacheRoot, version2));
35147
35291
  pluginNeed(expected === undefined || serialized === expected, "Current native cache differs from its exact registered producer receipt");
35148
35292
  pluginNeed([...approvals.values()].some((receipt) => nativeVersionMatches(version2, receipt) && JSON.stringify(receipt.plan.files) === serialized), "A retained native plugin cache version differs from every approved projection");
35149
35293
  }
35150
35294
  for (const row of rows)
35151
35295
  pluginNeed(names.includes(row.version), "Managed native plugin installation is missing");
35152
- const after = lstatSync17(cacheRoot);
35153
- safe3(cacheRoot);
35296
+ const after = lstatSync18(cacheRoot);
35297
+ safe4(cacheRoot);
35154
35298
  pluginNeed(before.dev === after.dev && before.ino === after.ino && before.mtimeMs === after.mtimeMs && before.ctimeMs === after.ctimeMs, "Managed cache version membership changed during verification");
35155
35299
  }
35156
35300
  pluginNeed(readRegistry(path).rawDigest === snapshot2.rawDigest, "Native plugin registry changed during content verification");
@@ -35163,50 +35307,50 @@ var init_plugin_discovery = __esm(() => {
35163
35307
  });
35164
35308
 
35165
35309
  // src/lib/claude-marketplace-registry.ts
35166
- import { createHash as createHash17 } from "crypto";
35167
- import { closeSync as closeSync14, constants as constants12, fstatSync as fstatSync14, lstatSync as lstatSync18, openSync as openSync14, readSync as readSync9 } from "fs";
35168
- import { basename as basename8, dirname as dirname16, isAbsolute as isAbsolute15, resolve as resolve17 } from "path";
35169
- function need7(value, reason2) {
35310
+ import { createHash as createHash18 } from "crypto";
35311
+ import { closeSync as closeSync15, constants as constants13, fstatSync as fstatSync15, lstatSync as lstatSync19, openSync as openSync15, readSync as readSync10 } from "fs";
35312
+ import { basename as basename8, dirname as dirname17, isAbsolute as isAbsolute17, resolve as resolve18 } from "path";
35313
+ function need8(value, reason2) {
35170
35314
  if (!value)
35171
35315
  throw new Error(`Claude marketplace registry ${reason2}`);
35172
35316
  }
35173
- function absolutePath3(value) {
35174
- need7(typeof value === "string" && value.length > 0 && value.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.pathCharacters && !/[\x00-\x1f\x7f]/.test(value) && isAbsolute15(value) && resolve17(value) === value, "requires a normalized absolute path");
35317
+ function absolutePath4(value) {
35318
+ need8(typeof value === "string" && value.length > 0 && value.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.pathCharacters && !/[\x00-\x1f\x7f]/.test(value) && isAbsolute17(value) && resolve18(value) === value, "requires a normalized absolute path");
35175
35319
  }
35176
35320
  function parents2(path) {
35177
35321
  const result = [];
35178
- for (let at = dirname16(path);; at = dirname16(at)) {
35179
- const stat2 = lstatSync18(at, { bigint: true });
35180
- need7(stat2.isDirectory() && !stat2.isSymbolicLink(), "path traverses a symlink or non-directory");
35322
+ for (let at = dirname17(path);; at = dirname17(at)) {
35323
+ const stat2 = lstatSync19(at, { bigint: true });
35324
+ need8(stat2.isDirectory() && !stat2.isSymbolicLink(), "path traverses a symlink or non-directory");
35181
35325
  result.push([at, stat2]);
35182
- if (at === dirname16(at))
35326
+ if (at === dirname17(at))
35183
35327
  return result;
35184
35328
  }
35185
35329
  }
35186
35330
  function readRegistry2(path, budget2) {
35187
- absolutePath3(path);
35188
- need7(basename8(path) === "known_marketplaces.json", "requires known_marketplaces.json");
35189
- need7(Number.isSafeInteger(budget2.remaining) && budget2.remaining >= 0, "has an invalid byte budget");
35190
- const ancestors2 = parents2(path), initial = lstatSync18(path, { bigint: true });
35191
- need7(initial.isFile() && !initial.isSymbolicLink() && initial.size <= BigInt(CLAUDE_MARKETPLACE_REGISTRY_LIMITS.bytes), "is not a bounded regular file");
35192
- need7(initial.size <= BigInt(budget2.remaining), "exceeds its aggregate byte limit");
35193
- const fd = openSync14(path, constants12.O_RDONLY | constants12.O_NOFOLLOW | constants12.O_NONBLOCK);
35331
+ absolutePath4(path);
35332
+ need8(basename8(path) === "known_marketplaces.json", "requires known_marketplaces.json");
35333
+ need8(Number.isSafeInteger(budget2.remaining) && budget2.remaining >= 0, "has an invalid byte budget");
35334
+ const ancestors2 = parents2(path), initial = lstatSync19(path, { bigint: true });
35335
+ need8(initial.isFile() && !initial.isSymbolicLink() && initial.size <= BigInt(CLAUDE_MARKETPLACE_REGISTRY_LIMITS.bytes), "is not a bounded regular file");
35336
+ need8(initial.size <= BigInt(budget2.remaining), "exceeds its aggregate byte limit");
35337
+ const fd = openSync15(path, constants13.O_RDONLY | constants13.O_NOFOLLOW | constants13.O_NONBLOCK);
35194
35338
  try {
35195
- const opened = fstatSync14(fd, { bigint: true });
35196
- need7(opened.isFile() && sameFile2(initial, opened), "changed during open");
35339
+ const opened = fstatSync15(fd, { bigint: true });
35340
+ need8(opened.isFile() && sameFile2(initial, opened), "changed during open");
35197
35341
  const bytes = Buffer.alloc(Number(opened.size) + 1);
35198
35342
  let length = 0;
35199
35343
  while (length < bytes.length) {
35200
- const count = readSync9(fd, bytes, length, bytes.length - length, null);
35344
+ const count = readSync10(fd, bytes, length, bytes.length - length, null);
35201
35345
  if (!count)
35202
35346
  break;
35203
35347
  length += count;
35204
35348
  }
35205
- const after = fstatSync14(fd, { bigint: true }), current = lstatSync18(path, { bigint: true });
35206
- need7(current.isFile() && sameFile2(opened, after) && sameFile2(after, current) && BigInt(length) === opened.size, "changed during read");
35349
+ const after = fstatSync15(fd, { bigint: true }), current = lstatSync19(path, { bigint: true });
35350
+ need8(current.isFile() && sameFile2(opened, after) && sameFile2(after, current) && BigInt(length) === opened.size, "changed during read");
35207
35351
  for (const [ancestor, before] of ancestors2) {
35208
- const now = lstatSync18(ancestor, { bigint: true });
35209
- need7(now.isDirectory() && before.dev === now.dev && before.ino === now.ino && before.mode === now.mode, "parent changed during read");
35352
+ const now = lstatSync19(ancestor, { bigint: true });
35353
+ need8(now.isDirectory() && before.dev === now.dev && before.ino === now.ino && before.mode === now.mode, "parent changed during read");
35210
35354
  }
35211
35355
  budget2.remaining -= length;
35212
35356
  try {
@@ -35215,7 +35359,7 @@ function readRegistry2(path, budget2) {
35215
35359
  throw new Error("Claude marketplace registry is not strict UTF-8");
35216
35360
  }
35217
35361
  } finally {
35218
- closeSync14(fd);
35362
+ closeSync15(fd);
35219
35363
  }
35220
35364
  }
35221
35365
  function parse11(text2) {
@@ -35226,7 +35370,7 @@ function parse11(text2) {
35226
35370
  at++;
35227
35371
  };
35228
35372
  function string4() {
35229
- need7(text2[at] === '"', "contains invalid JSON");
35373
+ need8(text2[at] === '"', "contains invalid JSON");
35230
35374
  const start = at++;
35231
35375
  while (at < text2.length) {
35232
35376
  const character = text2[at++];
@@ -35237,7 +35381,7 @@ function parse11(text2) {
35237
35381
  } catch {
35238
35382
  throw new Error("Claude marketplace registry contains invalid JSON string");
35239
35383
  }
35240
- need7(value2.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.stringCharacters, "exceeds its string limit");
35384
+ need8(value2.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.stringCharacters, "exceeds its string limit");
35241
35385
  return value2;
35242
35386
  }
35243
35387
  if (character === "\\")
@@ -35246,7 +35390,7 @@ function parse11(text2) {
35246
35390
  throw new Error("Claude marketplace registry contains an unterminated JSON string");
35247
35391
  }
35248
35392
  function value(depth) {
35249
- need7(depth <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.depth && ++nodes <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.nodes, "exceeds its nesting or node limit");
35393
+ need8(depth <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.depth && ++nodes <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.nodes, "exceeds its nesting or node limit");
35250
35394
  space();
35251
35395
  const character = text2[at];
35252
35396
  if (character === '"')
@@ -35254,26 +35398,26 @@ function parse11(text2) {
35254
35398
  if (character === "{" || character === "[") {
35255
35399
  at++;
35256
35400
  space();
35257
- const object5 = character === "{", end = object5 ? "}" : "]", entries = [], items = [], keys = new Set;
35401
+ const object6 = character === "{", end = object6 ? "}" : "]", entries = [], items = [], keys2 = new Set;
35258
35402
  if (text2[at] !== end)
35259
35403
  while (true) {
35260
- if (object5) {
35404
+ if (object6) {
35261
35405
  space();
35262
35406
  const key = string4();
35263
- need7(!keys.has(key), "contains a duplicate JSON key");
35264
- keys.add(key);
35407
+ need8(!keys2.has(key), "contains a duplicate JSON key");
35408
+ keys2.add(key);
35265
35409
  space();
35266
- need7(text2[at++] === ":", "contains invalid JSON");
35410
+ need8(text2[at++] === ":", "contains invalid JSON");
35267
35411
  entries.push([key, value(depth + 1)]);
35268
35412
  } else
35269
35413
  items.push(value(depth + 1));
35270
35414
  space();
35271
35415
  if (text2[at] === end)
35272
35416
  break;
35273
- need7(text2[at++] === ",", "contains invalid JSON");
35417
+ need8(text2[at++] === ",", "contains invalid JSON");
35274
35418
  }
35275
35419
  at++;
35276
- return object5 ? { kind: "object", entries } : { kind: "array", items };
35420
+ return object6 ? { kind: "object", entries } : { kind: "array", items };
35277
35421
  }
35278
35422
  for (const literal2 of ["true", "false", "null"])
35279
35423
  if (text2.startsWith(literal2, at)) {
@@ -35282,21 +35426,21 @@ function parse11(text2) {
35282
35426
  }
35283
35427
  numberPattern.lastIndex = at;
35284
35428
  const number4 = numberPattern.exec(text2);
35285
- need7(number4, "contains invalid JSON");
35429
+ need8(number4, "contains invalid JSON");
35286
35430
  at += number4[0].length;
35287
35431
  return { kind: "number", value: number4[0] };
35288
35432
  }
35289
35433
  const root = value(0);
35290
35434
  space();
35291
- need7(at === text2.length && root.kind === "object", "requires a JSON object without trailing content");
35292
- need7(root.entries.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.rows, "exceeds its marketplace row limit");
35435
+ need8(at === text2.length && root.kind === "object", "requires a JSON object without trailing content");
35436
+ need8(root.entries.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.rows, "exceeds its marketplace row limit");
35293
35437
  return root;
35294
35438
  }
35295
- function exactKeys(value, keys) {
35296
- return value?.kind === "object" && value.entries.length === keys.length && value.entries.every(([key]) => keys.includes(key));
35439
+ function exactKeys(value, keys2) {
35440
+ return value?.kind === "object" && value.entries.length === keys2.length && value.entries.every(([key]) => keys2.includes(key));
35297
35441
  }
35298
35442
  function textField(value) {
35299
- need7(value?.kind === "string" && value.value.length > 0 && !/[\x00-\x1f\x7f]/.test(value.value), "contains an invalid recognized field");
35443
+ need8(value?.kind === "string" && value.value.length > 0 && !/[\x00-\x1f\x7f]/.test(value.value), "contains an invalid recognized field");
35300
35444
  return value.value;
35301
35445
  }
35302
35446
  function normalizeRow(row, version2 = 1) {
@@ -35304,7 +35448,7 @@ function normalizeRow(row, version2 = 1) {
35304
35448
  if (version2 !== 2 || !exactKeys(row, ["source", "installLocation", "lastUpdated", "autoUpdate"]))
35305
35449
  return;
35306
35450
  const autoUpdate = field2(row, "autoUpdate");
35307
- need7(autoUpdate?.kind === "literal" && (autoUpdate.value === "true" || autoUpdate.value === "false"), "contains an invalid automatic-update preference");
35451
+ need8(autoUpdate?.kind === "literal" && (autoUpdate.value === "true" || autoUpdate.value === "false"), "contains an invalid automatic-update preference");
35308
35452
  }
35309
35453
  const source = field2(row, "source");
35310
35454
  if (source?.kind !== "object")
@@ -35317,29 +35461,29 @@ function normalizeRow(row, version2 = 1) {
35317
35461
  return;
35318
35462
  const sourceLocation = textField(field2(source, location));
35319
35463
  if (type.value === "directory")
35320
- absolutePath3(sourceLocation);
35321
- absolutePath3(textField(field2(row, "installLocation")));
35464
+ absolutePath4(sourceLocation);
35465
+ absolutePath4(textField(field2(row, "installLocation")));
35322
35466
  const updated = textField(field2(row, "lastUpdated"));
35323
- 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");
35467
+ need8(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(updated), "contains an invalid recognized update timestamp");
35324
35468
  const millis = Date.parse(updated);
35325
- need7(Number.isFinite(millis) && new Date(millis).toISOString() === updated, "contains an invalid recognized update timestamp");
35469
+ need8(Number.isFinite(millis) && new Date(millis).toISOString() === updated, "contains an invalid recognized update timestamp");
35326
35470
  row.entries = row.entries.map(([key, value]) => [key, key === "lastUpdated" ? { kind: "validated-update-time" } : value]);
35327
35471
  }
35328
35472
  function captureClaudeMarketplaceRegistry(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
35329
35473
  const value = parse11(readRegistry2(path, budget2));
35330
35474
  for (const [, row] of value.entries)
35331
35475
  normalizeRow(row);
35332
- const sha2562 = createHash17("sha256").update("hasna.skills.claude-marketplace-registry.v1\x00").update(JSON.stringify(value)).digest("hex");
35476
+ const sha2562 = createHash18("sha256").update("hasna.skills.claude-marketplace-registry.v1\x00").update(JSON.stringify(value)).digest("hex");
35333
35477
  return { path, hashMode: "claude-marketplace-registry", sha256: sha2562 };
35334
35478
  }
35335
35479
  function captureClaudeMarketplaceRegistryV2(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
35336
35480
  const value = parse11(readRegistry2(path, budget2));
35337
35481
  for (const [, row] of value.entries)
35338
35482
  normalizeRow(row, 2);
35339
- const sha2562 = createHash17("sha256").update("hasna.skills.claude-marketplace-registry.v2\x00").update(JSON.stringify(value)).digest("hex");
35483
+ const sha2562 = createHash18("sha256").update("hasna.skills.claude-marketplace-registry.v2\x00").update(JSON.stringify(value)).digest("hex");
35340
35484
  return { path, hashMode: "claude-marketplace-registry-v2", sha256: sha2562 };
35341
35485
  }
35342
- 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 = (object5, key) => object5.entries.find(([name]) => name === key)?.[1];
35486
+ 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 = (object6, key) => object6.entries.find(([name]) => name === key)?.[1];
35343
35487
  var init_claude_marketplace_registry = __esm(() => {
35344
35488
  CLAUDE_MARKETPLACE_REGISTRY_LIMITS = Object.freeze({ bytes: 1024 * 1024, rows: 1024, depth: 32, nodes: 65536, stringCharacters: 16384, pathCharacters: 4096 });
35345
35489
  });
@@ -35358,7 +35502,7 @@ var init_codex_hook_additions_review = __esm(() => {
35358
35502
  });
35359
35503
 
35360
35504
  // src/lib/codex-hook-discovery-recovery.ts
35361
- import { createHash as createHash18 } from "crypto";
35505
+ import { createHash as createHash19 } from "crypto";
35362
35506
  function assertCodexHookDiscoveryRecovery(binding, witness) {
35363
35507
  const proof = proofs2.get(witness);
35364
35508
  need6(!!proof && binding.agent === "codex" && witness.discoverySha256 === discoveryDigest(binding), "RECONCILE_DISCOVERY_RECOVERY_CHANGED");
@@ -35373,13 +35517,13 @@ function verifiesCodexHookDiscoverySource(binding, source, currentDigest, witnes
35373
35517
  need6(source.sha256 === witness.beforeSha256 && currentDigest === witness.currentSha256, "RECONCILE_DISCOVERY_RECOVERY_CHANGED");
35374
35518
  return true;
35375
35519
  }
35376
- var sha3 = (text2) => createHash18("sha256").update(text2).digest("hex"), fields, discoveryDigest = (binding) => {
35520
+ var sha4 = (text2) => createHash19("sha256").update(text2).digest("hex"), fields, discoveryDigest = (binding) => {
35377
35521
  const controls = binding.codexDisabledPluginSkills;
35378
35522
  if (!Object.hasOwn(binding, "codexDisabledPluginSkills") || Array.isArray(controls) && controls.length === 0) {
35379
35523
  const { codexDisabledPluginSkills: _controls, ...withoutControls } = binding;
35380
- return sha3(JSON.stringify({ ...withoutControls, codexDisabledPluginSkills: [] }));
35524
+ return sha4(JSON.stringify({ ...withoutControls, codexDisabledPluginSkills: [] }));
35381
35525
  }
35382
- return sha3(JSON.stringify(binding));
35526
+ return sha4(JSON.stringify(binding));
35383
35527
  }, proofs2;
35384
35528
  var init_codex_hook_discovery_recovery = __esm(() => {
35385
35529
  init_codex_hook_trust_files();
@@ -35391,16 +35535,16 @@ var init_codex_hook_discovery_recovery = __esm(() => {
35391
35535
  });
35392
35536
 
35393
35537
  // src/lib/agent-discovery.ts
35394
- import { createHash as createHash19 } from "crypto";
35395
- import { lstatSync as lstatSync19, readFileSync as readFileSync16, readdirSync as readdirSync7, realpathSync as realpathSync6 } from "fs";
35396
- import { basename as basename9, dirname as dirname17, isAbsolute as isAbsolute16, join as join27, resolve as resolve18, sep as sep7 } from "path";
35538
+ import { createHash as createHash20 } from "crypto";
35539
+ import { lstatSync as lstatSync20, readFileSync as readFileSync16, readdirSync as readdirSync7, realpathSync as realpathSync6 } from "fs";
35540
+ import { basename as basename9, dirname as dirname18, isAbsolute as isAbsolute18, join as join28, resolve as resolve19, sep as sep8 } from "path";
35397
35541
  import { isDeepStrictEqual as isDeepStrictEqual4 } from "util";
35398
35542
  function discoveryExecutable(agent) {
35399
35543
  const command = DISCOVERY_RUNTIME_COMMANDS[agent];
35400
35544
  const found = command ? Bun.which(command) : null;
35401
35545
  if (!command || !found)
35402
35546
  return null;
35403
- const path = resolve18(found), target = realpathOrNull(path);
35547
+ const path = resolve19(found), target = realpathOrNull(path);
35404
35548
  return target === null ? null : { command, path, target };
35405
35549
  }
35406
35550
  function parseConfig(text2, path, toml = false) {
@@ -35413,21 +35557,21 @@ function parseConfig(text2, path, toml = false) {
35413
35557
  throw new Error(`Invalid native discovery configuration: ${path}`);
35414
35558
  }
35415
35559
  }
35416
- function safe4(path) {
35417
- if (!isAbsolute16(path) || path.includes("\x00"))
35560
+ function safe5(path) {
35561
+ if (!isAbsolute18(path) || path.includes("\x00"))
35418
35562
  throw new Error("Expected an absolute native discovery path");
35419
- for (let cursor = path;; cursor = dirname17(cursor)) {
35420
- if (lstatSync19(cursor, { throwIfNoEntry: false })?.isSymbolicLink())
35563
+ for (let cursor = path;; cursor = dirname18(cursor)) {
35564
+ if (lstatSync20(cursor, { throwIfNoEntry: false })?.isSymbolicLink())
35421
35565
  throw new Error(`Refusing symlink native discovery input: ${cursor}`);
35422
- if (dirname17(cursor) === cursor)
35566
+ if (dirname18(cursor) === cursor)
35423
35567
  break;
35424
35568
  }
35425
35569
  }
35426
35570
  function read(path, changes) {
35427
- safe4(path);
35571
+ safe5(path);
35428
35572
  if (changes?.has(path))
35429
35573
  return changes.get(path);
35430
- const stat2 = lstatSync19(path, { throwIfNoEntry: false });
35574
+ const stat2 = lstatSync20(path, { throwIfNoEntry: false });
35431
35575
  if (!stat2)
35432
35576
  return null;
35433
35577
  if (!stat2.isFile() || stat2.size > 16 * 1024 * 1024)
@@ -35438,8 +35582,8 @@ function assertReviewedClaudeCacheClosures(home, config2, review, canonical8) {
35438
35582
  const enabledIds = Object.entries(config2.enabledPlugins ?? {}).filter(([, enabled]) => enabled === true).map(([id]) => id);
35439
35583
  if (enabledIds.length === 0)
35440
35584
  return;
35441
- const registryPath = canonical8(join27(home, ".claude/plugins/installed_plugins.json"));
35442
- const cacheAliasRoot = join27(home, ".claude/plugins/cache");
35585
+ const registryPath = canonical8(join28(home, ".claude/plugins/installed_plugins.json"));
35586
+ const cacheAliasRoot = join28(home, ".claude/plugins/cache");
35443
35587
  const cacheRoot = canonical8(cacheAliasRoot);
35444
35588
  const registryText = read(registryPath);
35445
35589
  if (registryText === null)
@@ -35447,7 +35591,7 @@ function assertReviewedClaudeCacheClosures(home, config2, review, canonical8) {
35447
35591
  const registry2 = parseConfig(registryText, registryPath);
35448
35592
  if (registry2.version !== 2 || !registry2.plugins || typeof registry2.plugins !== "object" || Array.isArray(registry2.plugins))
35449
35593
  throw new Error("Reviewed Claude installed plugin registrations are invalid");
35450
- const cachePath = (path) => typeof path === "string" && isAbsolute16(path) && resolve18(path) === path && [cacheAliasRoot, cacheRoot].some((root) => path === root || path.startsWith(root + sep7));
35594
+ const cachePath = (path) => typeof path === "string" && isAbsolute18(path) && resolve19(path) === path && [cacheAliasRoot, cacheRoot].some((root) => path === root || path.startsWith(root + sep8));
35451
35595
  const activeRoots = new Set;
35452
35596
  for (const id of enabledIds) {
35453
35597
  const rows = registry2.plugins[id];
@@ -35459,11 +35603,11 @@ function assertReviewedClaudeCacheClosures(home, config2, review, canonical8) {
35459
35603
  if (!row || typeof row !== "object" || Array.isArray(row) || typeof row.installPath !== "string") {
35460
35604
  throw new Error("Reviewed Claude enabled plugin registration requires an object with an installPath string");
35461
35605
  }
35462
- if ([cacheAliasRoot, cacheRoot].some((root) => row.installPath === root || row.installPath.startsWith(root + sep7))) {
35606
+ if ([cacheAliasRoot, cacheRoot].some((root) => row.installPath === root || row.installPath.startsWith(root + sep8))) {
35463
35607
  if (!cachePath(row.installPath) || row.installPath.length > AGENT_POLICY_LIMITS.pathCharacters || row.version !== undefined && (typeof row.version !== "string" || basename9(row.installPath) !== row.version)) {
35464
35608
  throw new Error("Reviewed Claude discovery has a malformed active cache registration");
35465
35609
  }
35466
- if (row.scope === "user" && (row.projectPath === undefined || row.projectPath === null)) {} else if (row.scope === "project" && typeof row.projectPath === "string" && isAbsolute16(row.projectPath) && resolve18(row.projectPath) === row.projectPath && row.projectPath.length <= AGENT_POLICY_LIMITS.pathCharacters) {} else
35610
+ if (row.scope === "user" && (row.projectPath === undefined || row.projectPath === null)) {} else if (row.scope === "project" && typeof row.projectPath === "string" && isAbsolute18(row.projectPath) && resolve19(row.projectPath) === row.projectPath && row.projectPath.length <= AGENT_POLICY_LIMITS.pathCharacters) {} else
35467
35611
  throw new Error("Reviewed Claude discovery has an unsupported active cache registration scope");
35468
35612
  activeRoots.add(canonical8(row.installPath));
35469
35613
  }
@@ -35480,12 +35624,12 @@ function assertReviewedClaudeCacheClosures(home, config2, review, canonical8) {
35480
35624
  throw new Error(`Reviewed active Claude cache plugin ${description} is not bound`);
35481
35625
  };
35482
35626
  for (const root of activeRoots) {
35483
- safe4(root);
35484
- const rootStat = lstatSync19(root, { throwIfNoEntry: false });
35627
+ safe5(root);
35628
+ const rootStat = lstatSync20(root, { throwIfNoEntry: false });
35485
35629
  if (!rootStat?.isDirectory() || realpathSync6(root) !== root)
35486
35630
  throw new Error("Reviewed Claude active cache plugin root is missing or unsafe");
35487
- const manifestPath = join27(root, ".claude-plugin/plugin.json");
35488
- const manifestStat = lstatSync19(manifestPath, { throwIfNoEntry: false });
35631
+ const manifestPath = join28(root, ".claude-plugin/plugin.json");
35632
+ const manifestStat = lstatSync20(manifestPath, { throwIfNoEntry: false });
35489
35633
  let manifest;
35490
35634
  if (manifestStat) {
35491
35635
  if (!manifestStat.isFile())
@@ -35500,37 +35644,37 @@ function assertReviewedClaudeCacheClosures(home, config2, review, canonical8) {
35500
35644
  } else if (!review.sources.some((source) => source.path === manifestPath && source.hashMode === "path-bytes" && source.sha256 !== null && source.format === undefined && source.fields === undefined && source.managedPlugins === undefined)) {
35501
35645
  throw new Error("Reviewed Claude active cache plugin manifest absence requires a path-bytes witness");
35502
35646
  }
35503
- const roots = new Set([join27(root, "skills")]);
35504
- if (lstatSync19(join27(root, "SKILL.md"), { throwIfNoEntry: false })?.isFile())
35647
+ const roots = new Set([join28(root, "skills")]);
35648
+ if (lstatSync20(join28(root, "SKILL.md"), { throwIfNoEntry: false })?.isFile())
35505
35649
  roots.add(root);
35506
35650
  const declared = manifest?.skills === undefined ? ["./skills"] : typeof manifest.skills === "string" ? [manifest.skills] : manifest.skills;
35507
35651
  if (!Array.isArray(declared) || declared.some((path) => typeof path !== "string"))
35508
35652
  throw new Error("Reviewed Claude active cache plugin has unsupported skill paths");
35509
35653
  for (const value of declared) {
35510
- const path = resolve18(root, value);
35511
- if (path !== root && !path.startsWith(root + sep7))
35654
+ const path = resolve19(root, value);
35655
+ if (path !== root && !path.startsWith(root + sep8))
35512
35656
  throw new Error("Reviewed Claude active cache plugin skill path escapes its root");
35513
- roots.add(path.endsWith(`${sep7}SKILL.md`) ? dirname17(path) : path);
35657
+ roots.add(path.endsWith(`${sep8}SKILL.md`) ? dirname18(path) : path);
35514
35658
  }
35515
35659
  for (const skillRoot of roots)
35516
35660
  if (!review.roots.includes(skillRoot))
35517
35661
  throw new Error("Reviewed Claude active cache plugin skill root is not covered");
35518
- const hooksPath = join27(root, "hooks/hooks.json");
35519
- const hooksStat = lstatSync19(hooksPath, { throwIfNoEntry: false });
35662
+ const hooksPath = join28(root, "hooks/hooks.json");
35663
+ const hooksStat = lstatSync20(hooksPath, { throwIfNoEntry: false });
35520
35664
  if (hooksStat) {
35521
35665
  if (!hooksStat.isFile())
35522
35666
  throw new Error("Reviewed Claude plugin hook manifest is unsupported");
35523
35667
  requireSource(hooksPath, "hook manifest");
35524
35668
  }
35525
35669
  if (typeof manifest?.hooks === "string")
35526
- requireSource(resolve18(root, manifest.hooks), "manifest-declared hook source");
35670
+ requireSource(resolve19(root, manifest.hooks), "manifest-declared hook source");
35527
35671
  }
35528
35672
  }
35529
35673
  function projectNativeDiscoveryFields(text2, format, fields2, path) {
35530
- const object5 = format === "yaml" ? parseHermesConfig(text2) : parseConfig(text2, path, format === "toml");
35531
- if (!object5 || typeof object5 !== "object" || Array.isArray(object5))
35674
+ const object6 = format === "yaml" ? parseHermesConfig(text2) : parseConfig(text2, path, format === "toml");
35675
+ if (!object6 || typeof object6 !== "object" || Array.isArray(object6))
35532
35676
  throw new Error("Expected native discovery configuration object");
35533
- return digest(JSON.stringify(Object.fromEntries(fields2.map((field3) => [field3, object5[field3] ?? null]))));
35677
+ return digest(JSON.stringify(Object.fromEntries(fields2.map((field3) => [field3, object6[field3] ?? null]))));
35534
35678
  }
35535
35679
  function isSupersededSettingsProjection(agent, configPath, source) {
35536
35680
  if (agent === "sumi")
@@ -35543,6 +35687,8 @@ function supersedesSettingsProjection(agent, sources, configPath) {
35543
35687
  return agent === "codex" && sources.some((source) => source.path === configPath && (source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")));
35544
35688
  }
35545
35689
  function projected(source, changes, budget2 = discoveryByteBudget()) {
35690
+ if (source.reviewArtifact !== undefined)
35691
+ verifyRetainedReviewArtifact(source);
35546
35692
  if (source.hashMode === "sumi-settings-v1") {
35547
35693
  if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
35548
35694
  throw new Error("Sumi settings witnesses require exact typed metadata");
@@ -35618,9 +35764,9 @@ function absentCodexSkillRoots(binding) {
35618
35764
  return [];
35619
35765
  if (binding.agent !== "codex" || !Array.isArray(controls) || controls.length > 4096)
35620
35766
  throw new Error("Invalid disabled Codex discovery proof");
35621
- if (binding.method !== "reviewed" || controls.every((control) => lstatSync19(control.pluginParent, { throwIfNoEntry: false })))
35767
+ if (binding.method !== "reviewed" || controls.every((control) => lstatSync20(control.pluginParent, { throwIfNoEntry: false })))
35622
35768
  return [];
35623
- const cache = dirname17(dirname17(controls[0].pluginParent)), config2 = join27(dirname17(dirname17(cache)), "config.toml");
35769
+ const cache = dirname18(dirname18(controls[0].pluginParent)), config2 = join28(dirname18(dirname18(cache)), "config.toml");
35624
35770
  const source = binding.sources.find((source2) => source2.path === config2 && source2.sha256 !== null && source2.format === undefined && source2.fields === undefined);
35625
35771
  if (!source || projected(source) !== source.sha256)
35626
35772
  throw new Error("Missing current disabled Codex configuration witness");
@@ -35628,8 +35774,8 @@ function absentCodexSkillRoots(binding) {
35628
35774
  return [...new Set(controls.map((control) => control.pluginParent))].filter((parent) => !codexDirectHookSelects(cache, parent) && absentDisabledCodexPluginParent(cache, parent, controls, rules));
35629
35775
  }
35630
35776
  function codexDirectHookSelects(cache, root) {
35631
- const codex = dirname17(dirname17(cache)), config2 = Bun.TOML.parse(read(join27(codex, "config.toml")) ?? "");
35632
- const hooks = read(join27(codex, "hooks.json"));
35777
+ const codex = dirname18(dirname18(cache)), config2 = Bun.TOML.parse(read(join28(codex, "config.toml")) ?? "");
35778
+ const hooks = read(join28(codex, "hooks.json"));
35633
35779
  if (hooks !== null)
35634
35780
  hashNativeJsonControls(hooks);
35635
35781
  return JSON.stringify(config2.hooks ?? {}).includes(root) || hooks !== null && JSON.stringify(JSON.parse(hooks)).includes(root);
@@ -35641,7 +35787,7 @@ function retiredCodexRoots(binding) {
35641
35787
  const controls = binding.codexDisabledPluginSkills;
35642
35788
  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)
35643
35789
  throw new Error("Invalid retired Codex materialization proof");
35644
- const cache = dirname17(dirname17(controls[0].pluginParent)), config2 = join27(dirname17(dirname17(cache)), "config.toml");
35790
+ const cache = dirname18(dirname18(controls[0].pluginParent)), config2 = join28(dirname18(dirname18(cache)), "config.toml");
35645
35791
  const source = binding.sources.find((source2) => source2.path === config2 && source2.sha256 !== null && source2.format === undefined && source2.fields === undefined);
35646
35792
  if (!source || projected(source) !== source.sha256)
35647
35793
  throw new Error("Missing current retired Codex configuration witness");
@@ -35649,7 +35795,7 @@ function retiredCodexRoots(binding) {
35649
35795
  if ((proof.parents ?? []).some((parent) => codexDirectHookSelects(cache, parent) || !reviewedDisabledCodexPluginParent(cache, parent, controls, rules)) || !reviewedCodexPluginCapabilitiesUnchanged(cache, controls, (path) => read(path), rules))
35650
35796
  throw new Error("Retired Codex parent capabilities changed");
35651
35797
  for (const root of proof.roots) {
35652
- const manifest = binding.sources.find((source2) => source2.path === join27(root, ".codex-plugin/plugin.json") && source2.sha256 !== null && source2.format === undefined && source2.fields === undefined && [undefined, "bytes"].includes(source2.hashMode));
35798
+ const manifest = binding.sources.find((source2) => source2.path === join28(root, ".codex-plugin/plugin.json") && source2.sha256 !== null && source2.format === undefined && source2.fields === undefined && [undefined, "bytes"].includes(source2.hashMode));
35653
35799
  if (!manifest || codexDirectHookSelects(cache, root) || !reviewedRetiredCodexRoot(cache, root, controls, rules, (path) => read(path), true))
35654
35800
  throw new Error("Retired Codex materialization changed");
35655
35801
  }
@@ -35658,7 +35804,7 @@ function retiredCodexRoots(binding) {
35658
35804
  function retainableAbsentSource(source) {
35659
35805
  if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined)
35660
35806
  return false;
35661
- return [undefined, "bytes"].includes(source.hashMode) || source.hashMode === "claude-plugin-manifest-v1" && source.sha256 !== null && source.path.endsWith(join27(sep7, ".claude-plugin", "plugin.json"));
35807
+ return [undefined, "bytes"].includes(source.hashMode) || source.hashMode === "claude-plugin-manifest-v1" && source.sha256 !== null && source.path.endsWith(join28(sep8, ".claude-plugin", "plugin.json"));
35662
35808
  }
35663
35809
  function absentRetiredClaudeRoots(binding) {
35664
35810
  if (binding.agent !== "claude" || binding.method !== "reviewed")
@@ -35667,17 +35813,17 @@ function absentRetiredClaudeRoots(binding) {
35667
35813
  for (const source of binding.sources) {
35668
35814
  if (!retainableAbsentSource(source) || source.sha256 === null)
35669
35815
  continue;
35670
- const marker = sep7 + ".claude" + sep7 + "plugins" + sep7 + "cache" + sep7, at = source.path.indexOf(marker);
35816
+ const marker = sep8 + ".claude" + sep8 + "plugins" + sep8 + "cache" + sep8, at = source.path.indexOf(marker);
35671
35817
  if (at < 0 || source.path.indexOf(marker, at + 1) >= 0)
35672
35818
  continue;
35673
- const cache = source.path.slice(0, at + marker.length - 1), parts = source.path.slice(at + marker.length).split(sep7);
35819
+ const cache = source.path.slice(0, at + marker.length - 1), parts = source.path.slice(at + marker.length).split(sep8);
35674
35820
  if (parts.length < 4 || parts.slice(0, 3).some((part) => !part || part === "." || part === ".."))
35675
35821
  continue;
35676
- const root = join27(cache, ...parts.slice(0, 3));
35677
- safe4(root);
35678
- if (lstatSync19(root, { throwIfNoEntry: false }))
35822
+ const root = join28(cache, ...parts.slice(0, 3));
35823
+ safe5(root);
35824
+ if (lstatSync20(root, { throwIfNoEntry: false }))
35679
35825
  continue;
35680
- const claude = dirname17(dirname17(cache)), settings = join27(claude, "settings.json"), registry2 = join27(claude, "plugins/installed_plugins.json");
35826
+ const claude = dirname18(dirname18(cache)), settings = join28(claude, "settings.json"), registry2 = join28(claude, "plugins/installed_plugins.json");
35681
35827
  const full = (path) => binding.sources.find((item) => item.path === path && item.sha256 !== null && item.format === undefined && item.fields === undefined);
35682
35828
  const configSource = full(settings), registrySource = full(registry2);
35683
35829
  if (!configSource || !registrySource || projected(configSource) !== configSource.sha256 || projected(registrySource) !== registrySource.sha256)
@@ -35694,15 +35840,15 @@ function absentRetiredClaudeRoots(binding) {
35694
35840
  if (!row || typeof row !== "object" || Array.isArray(row))
35695
35841
  return null;
35696
35842
  const value = row;
35697
- if (typeof value.installPath !== "string" || /[\x00-\x1f\x7f]/.test(value.installPath) || !isAbsolute16(value.installPath) || resolve18(value.installPath) !== value.installPath || value.installPath.length > AGENT_POLICY_LIMITS.pathCharacters)
35843
+ if (typeof value.installPath !== "string" || /[\x00-\x1f\x7f]/.test(value.installPath) || !isAbsolute18(value.installPath) || resolve19(value.installPath) !== value.installPath || value.installPath.length > AGENT_POLICY_LIMITS.pathCharacters)
35698
35844
  return null;
35699
35845
  if (value.scope === "user")
35700
35846
  return value.projectPath === undefined || value.projectPath === null ? "user\x00" : null;
35701
35847
  if (value.scope === "project")
35702
- return typeof value.projectPath === "string" && !/[\x00-\x1f\x7f]/.test(value.projectPath) && value.projectPath.length <= AGENT_POLICY_LIMITS.pathCharacters && isAbsolute16(value.projectPath) && resolve18(value.projectPath) === value.projectPath ? `project\x00${value.projectPath}` : null;
35848
+ return typeof value.projectPath === "string" && !/[\x00-\x1f\x7f]/.test(value.projectPath) && value.projectPath.length <= AGENT_POLICY_LIMITS.pathCharacters && isAbsolute18(value.projectPath) && resolve19(value.projectPath) === value.projectPath ? `project\x00${value.projectPath}` : null;
35703
35849
  return null;
35704
35850
  };
35705
- if (Object.values(installed.plugins).some((value) => !Array.isArray(value) || value.some((row) => !row || typeof row.installPath !== "string" || row.installPath === root || row.installPath.startsWith(root + sep7) || root.startsWith(row.installPath + sep7))))
35851
+ if (Object.values(installed.plugins).some((value) => !Array.isArray(value) || value.some((row) => !row || typeof row.installPath !== "string" || row.installPath === root || row.installPath.startsWith(root + sep8) || root.startsWith(row.installPath + sep8))))
35706
35852
  continue;
35707
35853
  const rows = installed.plugins[id];
35708
35854
  if (!Array.isArray(rows) || rows.length < 1)
@@ -35720,9 +35866,9 @@ function absentRetiredClaudeRoots(binding) {
35720
35866
  if (!targetValid || !targetScopes.has("user\x00"))
35721
35867
  continue;
35722
35868
  const active = rows[0]?.installPath;
35723
- if (typeof active !== "string" || rows[0]?.version !== basename9(active) || dirname17(active) !== dirname17(root) || active === root || !lstatSync19(active, { throwIfNoEntry: false })?.isDirectory() || realpathSync6(active) !== active)
35869
+ if (typeof active !== "string" || rows[0]?.version !== basename9(active) || dirname18(active) !== dirname18(root) || active === root || !lstatSync20(active, { throwIfNoEntry: false })?.isDirectory() || realpathSync6(active) !== active)
35724
35870
  continue;
35725
- const activeManifest = full(join27(active, ".claude-plugin/plugin.json"));
35871
+ const activeManifest = full(join28(active, ".claude-plugin/plugin.json"));
35726
35872
  if (!activeManifest || projected(activeManifest) !== activeManifest.sha256)
35727
35873
  continue;
35728
35874
  result.add(root);
@@ -35738,10 +35884,10 @@ function verifyAgentDiscovery(binding, codexRecovery) {
35738
35884
  throw new Error("Hermes discovery requires directory membership coverage; run skills hook install with a fresh discovery review");
35739
35885
  const installationRoots = codexInstallationRoots(binding);
35740
35886
  const retiredRoots = retiredCodexRoots(binding);
35741
- const installationInput = (path) => installationRoots.some((root) => path === root || path.startsWith(root + sep7));
35887
+ const installationInput = (path) => installationRoots.some((root) => path === root || path.startsWith(root + sep8));
35742
35888
  if (binding.directories !== undefined) {
35743
35889
  const projected2 = binding.codexInstallationInputs?.directories ?? [];
35744
- const ancestors2 = binding.directories.filter((directory) => installationRoots.some((root) => root.startsWith(directory.path + sep7)));
35890
+ const ancestors2 = binding.directories.filter((directory) => installationRoots.some((root) => root.startsWith(directory.path + sep8)));
35745
35891
  if (projected2.length !== ancestors2.length || projected2.some((directory) => !ancestors2.some((original) => original.path === directory.path)))
35746
35892
  throw new Error("Missing installation input directory projection");
35747
35893
  const ordinary = binding.directories.filter((directory) => !installationInput(directory.path) && !ancestors2.includes(directory));
@@ -35749,7 +35895,7 @@ function verifyAgentDiscovery(binding, codexRecovery) {
35749
35895
  const projection = binding.codexRetiredMaterializations.directories;
35750
35896
  if (projection.length !== ordinary.length || projection.some((item, index) => item.path !== ordinary[index]?.path))
35751
35897
  throw new Error("Missing retired Codex directory projection");
35752
- const omitted = [...retiredRoots, ...(binding.codexRetiredMaterializations.parents ?? []).filter((parent) => !lstatSync19(parent, { throwIfNoEntry: false }))];
35898
+ const omitted = [...retiredRoots, ...(binding.codexRetiredMaterializations.parents ?? []).filter((parent) => !lstatSync20(parent, { throwIfNoEntry: false }))];
35753
35899
  if (projection.every((item) => Array.isArray(item.entries)))
35754
35900
  verifyDiscoveryDirectoryProjection(projection, omitted);
35755
35901
  else {
@@ -35763,7 +35909,7 @@ function verifyAgentDiscovery(binding, codexRecovery) {
35763
35909
  verifyDiscoveryDirectories(ordinary);
35764
35910
  verifyDiscoveryDirectories(projected2, installationRoots);
35765
35911
  }
35766
- const absentRoots = [...absentCodexSkillRoots(binding), ...absentRetiredClaudeRoots(binding), ...retiredRoots.filter((root) => !lstatSync19(root, { throwIfNoEntry: false }))];
35912
+ const absentRoots = [...absentCodexSkillRoots(binding), ...absentRetiredClaudeRoots(binding), ...retiredRoots.filter((root) => !lstatSync20(root, { throwIfNoEntry: false }))];
35767
35913
  const budget2 = discoveryByteBudget();
35768
35914
  for (const source of binding.sources) {
35769
35915
  assertMarketplaceBinding(binding, source);
@@ -35774,11 +35920,11 @@ function verifyAgentDiscovery(binding, codexRecovery) {
35774
35920
  if (source.sha256 !== null && !/^[a-f0-9]{64}$/.test(source.sha256))
35775
35921
  throw new Error("Invalid native discovery digest");
35776
35922
  if (installationInput(source.path)) {
35777
- safe4(source.path);
35923
+ safe5(source.path);
35778
35924
  continue;
35779
35925
  }
35780
- if (absentRoots.some((root) => source.path.startsWith(root + sep7)) && retainableAbsentSource(source)) {
35781
- safe4(source.path);
35926
+ if (absentRoots.some((root) => source.path.startsWith(root + sep8)) && retainableAbsentSource(source)) {
35927
+ safe5(source.path);
35782
35928
  continue;
35783
35929
  }
35784
35930
  const current = projected(source, undefined, budget2);
@@ -35786,10 +35932,10 @@ function verifyAgentDiscovery(binding, codexRecovery) {
35786
35932
  throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
35787
35933
  }
35788
35934
  for (const root of binding.roots)
35789
- safe4(root);
35935
+ safe5(root);
35790
35936
  for (const root of absentRoots) {
35791
- safe4(root);
35792
- if (lstatSync19(root, { throwIfNoEntry: false }))
35937
+ safe5(root);
35938
+ if (lstatSync20(root, { throwIfNoEntry: false }))
35793
35939
  throw new Error("Retired native materialization changed during discovery verification");
35794
35940
  }
35795
35941
  }
@@ -35799,13 +35945,13 @@ function codexInstallationRoots(binding) {
35799
35945
  return [];
35800
35946
  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)
35801
35947
  throw new Error("Invalid native installation input proof");
35802
- const cache = dirname17(dirname17(proof.plugins[0].pluginParent));
35803
- const config2 = join27(dirname17(dirname17(cache)), "config.toml"), home = dirname17(dirname17(dirname17(cache)));
35948
+ const cache = dirname18(dirname18(proof.plugins[0].pluginParent));
35949
+ const config2 = join28(dirname18(dirname18(cache)), "config.toml"), home = dirname18(dirname18(dirname18(cache)));
35804
35950
  const configSource = binding.sources.find((source) => source.path === config2 && source.sha256 !== null && (!source.format || source.format === "toml" && source.fields?.includes("plugins")));
35805
- const nativeRoots = NATIVE_SKILL_ROOTS.filter(([agent]) => agent === "codex").map(([, path]) => join27(home, path));
35806
- if (!configSource || proof.plugins.some((input2) => nativeRoots.some((root) => root === input2.sourceRoot || root.startsWith(input2.sourceRoot + sep7) || input2.sourceRoot.startsWith(root + sep7)) || binding.sources.some((source) => basename9(source.path) === "config.toml" && (source.path === input2.sourceRoot || source.path.startsWith(input2.sourceRoot + sep7)))))
35951
+ const nativeRoots = NATIVE_SKILL_ROOTS.filter(([agent]) => agent === "codex").map(([, path]) => join28(home, path));
35952
+ if (!configSource || proof.plugins.some((input2) => nativeRoots.some((root) => root === input2.sourceRoot || root.startsWith(input2.sourceRoot + sep8) || input2.sourceRoot.startsWith(root + sep8)) || binding.sources.some((source) => basename9(source.path) === "config.toml" && (source.path === input2.sourceRoot || source.path.startsWith(input2.sourceRoot + sep8)))))
35807
35953
  throw new Error("Native installation input overlaps configuration or loading roots");
35808
- if (proof.plugins.some((input2) => dirname17(dirname17(input2.pluginParent)) !== cache || !binding.sources.some((source) => source.path === join27(input2.sourceRoot, ".codex-plugin/plugin.json") && source.sha256 !== null && source.format === undefined && source.fields === undefined)))
35954
+ if (proof.plugins.some((input2) => dirname18(dirname18(input2.pluginParent)) !== cache || !binding.sources.some((source) => source.path === join28(input2.sourceRoot, ".codex-plugin/plugin.json") && source.sha256 !== null && source.format === undefined && source.fields === undefined)))
35809
35955
  throw new Error("Missing native installation input source witness");
35810
35956
  return reviewedCodexPluginSourceRoots(cache, proof.plugins, (path) => {
35811
35957
  const text2 = read(path);
@@ -35815,7 +35961,7 @@ function codexInstallationRoots(binding) {
35815
35961
  });
35816
35962
  }
35817
35963
  function assertMarketplaceBinding(binding, source) {
35818
- if (source.hashMode === "claude-plugin-manifest-v1" && (binding.agent !== "claude" || basename9(source.path) !== "plugin.json" || !source.path.endsWith(join27(sep7, ".claude-plugin", "plugin.json"))))
35964
+ if (source.hashMode === "claude-plugin-manifest-v1" && (binding.agent !== "claude" || basename9(source.path) !== "plugin.json" || !source.path.endsWith(join28(sep8, ".claude-plugin", "plugin.json"))))
35819
35965
  throw new Error("Claude plugin manifest witnesses require Claude plugin discovery");
35820
35966
  if (source.hashMode === "sumi-settings-v1" && (binding.agent !== "sumi" || binding.method !== "reviewed" || basename9(source.path) !== "sumi.json"))
35821
35967
  throw new Error("Sumi settings witnesses require explicit reviewed Sumi configuration");
@@ -35831,10 +35977,10 @@ function assertMarketplaceBinding(binding, source) {
35831
35977
  function agentDiscoveryConfigPath(home, agent) {
35832
35978
  if (agent === "sumi")
35833
35979
  return sumiConfigPath(home);
35834
- return join27(home, agent === "hermes" ? ".hermes/config.yaml" : agent === "opencode" ? ".config/opencode/opencode.json" : `.${agent}/${agent === "codex" ? "config.toml" : agent === "cursor" ? "hooks.json" : "settings.json"}`);
35980
+ return join28(home, agent === "hermes" ? ".hermes/config.yaml" : agent === "opencode" ? ".config/opencode/opencode.json" : `.${agent}/${agent === "codex" ? "config.toml" : agent === "cursor" ? "hooks.json" : "settings.json"}`);
35835
35981
  }
35836
35982
  function resolveAgentDiscovery(options) {
35837
- const canonical8 = options.canonical ?? resolve18, home = resolve18(options.home), agent = options.agent;
35983
+ const canonical8 = options.canonical ?? resolve19, home = resolve19(options.home), agent = options.agent;
35838
35984
  const sources = [], roots = new Set, builtinNames = [];
35839
35985
  const witness = (path, format, fields2, hashMode) => {
35840
35986
  const source = { path: canonical8(path), sha256: null, ...format ? { format, fields: fields2 } : {}, ...hashMode ? { hashMode } : {} };
@@ -35855,42 +36001,42 @@ function resolveAgentDiscovery(options) {
35855
36001
  const review = options.reviewed?.agents.find((item) => item.agent === agent);
35856
36002
  if (agent === "sumi") {
35857
36003
  const directory = sumiConfigDirectory(home);
35858
- if (witness(join27(directory, "sumi.jsonc")) !== null)
36004
+ if (witness(join28(directory, "sumi.jsonc")) !== null)
35859
36005
  unresolved("JSONC configuration requires a supported format adapter");
35860
- for (const root of [directory, join27(home, ".claude"), join27(home, ".agents")])
36006
+ for (const root of [directory, join28(home, ".claude"), join28(home, ".agents")])
35861
36007
  for (const name of ["skill", "skills"])
35862
- roots.add(canonical8(join27(root, name)));
36008
+ roots.add(canonical8(join28(root, name)));
35863
36009
  if (config2.skills !== undefined && (!Array.isArray(config2.skills) || config2.skills.some((path) => typeof path !== "string")))
35864
36010
  unresolved("skills must be a string array");
35865
36011
  for (const value of config2.skills ?? []) {
35866
- if (typeof value !== "string" || /[\0$]/.test(value) || !value || !(isAbsolute16(value) || value.startsWith("~/")))
36012
+ if (typeof value !== "string" || /[\0$]/.test(value) || !value || !(isAbsolute18(value) || value.startsWith("~/")))
35867
36013
  unresolved("remote or relative skill sources need a dedicated discovery adapter");
35868
- roots.add(canonical8(value.startsWith("~/") ? join27(home, value.slice(2)) : value));
36014
+ roots.add(canonical8(value.startsWith("~/") ? join28(home, value.slice(2)) : value));
35869
36015
  }
35870
36016
  for (const key of ["plugin", "plugins"])
35871
36017
  if (config2[key] !== undefined && !Array.isArray(config2[key]))
35872
36018
  unresolved(`${key} must be an array`);
35873
- const plugins = [join27(directory, "plugin"), join27(directory, "plugins")];
36019
+ const plugins = [join28(directory, "plugin"), join28(directory, "plugins")];
35874
36020
  for (const path of plugins) {
35875
- safe4(path);
35876
- if (lstatSync19(path, { throwIfNoEntry: false })?.isDirectory())
36021
+ safe5(path);
36022
+ if (lstatSync20(path, { throwIfNoEntry: false })?.isDirectory())
35877
36023
  for (const name of readdirSync7(path).sort()) {
35878
36024
  if (name === "skills-cli.js" && path === plugins[1])
35879
36025
  continue;
35880
- const target = join27(path, name);
35881
- if (!lstatSync19(target).isFile())
36026
+ const target = join28(path, name);
36027
+ if (!lstatSync20(target).isFile())
35882
36028
  unresolved("local plugin packages need a dedicated discovery adapter");
35883
36029
  witness(target);
35884
36030
  }
35885
36031
  }
35886
36032
  for (const root of roots) {
35887
- safe4(root);
35888
- if (lstatSync19(root, { throwIfNoEntry: false })?.isDirectory() && readdirSync7(root).some((name) => name.endsWith(".md")))
36033
+ safe5(root);
36034
+ if (lstatSync20(root, { throwIfNoEntry: false })?.isDirectory() && readdirSync7(root).some((name) => name.endsWith(".md")))
35889
36035
  unresolved("flat markdown skills require a dedicated native migration adapter");
35890
36036
  }
35891
36037
  }
35892
36038
  if (agent === "hermes") {
35893
- const profile = witness(join27(home, ".hermes/active_profile"));
36039
+ const profile = witness(join28(home, ".hermes/active_profile"));
35894
36040
  if (profile?.trim() && profile.trim() !== "default")
35895
36041
  unresolved("a non-default profile is active");
35896
36042
  const declared = config2.skills?.external_dirs ?? [], paths = typeof declared === "string" ? [declared] : declared;
@@ -35904,8 +36050,8 @@ function resolveAgentDiscovery(options) {
35904
36050
  continue;
35905
36051
  if (normalized.startsWith("~") && normalized !== "~" && !normalized.startsWith("~/"))
35906
36052
  unresolved("user-specific tilde expansion requires a separate discovery adapter");
35907
- const path = normalized === "~" ? home : normalized.startsWith("~/") ? join27(home, normalized.slice(2)) : resolve18(home, ".hermes", normalized);
35908
- safe4(path);
36053
+ const path = normalized === "~" ? home : normalized.startsWith("~/") ? join28(home, normalized.slice(2)) : resolve19(home, ".hermes", normalized);
36054
+ safe5(path);
35909
36055
  roots.add(path);
35910
36056
  }
35911
36057
  }
@@ -35913,24 +36059,24 @@ function resolveAgentDiscovery(options) {
35913
36059
  const executable = options.executable === undefined ? discoveryExecutable(agent) : options.executable;
35914
36060
  if (executable) {
35915
36061
  let packageRoot;
35916
- for (let directory = dirname17(executable.target), depth = 0;depth < 8; directory = dirname17(directory), depth++) {
35917
- const path = join27(directory, "package.json"), raw = read(path);
36062
+ for (let directory = dirname18(executable.target), depth = 0;depth < 8; directory = dirname18(directory), depth++) {
36063
+ const path = join28(directory, "package.json"), raw = read(path);
35918
36064
  if (raw !== null && parseConfig(raw, path).name === "@google/gemini-cli") {
35919
36065
  packageRoot = directory;
35920
36066
  witness(path);
35921
36067
  break;
35922
36068
  }
35923
- if (dirname17(directory) === directory)
36069
+ if (dirname18(directory) === directory)
35924
36070
  break;
35925
36071
  }
35926
36072
  if (!packageRoot)
35927
36073
  unresolved("installed Gemini package layout is not recognized");
35928
- const builtinRoot = join27(packageRoot, "bundle/builtin");
35929
- safe4(builtinRoot);
35930
- if (!lstatSync19(builtinRoot, { throwIfNoEntry: false })?.isDirectory())
36074
+ const builtinRoot = join28(packageRoot, "bundle/builtin");
36075
+ safe5(builtinRoot);
36076
+ if (!lstatSync20(builtinRoot, { throwIfNoEntry: false })?.isDirectory())
35931
36077
  unresolved("installed Gemini builtin root is missing");
35932
36078
  for (const name of readdirSync7(builtinRoot).sort()) {
35933
- const text2 = witness(join27(builtinRoot, name, "SKILL.md"));
36079
+ const text2 = witness(join28(builtinRoot, name, "SKILL.md"));
35934
36080
  const match = text2?.match(/^---\r?\n[\s\S]*?^name:\s*([a-z0-9][a-z0-9-]*)\s*$/m);
35935
36081
  if (!match?.[1] || builtinNames.includes(match[1]))
35936
36082
  unresolved("installed Gemini builtin name is missing or ambiguous");
@@ -35965,10 +36111,10 @@ function resolveAgentDiscovery(options) {
35965
36111
  throw new Error("Discovery review must include the agent configuration source");
35966
36112
  const reviewedSources = supersedesSettingsProjection(agent, review.sources, canonical8(configPath)) ? sources.filter((source) => !isSupersededSettingsProjection(agent, canonical8(configPath), source)) : sources;
35967
36113
  const reviewedSourcesWithManifestProjection = review.sources.map((source) => {
35968
- 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(join27(sep7, ".claude-plugin", "plugin.json")))
36114
+ 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(join28(sep8, ".claude-plugin", "plugin.json")))
35969
36115
  return source;
35970
- const pluginRoot = dirname17(dirname17(source.path)), hooksPath = join27(pluginRoot, "hooks/hooks.json");
35971
- const hookStat = lstatSync19(hooksPath, { throwIfNoEntry: false });
36116
+ const pluginRoot = dirname18(dirname18(source.path)), hooksPath = join28(pluginRoot, "hooks/hooks.json");
36117
+ const hookStat = lstatSync20(hooksPath, { throwIfNoEntry: false });
35972
36118
  const text2 = read(source.path);
35973
36119
  if (text2 === null)
35974
36120
  throw new Error("Reviewed Claude plugin manifest is missing");
@@ -35982,8 +36128,8 @@ function resolveAgentDiscovery(options) {
35982
36128
  if (manifest.hooks !== undefined) {
35983
36129
  if (typeof manifest.hooks !== "string")
35984
36130
  throw new Error("Reviewed Claude plugin manifest has an unsupported hooks target");
35985
- const declaredHookPath = resolve18(pluginRoot, manifest.hooks);
35986
- if (!declaredHookPath.startsWith(pluginRoot + sep7))
36131
+ const declaredHookPath = resolve19(pluginRoot, manifest.hooks);
36132
+ if (!declaredHookPath.startsWith(pluginRoot + sep8))
35987
36133
  throw new Error("Reviewed Claude plugin hooks target escapes its root");
35988
36134
  reviewedHookPaths.add(declaredHookPath);
35989
36135
  }
@@ -36000,40 +36146,40 @@ function resolveAgentDiscovery(options) {
36000
36146
  }
36001
36147
  function plugin(root) {
36002
36148
  root = canonical8(root);
36003
- safe4(root);
36004
- const manifestPath = join27(root, agent === "claude" ? ".claude-plugin/plugin.json" : ".codex-plugin/plugin.json");
36149
+ safe5(root);
36150
+ const manifestPath = join28(root, agent === "claude" ? ".claude-plugin/plugin.json" : ".codex-plugin/plugin.json");
36005
36151
  const raw = witness(manifestPath, undefined, undefined, agent === "claude" ? "claude-plugin-manifest-v1" : undefined);
36006
36152
  if (raw === null)
36007
36153
  unresolved("plugin manifest missing");
36008
36154
  const manifest = parseConfig(raw, manifestPath);
36009
- const hooks = witness(join27(root, "hooks/hooks.json"));
36155
+ const hooks = witness(join28(root, "hooks/hooks.json"));
36010
36156
  if (manifest.hooks !== undefined || hooks !== null)
36011
36157
  unresolved("plugin hooks require a separate no-skill-injection review");
36012
- const commands = join27(root, "commands");
36013
- safe4(commands);
36014
- if (agent === "claude" && (manifest.commands !== undefined || lstatSync19(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync7(commands).length))
36158
+ const commands = join28(root, "commands");
36159
+ safe5(commands);
36160
+ if (agent === "claude" && (manifest.commands !== undefined || lstatSync20(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync7(commands).length))
36015
36161
  unresolved("legacy command discovery requires retirement or a dedicated format adapter");
36016
- const rootSkill = witness(join27(root, "SKILL.md"));
36162
+ const rootSkill = witness(join28(root, "SKILL.md"));
36017
36163
  if (rootSkill !== null)
36018
36164
  roots.add(root);
36019
36165
  const declared = manifest.skills === undefined ? ["./skills"] : typeof manifest.skills === "string" ? [manifest.skills] : manifest.skills;
36020
36166
  if (!Array.isArray(declared) || declared.some((path) => typeof path !== "string"))
36021
36167
  unresolved("unsupported plugin skill paths");
36022
36168
  if (agent === "claude")
36023
- roots.add(join27(root, "skills"));
36169
+ roots.add(join28(root, "skills"));
36024
36170
  for (const value of declared) {
36025
- const path = resolve18(root, value);
36026
- if (path !== root && !path.startsWith(root + sep7))
36171
+ const path = resolve19(root, value);
36172
+ if (path !== root && !path.startsWith(root + sep8))
36027
36173
  unresolved("plugin skill path escapes its root");
36028
- roots.add(path.endsWith(`${sep7}SKILL.md`) ? dirname17(path) : path);
36174
+ roots.add(path.endsWith(`${sep8}SKILL.md`) ? dirname18(path) : path);
36029
36175
  }
36030
36176
  }
36031
36177
  if (agent === "claude") {
36032
- const registrations = witness(join27(home, ".claude/plugins/installed_plugins.json"));
36033
- const installed = registrations === null ? {} : parseConfig(registrations, join27(home, ".claude/plugins/installed_plugins.json")).plugins;
36034
- const commands = canonical8(join27(home, ".claude/commands"));
36035
- safe4(commands);
36036
- if (lstatSync19(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync7(commands).length)
36178
+ const registrations = witness(join28(home, ".claude/plugins/installed_plugins.json"));
36179
+ const installed = registrations === null ? {} : parseConfig(registrations, join28(home, ".claude/plugins/installed_plugins.json")).plugins;
36180
+ const commands = canonical8(join28(home, ".claude/commands"));
36181
+ safe5(commands);
36182
+ if (lstatSync20(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync7(commands).length)
36037
36183
  unresolved("legacy home command discovery requires a dedicated format adapter");
36038
36184
  for (const [id, enabled] of Object.entries(config2.enabledPlugins ?? {})) {
36039
36185
  if (enabled === false)
@@ -36053,37 +36199,37 @@ function resolveAgentDiscovery(options) {
36053
36199
  unresolved("unsupported plugin enablement");
36054
36200
  const split = id.lastIndexOf("@"), name = id.slice(0, split), marketplace = id.slice(split + 1);
36055
36201
  const market = config2.marketplaces?.[marketplace] ?? (marketplace === "personal" ? { source_type: "local", source: home } : undefined);
36056
- if (split < 1 || market?.source_type !== "local" || typeof market.source !== "string" || !isAbsolute16(market.source))
36202
+ if (split < 1 || market?.source_type !== "local" || typeof market.source !== "string" || !isAbsolute18(market.source))
36057
36203
  unresolved("enabled plugin marketplace is not an explicit local source");
36058
- const catalogText = witness(join27(market.source, ".agents/plugins/marketplace.json"));
36204
+ const catalogText = witness(join28(market.source, ".agents/plugins/marketplace.json"));
36059
36205
  if (catalogText === null)
36060
36206
  unresolved("marketplace catalog missing");
36061
- const catalog = parseConfig(catalogText, join27(market.source, ".agents/plugins/marketplace.json")), matches = Array.isArray(catalog.plugins) ? catalog.plugins.filter((item) => item.name === name) : [];
36207
+ const catalog = parseConfig(catalogText, join28(market.source, ".agents/plugins/marketplace.json")), matches = Array.isArray(catalog.plugins) ? catalog.plugins.filter((item) => item.name === name) : [];
36062
36208
  if (matches.length !== 1 || matches[0]?.source?.source !== "local" || typeof matches[0]?.source?.path !== "string")
36063
36209
  unresolved("plugin catalog source is missing or ambiguous");
36064
- plugin(resolve18(market.source, matches[0].source.path));
36210
+ plugin(resolve19(market.source, matches[0].source.path));
36065
36211
  }
36066
36212
  } else if (agent === "opencode") {
36067
- if (witness(join27(home, ".config/opencode/opencode.jsonc")) !== null || witness(join27(home, ".config/opencode/config.json")) !== null)
36213
+ if (witness(join28(home, ".config/opencode/opencode.jsonc")) !== null || witness(join28(home, ".config/opencode/config.json")) !== null)
36068
36214
  unresolved("additional config layers require review");
36069
36215
  if ((config2.plugin?.length ?? 0) > 0 || config2.skills?.urls?.length)
36070
36216
  unresolved("external plugin or remote skill source");
36071
36217
  for (const path of config2.skills?.paths ?? []) {
36072
- if (typeof path !== "string" || !isAbsolute16(path))
36218
+ if (typeof path !== "string" || !isAbsolute18(path))
36073
36219
  unresolved("relative or malformed added skill root");
36074
36220
  roots.add(path);
36075
36221
  }
36076
- const localPlugins = join27(home, ".config/opencode/plugins");
36077
- safe4(localPlugins);
36078
- if (lstatSync19(localPlugins, { throwIfNoEntry: false }) && readdirSync7(localPlugins).some((name) => name !== "skills-cli.js"))
36222
+ const localPlugins = join28(home, ".config/opencode/plugins");
36223
+ safe5(localPlugins);
36224
+ if (lstatSync20(localPlugins, { throwIfNoEntry: false }) && readdirSync7(localPlugins).some((name) => name !== "skills-cli.js"))
36079
36225
  unresolved("additional local plugin hooks require review");
36080
36226
  } else if (agent === "sumi") {
36081
- if ((config2.plugin?.length ?? 0) > 0 || (config2.plugins?.length ?? 0) > 0 || sources.some((source) => source.path !== canonical8(configPath) && source.path !== canonical8(join27(sumiConfigDirectory(home), "sumi.jsonc")) && source.sha256 !== null))
36227
+ if ((config2.plugin?.length ?? 0) > 0 || (config2.plugins?.length ?? 0) > 0 || sources.some((source) => source.path !== canonical8(configPath) && source.path !== canonical8(join28(sumiConfigDirectory(home), "sumi.jsonc")) && source.sha256 !== null))
36082
36228
  unresolved("external or foreign local plugins require review");
36083
36229
  } else if (agent === "hermes") {
36084
- for (const directory of [join27(home, ".hermes/plugins"), join27(home, ".hermes/hermes-agent")]) {
36085
- safe4(directory);
36086
- if (lstatSync19(directory, { throwIfNoEntry: false }))
36230
+ for (const directory of [join28(home, ".hermes/plugins"), join28(home, ".hermes/hermes-agent")]) {
36231
+ safe5(directory);
36232
+ if (lstatSync20(directory, { throwIfNoEntry: false }))
36087
36233
  unresolved("installed runtime/plugin discovery requires reviewed source bindings");
36088
36234
  }
36089
36235
  if (Bun.which("hermes") || Object.keys(config2.plugins ?? {}).length)
@@ -36091,24 +36237,24 @@ function resolveAgentDiscovery(options) {
36091
36237
  } else if (agent === "gemini") {
36092
36238
  if (Object.keys(config2.extensions ?? {}).length || config2.skills?.paths?.length)
36093
36239
  unresolved("custom extension or skill paths");
36094
- const directory = join27(home, ".gemini/extensions");
36095
- safe4(directory);
36096
- if (lstatSync19(directory, { throwIfNoEntry: false }))
36240
+ const directory = join28(home, ".gemini/extensions");
36241
+ safe5(directory);
36242
+ if (lstatSync20(directory, { throwIfNoEntry: false }))
36097
36243
  for (const name of readdirSync7(directory)) {
36098
- const root = join27(directory, name);
36099
- safe4(root);
36100
- if (!lstatSync19(root)?.isDirectory())
36244
+ const root = join28(directory, name);
36245
+ safe5(root);
36246
+ if (!lstatSync20(root)?.isDirectory())
36101
36247
  continue;
36102
- const raw = witness(join27(root, "gemini-extension.json"));
36248
+ const raw = witness(join28(root, "gemini-extension.json"));
36103
36249
  if (raw === null)
36104
36250
  unresolved("extension registration missing");
36105
- const manifest = parseConfig(raw, join27(root, "gemini-extension.json"));
36106
- if (manifest.hooks !== undefined || witness(join27(root, "hooks/hooks.json")) !== null || witness(join27(root, ".gemini-extension-install.json")) !== null)
36251
+ const manifest = parseConfig(raw, join28(root, "gemini-extension.json"));
36252
+ if (manifest.hooks !== undefined || witness(join28(root, "hooks/hooks.json")) !== null || witness(join28(root, ".gemini-extension-install.json")) !== null)
36107
36253
  unresolved("extension hooks or linked registration require review");
36108
- roots.add(join27(root, "skills"));
36254
+ roots.add(join28(root, "skills"));
36109
36255
  }
36110
36256
  }
36111
- return { agent, roots: [...roots].sort(), sources, method: "automatic", ...agent === "gemini" ? { builtinNames } : {}, ...agent === "hermes" ? { directories: captureDiscoveryDirectories([join27(home, ".hermes/plugins"), join27(home, ".hermes/hermes-agent")].map((path) => canonical8(path))) } : {} };
36257
+ return { agent, roots: [...roots].sort(), sources, method: "automatic", ...agent === "gemini" ? { builtinNames } : {}, ...agent === "hermes" ? { directories: captureDiscoveryDirectories([join28(home, ".hermes/plugins"), join28(home, ".hermes/hermes-agent")].map((path) => canonical8(path))) } : {} };
36112
36258
  }
36113
36259
  var DISCOVERY_RUNTIME_COMMANDS, realpathOrNull = (path) => {
36114
36260
  try {
@@ -36116,7 +36262,7 @@ var DISCOVERY_RUNTIME_COMMANDS, realpathOrNull = (path) => {
36116
36262
  } catch {
36117
36263
  return null;
36118
36264
  }
36119
- }, digest = (text2) => createHash19("sha256").update(text2).digest("hex");
36265
+ }, digest = (text2) => createHash20("sha256").update(text2).digest("hex");
36120
36266
  var init_agent_discovery = __esm(() => {
36121
36267
  init_sumi_settings_witness();
36122
36268
  init_agent_policy_limits();
@@ -36136,16 +36282,17 @@ var init_agent_discovery = __esm(() => {
36136
36282
  init_agent_sumi();
36137
36283
  init_native_discovery_roots();
36138
36284
  init_codex_native_compatibility();
36285
+ init_retained_review_artifacts();
36139
36286
  init_agent_discovery_directories();
36140
36287
  DISCOVERY_RUNTIME_COMMANDS = Object.freeze({ gemini: "gemini" });
36141
36288
  });
36142
36289
 
36143
36290
  // src/lib/authoring-path.ts
36144
- import { lstatSync as lstatSync20, realpathSync as realpathSync7 } from "fs";
36291
+ import { lstatSync as lstatSync21, realpathSync as realpathSync7 } from "fs";
36145
36292
  import { homedir as homedir3 } from "os";
36146
- import { basename as basename10, dirname as dirname18, join as join28, resolve as resolve19, sep as sep8 } from "path";
36293
+ import { basename as basename10, dirname as dirname19, join as join29, resolve as resolve20, sep as sep9 } from "path";
36147
36294
  function pathParts(path) {
36148
- return resolve19(path).split(sep8).filter(Boolean);
36295
+ return resolve20(path).split(sep9).filter(Boolean);
36149
36296
  }
36150
36297
  function nativeRootMatch(path) {
36151
36298
  const parts = pathParts(path);
@@ -36159,24 +36306,24 @@ function nativeRootMatch(path) {
36159
36306
  return;
36160
36307
  }
36161
36308
  function physicalPath(path) {
36162
- let cursor = resolve19(path);
36309
+ let cursor = resolve20(path);
36163
36310
  const suffix = [];
36164
- while (!lstatSync20(cursor, { throwIfNoEntry: false })) {
36311
+ while (!lstatSync21(cursor, { throwIfNoEntry: false })) {
36165
36312
  suffix.unshift(basename10(cursor));
36166
- const parent = dirname18(cursor);
36313
+ const parent = dirname19(cursor);
36167
36314
  if (parent === cursor)
36168
- return resolve19(path);
36315
+ return resolve20(path);
36169
36316
  cursor = parent;
36170
36317
  }
36171
- return resolve19(realpathSync7(cursor), ...suffix);
36318
+ return resolve20(realpathSync7(cursor), ...suffix);
36172
36319
  }
36173
36320
  function contains(root, path) {
36174
- return path === root || path.startsWith(root + sep8);
36321
+ return path === root || path.startsWith(root + sep9);
36175
36322
  }
36176
36323
  function configuredRoots(home, explicitHome) {
36177
- const homeData = join28(home, ".hasna", "skills");
36324
+ const homeData = join29(home, ".hasna", "skills");
36178
36325
  const homePolicy = readManagedSkillPolicySnapshot(homeData);
36179
- const configuredPolicy = !explicitHome && resolve19(getDataDirReadOnly()) !== resolve19(homeData) ? readManagedSkillPolicySnapshot(getDataDirReadOnly()) : null;
36326
+ const configuredPolicy = !explicitHome && resolve20(getDataDirReadOnly()) !== resolve20(homeData) ? readManagedSkillPolicySnapshot(getDataDirReadOnly()) : null;
36180
36327
  const policy = homePolicy ?? configuredPolicy;
36181
36328
  const bridge = policy?.value.bridge;
36182
36329
  if (bridge && (typeof bridge.home !== "string" || physicalPath(bridge.home) !== physicalPath(home))) {
@@ -36205,8 +36352,8 @@ function configuredRoots(home, explicitHome) {
36205
36352
  admitBinding(binding);
36206
36353
  continue;
36207
36354
  }
36208
- const nativeHome = join28(home, agent === "opencode" ? ".config/opencode" : `.${agent}`);
36209
- if (!lstatSync20(nativeHome, { throwIfNoEntry: false }))
36355
+ const nativeHome = join29(home, agent === "opencode" ? ".config/opencode" : `.${agent}`);
36356
+ if (!lstatSync21(nativeHome, { throwIfNoEntry: false }))
36210
36357
  continue;
36211
36358
  roots.push(...resolveAgentDiscovery({ home, agent, canonical: physicalPath }).roots);
36212
36359
  }
@@ -36215,22 +36362,22 @@ function configuredRoots(home, explicitHome) {
36215
36362
  function assertPortableAuthoringPath(path, options = {}) {
36216
36363
  if (typeof path !== "string" || !path || path.includes("\x00"))
36217
36364
  throw new Error("Invalid portable authoring path");
36218
- const lexical = resolve19(path);
36365
+ const lexical = resolve20(path);
36219
36366
  const physical = physicalPath(lexical);
36220
36367
  const candidates = [lexical, physical];
36221
36368
  let native = candidates.map(nativeRootMatch).find(Boolean);
36222
- const home = resolve19(options.homeDir ?? homedir3());
36223
- const defaults = NATIVE_DISCOVERY_ROOTS.map((parts) => join28(home, ...parts));
36224
- defaults.push(join28(home, ".codex/plugins/cache"), join28(home, ".claude/plugins/cache"), join28(home, ".claude/plugins/synced"), join28(home, ".gemini/extensions"));
36369
+ const home = resolve20(options.homeDir ?? homedir3());
36370
+ const defaults = NATIVE_DISCOVERY_ROOTS.map((parts) => join29(home, ...parts));
36371
+ defaults.push(join29(home, ".codex/plugins/cache"), join29(home, ".claude/plugins/cache"), join29(home, ".claude/plugins/synced"), join29(home, ".gemini/extensions"));
36225
36372
  for (const root of defaults) {
36226
- if (candidates.some((candidate) => contains(resolve19(root), candidate) || contains(physicalPath(root), candidate)))
36373
+ if (candidates.some((candidate) => contains(resolve20(root), candidate) || contains(physicalPath(root), candidate)))
36227
36374
  native ??= root;
36228
36375
  }
36229
36376
  if (native) {
36230
36377
  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.`);
36231
36378
  }
36232
36379
  for (const root of configuredRoots(home, options.homeDir !== undefined)) {
36233
- if (candidates.some((candidate) => contains(resolve19(root), candidate) || contains(physicalPath(root), candidate))) {
36380
+ if (candidates.some((candidate) => contains(resolve20(root), candidate) || contains(physicalPath(root), candidate))) {
36234
36381
  throw new Error(`Refusing portable Skills authoring below configured native discovery root: ${lexical}`);
36235
36382
  }
36236
36383
  }
@@ -36248,7 +36395,7 @@ var init_authoring_path = __esm(() => {
36248
36395
  // src/lib/portable-skills.ts
36249
36396
  import {
36250
36397
  existsSync as existsSync12,
36251
- mkdirSync as mkdirSync7,
36398
+ mkdirSync as mkdirSync8,
36252
36399
  mkdtempSync,
36253
36400
  readdirSync as readdirSync8,
36254
36401
  realpathSync as realpathSync8,
@@ -36257,22 +36404,22 @@ import {
36257
36404
  statSync as statSync8,
36258
36405
  writeFileSync as writeFileSync6
36259
36406
  } from "fs";
36260
- import { basename as basename11, dirname as dirname19, isAbsolute as isAbsolute17, join as join29, normalize as normalize3, relative as relative6, resolve as resolve20, sep as sep9 } from "path";
36407
+ import { basename as basename11, dirname as dirname20, isAbsolute as isAbsolute19, join as join30, normalize as normalize4, relative as relative6, resolve as resolve21, sep as sep10 } from "path";
36261
36408
  function getPortableSkillsRoot(options = {}) {
36262
36409
  return resolvePortableSkillsRoot(options, true);
36263
36410
  }
36264
36411
  function resolvePortableSkillsRoot(options, migrate) {
36265
36412
  if (options.rootDir)
36266
36413
  return options.rootDir;
36267
- const appDir = options.homeDir ? join29(options.homeDir, ".hasna", "skills") : migrate ? getDataDir() : getDataDirReadOnly();
36268
- const cache = join29(appDir, SKILLS_CACHE_DIRNAME);
36414
+ const appDir = options.homeDir ? join30(options.homeDir, ".hasna", "skills") : migrate ? getDataDir() : getDataDirReadOnly();
36415
+ const cache = join30(appDir, SKILLS_CACHE_DIRNAME);
36269
36416
  if (isOwnerLayoutMigrated(appDir) && safeIsDirectory(cache))
36270
36417
  return cache;
36271
- const installed = join29(appDir, INSTALLED_SKILLS_DIRNAME);
36418
+ const installed = join30(appDir, INSTALLED_SKILLS_DIRNAME);
36272
36419
  return installed;
36273
36420
  }
36274
36421
  function getPortableSkillPath(name, options = {}) {
36275
- return join29(getPortableSkillsRoot(options), normalizePortableSkillName(name));
36422
+ return join30(getPortableSkillsRoot(options), normalizePortableSkillName(name));
36276
36423
  }
36277
36424
  function findPortableSkill(name, options = {}) {
36278
36425
  let normalized;
@@ -36298,7 +36445,7 @@ function listPortableSkills(options = {}) {
36298
36445
  for (const entry of readdirSync8(root).sort()) {
36299
36446
  if (entry.startsWith("."))
36300
36447
  continue;
36301
- const path = join29(root, entry);
36448
+ const path = join30(root, entry);
36302
36449
  if (!safeIsDirectory(path))
36303
36450
  continue;
36304
36451
  try {
@@ -36331,9 +36478,9 @@ function isOfficialSkillName(name) {
36331
36478
  function scaffoldPortableSkill(name, options = {}) {
36332
36479
  const skillName = normalizeNewPortableSkillName(name);
36333
36480
  const readOnlyRoot = resolvePortableSkillsRoot(options, false);
36334
- assertPortableAuthoringPath(join29(readOnlyRoot, skillName), options);
36481
+ assertPortableAuthoringPath(join30(readOnlyRoot, skillName), options);
36335
36482
  const root = getPortableSkillsRoot(options);
36336
- const skillPath = join29(root, skillName);
36483
+ const skillPath = join30(root, skillName);
36337
36484
  assertPortableAuthoringPath(skillPath, options);
36338
36485
  if (existsSync12(skillPath)) {
36339
36486
  if (!options.overwrite)
@@ -36352,27 +36499,27 @@ function scaffoldPortableSkill(name, options = {}) {
36352
36499
  return { name: skillName, path: skillPath, manifest, created: true };
36353
36500
  }
36354
36501
  function physicalImportPath(path) {
36355
- let ancestor = resolve20(path);
36502
+ let ancestor = resolve21(path);
36356
36503
  const suffix = [];
36357
36504
  while (!existsSync12(ancestor)) {
36358
36505
  suffix.unshift(basename11(ancestor));
36359
- ancestor = dirname19(ancestor);
36506
+ ancestor = dirname20(ancestor);
36360
36507
  }
36361
- return join29(realpathSync8(ancestor), ...suffix);
36508
+ return join30(realpathSync8(ancestor), ...suffix);
36362
36509
  }
36363
36510
  function assertDisjointImportPaths(source, destination) {
36364
36511
  const sourcePath = realpathSync8(source);
36365
36512
  const destinationPath = physicalImportPath(destination);
36366
36513
  const contains2 = (parent, child2) => {
36367
36514
  const path = relative6(parent, child2);
36368
- return path === "" || !isAbsolute17(path) && path !== ".." && !path.startsWith(`..${sep9}`);
36515
+ return path === "" || !isAbsolute19(path) && path !== ".." && !path.startsWith(`..${sep10}`);
36369
36516
  };
36370
36517
  if (contains2(sourcePath, destinationPath) || contains2(destinationPath, sourcePath)) {
36371
36518
  throw new Error("Source and destination skill directories must not overlap");
36372
36519
  }
36373
36520
  }
36374
36521
  function portPortableSkill(sourcePath, options = {}) {
36375
- const absoluteSource = normalize3(sourcePath);
36522
+ const absoluteSource = normalize4(sourcePath);
36376
36523
  if (!existsSync12(absoluteSource) || !statSync8(absoluteSource).isDirectory()) {
36377
36524
  throw new Error(`Skill source directory not found: ${sourcePath}`);
36378
36525
  }
@@ -36384,11 +36531,11 @@ function portPortableSkill(sourcePath, options = {}) {
36384
36531
  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.`;
36385
36532
  throw new Error(`${via} Importing it would shadow the official '${skillName}'. ` + `Pass --name to choose a different name, or --allow-shadow to override deliberately.`);
36386
36533
  }
36387
- const readOnlyDestination = join29(resolvePortableSkillsRoot(options, false), skillName);
36534
+ const readOnlyDestination = join30(resolvePortableSkillsRoot(options, false), skillName);
36388
36535
  assertPortableAuthoringPath(readOnlyDestination, options);
36389
36536
  assertDisjointImportPaths(absoluteSource, readOnlyDestination);
36390
36537
  const root = getPortableSkillsRoot(options);
36391
- const destination = join29(root, skillName);
36538
+ const destination = join30(root, skillName);
36392
36539
  assertPortableAuthoringPath(destination, options);
36393
36540
  assertDisjointImportPaths(absoluteSource, destination);
36394
36541
  if (existsSync12(destination)) {
@@ -36396,7 +36543,7 @@ function portPortableSkill(sourcePath, options = {}) {
36396
36543
  throw new Error(`Skill '${skillName}' already exists at ${destination}`);
36397
36544
  rmSync3(destination, { recursive: true, force: true });
36398
36545
  }
36399
- mkdirSync7(dirname19(destination), { recursive: true });
36546
+ mkdirSync8(dirname20(destination), { recursive: true });
36400
36547
  copySkillDirectory(absoluteSource, destination);
36401
36548
  const base = {
36402
36549
  ...inferred,
@@ -36420,8 +36567,8 @@ function validatePortableSkillDirectory(name, skillPath) {
36420
36567
  const warnings = [...base.warnings];
36421
36568
  let manifest;
36422
36569
  if (existsSync12(skillPath)) {
36423
- const skillJsonPath = join29(skillPath, "skill.json");
36424
- const skillMdPath = join29(skillPath, "SKILL.md");
36570
+ const skillJsonPath = join30(skillPath, "skill.json");
36571
+ const skillMdPath = join30(skillPath, "SKILL.md");
36425
36572
  if (!existsSync12(skillJsonPath) && !existsSync12(skillMdPath)) {
36426
36573
  add3(issues, "portable.manifest_missing", "Missing portable manifest: expected SKILL.md frontmatter and/or skill.json");
36427
36574
  }
@@ -36441,7 +36588,7 @@ function validatePortableSkillDirectory(name, skillPath) {
36441
36588
  add3(issues, "portable.version_missing", "Portable manifest missing version");
36442
36589
  }
36443
36590
  const contractIssues = validatePortableManifestContract(manifest, {
36444
- strict: existsSync12(join29(skillPath, "skill.json")),
36591
+ strict: existsSync12(join30(skillPath, "skill.json")),
36445
36592
  skillPath
36446
36593
  });
36447
36594
  for (const issue2 of contractIssues)
@@ -36481,7 +36628,7 @@ function validatePortableSkillDirectory(name, skillPath) {
36481
36628
  add3(issues, "portable.command_entry_unsafe", `Command '${command.name}' entry '${command.entry}' must stay inside the skill directory`);
36482
36629
  continue;
36483
36630
  }
36484
- const entryPath = join29(skillPath, command.entry);
36631
+ const entryPath = join30(skillPath, command.entry);
36485
36632
  if (!existsSync12(entryPath))
36486
36633
  add3(issues, "portable.command_entry_missing", `Command '${command.name}' entry '${command.entry}' is missing`);
36487
36634
  else if (statSync8(entryPath).isDirectory())
@@ -36492,7 +36639,7 @@ function validatePortableSkillDirectory(name, skillPath) {
36492
36639
  } catch (error61) {
36493
36640
  add3(issues, "portable.manifest_invalid", error61.message);
36494
36641
  }
36495
- if (manifest?.kind !== "instruction" && !existsSync12(join29(skillPath, "AGENTS.md"))) {
36642
+ if (manifest?.kind !== "instruction" && !existsSync12(join30(skillPath, "AGENTS.md"))) {
36496
36643
  add3(issues, "portable.agents_missing", "Missing AGENTS.md with build-out instructions for coding agents");
36497
36644
  }
36498
36645
  }
@@ -36530,9 +36677,9 @@ function safeIsDirectory(path) {
36530
36677
  }
36531
36678
  }
36532
36679
  function isSafeRelativePath2(value) {
36533
- if (!value.trim() || isAbsolute17(value))
36680
+ if (!value.trim() || isAbsolute19(value))
36534
36681
  return false;
36535
- const normalized = normalize3(value).replace(/\\/g, "/");
36682
+ const normalized = normalize4(value).replace(/\\/g, "/");
36536
36683
  return normalized !== ".." && !normalized.startsWith("../") && !normalized.includes("/../");
36537
36684
  }
36538
36685
  function add3(target, code, message) {
@@ -36720,7 +36867,7 @@ var init_search = __esm(() => {
36720
36867
 
36721
36868
  // src/lib/registry.ts
36722
36869
  import { existsSync as existsSync13, readFileSync as readFileSync17, readdirSync as readdirSync9 } from "fs";
36723
- import { join as join30 } from "path";
36870
+ import { join as join31 } from "path";
36724
36871
  function parseSkillMdFrontmatter(content) {
36725
36872
  const match = content.match(/^---\n([\s\S]*?)\n---/);
36726
36873
  if (!match)
@@ -36761,7 +36908,7 @@ function discoverSkillsInDir(dir, source = "custom") {
36761
36908
  for (const entry of entries) {
36762
36909
  if (!entry.isDirectory())
36763
36910
  continue;
36764
- const skillMdPath = join30(dir, entry.name, "SKILL.md");
36911
+ const skillMdPath = join31(dir, entry.name, "SKILL.md");
36765
36912
  if (!existsSync13(skillMdPath))
36766
36913
  continue;
36767
36914
  let content;
@@ -36781,7 +36928,7 @@ function discoverSkillsInDir(dir, source = "custom") {
36781
36928
  category: fm.category || "Development Tools",
36782
36929
  tags: fm.tags || [],
36783
36930
  ...fm.kind ? { kind: fm.kind } : {},
36784
- ...isHostedMetadataSkillDir(join30(dir, entry.name)) ? { serverOwned: true } : {},
36931
+ ...isHostedMetadataSkillDir(join31(dir, entry.name)) ? { serverOwned: true } : {},
36785
36932
  source
36786
36933
  });
36787
36934
  }
@@ -36797,8 +36944,8 @@ function findExtensionSkillPath(name) {
36797
36944
  for (const entry of entries) {
36798
36945
  if (!entry.isDirectory())
36799
36946
  continue;
36800
- const skillDir = join30(config2.extensionsDir, entry.name);
36801
- const skillMdPath = join30(skillDir, "SKILL.md");
36947
+ const skillDir = join31(config2.extensionsDir, entry.name);
36948
+ const skillMdPath = join31(skillDir, "SKILL.md");
36802
36949
  if (!existsSync13(skillMdPath))
36803
36950
  continue;
36804
36951
  let content;
@@ -37215,7 +37362,7 @@ var init_v4 = __esm(() => {
37215
37362
  });
37216
37363
 
37217
37364
  // src/lib/canonical-json.ts
37218
- import { createHash as createHash20 } from "crypto";
37365
+ import { createHash as createHash21 } from "crypto";
37219
37366
  function canonicalJson2(value, maximumBytes = 2 * 1024 * 1024) {
37220
37367
  return canonicalJsonAtDepth(value, maximumBytes, 64);
37221
37368
  }
@@ -37259,7 +37406,7 @@ function canonicalJsonAtDepth(value, maximumBytes, maximumDepth) {
37259
37406
  return visit3(value, 0);
37260
37407
  }
37261
37408
  function canonicalJsonSha256(value, maximumBytes) {
37262
- return createHash20("sha256").update(canonicalJson2(value, maximumBytes)).digest("hex");
37409
+ return createHash21("sha256").update(canonicalJson2(value, maximumBytes)).digest("hex");
37263
37410
  }
37264
37411
  var init_canonical_json = () => {};
37265
37412
 
@@ -37602,7 +37749,7 @@ function invitationFailure(value, status) {
37602
37749
  function invitationInput(action, input2) {
37603
37750
  if (!record4(input2))
37604
37751
  return inputFailure();
37605
- const keys = {
37752
+ const keys2 = {
37606
37753
  list: ["after"],
37607
37754
  get: ["invitationId"],
37608
37755
  issue: ["email", "role", "idempotencyKey", "confirm"],
@@ -37610,7 +37757,7 @@ function invitationInput(action, input2) {
37610
37757
  revoke: ["invitationId", "expectedGeneration", "confirm"],
37611
37758
  accept: ["invitationId", "token", "confirm"]
37612
37759
  };
37613
- if (Object.keys(input2).some((key) => !keys[action].includes(key)) || action !== "list" && keys[action].some((key) => !Object.hasOwn(input2, key)))
37760
+ if (Object.keys(input2).some((key) => !keys2[action].includes(key)) || action !== "list" && keys2[action].some((key) => !Object.hasOwn(input2, key)))
37614
37761
  return inputFailure();
37615
37762
  const value = { ...input2 };
37616
37763
  if (action === "list") {
@@ -38009,14 +38156,14 @@ var init_remote_workspace_leave = __esm(() => {
38009
38156
  });
38010
38157
 
38011
38158
  // src/lib/auth-store.ts
38012
- import { chmodSync, existsSync as existsSync14, mkdirSync as mkdirSync8, readFileSync as readFileSync18, renameSync as renameSync4, statSync as statSync9, unlinkSync as unlinkSync4, writeFileSync as writeFileSync7 } from "fs";
38013
- import { basename as basename12, dirname as dirname20, join as join31 } from "path";
38159
+ import { chmodSync, existsSync as existsSync14, mkdirSync as mkdirSync9, readFileSync as readFileSync18, renameSync as renameSync4, statSync as statSync9, unlinkSync as unlinkSync4, writeFileSync as writeFileSync7 } from "fs";
38160
+ import { basename as basename12, dirname as dirname21, join as join32 } from "path";
38014
38161
  function getAuthFilePath(env = process.env) {
38015
38162
  return skillsCredentialFilePath(env);
38016
38163
  }
38017
38164
  function getIdentityFilePath(env = process.env) {
38018
38165
  const file2 = skillsCredentialFilePath(env);
38019
- return join31(dirname20(file2), basename12(file2).replace(/^credentials/, "identity") + ".json");
38166
+ return join32(dirname21(file2), basename12(file2).replace(/^credentials/, "identity") + ".json");
38020
38167
  }
38021
38168
  function getApiUrl(action, env = process.env, options = {}) {
38022
38169
  return requireSkillsApiOrigin(action, env, options);
@@ -38098,15 +38245,15 @@ function runQuoteReceipt(value) {
38098
38245
  return value;
38099
38246
  }
38100
38247
  function parseRemoteRunQuote(value) {
38101
- const quote3 = object5(value);
38248
+ const quote3 = object6(value);
38102
38249
  runQuoteReceipt(quote3.quoteReceipt);
38103
- const pricing = object5(quote3.pricing);
38250
+ const pricing = object6(quote3.pricing);
38104
38251
  if (typeof quote3.skill !== "string" || !/^[a-z0-9][a-z0-9-]*$/.test(quote3.skill))
38105
38252
  throw new Error("Invalid quoted skill");
38106
38253
  const costCents = creditCount(pricing.costCredits ?? pricing.costCents);
38107
38254
  if (pricing.costCredits !== undefined && pricing.costCents !== undefined && pricing.costCents !== costCents)
38108
38255
  throw new Error("Inconsistent quoted credit count");
38109
- if (quote3.availability && object5(quote3.availability).status !== "available")
38256
+ if (quote3.availability && object6(quote3.availability).status !== "available")
38110
38257
  throw new Error("This skill is unavailable for remote execution");
38111
38258
  return { ...quote3, skill: quote3.skill, pricing: { ...pricing, costCredits: costCents, costCents, formattedCost: `${costCents} credits` } };
38112
38259
  }
@@ -38115,7 +38262,7 @@ function parseRemoteCreditPacks(value) {
38115
38262
  throw new Error("Invalid credit pack response");
38116
38263
  const ids = new Set;
38117
38264
  return value.map((value2) => {
38118
- const row = object5(value2);
38265
+ const row = object6(value2);
38119
38266
  const counts = [row.credits, row.creditsCents, row.amountCents].filter((value3) => value3 !== undefined).map(creditCount);
38120
38267
  if (!counts.length || counts[0] === 0 || counts.some((count) => count !== counts[0]))
38121
38268
  throw new Error("Inconsistent credit pack counts");
@@ -38130,7 +38277,7 @@ function parseRemoteCreditPacks(value) {
38130
38277
  });
38131
38278
  }
38132
38279
  function parseRemoteBillingStatus(value) {
38133
- const row = object5(value);
38280
+ const row = object6(value);
38134
38281
  const counts = [row.creditBalance, row.balanceCents].filter((value2) => value2 !== undefined).map(creditCount);
38135
38282
  if (!counts.length || counts.some((count) => count !== counts[0]))
38136
38283
  throw new Error("Inconsistent credit balance");
@@ -38142,7 +38289,7 @@ function parseRemoteBillingStatus(value) {
38142
38289
  };
38143
38290
  }
38144
38291
  function parseRemoteCheckout(value) {
38145
- const row = object5(value);
38292
+ const row = object6(value);
38146
38293
  if (typeof row.url !== "string")
38147
38294
  throw new Error("Invalid checkout URL");
38148
38295
  const url2 = new URL(row.url);
@@ -38150,7 +38297,7 @@ function parseRemoteCheckout(value) {
38150
38297
  throw new Error("Invalid checkout URL");
38151
38298
  return { url: row.url };
38152
38299
  }
38153
- function object5(value) {
38300
+ function object6(value) {
38154
38301
  if (!value || typeof value !== "object" || Array.isArray(value))
38155
38302
  throw new Error("Invalid Skills server response");
38156
38303
  return value;
@@ -38244,10 +38391,10 @@ async function readQuoteUnavailableCode(response) {
38244
38391
  let timer;
38245
38392
  let deadlineExceeded = false;
38246
38393
  const expired = Symbol("quote body deadline");
38247
- const deadline = new Promise((resolve21) => {
38394
+ const deadline = new Promise((resolve22) => {
38248
38395
  timer = setTimeout(() => {
38249
38396
  deadlineExceeded = true;
38250
- resolve21(expired);
38397
+ resolve22(expired);
38251
38398
  reader.cancel().catch(() => {});
38252
38399
  }, 1500);
38253
38400
  });
@@ -39390,8 +39537,8 @@ function invitationEmailIds(invitationId, challengeId) {
39390
39537
  return { invitationId, challengeId };
39391
39538
  }
39392
39539
  function invitationEmailInput(action, input2) {
39393
- const keys = ["invitationId", "token", "challengeId", "confirm", ...action === "accept" ? ["code"] : []];
39394
- if (!record8(input2) || Object.keys(input2).length !== keys.length || keys.some((key) => !Object.hasOwn(input2, key)))
39540
+ const keys2 = ["invitationId", "token", "challengeId", "confirm", ...action === "accept" ? ["code"] : []];
39541
+ if (!record8(input2) || Object.keys(input2).length !== keys2.length || keys2.some((key) => !Object.hasOwn(input2, key)))
39395
39542
  throw new InvitationEmailInputError;
39396
39543
  const value = { ...input2 };
39397
39544
  const ids = invitationEmailIds(value.invitationId, value.challengeId);
@@ -39485,7 +39632,7 @@ var init_remote_invitation_recovery = __esm(() => {
39485
39632
  });
39486
39633
 
39487
39634
  // src/lib/remote-private-publications.ts
39488
- import { createHash as createHash21 } from "crypto";
39635
+ import { createHash as createHash22 } from "crypto";
39489
39636
  function checkedPublicationDeclaration(value) {
39490
39637
  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)
39491
39638
  return bad();
@@ -39730,12 +39877,12 @@ class RemotePrivatePublicationsClient {
39730
39877
  previous = view;
39731
39878
  if (!["queued", "verifying"].includes(view.state) || Date.now() >= until)
39732
39879
  return view;
39733
- await new Promise((resolve21) => {
39880
+ await new Promise((resolve22) => {
39734
39881
  const timer = setTimeout(done, Math.min(1000, until - Date.now()));
39735
39882
  function done() {
39736
39883
  clearTimeout(timer);
39737
39884
  options.signal?.removeEventListener("abort", done);
39738
- resolve21();
39885
+ resolve22();
39739
39886
  }
39740
39887
  options.signal?.addEventListener("abort", done, { once: true });
39741
39888
  });
@@ -39746,7 +39893,7 @@ var PRIVATE_PUBLICATION_MAX_BYTES, failures2, PrivatePublicationError, bad = ()
39746
39893
  throw new PrivatePublicationError("INVALID_PUBLICATION_INPUT", "Invalid publication input or recovery data.");
39747
39894
  }, invalid4 = () => {
39748
39895
  throw new PrivatePublicationError("INVALID_PUBLICATION_RESPONSE", "The server returned an invalid publication result.");
39749
- }, publicationUuid = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), hash3 = (v) => typeof v === "string" && /^[a-f0-9]{64}$/.test(v), record9 = (v) => !!v && typeof v === "object" && !Array.isArray(v), exact = (v, keys) => record9(v) && Object.keys(v).sort().join(",") === keys.sort().join(","), date5 = (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) => createHash21("sha256").update(bytes).digest("hex");
39896
+ }, publicationUuid = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), hash3 = (v) => typeof v === "string" && /^[a-f0-9]{64}$/.test(v), record9 = (v) => !!v && typeof v === "object" && !Array.isArray(v), exact = (v, keys2) => record9(v) && Object.keys(v).sort().join(",") === keys2.sort().join(","), date5 = (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) => createHash22("sha256").update(bytes).digest("hex");
39750
39897
  var init_remote_private_publications = __esm(() => {
39751
39898
  init_fleet_credentials();
39752
39899
  init_remote_workspace_selection();
@@ -40023,10 +40170,10 @@ var init_remote_auth = __esm(() => {
40023
40170
  });
40024
40171
 
40025
40172
  // src/lib/workspace-profile.ts
40026
- import { constants as constants13, closeSync as closeSync15, fstatSync as fstatSync15, lstatSync as lstatSync21, mkdirSync as mkdirSync9, mkdtempSync as mkdtempSync2, openSync as openSync15, readFileSync as readFileSync19, renameSync as renameSync5, rmSync as rmSync4, writeFileSync as writeFileSync8 } from "fs";
40173
+ import { constants as constants14, closeSync as closeSync16, fstatSync as fstatSync16, lstatSync as lstatSync22, mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync2, openSync as openSync16, readFileSync as readFileSync19, renameSync as renameSync5, rmSync as rmSync4, writeFileSync as writeFileSync8 } from "fs";
40027
40174
  function stat2(path) {
40028
40175
  try {
40029
- return lstatSync21(path);
40176
+ return lstatSync22(path);
40030
40177
  } catch (error61) {
40031
40178
  if (error61.code === "ENOENT")
40032
40179
  return null;
@@ -40036,14 +40183,14 @@ function stat2(path) {
40036
40183
  function safeText(file2) {
40037
40184
  if (stat2(file2) === null)
40038
40185
  return null;
40039
- const fd = openSync15(file2, constants13.O_RDONLY | constants13.O_NOFOLLOW | constants13.O_NONBLOCK);
40186
+ const fd = openSync16(file2, constants14.O_RDONLY | constants14.O_NOFOLLOW | constants14.O_NONBLOCK);
40040
40187
  try {
40041
- const s = fstatSync15(fd);
40188
+ const s = fstatSync16(fd);
40042
40189
  if (!s.isFile() || s.size > 65536 || ![256, 384].includes(s.mode & 4095) || process.getuid && s.uid !== process.getuid())
40043
40190
  return fail("The selected profile must use bounded owner-only regular files.");
40044
40191
  return readFileSync19(fd, "utf8");
40045
40192
  } finally {
40046
- closeSync15(fd);
40193
+ closeSync16(fd);
40047
40194
  }
40048
40195
  }
40049
40196
  function checkIdentityMetadata(file2, identity3) {
@@ -40255,8 +40402,8 @@ var init_recurring_customer = __esm(() => {
40255
40402
  });
40256
40403
 
40257
40404
  // src/lib/recurring-recovery.ts
40258
- import { constants as constants14, closeSync as closeSync16, fsyncSync as fsyncSync4, fstatSync as fstatSync16, lstatSync as lstatSync22, mkdirSync as mkdirSync10, openSync as openSync16, readSync as readSync10, realpathSync as realpathSync9, renameSync as renameSync6, unlinkSync as unlinkSync5, writeFileSync as writeFileSync9 } from "fs";
40259
- import { dirname as dirname21, isAbsolute as isAbsolute18, join as join32, resolve as resolve21 } from "path";
40405
+ import { constants as constants15, closeSync as closeSync17, fsyncSync as fsyncSync5, fstatSync as fstatSync17, lstatSync as lstatSync23, mkdirSync as mkdirSync11, openSync as openSync17, readSync as readSync11, realpathSync as realpathSync9, renameSync as renameSync6, unlinkSync as unlinkSync5, writeFileSync as writeFileSync9 } from "fs";
40406
+ import { dirname as dirname22, isAbsolute as isAbsolute20, join as join33, resolve as resolve22 } from "path";
40260
40407
  import { randomUUID as randomUUID2 } from "crypto";
40261
40408
 
40262
40409
  class RecoveryOwner {
@@ -40264,14 +40411,14 @@ class RecoveryOwner {
40264
40411
  parents = [];
40265
40412
  constructor(directory) {
40266
40413
  this.directory = directory;
40267
- if (!isAbsolute18(directory) || resolve21(directory) !== directory || realpathSync9(directory) !== directory)
40414
+ if (!isAbsolute20(directory) || resolve22(directory) !== directory || realpathSync9(directory) !== directory)
40268
40415
  invalid5();
40269
- for (let path = directory;; path = dirname21(path)) {
40270
- const stat3 = lstatSync22(path);
40416
+ for (let path = directory;; path = dirname22(path)) {
40417
+ const stat3 = lstatSync23(path);
40271
40418
  if (!stat3.isDirectory() || stat3.isSymbolicLink())
40272
40419
  invalid5();
40273
40420
  this.parents.push({ path, dev: stat3.dev, ino: stat3.ino });
40274
- if (path === dirname21(path))
40421
+ if (path === dirname22(path))
40275
40422
  break;
40276
40423
  }
40277
40424
  this.assert();
@@ -40280,59 +40427,59 @@ class RecoveryOwner {
40280
40427
  if (realpathSync9(this.directory) !== this.directory)
40281
40428
  invalid5();
40282
40429
  for (const prior of this.parents) {
40283
- const now = lstatSync22(prior.path);
40430
+ const now = lstatSync23(prior.path);
40284
40431
  if (!now.isDirectory() || now.isSymbolicLink() || now.dev !== prior.dev || now.ino !== prior.ino)
40285
40432
  invalid5();
40286
40433
  }
40287
- const own2 = lstatSync22(this.directory);
40434
+ const own2 = lstatSync23(this.directory);
40288
40435
  if ((own2.mode & 511) !== 448 || (own2.mode & 3584) !== 0 || process.getuid && own2.uid !== process.getuid())
40289
40436
  invalid5();
40290
40437
  }
40291
40438
  read(name) {
40292
40439
  this.assert();
40293
- const fd = openSync16(join32(this.directory, name), constants14.O_RDONLY | constants14.O_NOFOLLOW | constants14.O_NONBLOCK);
40440
+ const fd = openSync17(join33(this.directory, name), constants15.O_RDONLY | constants15.O_NOFOLLOW | constants15.O_NONBLOCK);
40294
40441
  try {
40295
- const before = fstatSync16(fd);
40442
+ const before = fstatSync17(fd);
40296
40443
  if (!before.isFile() || before.nlink !== 1 || (before.mode & 4095) !== 384 || before.size < 1 || before.size > 8192 || process.getuid && before.uid !== process.getuid())
40297
40444
  invalid5();
40298
40445
  const bytes = Buffer.alloc(before.size + 1);
40299
40446
  let size = 0;
40300
40447
  while (size < bytes.length) {
40301
- const n2 = readSync10(fd, bytes, size, bytes.length - size, size);
40448
+ const n2 = readSync11(fd, bytes, size, bytes.length - size, size);
40302
40449
  if (!n2)
40303
40450
  break;
40304
40451
  size += n2;
40305
40452
  }
40306
- const after = fstatSync16(fd), path = lstatSync22(join32(this.directory, name));
40453
+ const after = fstatSync17(fd), path = lstatSync23(join33(this.directory, name));
40307
40454
  if (size !== before.size || after.size !== before.size || before.mtimeMs !== after.mtimeMs || before.ctimeMs !== after.ctimeMs || path.dev !== before.dev || path.ino !== before.ino || !path.isFile() || path.isSymbolicLink())
40308
40455
  invalid5();
40309
40456
  this.assert();
40310
40457
  return new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(0, size));
40311
40458
  } finally {
40312
- closeSync16(fd);
40459
+ closeSync17(fd);
40313
40460
  }
40314
40461
  }
40315
40462
  write(name, value) {
40316
40463
  this.assert();
40317
40464
  const bytes = canonicalJson2(value, 8192) + `
40318
40465
  `;
40319
- const fd = openSync16(join32(this.directory, name), constants14.O_WRONLY | constants14.O_CREAT | constants14.O_EXCL | constants14.O_NOFOLLOW, 384);
40466
+ const fd = openSync17(join33(this.directory, name), constants15.O_WRONLY | constants15.O_CREAT | constants15.O_EXCL | constants15.O_NOFOLLOW, 384);
40320
40467
  try {
40321
40468
  writeFileSync9(fd, bytes);
40322
- fsyncSync4(fd);
40469
+ fsyncSync5(fd);
40323
40470
  } finally {
40324
- closeSync16(fd);
40471
+ closeSync17(fd);
40325
40472
  }
40326
40473
  this.assert();
40327
40474
  this.sync();
40328
40475
  }
40329
40476
  sync() {
40330
40477
  this.assert();
40331
- const fd = openSync16(this.directory, constants14.O_RDONLY | constants14.O_NOFOLLOW);
40478
+ const fd = openSync17(this.directory, constants15.O_RDONLY | constants15.O_NOFOLLOW);
40332
40479
  try {
40333
- fsyncSync4(fd);
40480
+ fsyncSync5(fd);
40334
40481
  } finally {
40335
- closeSync16(fd);
40482
+ closeSync17(fd);
40336
40483
  }
40337
40484
  }
40338
40485
  saveState(state, expected) {
@@ -40343,30 +40490,30 @@ class RecoveryOwner {
40343
40490
  if (this.read("state.json") !== expected)
40344
40491
  invalid5();
40345
40492
  this.assert();
40346
- renameSync6(join32(this.directory, name), join32(this.directory, "state.json"));
40493
+ renameSync6(join33(this.directory, name), join33(this.directory, "state.json"));
40347
40494
  this.sync();
40348
40495
  }
40349
40496
  async locked(action) {
40350
40497
  this.assert();
40351
40498
  let fd;
40352
40499
  try {
40353
- fd = openSync16(join32(this.directory, "operation.lock"), constants14.O_WRONLY | constants14.O_CREAT | constants14.O_EXCL | constants14.O_NOFOLLOW, 384);
40500
+ fd = openSync17(join33(this.directory, "operation.lock"), constants15.O_WRONLY | constants15.O_CREAT | constants15.O_EXCL | constants15.O_NOFOLLOW, 384);
40354
40501
  } catch {
40355
40502
  throw new RecurringCustomerError("RECURRING_RECOVERY_BUSY", "Recovery is locked. Confirm the original process has stopped before explicitly reconciling the retained lock; no request was retried.");
40356
40503
  }
40357
- const owner2 = fstatSync16(fd);
40504
+ const owner2 = fstatSync17(fd);
40358
40505
  try {
40359
40506
  writeFileSync9(fd, JSON.stringify({ pid: process.pid }));
40360
- fsyncSync4(fd);
40507
+ fsyncSync5(fd);
40361
40508
  this.sync();
40362
40509
  return await action();
40363
40510
  } finally {
40364
- closeSync16(fd);
40511
+ closeSync17(fd);
40365
40512
  this.assert();
40366
- const now = lstatSync22(join32(this.directory, "operation.lock"));
40513
+ const now = lstatSync23(join33(this.directory, "operation.lock"));
40367
40514
  if (owner2.dev !== now.dev || owner2.ino !== now.ino || !now.isFile() || now.isSymbolicLink())
40368
40515
  invalid5();
40369
- unlinkSync5(join32(this.directory, "operation.lock"));
40516
+ unlinkSync5(join33(this.directory, "operation.lock"));
40370
40517
  this.sync();
40371
40518
  }
40372
40519
  }
@@ -40399,9 +40546,9 @@ function base(customer, organizationId) {
40399
40546
  };
40400
40547
  }
40401
40548
  function create(directory, intent) {
40402
- if (!isAbsolute18(directory) || resolve21(directory) !== directory || realpathSync9(dirname21(directory)) !== dirname21(directory))
40549
+ if (!isAbsolute20(directory) || resolve22(directory) !== directory || realpathSync9(dirname22(directory)) !== dirname22(directory))
40403
40550
  invalid5();
40404
- mkdirSync10(directory, { mode: 448 });
40551
+ mkdirSync11(directory, { mode: 448 });
40405
40552
  const owner2 = new RecoveryOwner(directory), checked = intentSchema.parse(intent), intentSha256 = canonicalJsonSha256(checked);
40406
40553
  owner2.write(`intent-${intentSha256}.json`, checked);
40407
40554
  owner2.write("state.json", { contractVersion: 1, intentSha256, phase: "prepared", consentId: null });
@@ -40524,7 +40671,7 @@ async function continueRecurringRecovery(customer, directory, options) {
40524
40671
  throw error61;
40525
40672
  }
40526
40673
  }
40527
- var uuid12, sha4, common, intentSchema, stateSchema, invalid5 = () => {
40674
+ var uuid12, sha5, common, intentSchema, stateSchema, invalid5 = () => {
40528
40675
  throw new RecurringCustomerError("RECURRING_RECOVERY_INVALID", "The original recovery directory or record is invalid or changed. Preserve it; do not create a replacement activation automatically.");
40529
40676
  };
40530
40677
  var init_recurring_recovery = __esm(() => {
@@ -40534,7 +40681,7 @@ var init_recurring_recovery = __esm(() => {
40534
40681
  init_remote_recurring();
40535
40682
  init_recurring_customer();
40536
40683
  uuid12 = exports_external.string().regex(/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/);
40537
- sha4 = exports_external.string().regex(/^[a-f0-9]{64}$/);
40684
+ sha5 = exports_external.string().regex(/^[a-f0-9]{64}$/);
40538
40685
  common = exports_external.object({
40539
40686
  contractVersion: exports_external.literal(1),
40540
40687
  apiOrigin: exports_external.string().min(1).max(4096),
@@ -40547,7 +40694,7 @@ var init_recurring_recovery = __esm(() => {
40547
40694
  common.extend({
40548
40695
  operation: exports_external.literal("activate"),
40549
40696
  draftId: uuid12,
40550
- termsSha256: sha4,
40697
+ termsSha256: sha5,
40551
40698
  approvalDeadline: exports_external.string().datetime(),
40552
40699
  approval: recurringActivationSchema
40553
40700
  }).strict(),
@@ -40555,14 +40702,14 @@ var init_recurring_recovery = __esm(() => {
40555
40702
  ]);
40556
40703
  stateSchema = exports_external.object({
40557
40704
  contractVersion: exports_external.literal(1),
40558
- intentSha256: sha4,
40705
+ intentSha256: sha5,
40559
40706
  phase: exports_external.enum(["prepared", "pending", "observed"]),
40560
40707
  consentId: uuid12.nullable()
40561
40708
  }).strict();
40562
40709
  });
40563
40710
 
40564
40711
  // src/lib/recurring-surface.ts
40565
- import { isAbsolute as isAbsolute19 } from "path";
40712
+ import { isAbsolute as isAbsolute21 } from "path";
40566
40713
  function recurringMcpSchema(action) {
40567
40714
  return action === "activate" ? recurringSurfaceSchemas.activate.extend({ code, confirm: exports_external.literal(true) }) : recurringSurfaceSchemas[action];
40568
40715
  }
@@ -40667,7 +40814,7 @@ var init_recurring_surface = __esm(() => {
40667
40814
  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}$/);
40668
40815
  context = { userId: uuid13.optional(), membershipId: uuid13.optional() };
40669
40816
  page2 = { limit: exports_external.number().int().min(1).max(100).optional(), cursor: exports_external.string().min(1).max(2048).optional() };
40670
- directory = exports_external.string().max(4096).refine(isAbsolute19, "Use an absolute recovery directory");
40817
+ directory = exports_external.string().max(4096).refine(isAbsolute21, "Use an absolute recovery directory");
40671
40818
  email4 = exports_external.string().trim().toLowerCase().email().max(254);
40672
40819
  code = exports_external.string().regex(/^\d{6}$/);
40673
40820
  recurringSurfaceSchemas = {
@@ -42496,21 +42643,21 @@ var init_credential_state = __esm(() => {
42496
42643
  });
42497
42644
 
42498
42645
  // src/lib/run-state.ts
42499
- import { createHash as createHash22, randomBytes } from "crypto";
42500
- import { existsSync as existsSync15, mkdirSync as mkdirSync11, readFileSync as readFileSync20, readdirSync as readdirSync10, statSync as statSync10, writeFileSync as writeFileSync10 } from "fs";
42501
- import { extname, join as join33, relative as relative7 } from "path";
42646
+ import { createHash as createHash23, randomBytes } from "crypto";
42647
+ import { existsSync as existsSync15, mkdirSync as mkdirSync12, readFileSync as readFileSync20, readdirSync as readdirSync10, statSync as statSync10, writeFileSync as writeFileSync10 } from "fs";
42648
+ import { extname, join as join34, relative as relative7 } from "path";
42502
42649
  function createSkillRun(params, targetDir = process.cwd()) {
42503
42650
  const now = new Date;
42504
42651
  const id = createRunId(now);
42505
42652
  const day = now.toISOString().slice(0, 10);
42506
42653
  const skillName = normalizeSkillName(params.skill);
42507
42654
  const root = getProjectStateDir(targetDir);
42508
- const runDir = join33(root, "runs", day, id);
42509
- const logsDir = join33(runDir, "logs");
42510
- const exportDir = join33(root, "exports", skillName, id);
42511
- mkdirSync11(logsDir, { recursive: true });
42512
- mkdirSync11(exportDir, { recursive: true });
42513
- mkdirSync11(join33(root, "tmp"), { recursive: true });
42655
+ const runDir = join34(root, "runs", day, id);
42656
+ const logsDir = join34(runDir, "logs");
42657
+ const exportDir = join34(root, "exports", skillName, id);
42658
+ mkdirSync12(logsDir, { recursive: true });
42659
+ mkdirSync12(exportDir, { recursive: true });
42660
+ mkdirSync12(join34(root, "tmp"), { recursive: true });
42514
42661
  const record10 = {
42515
42662
  id,
42516
42663
  skill: skillName,
@@ -42562,22 +42709,22 @@ function updateSkillRun(context2, patch) {
42562
42709
  return context2.record;
42563
42710
  }
42564
42711
  function writeRunLogs(context2, stdout = "", stderr = "") {
42565
- writeFileSync10(join33(context2.logsDir, "stdout.log"), stdout);
42566
- writeFileSync10(join33(context2.logsDir, "stderr.log"), stderr);
42712
+ writeFileSync10(join34(context2.logsDir, "stdout.log"), stdout);
42713
+ writeFileSync10(join34(context2.logsDir, "stderr.log"), stderr);
42567
42714
  }
42568
42715
  function appendRunEvent(context2, event, data = {}) {
42569
42716
  const line = JSON.stringify({ ts: new Date().toISOString(), event, ...data }) + `
42570
42717
  `;
42571
- const path = join33(context2.runDir, "events.ndjson");
42718
+ const path = join34(context2.runDir, "events.ndjson");
42572
42719
  const previous = existsSync15(path) ? readFileSync20(path, "utf-8") : "";
42573
42720
  writeFileSync10(path, previous + line);
42574
42721
  }
42575
42722
  function findSkillRun(runId, targetDir = process.cwd()) {
42576
- const runsRoot = join33(getProjectStateDir(targetDir), "runs");
42723
+ const runsRoot = join34(getProjectStateDir(targetDir), "runs");
42577
42724
  if (!existsSync15(runsRoot))
42578
42725
  return null;
42579
42726
  for (const day of readdirSync10(runsRoot)) {
42580
- const record10 = readRunRecord(join33(runsRoot, day, runId));
42727
+ const record10 = readRunRecord(join34(runsRoot, day, runId));
42581
42728
  if (record10)
42582
42729
  return record10;
42583
42730
  }
@@ -42594,11 +42741,11 @@ function skillRunEnv(context2) {
42594
42741
  };
42595
42742
  }
42596
42743
  function writeRunRecord(context2) {
42597
- writeFileSync10(join33(context2.runDir, "run.json"), JSON.stringify(context2.record, null, 2) + `
42744
+ writeFileSync10(join34(context2.runDir, "run.json"), JSON.stringify(context2.record, null, 2) + `
42598
42745
  `);
42599
42746
  }
42600
42747
  function writeArtifactsManifest(context2, artifacts) {
42601
- writeFileSync10(join33(context2.runDir, "artifacts.json"), JSON.stringify({ runId: context2.record.id, artifacts }, null, 2) + `
42748
+ writeFileSync10(join34(context2.runDir, "artifacts.json"), JSON.stringify({ runId: context2.record.id, artifacts }, null, 2) + `
42602
42749
  `);
42603
42750
  }
42604
42751
  function collectRunArtifacts(context2) {
@@ -42611,14 +42758,14 @@ function collectRunArtifacts(context2) {
42611
42758
  artifacts.push({
42612
42759
  path: toProjectRelative(context2.targetDir, path),
42613
42760
  mime: mimeForPath(path),
42614
- sha256: createHash22("sha256").update(bytes).digest("hex"),
42761
+ sha256: createHash23("sha256").update(bytes).digest("hex"),
42615
42762
  sizeBytes: stat3.size
42616
42763
  });
42617
42764
  }
42618
42765
  return artifacts.sort((a, b) => a.path.localeCompare(b.path));
42619
42766
  }
42620
42767
  function readRunRecord(runDir) {
42621
- const path = join33(runDir, "run.json");
42768
+ const path = join34(runDir, "run.json");
42622
42769
  if (!existsSync15(path))
42623
42770
  return null;
42624
42771
  try {
@@ -42630,7 +42777,7 @@ function readRunRecord(runDir) {
42630
42777
  function walkFiles(dir) {
42631
42778
  const files = [];
42632
42779
  for (const entry of readdirSync10(dir)) {
42633
- const full = join33(dir, entry);
42780
+ const full = join34(dir, entry);
42634
42781
  if (statSync10(full).isDirectory())
42635
42782
  files.push(...walkFiles(full));
42636
42783
  else
@@ -42883,11 +43030,11 @@ var init_cloud_executions = __esm(() => {
42883
43030
  // node_modules/@hasna/secrets/dist/sdk.js
42884
43031
  import { isIP as isIP2 } from "net";
42885
43032
  import { spawnSync as spawnSync5 } from "child_process";
42886
- import { closeSync as closeSync17, fstatSync as fstatSync17, openSync as openSync17, readFileSync as readFileSync21 } from "fs";
43033
+ import { closeSync as closeSync18, fstatSync as fstatSync18, openSync as openSync18, readFileSync as readFileSync21 } from "fs";
42887
43034
  import { O_NOFOLLOW as O_NOFOLLOW3, O_NONBLOCK as O_NONBLOCK3, O_RDONLY as O_RDONLY3 } from "constants";
42888
43035
  import { createRequire as createRequire2 } from "module";
42889
43036
  import { hostname as osHostname2 } from "os";
42890
- import { isAbsolute as isAbsolute20, join as join34 } from "path";
43037
+ import { isAbsolute as isAbsolute22, join as join35 } from "path";
42891
43038
  import { createRequire as createRequire22 } from "module";
42892
43039
  function envToken2(name) {
42893
43040
  return name.toUpperCase().replace(/-/g, "_");
@@ -42911,21 +43058,21 @@ function homeDir2(env) {
42911
43058
  }
42912
43059
  function absoluteOverride2(env, key) {
42913
43060
  const value = env[key]?.trim();
42914
- return value && isAbsolute20(value) ? value : null;
43061
+ return value && isAbsolute22(value) ? value : null;
42915
43062
  }
42916
43063
  function hasnaHomeDir2(env) {
42917
43064
  const override = absoluteOverride2(env, HASNA_HOME_ENV_KEY2);
42918
43065
  if (override)
42919
43066
  return override;
42920
43067
  const home = homeDir2(env);
42921
- return home ? join34(home, HASNA_HOME_DIR2) : null;
43068
+ return home ? join35(home, HASNA_HOME_DIR2) : null;
42922
43069
  }
42923
43070
  function appConfigDir2(name, env) {
42924
43071
  const configRoot = absoluteOverride2(env, HASNA_CONFIG_HOME_ENV_KEY2);
42925
43072
  if (configRoot)
42926
- return join34(configRoot, name);
43073
+ return join35(configRoot, name);
42927
43074
  const root = hasnaHomeDir2(env);
42928
- return root ? join34(root, name, CONFIG_SUBDIR2) : null;
43075
+ return root ? join35(root, name, CONFIG_SUBDIR2) : null;
42929
43076
  }
42930
43077
  function credentialDiskSourceList2(name, env, profile = null) {
42931
43078
  if (!SAFE_APP_SLUG2.test(name))
@@ -42934,7 +43081,7 @@ function credentialDiskSourceList2(name, env, profile = null) {
42934
43081
  if (!directory2)
42935
43082
  return [];
42936
43083
  const file2 = profile ? `${CREDENTIALS_FILE2}-${profile}` : CREDENTIALS_FILE2;
42937
- return [{ path: join34(directory2, file2), tier: "disk" }];
43084
+ return [{ path: join35(directory2, file2), tier: "disk" }];
42938
43085
  }
42939
43086
  function credentialDiskSources2(name, env) {
42940
43087
  return credentialDiskSourceList2(name, env, null).map((s) => s.path);
@@ -42988,7 +43135,7 @@ function readAppConfigFile2(path) {
42988
43135
  };
42989
43136
  let fd = -1;
42990
43137
  try {
42991
- fd = openSync17(path, O_RDONLY3 | O_NOFOLLOW3 | O_NONBLOCK3);
43138
+ fd = openSync18(path, O_RDONLY3 | O_NOFOLLOW3 | O_NONBLOCK3);
42992
43139
  } catch (error61) {
42993
43140
  const code2 = error61.code;
42994
43141
  if (code2 === "ENOENT" || code2 === "ENOTDIR")
@@ -42998,7 +43145,7 @@ function readAppConfigFile2(path) {
42998
43145
  unsafe(`the path could not be opened (${code2 ?? "unknown error"})`);
42999
43146
  }
43000
43147
  try {
43001
- const before = fstatSync17(fd);
43148
+ const before = fstatSync18(fd);
43002
43149
  if (!before.isFile())
43003
43150
  unsafe("the path is not a regular file");
43004
43151
  if (!configFileModeAllowed2(before.mode)) {
@@ -43010,14 +43157,14 @@ function readAppConfigFile2(path) {
43010
43157
  if (before.size > MAX_CREDENTIAL_FILE_BYTES2)
43011
43158
  unsafe("the file exceeds the size limit");
43012
43159
  const bytes = readFileSync21(fd);
43013
- const after = fstatSync17(fd);
43160
+ const after = fstatSync18(fd);
43014
43161
  if (!configFileReadsCoherent2(before, after)) {
43015
43162
  unsafe("the file changed while being read");
43016
43163
  }
43017
43164
  return parseEnvFile2(bytes.toString("utf8"));
43018
43165
  } finally {
43019
43166
  if (fd !== -1)
43020
- closeSync17(fd);
43167
+ closeSync18(fd);
43021
43168
  }
43022
43169
  }
43023
43170
  function readCredentialFile2(path, apiKeyKeys) {
@@ -43035,8 +43182,8 @@ function readCredentialFile2(path, apiKeyKeys) {
43035
43182
  }
43036
43183
  return values[0] ?? null;
43037
43184
  }
43038
- function appConfigDiskValue2(name, env, keys) {
43039
- const wanted = keys.filter((key) => !CREDENTIAL_SHAPED_KEY2.test(key));
43185
+ function appConfigDiskValue2(name, env, keys2) {
43186
+ const wanted = keys2.filter((key) => !CREDENTIAL_SHAPED_KEY2.test(key));
43040
43187
  if (wanted.length === 0)
43041
43188
  return null;
43042
43189
  for (const path of credentialDiskSources2(name, env)) {
@@ -43143,8 +43290,8 @@ function validateAndSealResolvedCredential(appName, credential) {
43143
43290
  ...credential.pointerVaultKey !== undefined ? { pointerVaultKey: credential.pointerVaultKey } : {}
43144
43291
  });
43145
43292
  }
43146
- function firstEnvValue2(env, keys) {
43147
- for (const key of keys) {
43293
+ function firstEnvValue2(env, keys2) {
43294
+ for (const key of keys2) {
43148
43295
  if (!Object.prototype.hasOwnProperty.call(env, key))
43149
43296
  continue;
43150
43297
  const value = env[key]?.trim();
@@ -43221,12 +43368,12 @@ function keychainConfigValue2(name, env, options = {}) {
43221
43368
  return readKeychainItem2(name, env, "api-url", options);
43222
43369
  }
43223
43370
  function snapshotClientEnvironment2(name, env) {
43224
- const keys = clientTransportEnvKeys2(name);
43371
+ const keys2 = clientTransportEnvKeys2(name);
43225
43372
  const ambient = isAmbientEnvironment2(env);
43226
43373
  const snapshot2 = Object.create(null);
43227
43374
  for (const key of [
43228
- ...keys.apiUrlKeys,
43229
- ...keys.apiKeyKeys,
43375
+ ...keys2.apiUrlKeys,
43376
+ ...keys2.apiKeyKeys,
43230
43377
  credentialOverrideEnvKey2(name),
43231
43378
  credentialPointerEnvKey2(name),
43232
43379
  CREDENTIAL_PROFILE_ENV_KEY2,
@@ -43553,8 +43700,8 @@ function toV1BaseUrl2(apiUrl) {
43553
43700
  }
43554
43701
  function resolveClientTransportSnapshot(name, env = process.env, options = {}) {
43555
43702
  env = snapshotClientEnvironment2(name, env);
43556
- const keys = clientTransportEnvKeys2(name);
43557
- const definedUrlEntries = keys.apiUrlKeys.filter((key) => Object.prototype.hasOwnProperty.call(env, key) && env[key] !== undefined).map((key) => ({ key, raw: String(env[key]) }));
43703
+ const keys2 = clientTransportEnvKeys2(name);
43704
+ const definedUrlEntries = keys2.apiUrlKeys.filter((key) => Object.prototype.hasOwnProperty.call(env, key) && env[key] !== undefined).map((key) => ({ key, raw: String(env[key]) }));
43558
43705
  const blankUrl = definedUrlEntries.find((entry) => entry.raw.trim().length === 0);
43559
43706
  if (blankUrl) {
43560
43707
  throw new ClientTransportConfigurationError2(name, `${blankUrl.key} is set but blank; public clients require an explicit HTTPS API URL and never select local storage.`, [blankUrl.key]);
@@ -43569,7 +43716,7 @@ function resolveClientTransportSnapshot(name, env = process.env, options = {}) {
43569
43716
  }
43570
43717
  const envUrlHit = usableUrlEntries[0] ?? null;
43571
43718
  const keychainUrlHit = keychainConfigValue2(name, env, options.credentials?.keychain);
43572
- const diskConfigUrlHit = appConfigDiskValue2(name, env, keys.apiUrlKeys);
43719
+ const diskConfigUrlHit = appConfigDiskValue2(name, env, keys2.apiUrlKeys);
43573
43720
  if (diskConfigUrlHit?.unusable) {
43574
43721
  throw new ClientTransportConfigurationError2(name, `${diskConfigUrlHit.key} in ${diskConfigUrlHit.path} is declared but blank or malformed; public clients require a valid HTTPS service authority.`, [diskConfigUrlHit.path]);
43575
43722
  }
@@ -43585,14 +43732,14 @@ function resolveClientTransportSnapshot(name, env = process.env, options = {}) {
43585
43732
  }
43586
43733
  const warnings = [];
43587
43734
  if (configuredUrl && !envUrlHit) {
43588
- warnings.push(`No ${keys.apiUrlKeys[0]} in the environment; the server URL in ${configuredUrl.key} was used, so this client connects to the server. ` + `Keep that entry aligned with the intended service authority.`);
43735
+ warnings.push(`No ${keys2.apiUrlKeys[0]} in the environment; the server URL in ${configuredUrl.key} was used, so this client connects to the server. ` + `Keep that entry aligned with the intended service authority.`);
43589
43736
  }
43590
43737
  const credential = resolveCredential2(name, env, options.credentials);
43591
43738
  if (!credential) {
43592
43739
  const diskHint = credentialDiskSourcesForMessage(name, env);
43593
- const lead = configuredUrl ? `${configuredUrl.key} selects the HTTP server for '${name}', but no API key could be resolved` : `${keys.apiUrlKeys[0]} is not set and no API key could be resolved for '${name}'; a credential is required before the default fleet gateway authority applies`;
43594
- warnings.push(`${lead}; refusing to create an unauthenticated client \u2014 public clients never fall back to SQLite or another local store. ` + `Looked in the Keychain (macOS only), then for a credential file at ${diskHint}, then for ${keys.apiKeyKeys[0]} in the environment.`);
43595
- throw new ClientTransportConfigurationError2(name, warnings.join(" "), [configuredUrl?.key ?? keys.apiUrlKeys[0]]);
43740
+ const lead = configuredUrl ? `${configuredUrl.key} selects the HTTP server for '${name}', but no API key could be resolved` : `${keys2.apiUrlKeys[0]} is not set and no API key could be resolved for '${name}'; a credential is required before the default fleet gateway authority applies`;
43741
+ warnings.push(`${lead}; refusing to create an unauthenticated client \u2014 public clients never fall back to SQLite or another local store. ` + `Looked in the Keychain (macOS only), then for a credential file at ${diskHint}, then for ${keys2.apiKeyKeys[0]} in the environment.`);
43742
+ throw new ClientTransportConfigurationError2(name, warnings.join(" "), [configuredUrl?.key ?? keys2.apiUrlKeys[0]]);
43596
43743
  }
43597
43744
  if (credential.warning)
43598
43745
  warnings.push(credential.warning);
@@ -43604,7 +43751,7 @@ function resolveClientTransportSnapshot(name, env = process.env, options = {}) {
43604
43751
  urlHit = { key: DEFAULT_AUTHORITY_SOURCE, value: defaultFleetGatewayBaseUrl2(name) };
43605
43752
  } catch (error61) {
43606
43753
  const message = error61 instanceof Error ? error61.message : String(error61);
43607
- throw new ClientTransportConfigurationError2(name, `No ${keys.apiUrlKeys[0]} is configured and the default fleet gateway authority cannot be composed for '${name}': ${message}`, [keys.apiUrlKeys[0]]);
43754
+ throw new ClientTransportConfigurationError2(name, `No ${keys2.apiUrlKeys[0]} is configured and the default fleet gateway authority cannot be composed for '${name}': ${message}`, [keys2.apiUrlKeys[0]]);
43608
43755
  }
43609
43756
  }
43610
43757
  const apiUrlSource = urlHit.key;
@@ -44048,7 +44195,7 @@ function createSecretsClientFromEnv(env = process.env, overrides = {}) {
44048
44195
  });
44049
44196
  return new SecretsClient({ ...clientOverrides, baseUrl, apiKey });
44050
44197
  }
44051
- 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((resolve22) => setTimeout(resolve22, 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;
44198
+ 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((resolve23) => setTimeout(resolve23, 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;
44052
44199
  var init_sdk = __esm(() => {
44053
44200
  init_transport2 = __esm2(() => {
44054
44201
  CredentialResolutionError2 = class CredentialResolutionError3 extends Error {
@@ -44183,14 +44330,14 @@ var init_sdk = __esm(() => {
44183
44330
  });
44184
44331
 
44185
44332
  // src/lib/execution-secrets.ts
44186
- import { constants as constants15, closeSync as closeSync18, fstatSync as fstatSync18, openSync as openSync18, readSync as readSync11, realpathSync as realpathSync10 } from "fs";
44333
+ import { constants as constants16, closeSync as closeSync19, fstatSync as fstatSync19, openSync as openSync19, readSync as readSync12, realpathSync as realpathSync10 } from "fs";
44187
44334
  import { hostname as stationHostname } from "os";
44188
44335
  function selectedSecretBindingsTemplate(scope, names, createClient = createSecretsClientFromEnv) {
44189
44336
  let secretsAuthority;
44190
44337
  try {
44191
44338
  secretsAuthority = createClient().baseUrl;
44192
44339
  } catch {
44193
- return refuse2("LOCAL_SECRET_UNAVAILABLE", "Configure the Secrets CLI authority and authentication before preparing execution bindings.");
44340
+ return refuse4("LOCAL_SECRET_UNAVAILABLE", "Configure the Secrets CLI authority and authentication before preparing execution bindings.");
44194
44341
  }
44195
44342
  const { authority, workspaceId, profileRevision, slug: slug2, version: version2, bundleDigest } = scope.selection;
44196
44343
  return {
@@ -44201,14 +44348,14 @@ function selectedSecretBindingsTemplate(scope, names, createClient = createSecre
44201
44348
  bindings: Object.fromEntries(names.map((name) => [name, ""]))
44202
44349
  };
44203
44350
  }
44204
- function refuse2(code2, message) {
44351
+ function refuse4(code2, message) {
44205
44352
  throw new SkillSelectionError(code2, message);
44206
44353
  }
44207
44354
  function record10(value) {
44208
44355
  return !!value && typeof value === "object" && !Array.isArray(value);
44209
44356
  }
44210
- function exactKeys2(value, keys) {
44211
- return Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
44357
+ function exactKeys2(value, keys2) {
44358
+ return Object.keys(value).length === keys2.length && keys2.every((key) => Object.hasOwn(value, key));
44212
44359
  }
44213
44360
  function identifier3(value) {
44214
44361
  return typeof value === "string" && value.length > 0 && value.length <= 2048 && !/[\x00-\x20\x7f]/.test(value);
@@ -44217,29 +44364,29 @@ function declaredSecretNames(value) {
44217
44364
  if (value === undefined)
44218
44365
  return [];
44219
44366
  if (!Array.isArray(value) || value.length > 32 || value.some((name) => typeof name !== "string" || !/^[A-Z][A-Z0-9_]{0,127}$/.test(name)) || new Set(value).size !== value.length) {
44220
- return refuse2("INVALID_SKILL_MANIFEST", "Runtime environment references must be unique uppercase identifiers (at most 32).");
44367
+ return refuse4("INVALID_SKILL_MANIFEST", "Runtime environment references must be unique uppercase identifiers (at most 32).");
44221
44368
  }
44222
44369
  if (value.some((name) => /^(?:PATH|HOME|TMPDIR|TEMP|TMP|LANG|LC_ALL|TERM|SHELL|ENV|BASH_ENV|IFS|NODE_OPTIONS|NODE_PATH)$/.test(name) || /^(?:SKILLS_|BUN_|PYTHON|LD_|DYLD_)/.test(name))) {
44223
- return refuse2("INVALID_SKILL_MANIFEST", "Runtime environment references cannot override execution controls.");
44370
+ return refuse4("INVALID_SKILL_MANIFEST", "Runtime environment references cannot override execution controls.");
44224
44371
  }
44225
44372
  return value;
44226
44373
  }
44227
44374
  function validateSelectedSecretBindings(value, scope, names) {
44228
44375
  if (!record10(value) || !exactKeys2(value, ["schema", "selection", "consumer", "secretsAuthority", "bindings"]) || value.schema !== "hasna.skills-secret-bindings.v1" || !record10(value.selection) || !exactKeys2(value.selection, ["authority", "workspaceId", "profileId", "profileRevision", "slug", "version", "bundleDigest"]) || !record10(value.consumer) || !exactKeys2(value.consumer, ["stationId", "workspaceDirectory"]) || !record10(value.bindings)) {
44229
- return refuse2("INVALID_SECRET_BINDINGS", "Secret bindings do not match the hasna.skills-secret-bindings.v1 contract.");
44376
+ return refuse4("INVALID_SECRET_BINDINGS", "Secret bindings do not match the hasna.skills-secret-bindings.v1 contract.");
44230
44377
  }
44231
44378
  for (const [key, expected] of Object.entries({ authority: scope.selection.authority, workspaceId: scope.selection.workspaceId, profileId: scope.profileId, profileRevision: scope.selection.profileRevision, slug: scope.selection.slug, version: scope.selection.version, bundleDigest: scope.selection.bundleDigest })) {
44232
44379
  if (value.selection[key] !== expected)
44233
- return refuse2("SECRET_BINDING_SCOPE_MISMATCH", "Secret bindings do not match the exact selected authority, workspace, profile, revision, version and digest.");
44380
+ return refuse4("SECRET_BINDING_SCOPE_MISMATCH", "Secret bindings do not match the exact selected authority, workspace, profile, revision, version and digest.");
44234
44381
  }
44235
44382
  let workspaceDirectory;
44236
44383
  try {
44237
44384
  workspaceDirectory = realpathSync10(scope.cwd);
44238
44385
  } catch {
44239
- return refuse2("SECRET_BINDING_CONSUMER_MISMATCH", "The execution workspace cannot be resolved.");
44386
+ return refuse4("SECRET_BINDING_CONSUMER_MISMATCH", "The execution workspace cannot be resolved.");
44240
44387
  }
44241
44388
  if (value.consumer.stationId !== (process.env.HASNA_STATION || stationHostname()) || value.consumer.workspaceDirectory !== workspaceDirectory) {
44242
- return refuse2("SECRET_BINDING_CONSUMER_MISMATCH", "Secret bindings do not match this station and canonical workspace directory.");
44389
+ return refuse4("SECRET_BINDING_CONSUMER_MISMATCH", "Secret bindings do not match this station and canonical workspace directory.");
44243
44390
  }
44244
44391
  try {
44245
44392
  if (!identifier3(value.secretsAuthority))
@@ -44248,10 +44395,10 @@ function validateSelectedSecretBindings(value, scope, names) {
44248
44395
  if (url2.protocol !== "https:" && !(url2.protocol === "http:" && ["127.0.0.1", "[::1]", "localhost"].includes(url2.hostname)) || url2.username || url2.password || url2.search || url2.hash || !url2.pathname.endsWith("/v1") || url2.href !== value.secretsAuthority)
44249
44396
  throw new Error;
44250
44397
  } catch {
44251
- return refuse2("INVALID_SECRET_BINDINGS", "Secret bindings require a canonical HTTPS Secrets /v1 authority (loopback HTTP is allowed).");
44398
+ return refuse4("INVALID_SECRET_BINDINGS", "Secret bindings require a canonical HTTPS Secrets /v1 authority (loopback HTTP is allowed).");
44252
44399
  }
44253
44400
  if (!exactKeys2(value.bindings, names) || Object.values(value.bindings).some((key) => !identifier3(key) || !/^[A-Za-z0-9][A-Za-z0-9._/-]*$/.test(key) || key.split("/").some((part) => !part || part === "." || part === ".."))) {
44254
- return refuse2("INVALID_SECRET_BINDINGS", "Bind every declared environment name exactly once to a vault key; undeclared bindings and values are refused.");
44401
+ return refuse4("INVALID_SECRET_BINDINGS", "Bind every declared environment name exactly once to a vault key; undeclared bindings and values are refused.");
44255
44402
  }
44256
44403
  return structuredClone(value);
44257
44404
  }
@@ -44262,10 +44409,10 @@ async function resolveSelectedSecrets(bindings, createClient = createSecretsClie
44262
44409
  try {
44263
44410
  client = createClient();
44264
44411
  } catch {
44265
- return refuse2("LOCAL_SECRET_UNAVAILABLE", "The configured Secrets client could not authenticate. No ambient credential fallback was attempted.");
44412
+ return refuse4("LOCAL_SECRET_UNAVAILABLE", "The configured Secrets client could not authenticate. No ambient credential fallback was attempted.");
44266
44413
  }
44267
44414
  if (client.baseUrl !== bindings.secretsAuthority)
44268
- return refuse2("SECRET_BINDING_AUTHORITY_MISMATCH", "The configured Secrets authority differs from the reviewed binding. No secret was requested.");
44415
+ return refuse4("SECRET_BINDING_AUTHORITY_MISMATCH", "The configured Secrets authority differs from the reviewed binding. No secret was requested.");
44269
44416
  const env = {};
44270
44417
  const signal = AbortSignal.timeout(15000);
44271
44418
  try {
@@ -44277,7 +44424,7 @@ async function resolveSelectedSecrets(bindings, createClient = createSecretsClie
44277
44424
  }
44278
44425
  return env;
44279
44426
  } catch {
44280
- return refuse2("LOCAL_SECRET_UNAVAILABLE", "A declared secret could not be resolved, was invalid, or has expired. The skill was not started; no fallback was attempted.");
44427
+ return refuse4("LOCAL_SECRET_UNAVAILABLE", "A declared secret could not be resolved, was invalid, or has expired. The skill was not started; no fallback was attempted.");
44281
44428
  }
44282
44429
  }
44283
44430
  function redactExecutionSecrets(text3, env) {
@@ -44305,7 +44452,7 @@ function grantIdentifier(v) {
44305
44452
  function grantRecord(v) {
44306
44453
  return !!v && typeof v === "object" && !Array.isArray(v);
44307
44454
  }
44308
- function keys(v, required2, optional2 = []) {
44455
+ function keys2(v, required2, optional2 = []) {
44309
44456
  return required2.every((k) => Object.hasOwn(v, k)) && Object.keys(v).every((k) => required2.includes(k) || optional2.includes(k));
44310
44457
  }
44311
44458
  function invalid6() {
@@ -44333,10 +44480,10 @@ function grantWorkspace(v) {
44333
44480
  return flavor.isAbsolute(v) && flavor.normalize(v) === v;
44334
44481
  }
44335
44482
  function selection(v) {
44336
- return grantRecord(v) && keys(v, ["slug", "version", "bundleDigest"]) && grantIdentifier(v.slug) && isValidSkillVersion(v.version) && typeof v.bundleDigest === "string" && /^sha256:[a-f0-9]{64}$/.test(v.bundleDigest);
44483
+ return grantRecord(v) && keys2(v, ["slug", "version", "bundleDigest"]) && grantIdentifier(v.slug) && isValidSkillVersion(v.version) && typeof v.bundleDigest === "string" && /^sha256:[a-f0-9]{64}$/.test(v.bundleDigest);
44337
44484
  }
44338
44485
  function validateExecutionGrantRequest(value) {
44339
- if (!grantRecord(value) || !keys(value, ["selection", "consumer"]) || !grantRecord(value.selection) || !keys(value.selection, [
44486
+ if (!grantRecord(value) || !keys2(value, ["selection", "consumer"]) || !grantRecord(value.selection) || !keys2(value.selection, [
44340
44487
  "authority",
44341
44488
  "workspaceId",
44342
44489
  "profileId",
@@ -44344,7 +44491,7 @@ function validateExecutionGrantRequest(value) {
44344
44491
  "slug",
44345
44492
  "version",
44346
44493
  "bundleDigest"
44347
- ]) || !grantRecord(value.consumer) || !keys(value.consumer, ["stationId", "workspaceDirectory"]))
44494
+ ]) || !grantRecord(value.consumer) || !keys2(value.consumer, ["stationId", "workspaceDirectory"]))
44348
44495
  invalid6();
44349
44496
  const { selection: s, consumer: c } = value;
44350
44497
  if (!selection({
@@ -44425,10 +44572,10 @@ __export(exports_selected_run, {
44425
44572
  prepareSelectedSecretBindings: () => prepareSelectedSecretBindings,
44426
44573
  executeSelectedLocal: () => executeSelectedLocal
44427
44574
  });
44428
- import { createHash as createHash23 } from "crypto";
44575
+ import { createHash as createHash24 } from "crypto";
44429
44576
  import { spawn as spawn2 } from "child_process";
44430
- import { mkdirSync as mkdirSync12, mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync11, realpathSync as realpathSync11 } from "fs";
44431
- import { dirname as dirname22, join as join35, resolve as resolve22 } from "path";
44577
+ import { mkdirSync as mkdirSync13, mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync11, realpathSync as realpathSync11 } from "fs";
44578
+ import { dirname as dirname23, join as join36, resolve as resolve23 } from "path";
44432
44579
  import { tmpdir, hostname as stationHostname2 } from "os";
44433
44580
  async function resolveSelectedRun(spec, profileId, options = {}) {
44434
44581
  const context2 = await resolveSelectionContext(profileId, options);
@@ -44508,7 +44655,7 @@ async function executeSelectedLocal(selected, options = {}) {
44508
44655
  throw new SkillSelectionError("INVALID_SECRET_BINDINGS", "Explicit environment values must be bounded strings without NUL bytes.");
44509
44656
  secretEnv[name] = value;
44510
44657
  }
44511
- const runDirectory = mkdtempSync3(join35(tmpdir(), "skills-execution-"));
44658
+ const runDirectory = mkdtempSync3(join36(tmpdir(), "skills-execution-"));
44512
44659
  const paths = new SkillEntryPaths;
44513
44660
  for (const entry of entries) {
44514
44661
  paths.add(entry.path, 100, () => {
@@ -44516,12 +44663,12 @@ async function executeSelectedLocal(selected, options = {}) {
44516
44663
  }, () => {
44517
44664
  throw new SkillSelectionError("INVALID_BUNDLE_PATH", "The execution bundle path exceeds its limit.");
44518
44665
  });
44519
- const destination = join35(runDirectory, entry.path);
44520
- mkdirSync12(dirname22(destination), { recursive: true, mode: 448 });
44666
+ const destination = join36(runDirectory, entry.path);
44667
+ mkdirSync13(dirname23(destination), { recursive: true, mode: 448 });
44521
44668
  writeFileSync11(destination, entry.bytes, { flag: "wx", mode: entry.mode & 511 });
44522
44669
  }
44523
44670
  env.SKILLS_INPUT_JSON = input2;
44524
- env.SKILLS_WORKSPACE_DIR = resolve22(options.cwd ?? process.cwd());
44671
+ env.SKILLS_WORKSPACE_DIR = resolve23(options.cwd ?? process.cwd());
44525
44672
  env.SKILLS_RUN_DIR = runDirectory;
44526
44673
  if (runtime.version) {
44527
44674
  const version2 = await subprocess([executable, ...runtimeName === "bun" ? ["--no-env-file"] : [], "--version"], runDirectory, env, "", Math.min(timeoutMs, 5000));
@@ -44544,20 +44691,20 @@ async function executeSelectedLocal(selected, options = {}) {
44544
44691
  }
44545
44692
  if (bindings)
44546
44693
  secretEnv = await resolveSelectedSecrets(bindings, options.createSecretsClient);
44547
- const result = await subprocess([executable, ...runtimeName === "bun" ? ["--no-env-file"] : [], join35(runDirectory, declaredEntry), ...args], runDirectory, { ...env, ...secretEnv }, input2, timeoutMs);
44694
+ const result = await subprocess([executable, ...runtimeName === "bun" ? ["--no-env-file"] : [], join36(runDirectory, declaredEntry), ...args], runDirectory, { ...env, ...secretEnv }, input2, timeoutMs);
44548
44695
  result.stdout = redactExecutionSecrets(result.stdout, secretEnv);
44549
44696
  result.stderr = redactExecutionSecrets(result.stderr, secretEnv);
44550
44697
  const receipt = {
44551
44698
  selection: selection2,
44552
44699
  target: "local",
44553
44700
  runtime: runtimeName,
44554
- inputDigest: `sha256:${createHash23("sha256").update(input2).digest("hex")}`,
44701
+ inputDigest: `sha256:${createHash24("sha256").update(input2).digest("hex")}`,
44555
44702
  runDirectory,
44556
44703
  ...executionGrant ? { executionGrant } : {},
44557
44704
  ...bindings ? { secretBinding: { schema: bindings.schema, selection: bindings.selection, consumer: bindings.consumer, secretsAuthority: bindings.secretsAuthority, bindings: bindings.bindings } } : {},
44558
44705
  ...result
44559
44706
  };
44560
- writeFileSync11(join35(runDirectory, ".execution-receipt.json"), JSON.stringify({ ...receipt, stdout: undefined, stderr: undefined }), { mode: 384 });
44707
+ writeFileSync11(join36(runDirectory, ".execution-receipt.json"), JSON.stringify({ ...receipt, stdout: undefined, stderr: undefined }), { mode: 384 });
44561
44708
  return receipt;
44562
44709
  }
44563
44710
  async function subprocess(command, cwd, env, input2, timeoutMs) {
@@ -44747,7 +44894,7 @@ var init_blog_article = __esm(() => {
44747
44894
 
44748
44895
  // src/mcp/operation-tools.ts
44749
44896
  import { existsSync as existsSync16, readdirSync as readdirSync11, statSync as statSync11 } from "fs";
44750
- import { join as join36 } from "path";
44897
+ import { join as join37 } from "path";
44751
44898
  function registerOperationTools(server) {
44752
44899
  server.registerTool("cloud_skill_eligibility", {
44753
44900
  title: "Cloud Skill Eligibility",
@@ -45224,7 +45371,7 @@ function registerOperationTools(server) {
45224
45371
  if (exists) {
45225
45372
  try {
45226
45373
  skillCount = readdirSync11(agentSkillsPath).filter((f) => {
45227
- const full = join36(agentSkillsPath, f);
45374
+ const full = join37(agentSkillsPath, f);
45228
45375
  return !f.startsWith(".") && statSync11(full).isDirectory();
45229
45376
  }).length;
45230
45377
  } catch {}
@@ -45291,17 +45438,17 @@ var init_operation_tools = __esm(() => {
45291
45438
  });
45292
45439
 
45293
45440
  // src/lib/feedback.ts
45294
- import { appendFileSync, existsSync as existsSync17, mkdirSync as mkdirSync13 } from "fs";
45295
- import { dirname as dirname23, join as join37 } from "path";
45441
+ import { appendFileSync, existsSync as existsSync17, mkdirSync as mkdirSync14 } from "fs";
45442
+ import { dirname as dirname24, join as join38 } from "path";
45296
45443
  import { Database } from "bun:sqlite";
45297
45444
  function getFeedbackDbPath() {
45298
- return join37(getDataDir(), "skills.db");
45445
+ return join38(getDataDir(), "skills.db");
45299
45446
  }
45300
45447
  function getFeedbackDb() {
45301
45448
  const dbPath = getFeedbackDbPath();
45302
- const dir = dirname23(dbPath);
45449
+ const dir = dirname24(dbPath);
45303
45450
  if (!existsSync17(dir))
45304
- mkdirSync13(dir, { recursive: true });
45451
+ mkdirSync14(dir, { recursive: true });
45305
45452
  const db = new Database(dbPath);
45306
45453
  db.exec("PRAGMA journal_mode = WAL");
45307
45454
  db.exec([
@@ -45327,10 +45474,10 @@ function saveFeedback(input2) {
45327
45474
  throw new Error("Feedback message is required");
45328
45475
  const category = input2.category ?? "general";
45329
45476
  if (isApiMode()) {
45330
- const path = join37(getDataDir(), "feedback.jsonl");
45331
- const dir = dirname23(path);
45477
+ const path = join38(getDataDir(), "feedback.jsonl");
45478
+ const dir = dirname24(path);
45332
45479
  if (!existsSync17(dir))
45333
- mkdirSync13(dir, { recursive: true });
45480
+ mkdirSync14(dir, { recursive: true });
45334
45481
  appendFileSync(path, JSON.stringify({ message, category, email: input2.email ?? null, agent: input2.agent ?? null, version: input2.version ?? null, createdAt: new Date().toISOString() }) + `
45335
45482
  `);
45336
45483
  return { saved: true, category, path };
@@ -45491,10 +45638,10 @@ var init_resource_meta_tools = __esm(() => {
45491
45638
  });
45492
45639
 
45493
45640
  // src/lib/scheduler.ts
45494
- import { existsSync as existsSync18, readFileSync as readFileSync22, writeFileSync as writeFileSync12, mkdirSync as mkdirSync14 } from "fs";
45495
- import { join as join38 } from "path";
45641
+ import { existsSync as existsSync18, readFileSync as readFileSync22, writeFileSync as writeFileSync12, mkdirSync as mkdirSync15 } from "fs";
45642
+ import { join as join39 } from "path";
45496
45643
  function getSchedulesPath(targetDir = process.cwd()) {
45497
- return join38(targetDir, ".skills", "schedules.json");
45644
+ return join39(targetDir, ".skills", "schedules.json");
45498
45645
  }
45499
45646
  function loadSchedules(targetDir = process.cwd()) {
45500
45647
  const path = getSchedulesPath(targetDir);
@@ -45507,9 +45654,9 @@ function loadSchedules(targetDir = process.cwd()) {
45507
45654
  }
45508
45655
  function saveSchedules(data, targetDir = process.cwd()) {
45509
45656
  const path = getSchedulesPath(targetDir);
45510
- const dir = join38(targetDir, ".skills");
45657
+ const dir = join39(targetDir, ".skills");
45511
45658
  if (!existsSync18(dir))
45512
- mkdirSync14(dir, { recursive: true });
45659
+ mkdirSync15(dir, { recursive: true });
45513
45660
  writeFileSync12(path, JSON.stringify(data, null, 2));
45514
45661
  }
45515
45662
  function validateCronField(expr, min, max, label) {
@@ -45779,16 +45926,16 @@ var init_schedule_tools = __esm(() => {
45779
45926
  });
45780
45927
 
45781
45928
  // src/lib/native-storage.ts
45782
- import { createHash as createHash24, createHmac } from "crypto";
45929
+ import { createHash as createHash25, createHmac } from "crypto";
45783
45930
  import {
45784
45931
  existsSync as existsSync19,
45785
- mkdirSync as mkdirSync15,
45932
+ mkdirSync as mkdirSync16,
45786
45933
  readFileSync as readFileSync23,
45787
45934
  readdirSync as readdirSync12,
45788
45935
  statSync as statSync12,
45789
45936
  writeFileSync as writeFileSync13
45790
45937
  } from "fs";
45791
- import { dirname as dirname24, join as join39, normalize as normalize4, relative as relative8, sep as sep10 } from "path";
45938
+ import { dirname as dirname25, join as join40, normalize as normalize5, relative as relative8, sep as sep11 } from "path";
45792
45939
  function resolveSkillsNativeStorageConfig(env = process.env) {
45793
45940
  assertNoRetiredModeEnvVars(env, {
45794
45941
  app: SKILLS_ENV_NAMESPACE,
@@ -45829,7 +45976,7 @@ function getSkillsNativeStorageStatus(options = {}) {
45829
45976
  local: {
45830
45977
  dataDir: getDataDir(),
45831
45978
  projectStateDir: getProjectStateDir(targetDir),
45832
- feedbackDbPath: join39(getDataDir(), "skills.db")
45979
+ feedbackDbPath: join40(getDataDir(), "skills.db")
45833
45980
  },
45834
45981
  remote: {
45835
45982
  databaseConfigured: Boolean(config2.databaseUrl),
@@ -45856,7 +46003,7 @@ function exportSkillsLocalSnapshot(targetDir = process.cwd(), options = {}) {
45856
46003
  files.push({
45857
46004
  path: relativePath,
45858
46005
  sizeBytes: bytes.byteLength,
45859
- sha256: createHash24("sha256").update(bytes).digest("hex"),
46006
+ sha256: createHash25("sha256").update(bytes).digest("hex"),
45860
46007
  ...options.includeFileContents ? { contentBase64: Buffer.from(bytes).toString("base64") } : {}
45861
46008
  });
45862
46009
  }
@@ -45910,7 +46057,7 @@ function parsePositiveInteger(value) {
45910
46057
  function walkFiles2(dir) {
45911
46058
  const files = [];
45912
46059
  for (const entry of readdirSync12(dir)) {
45913
- const full = join39(dir, entry);
46060
+ const full = join40(dir, entry);
45914
46061
  const stats = statSync12(full);
45915
46062
  if (stats.isDirectory())
45916
46063
  files.push(...walkFiles2(full));
@@ -46148,20 +46295,20 @@ var init_private_publication_customer = __esm(() => {
46148
46295
  });
46149
46296
 
46150
46297
  // src/lib/private-publication-recovery.ts
46151
- import { constants as constants16, closeSync as closeSync19, fsyncSync as fsyncSync5, fstatSync as fstatSync19, lstatSync as lstatSync23, mkdirSync as mkdirSync16, openSync as openSync19, readSync as readSync12, realpathSync as realpathSync12, renameSync as renameSync7, unlinkSync as unlinkSync6, writeFileSync as writeFileSync14 } from "fs";
46152
- import { dirname as dirname25, isAbsolute as isAbsolute21, join as join40, resolve as resolve23 } from "path";
46298
+ import { constants as constants17, closeSync as closeSync20, fsyncSync as fsyncSync6, fstatSync as fstatSync20, lstatSync as lstatSync24, mkdirSync as mkdirSync17, openSync as openSync20, readSync as readSync13, realpathSync as realpathSync12, renameSync as renameSync7, unlinkSync as unlinkSync6, writeFileSync as writeFileSync14 } from "fs";
46299
+ import { dirname as dirname26, isAbsolute as isAbsolute23, join as join41, resolve as resolve24 } from "path";
46153
46300
  import { randomUUID as randomUUID3 } from "crypto";
46154
46301
  function safeDirectory(directory2) {
46155
- if (!isAbsolute21(directory2) || directory2 !== resolve23(directory2) || realpathSync12(directory2) !== directory2)
46302
+ if (!isAbsolute23(directory2) || directory2 !== resolve24(directory2) || realpathSync12(directory2) !== directory2)
46156
46303
  return fail2();
46157
- for (let path = directory2;; path = dirname25(path)) {
46158
- const stat3 = lstatSync23(path);
46304
+ for (let path = directory2;; path = dirname26(path)) {
46305
+ const stat3 = lstatSync24(path);
46159
46306
  if (!stat3.isDirectory() || stat3.isSymbolicLink())
46160
46307
  return fail2();
46161
- if (path === dirname25(path))
46308
+ if (path === dirname26(path))
46162
46309
  break;
46163
46310
  }
46164
- const own2 = lstatSync23(directory2);
46311
+ const own2 = lstatSync24(directory2);
46165
46312
  if ((own2.mode & 63) !== 0 || process.getuid && own2.uid !== process.getuid())
46166
46313
  return fail2();
46167
46314
  return { dev: own2.dev, ino: own2.ino };
@@ -46172,36 +46319,36 @@ function unchangedDirectory(directory2, identity3) {
46172
46319
  return fail2();
46173
46320
  }
46174
46321
  function readOwned(directory2, name, max) {
46175
- const identity3 = safeDirectory(directory2), file2 = join40(directory2, name);
46176
- const fd = openSync19(file2, constants16.O_RDONLY | constants16.O_NOFOLLOW);
46322
+ const identity3 = safeDirectory(directory2), file2 = join41(directory2, name);
46323
+ const fd = openSync20(file2, constants17.O_RDONLY | constants17.O_NOFOLLOW);
46177
46324
  try {
46178
- const stat3 = fstatSync19(fd);
46325
+ const stat3 = fstatSync20(fd);
46179
46326
  if (!stat3.isFile() || stat3.nlink !== 1 || stat3.size > max || stat3.size < 1 || (stat3.mode & 63) !== 0 || process.getuid && stat3.uid !== process.getuid())
46180
46327
  return fail2();
46181
46328
  const buffer = Buffer.alloc(Math.min(max, stat3.size) + 1);
46182
46329
  let length = 0;
46183
46330
  while (length < buffer.length) {
46184
- const count = readSync12(fd, buffer, length, buffer.length - length, length);
46331
+ const count = readSync13(fd, buffer, length, buffer.length - length, length);
46185
46332
  if (count === 0)
46186
46333
  break;
46187
46334
  length += count;
46188
46335
  }
46189
- const bytes = buffer.subarray(0, length), after = fstatSync19(fd);
46336
+ const bytes = buffer.subarray(0, length), after = fstatSync20(fd);
46190
46337
  unchangedDirectory(directory2, identity3);
46191
46338
  if (bytes.length !== stat3.size || stat3.size !== after.size || stat3.mtimeMs !== after.mtimeMs || stat3.ctimeMs !== after.ctimeMs)
46192
46339
  return fail2();
46193
46340
  return bytes;
46194
46341
  } finally {
46195
- closeSync19(fd);
46342
+ closeSync20(fd);
46196
46343
  }
46197
46344
  }
46198
46345
  function writeOwned(directory2, name, bytes) {
46199
- const fd = openSync19(join40(directory2, name), constants16.O_WRONLY | constants16.O_CREAT | constants16.O_EXCL | constants16.O_NOFOLLOW, 384);
46346
+ const fd = openSync20(join41(directory2, name), constants17.O_WRONLY | constants17.O_CREAT | constants17.O_EXCL | constants17.O_NOFOLLOW, 384);
46200
46347
  try {
46201
46348
  writeFileSync14(fd, bytes);
46202
- fsyncSync5(fd);
46349
+ fsyncSync6(fd);
46203
46350
  } finally {
46204
- closeSync19(fd);
46351
+ closeSync20(fd);
46205
46352
  }
46206
46353
  }
46207
46354
  function save(directory2, value) {
@@ -46209,12 +46356,12 @@ function save(directory2, value) {
46209
46356
  writeOwned(directory2, temporary, JSON.stringify(value) + `
46210
46357
  `);
46211
46358
  unchangedDirectory(directory2, identity3);
46212
- renameSync7(join40(directory2, temporary), join40(directory2, "receipt.json"));
46213
- const fd = openSync19(directory2, constants16.O_RDONLY | constants16.O_NOFOLLOW);
46359
+ renameSync7(join41(directory2, temporary), join41(directory2, "receipt.json"));
46360
+ const fd = openSync20(directory2, constants17.O_RDONLY | constants17.O_NOFOLLOW);
46214
46361
  try {
46215
- fsyncSync5(fd);
46362
+ fsyncSync6(fd);
46216
46363
  } finally {
46217
- closeSync19(fd);
46364
+ closeSync20(fd);
46218
46365
  }
46219
46366
  }
46220
46367
  function bind(client, receipt) {
@@ -46222,23 +46369,23 @@ function bind(client, receipt) {
46222
46369
  throw new PrivatePublicationError("PUBLICATION_IDENTITY_CHANGED", "The fresh session does not match the recovery directory's server, account and membership.");
46223
46370
  }
46224
46371
  async function locked(directory2, action) {
46225
- const identity3 = safeDirectory(directory2), file2 = join40(directory2, "operation.lock");
46372
+ const identity3 = safeDirectory(directory2), file2 = join41(directory2, "operation.lock");
46226
46373
  let fd;
46227
46374
  try {
46228
- fd = openSync19(file2, constants16.O_WRONLY | constants16.O_CREAT | constants16.O_EXCL | constants16.O_NOFOLLOW, 384);
46375
+ fd = openSync20(file2, constants17.O_WRONLY | constants17.O_CREAT | constants17.O_EXCL | constants17.O_NOFOLLOW, 384);
46229
46376
  } catch {
46230
46377
  throw new PrivatePublicationError("PUBLICATION_RECOVERY_BUSY", "Another operation holds this recovery directory. If it crashed, confirm that process has stopped before explicitly removing operation.lock and resuming.");
46231
46378
  }
46232
- const lock = fstatSync19(fd);
46379
+ const lock = fstatSync20(fd);
46233
46380
  try {
46234
46381
  writeFileSync14(fd, JSON.stringify({ pid: process.pid }) + `
46235
46382
  `);
46236
- fsyncSync5(fd);
46383
+ fsyncSync6(fd);
46237
46384
  return await action();
46238
46385
  } finally {
46239
- closeSync19(fd);
46386
+ closeSync20(fd);
46240
46387
  unchangedDirectory(directory2, identity3);
46241
- const now = lstatSync23(file2);
46388
+ const now = lstatSync24(file2);
46242
46389
  if (now.dev !== lock.dev || now.ino !== lock.ino || !now.isFile() || now.isSymbolicLink())
46243
46390
  fail2();
46244
46391
  unlinkSync6(file2);
@@ -46290,15 +46437,15 @@ async function preparePrivatePublication(client, sourceDirectory, recoveryDirect
46290
46437
  phase: "prepared",
46291
46438
  intent: null
46292
46439
  };
46293
- if (!isAbsolute21(recoveryDirectory) || resolve23(recoveryDirectory) !== recoveryDirectory || realpathSync12(dirname25(recoveryDirectory)) !== dirname25(recoveryDirectory))
46440
+ if (!isAbsolute23(recoveryDirectory) || resolve24(recoveryDirectory) !== recoveryDirectory || realpathSync12(dirname26(recoveryDirectory)) !== dirname26(recoveryDirectory))
46294
46441
  return fail2();
46295
- mkdirSync16(recoveryDirectory, { mode: 448 });
46442
+ mkdirSync17(recoveryDirectory, { mode: 448 });
46296
46443
  safeDirectory(recoveryDirectory);
46297
- const parent = openSync19(dirname25(recoveryDirectory), constants16.O_RDONLY | constants16.O_NOFOLLOW);
46444
+ const parent = openSync20(dirname26(recoveryDirectory), constants17.O_RDONLY | constants17.O_NOFOLLOW);
46298
46445
  try {
46299
- fsyncSync5(parent);
46446
+ fsyncSync6(parent);
46300
46447
  } finally {
46301
- closeSync19(parent);
46448
+ closeSync20(parent);
46302
46449
  }
46303
46450
  writeOwned(recoveryDirectory, "bundle.tgz", packed.bytes);
46304
46451
  save(recoveryDirectory, receipt);
@@ -46391,10 +46538,10 @@ var init_private_publication_recovery = __esm(() => {
46391
46538
  });
46392
46539
 
46393
46540
  // src/mcp/private-publication-tools.ts
46394
- import { isAbsolute as isAbsolute22 } from "path";
46541
+ import { isAbsolute as isAbsolute24 } from "path";
46395
46542
  function registerPrivatePublicationTools(server) {
46396
46543
  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}$/);
46397
- const directory2 = exports_external.string().max(4096).refine(isAbsolute22, "Use an absolute local directory");
46544
+ const directory2 = exports_external.string().max(4096).refine(isAbsolute24, "Use an absolute local directory");
46398
46545
  const verification2 = { email: exports_external.string().email().max(254), code: exports_external.string().regex(/^\d{6}$/), userId: uuid9, membershipId: uuid9, recoveryDirectory: directory2 };
46399
46546
  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.";
46400
46547
  const handler = (action) => async (value) => {
@@ -46827,19 +46974,19 @@ async function connectMcpForNode() {
46827
46974
  return { server: server2, transport };
46828
46975
  }
46829
46976
  function readBody(req) {
46830
- return new Promise((resolve24, reject) => {
46977
+ return new Promise((resolve25, reject) => {
46831
46978
  const chunks = [];
46832
46979
  req.on("data", (chunk) => chunks.push(Buffer.from(chunk)));
46833
46980
  req.on("end", () => {
46834
46981
  const raw = Buffer.concat(chunks).toString("utf-8");
46835
46982
  if (!raw.trim()) {
46836
- resolve24(undefined);
46983
+ resolve25(undefined);
46837
46984
  return;
46838
46985
  }
46839
46986
  try {
46840
- resolve24(JSON.parse(raw));
46987
+ resolve25(JSON.parse(raw));
46841
46988
  } catch {
46842
- resolve24(undefined);
46989
+ resolve25(undefined);
46843
46990
  }
46844
46991
  });
46845
46992
  req.on("error", reject);
@@ -46881,9 +47028,9 @@ async function startSkillsMcpHttpServer(options = {}) {
46881
47028
  }
46882
47029
  }
46883
47030
  });
46884
- await new Promise((resolve24, reject) => {
47031
+ await new Promise((resolve25, reject) => {
46885
47032
  httpServer.once("error", reject);
46886
- httpServer.listen(port, hostname4, () => resolve24());
47033
+ httpServer.listen(port, hostname4, () => resolve25());
46887
47034
  });
46888
47035
  const address = httpServer.address();
46889
47036
  const listenPort = typeof address === "object" && address ? address.port : port;