@hasna/skills 0.10.61 → 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.61",
26
+ version: "0.10.63",
27
27
  description: "Skills library for AI coding agents",
28
28
  type: "module",
29
29
  bin: {
@@ -64,6 +64,7 @@ var init_package = __esm(() => {
64
64
  "migrations/",
65
65
  "docs/skill-standard.md",
66
66
  "docs/plugin-admission.md",
67
+ "docs/runtime-activation.md",
67
68
  "schemas/",
68
69
  "LICENSE",
69
70
  "README.md",
@@ -74,8 +75,8 @@ var init_package = __esm(() => {
74
75
  types: "./dist/index.d.ts",
75
76
  scripts: {
76
77
  clean: "rm -rf bin/ dist/",
77
- build: "bun run clean && bun build --external @hasna/contracts/kernel-lock ./src/cli/index.tsx --outdir ./bin --target bun && bun build --external @modelcontextprotocol/sdk ./src/mcp/index.ts --outfile ./bin/mcp.js --target bun && bun build --external @hasna/contracts/kernel-lock ./src/server/index.ts --outfile ./bin/server.js --target bun && bun build --external @hasna/contracts/kernel-lock ./src/server/worker.ts --outfile ./bin/worker.js --target bun && bun build --external @hasna/contracts/kernel-lock ./src/server/migrate.ts --outfile ./bin/migrate.js --target bun && bun build --external @hasna/contracts/kernel-lock ./src/server/maintenance.ts --outfile ./bin/maintenance.js --target bun && bun build ./src/index.ts ./src/storage.ts ./src/sdk/index.ts ./src/admin-contract.ts --outdir ./dist --target bun && tsc --emitDeclarationOnly --declaration --outDir dist && bun scripts/stage-kernel-lock-assets.ts",
78
- "build:js": "rm -rf dist && bun build ./src/index.ts ./src/storage.ts ./src/sdk/index.ts ./src/admin-contract.ts --outdir ./dist --target bun && tsc --emitDeclarationOnly --declaration --outDir dist && bun scripts/stage-kernel-lock-assets.ts",
78
+ build: "bun run clean && bun build --external @hasna/contracts/kernel-lock ./src/cli/index.tsx --outdir ./bin --target bun && bun build --external @modelcontextprotocol/sdk ./src/mcp/index.ts --outfile ./bin/mcp.js --target bun && bun build --external @hasna/contracts/kernel-lock ./src/server/index.ts --outfile ./bin/server.js --target bun && bun build --external @hasna/contracts/kernel-lock ./src/server/worker.ts --outfile ./bin/worker.js --target bun && bun build --external @hasna/contracts/kernel-lock ./src/server/migrate.ts --outfile ./bin/migrate.js --target bun && bun build --external @hasna/contracts/kernel-lock ./src/server/maintenance.ts --outfile ./bin/maintenance.js --target bun && bun build ./src/index.ts ./src/storage.ts ./src/sdk/index.ts ./src/admin-contract.ts ./src/runtime-prerequisites.ts --outdir ./dist --target bun && tsc --emitDeclarationOnly --declaration --outDir dist && bun scripts/stage-kernel-lock-assets.ts",
79
+ "build:js": "rm -rf dist && bun build ./src/index.ts ./src/storage.ts ./src/sdk/index.ts ./src/admin-contract.ts ./src/runtime-prerequisites.ts --outdir ./dist --target bun && tsc --emitDeclarationOnly --declaration --outDir dist && bun scripts/stage-kernel-lock-assets.ts",
79
80
  test: "bun test --timeout 30000",
80
81
  dev: "bun run ./src/cli/index.tsx",
81
82
  "dev:watch": "bun --watch run ./src/cli/index.tsx",
@@ -152,6 +153,10 @@ var init_package = __esm(() => {
152
153
  homepage: "https://github.com/hasna/skills/tree/main/apps/skills",
153
154
  bugs: {
154
155
  url: "https://github.com/hasna/skills/issues"
156
+ },
157
+ skillsRuntimePrerequisites: {
158
+ version: 1,
159
+ entry: "dist/runtime-prerequisites.js"
155
160
  }
156
161
  };
157
162
  });
@@ -23114,6 +23119,15 @@ function assertAgentPolicyCollections(policy) {
23114
23119
  }
23115
23120
  } else
23116
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
+ }
23117
23131
  if (source.format !== undefined)
23118
23132
  requireBound(["json", "toml", "yaml"].includes(source.format));
23119
23133
  if (source.fields !== undefined)
@@ -32717,11 +32731,55 @@ var init_codex_hook_rpc = __esm(() => {
32717
32731
  });
32718
32732
 
32719
32733
  // src/lib/codex-native-skill-catalog.ts
32734
+ import { isAbsolute as isAbsolute10, normalize as normalize2 } from "path";
32720
32735
  function codexPluginSourceIsConfigControlled(plugin) {
32721
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"];
32722
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)));
32723
32738
  }
32724
- 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);
32725
32783
  var init_codex_native_skill_catalog = __esm(() => {
32726
32784
  init_codex_hook_rpc();
32727
32785
  init_codex_native_compatibility();
@@ -32731,7 +32789,7 @@ var init_codex_native_skill_catalog = __esm(() => {
32731
32789
  // src/lib/codex-plugin-skill-controls.ts
32732
32790
  import { basename as basename6, dirname as dirname12, join as join18, relative as relative5, resolve as resolve11, sep as sep6 } from "path";
32733
32791
  import { lstatSync as lstatSync12, readdirSync as readdirSync6, readlinkSync as readlinkSync3, realpathSync as realpathSync4 } from "fs";
32734
- function refuse() {
32792
+ function refuse2() {
32735
32793
  throw new Error("CODEX_NATIVE_SKILL_IDENTITY_UNSUPPORTED: review native plugin names and hook controls");
32736
32794
  }
32737
32795
  function remoteInstallationMatches(parent, remotePluginId, read) {
@@ -32756,17 +32814,17 @@ function appControls(path, read) {
32756
32814
  sha2562 = hashNativeJsonControls(text2);
32757
32815
  value = JSON.parse(text2);
32758
32816
  } catch {
32759
- refuse();
32817
+ refuse2();
32760
32818
  }
32761
- const object5 = (v) => Boolean(v && typeof v === "object" && !Array.isArray(v));
32762
- if (!object5(value) || Object.keys(value).length !== 1 || !object5(value.apps))
32763
- 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();
32764
32822
  const apps = Object.entries(value.apps);
32765
32823
  if (!apps.length || apps.length > 256)
32766
- refuse();
32824
+ refuse2();
32767
32825
  for (const [name, entry] of apps) {
32768
- 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")
32769
- 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();
32770
32828
  }
32771
32829
  return sha2562;
32772
32830
  }
@@ -32777,26 +32835,26 @@ function mcpControls(path, read) {
32777
32835
  sha2562 = hashNativeJsonControls(text2);
32778
32836
  value = JSON.parse(text2);
32779
32837
  } catch {
32780
- refuse();
32838
+ refuse2();
32781
32839
  }
32782
- const object5 = (v) => Boolean(v && typeof v === "object" && !Array.isArray(v));
32783
- if (!object5(value) || Object.keys(value).length !== 1 || !object5(value.mcpServers))
32784
- 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();
32785
32843
  const servers = Object.entries(value.mcpServers);
32786
32844
  if (!servers.length || servers.length > 256)
32787
- refuse();
32845
+ refuse2();
32788
32846
  for (const [name, server] of servers)
32789
32847
  if (!isCodexLocalStdioMcpServer(name, server))
32790
- refuse();
32848
+ refuse2();
32791
32849
  return sha2562;
32792
32850
  }
32793
32851
  function isBundledCleanupHooks(root, namespace, value) {
32794
- const object5 = (v) => Boolean(v && typeof v === "object" && !Array.isArray(v));
32852
+ const object6 = (v) => Boolean(v && typeof v === "object" && !Array.isArray(v));
32795
32853
  const exactKeys = (v, keys) => Object.keys(v).length === keys.length && keys.every((key) => Object.hasOwn(v, key));
32796
32854
  if (basename6(dirname12(root)) !== namespace || basename6(dirname12(dirname12(root))) !== "openai-bundled")
32797
32855
  return false;
32798
32856
  const server = namespace === "unified-computer-use" ? "cua_repl" : ["browser", "chrome", "chrome-dev", "chrome-internal", "computer-use"].includes(namespace) ? "node_repl" : undefined;
32799
- if (!server || !object5(value) || !exactKeys(value, ["hooks"]) || !object5(value.hooks))
32857
+ if (!server || !object6(value) || !exactKeys(value, ["hooks"]) || !object6(value.hooks))
32800
32858
  return false;
32801
32859
  const events = Object.entries(value.hooks);
32802
32860
  if (!events.length || events.length > 3)
@@ -32805,10 +32863,10 @@ function isBundledCleanupHooks(root, namespace, value) {
32805
32863
  if (!["Interrupt", "SubagentStop", "Stop"].includes(event) || !Array.isArray(groups) || groups.length !== 1)
32806
32864
  return false;
32807
32865
  const group = groups[0];
32808
- 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)
32809
32867
  return false;
32810
32868
  const handler = group.hooks[0];
32811
- 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}"))
32812
32870
  return false;
32813
32871
  }
32814
32872
  return true;
@@ -32816,35 +32874,35 @@ function isBundledCleanupHooks(root, namespace, value) {
32816
32874
  function rootControls(root, read) {
32817
32875
  const manifestPath = join18(root, ".codex-plugin/plugin.json"), manifestFile = lstatSync12(manifestPath, { throwIfNoEntry: false });
32818
32876
  if (!lstatSync12(join18(root, ".codex-plugin"), { throwIfNoEntry: false })?.isDirectory() || !manifestFile?.isFile() || manifestFile.size > 1024 * 1024)
32819
- refuse();
32877
+ refuse2();
32820
32878
  let manifest, manifestSha256;
32821
32879
  try {
32822
32880
  const text2 = read(manifestPath);
32823
32881
  manifestSha256 = hashNativeJsonControls(text2, "version");
32824
32882
  manifest = JSON.parse(text2);
32825
32883
  } catch {
32826
- refuse();
32884
+ refuse2();
32827
32885
  }
32828
32886
  if (!manifest || typeof manifest !== "object" || Array.isArray(manifest) || !identifier2(manifest.name))
32829
- refuse();
32887
+ refuse2();
32830
32888
  const cacheVersion = basename6(root), declaredVersion = manifest.version === undefined ? "" : typeof manifest.version === "string" ? manifest.version.trim() : null;
32831
32889
  if (declaredVersion === null || (declaredVersion ? declaredVersion !== cacheVersion : cacheVersion !== CODEX_DEFAULT_AGENT_PLUGIN_VERSION))
32832
- refuse();
32890
+ refuse2();
32833
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 }))
32834
- refuse();
32892
+ refuse2();
32835
32893
  const mcp = join18(root, ".mcp.json"), mcpPresent = lstatSync12(mcp, { throwIfNoEntry: false });
32836
32894
  if (manifest.hooks !== undefined && (manifest.mcpServers !== undefined || mcpPresent))
32837
- refuse();
32895
+ refuse2();
32838
32896
  if (mcpPresent && (!mcpPresent.isFile() || mcpPresent.isSymbolicLink() || mcpPresent.size > 1024 * 1024 || realpathSync4(mcp) !== mcp))
32839
- refuse();
32897
+ refuse2();
32840
32898
  if (Boolean(mcpPresent) !== (manifest.mcpServers !== undefined))
32841
- refuse();
32899
+ refuse2();
32842
32900
  const mcpSha256 = mcpPresent ? mcpControls(mcp, read) : undefined;
32843
32901
  const app = join18(root, ".app.json"), present = lstatSync12(app, { throwIfNoEntry: false });
32844
32902
  if (present && (!present.isFile() || present.isSymbolicLink() || present.size > 1024 * 1024))
32845
- refuse();
32903
+ refuse2();
32846
32904
  if (manifest.apps !== undefined && !present)
32847
- refuse();
32905
+ refuse2();
32848
32906
  const appSha256 = present ? appControls(app, read) : undefined;
32849
32907
  return { namespace: manifest.name, manifestSha256, ...appSha256 ? { appSha256 } : {}, ...mcpSha256 ? { mcpSha256 } : {} };
32850
32908
  }
@@ -32960,10 +33018,10 @@ function sourceInputUnchanged(input2, cache, read) {
32960
33018
  }
32961
33019
  function reviewedCodexPluginSourceRoots(cache, inputs, read) {
32962
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)))
32963
- refuse();
33021
+ refuse2();
32964
33022
  const roots = inputs.map((input2) => input2.sourceRoot);
32965
33023
  if (roots.some((root) => roots.some((other) => root !== other && root.startsWith(other + sep6))))
32966
- refuse();
33024
+ refuse2();
32967
33025
  return roots;
32968
33026
  }
32969
33027
  var identifier2 = (v) => typeof v === "string" && /^[A-Za-z0-9_-]{1,64}$/.test(v), CODEX_DEFAULT_AGENT_PLUGIN_VERSION = "1.0.0";
@@ -33218,7 +33276,7 @@ function canonical6(value, depth = 0, budget2 = { remaining: 65536 }) {
33218
33276
  need5(isRecord3(value));
33219
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)])];
33220
33278
  }
33221
- function normalize2(config2, version2 = 2) {
33279
+ function normalize3(config2, version2 = 2) {
33222
33280
  if (isRecord3(config2.hooks)) {
33223
33281
  delete config2.hooks.state;
33224
33282
  if (!Object.keys(config2.hooks).length)
@@ -33389,7 +33447,7 @@ function settingsDigest2(text2, version2 = 2) {
33389
33447
  need5(isRecord3(config2));
33390
33448
  const mcp = version2 >= 3 ? projectRegularCodexMcp(config2, text2) : { config: config2, numericSource: text2 };
33391
33449
  const projected = version2 === 4 ? projectModelAvailabilityNux(mcp.config, mcp.numericSource) : mcp;
33392
- normalize2(projected.config, version2);
33450
+ normalize3(projected.config, version2);
33393
33451
  return sha2(`hasna.skills.codex-settings.v${version2}\x00${JSON.stringify([canonical6(projected.config), numericTokens2(projected.numericSource)])}`);
33394
33452
  }
33395
33453
  function hashCodexSettingsReplacementV2(text2, budget2 = { remaining: 256 * 1024 * 1024 }) {
@@ -33540,15 +33598,15 @@ var init_agent_codex = () => {};
33540
33598
  // src/lib/agent-sumi.ts
33541
33599
  import { spawnSync as spawnSync4 } from "child_process";
33542
33600
  import { accessSync, constants as constants8, existsSync as existsSync8, lstatSync as lstatSync14, realpathSync as realpathSync5, statSync as statSync7 } from "fs";
33543
- 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";
33544
33602
  function recordWithKeys(value, keys) {
33545
33603
  return value !== null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
33546
33604
  }
33547
- function absolutePath2(value) {
33548
- 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;
33549
33607
  }
33550
33608
  function absoluteInput(value) {
33551
- 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);
33552
33610
  }
33553
33611
  function resolveSumiPathsCommand(pathValue) {
33554
33612
  if (!pathValue)
@@ -33573,18 +33631,18 @@ function validPathPlan(value, home, cwd) {
33573
33631
  if (!recordWithKeys(value.roots, SUMI_PATH_KEYS) || !recordWithKeys(value.legacyRoots, SUMI_PATH_KEYS))
33574
33632
  return false;
33575
33633
  for (const key of SUMI_PATH_KEYS) {
33576
- if (!absolutePath2(value.roots[key]))
33634
+ if (!absolutePath3(value.roots[key]))
33577
33635
  return false;
33578
- if (value.legacyRoots[key] !== null && !absolutePath2(value.legacyRoots[key]))
33636
+ if (value.legacyRoots[key] !== null && !absolutePath3(value.legacyRoots[key]))
33579
33637
  return false;
33580
33638
  }
33581
33639
  if (!recordWithKeys(value.configFiles, ["canonical", "legacy"]) || !recordWithKeys(value.skillRoots, ["canonical", "legacy"]))
33582
33640
  return false;
33583
- if (!absolutePath2(value.configFiles.canonical) || !absolutePath2(value.skillRoots.canonical))
33641
+ if (!absolutePath3(value.configFiles.canonical) || !absolutePath3(value.skillRoots.canonical))
33584
33642
  return false;
33585
- if (value.configFiles.legacy !== null && !absolutePath2(value.configFiles.legacy))
33643
+ if (value.configFiles.legacy !== null && !absolutePath3(value.configFiles.legacy))
33586
33644
  return false;
33587
- if (value.skillRoots.legacy !== null && !absolutePath2(value.skillRoots.legacy))
33645
+ if (value.skillRoots.legacy !== null && !absolutePath3(value.skillRoots.legacy))
33588
33646
  return false;
33589
33647
  const configRoot = value.roots.config;
33590
33648
  const legacyConfigRoot = value.legacyRoots.config;
@@ -33604,7 +33662,7 @@ function sumiPathPlan(home, cwd = process.cwd(), env = process.env) {
33604
33662
  throw new SumiPathResolverError("SUMI_PATH_INPUT_REFUSED");
33605
33663
  const runtimePath = process.env.PATH ?? "";
33606
33664
  const executable = resolveSumiPathsCommand(runtimePath);
33607
- if (!executable || !isAbsolute10(executable))
33665
+ if (!executable || !isAbsolute11(executable))
33608
33666
  throw new SumiPathResolverError("SUMI_PATH_RESOLVER_UNAVAILABLE");
33609
33667
  const childEnv = { PATH: runtimePath };
33610
33668
  for (const key of SUMI_PATH_SELECTORS)
@@ -33680,7 +33738,7 @@ var init_agent_sumi = __esm(() => {
33680
33738
  // src/lib/codex-hook-trust-files.ts
33681
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";
33682
33740
  import { createHash as createHash15 } from "crypto";
33683
- 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";
33684
33742
  function need6(value, code) {
33685
33743
  if (!value)
33686
33744
  throw new Error(`CODEX_HOOK_TRUST_${code}`);
@@ -33780,6 +33838,96 @@ var init_runtime_launcher = __esm(() => {
33780
33838
  PINNED_LAUNCHER_MAX_BYTES = 16 * 1024;
33781
33839
  });
33782
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
+
33783
33931
  // src/lib/agent-integration.ts
33784
33932
  var init_agent_integration = __esm(() => {
33785
33933
  init_sumi_settings_witness();
@@ -33801,6 +33949,7 @@ var init_agent_integration = __esm(() => {
33801
33949
  init_claude_settings_witness();
33802
33950
  init_codex_hook_trust_files();
33803
33951
  init_runtime_launcher();
33952
+ init_retained_review_artifacts();
33804
33953
  });
33805
33954
 
33806
33955
  // src/lib/home-migration.ts
@@ -33837,13 +33986,13 @@ var init_skill_aliases = __esm(() => {
33837
33986
  });
33838
33987
 
33839
33988
  // src/lib/project-state.ts
33840
- import { existsSync as existsSync9, mkdirSync as mkdirSync5, readFileSync as readFileSync13, writeFileSync as writeFileSync5 } from "fs";
33841
- 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";
33842
33991
  function getProjectStateDir(targetDir = process.cwd()) {
33843
- return join21(targetDir, SKILLS_PROJECT_DIR);
33992
+ return join22(targetDir, SKILLS_PROJECT_DIR);
33844
33993
  }
33845
33994
  function getProjectConfigPath(targetDir = process.cwd()) {
33846
- return join21(getProjectStateDir(targetDir), PROJECT_CONFIG_FILE);
33995
+ return join22(getProjectStateDir(targetDir), PROJECT_CONFIG_FILE);
33847
33996
  }
33848
33997
  function loadProjectConfig(targetDir = process.cwd()) {
33849
33998
  const path = getProjectConfigPath(targetDir);
@@ -33871,7 +34020,7 @@ function ensureProjectConfig(targetDir = process.cwd()) {
33871
34020
  }
33872
34021
  function saveProjectConfig(config2, targetDir = process.cwd()) {
33873
34022
  const dir = getProjectStateDir(targetDir);
33874
- mkdirSync5(dir, { recursive: true });
34023
+ mkdirSync6(dir, { recursive: true });
33875
34024
  const normalized = normalizeProjectConfig({ ...config2, updatedAt: new Date().toISOString() });
33876
34025
  writeFileSync5(getProjectConfigPath(targetDir), JSON.stringify(normalized, null, 2) + `
33877
34026
  `);
@@ -33959,7 +34108,7 @@ var init_project_state = __esm(() => {
33959
34108
 
33960
34109
  // src/lib/installer.ts
33961
34110
  import { existsSync as existsSync10, readFileSync as readFileSync14, rmSync } from "fs";
33962
- import { join as join22 } from "path";
34111
+ import { join as join23 } from "path";
33963
34112
  import { homedir as homedir2 } from "os";
33964
34113
  function getSkillPath(name) {
33965
34114
  const skillName = normalizeSkillName(getCanonicalSkillName(name));
@@ -33969,7 +34118,7 @@ function getSkillPath(name) {
33969
34118
  const extensionPath = findExtensionSkillPath(skillName);
33970
34119
  if (extensionPath)
33971
34120
  return extensionPath;
33972
- return join22(getPortableSkillsRoot(), skillName);
34121
+ return join23(getPortableSkillsRoot(), skillName);
33973
34122
  }
33974
34123
  function getCanonicalSkillName(name) {
33975
34124
  return getSkill(name)?.name ?? resolveSkillAlias(normalizeSkillSlug(name));
@@ -34023,11 +34172,11 @@ function getAgentSkillsDir(agent, scope = "global", projectDir) {
34023
34172
  const base = projectDir || process.cwd();
34024
34173
  switch (agent) {
34025
34174
  case "pi":
34026
- 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");
34027
34176
  case "opencode":
34028
- 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");
34029
34178
  default:
34030
- return scope === "project" ? join22(base, `.${agent}`, "skills") : join22(homedir2(), `.${agent}`, "skills");
34179
+ return scope === "project" ? join23(base, `.${agent}`, "skills") : join23(homedir2(), `.${agent}`, "skills");
34031
34180
  }
34032
34181
  }
34033
34182
  function warnMissingDependencies(name, targetDir) {
@@ -34042,7 +34191,7 @@ function warnMissingDependencies(name, targetDir) {
34042
34191
  }
34043
34192
  }
34044
34193
  function readBundledSkillVersion(name) {
34045
- const pkgPath = join22(getSkillPath(name), "package.json");
34194
+ const pkgPath = join23(getSkillPath(name), "package.json");
34046
34195
  if (!existsSync10(pkgPath))
34047
34196
  return "unknown";
34048
34197
  try {
@@ -34112,11 +34261,11 @@ var init_skill_doc_file = __esm(() => {
34112
34261
 
34113
34262
  // src/lib/skillinfo.ts
34114
34263
  import { existsSync as existsSync11, readFileSync as readFileSync15 } from "fs";
34115
- import { join as join23 } from "path";
34264
+ import { join as join24 } from "path";
34116
34265
  function isInstructionSkillDir(skillPath, meta3) {
34117
34266
  if (meta3?.kind === "instruction")
34118
34267
  return true;
34119
- const skillMdPath = join23(skillPath, "SKILL.md");
34268
+ const skillMdPath = join24(skillPath, "SKILL.md");
34120
34269
  if (!existsSync11(skillMdPath))
34121
34270
  return false;
34122
34271
  try {
@@ -34130,9 +34279,9 @@ function getSkillDocs(name) {
34130
34279
  if (!existsSync11(skillPath))
34131
34280
  return null;
34132
34281
  return {
34133
- skillMd: readIfExists(join23(skillPath, "SKILL.md")),
34134
- readme: readIfExists(join23(skillPath, "README.md")),
34135
- 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"))
34136
34285
  };
34137
34286
  }
34138
34287
  function getSkillBestDoc(name, file2) {
@@ -34148,14 +34297,14 @@ function getSkillRequirements(name) {
34148
34297
  return null;
34149
34298
  const texts = [];
34150
34299
  for (const file2 of ["SKILL.md", "README.md", "CLAUDE.md", ".env.example", ".env.local.example"]) {
34151
- const content = readIfExists(join23(skillPath, file2));
34300
+ const content = readIfExists(join24(skillPath, file2));
34152
34301
  if (content)
34153
34302
  texts.push(content);
34154
34303
  }
34155
34304
  const meta3 = getSkill(name);
34156
34305
  let dependencies = {};
34157
34306
  try {
34158
- dependencies = JSON.parse(readFileSync15(join23(skillPath, "package.json"), "utf8")).dependencies || {};
34307
+ dependencies = JSON.parse(readFileSync15(join24(skillPath, "package.json"), "utf8")).dependencies || {};
34159
34308
  } catch {}
34160
34309
  return getSkillRequirementsFromContent(name, texts, dependencies, meta3);
34161
34310
  }
@@ -34217,7 +34366,7 @@ async function runSkill(name, args, options = {}) {
34217
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'.`
34218
34367
  };
34219
34368
  }
34220
- const pkgPath = join23(skillPath, "package.json");
34369
+ const pkgPath = join24(skillPath, "package.json");
34221
34370
  if (!existsSync11(pkgPath)) {
34222
34371
  return { exitCode: 1, error: `No package.json in skill '${name}'` };
34223
34372
  }
@@ -34237,12 +34386,12 @@ async function runSkill(name, args, options = {}) {
34237
34386
  } catch {
34238
34387
  return { exitCode: 1, error: `Failed to parse package.json for skill '${name}'` };
34239
34388
  }
34240
- const entryPath = join23(skillPath, entryPoint2);
34389
+ const entryPath = join24(skillPath, entryPoint2);
34241
34390
  if (!existsSync11(entryPath)) {
34242
34391
  return { exitCode: 1, error: `Entry point '${entryPoint2}' not found in skill '${name}'` };
34243
34392
  }
34244
34393
  const env = { ...process.env, ...options.env };
34245
- if (!existsSync11(join23(skillPath, "node_modules")) || hasDependencyPreparationMarker(skillPath)) {
34394
+ if (!existsSync11(join24(skillPath, "node_modules")) || hasDependencyPreparationMarker(skillPath)) {
34246
34395
  const failure = await prepareSkillDependencies(skillPath, env, options.preparationTimeoutMs);
34247
34396
  if (failure)
34248
34397
  return failure;
@@ -34268,7 +34417,7 @@ async function runSkill(name, args, options = {}) {
34268
34417
  function detectProjectSkills(cwd = process.cwd()) {
34269
34418
  let pkg;
34270
34419
  try {
34271
- pkg = JSON.parse(readFileSync15(join23(cwd, "package.json"), "utf8"));
34420
+ pkg = JSON.parse(readFileSync15(join24(cwd, "package.json"), "utf8"));
34272
34421
  } catch {
34273
34422
  return { detected: [], recommended: [] };
34274
34423
  }
@@ -34473,7 +34622,7 @@ var init_selection_resolver = __esm(() => {
34473
34622
  });
34474
34623
 
34475
34624
  // src/lib/plugin-projection.ts
34476
- import { createHash as createHash16 } from "crypto";
34625
+ import { createHash as createHash17 } from "crypto";
34477
34626
  function pluginRefusal(message) {
34478
34627
  throw new SkillSelectionError("PLUGIN_ADMISSION_REFUSED", message);
34479
34628
  }
@@ -34484,8 +34633,8 @@ function pluginNeed(value, message) {
34484
34633
  function pluginObject(value) {
34485
34634
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
34486
34635
  }
34487
- function pluginKeys(value, keys) {
34488
- 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");
34489
34638
  }
34490
34639
  function pluginText(value, limit = 4096) {
34491
34640
  pluginNeed(typeof value === "string" && value.length > 0 && value.length <= limit && !/[\x00-\x1f\x7f]/.test(value), "Invalid plugin contract text");
@@ -34551,18 +34700,18 @@ function pluginFileWitnesses(entries) {
34551
34700
  return { path: item.path, mode: item.mode, size: item.bytes.byteLength, sha256: pluginHash(item.bytes) };
34552
34701
  });
34553
34702
  }
34554
- 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");
34555
34704
  var init_plugin_projection = __esm(() => {
34556
34705
  init_selection_cache();
34557
34706
  PLUGIN_PROJECTION_LIMITS = Object.freeze({ files: 1024, bytes: 64 * 1024 * 1024, fileBytes: 16 * 1024 * 1024, metadataBytes: 512 * 1024, registrations: 64, history: 128 });
34558
34707
  });
34559
34708
 
34560
34709
  // src/lib/plugin-projection-store.ts
34561
- 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";
34562
- 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";
34563
34712
  function stat(path) {
34564
34713
  try {
34565
- return lstatSync16(path, { bigint: true });
34714
+ return lstatSync17(path, { bigint: true });
34566
34715
  } catch (error61) {
34567
34716
  if (missing(error61))
34568
34717
  return null;
@@ -34570,7 +34719,7 @@ function stat(path) {
34570
34719
  }
34571
34720
  }
34572
34721
  function canonical7(path) {
34573
- 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");
34574
34723
  }
34575
34724
  function owner(stats, system = false) {
34576
34725
  const current = uid();
@@ -34581,15 +34730,15 @@ function same3(left, right, identityOnly = false) {
34581
34730
  }
34582
34731
  function ancestors(path, create = false) {
34583
34732
  canonical7(path);
34584
- const result = [], parent = dirname14(path), filesystemRoot = parse10(parent).root;
34733
+ const result = [], parent = dirname15(path), filesystemRoot = parse10(parent).root;
34585
34734
  let current = filesystemRoot;
34586
34735
  for (const segment of ["", ...parent.slice(filesystemRoot.length).split("/").filter(Boolean)]) {
34587
34736
  if (segment)
34588
- current = join24(current, segment);
34737
+ current = join25(current, segment);
34589
34738
  let currentStat = stat(current);
34590
34739
  if (!currentStat && create) {
34591
34740
  try {
34592
- mkdirSync6(current, { mode: 448 });
34741
+ mkdirSync7(current, { mode: 448 });
34593
34742
  } catch (error61) {
34594
34743
  if (!(error61 && typeof error61 === "object" && ("code" in error61) && error61.code === "EEXIST"))
34595
34744
  pluginRefusal("Cannot create private plugin storage directory");
@@ -34631,19 +34780,19 @@ function readBytes(path, maximum, kind) {
34631
34780
  fileShape(before, maximum, kind);
34632
34781
  let fd;
34633
34782
  try {
34634
- fd = openSync12(path, READ_FLAGS);
34635
- const opened = fstatSync12(fd, { bigint: true });
34783
+ fd = openSync13(path, READ_FLAGS);
34784
+ const opened = fstatSync13(fd, { bigint: true });
34636
34785
  same3(before, opened);
34637
34786
  fileShape(opened, maximum, kind);
34638
34787
  const bytes = new Uint8Array(Number(opened.size));
34639
34788
  let offset = 0;
34640
34789
  while (offset < bytes.byteLength) {
34641
- const count = readSync7(fd, bytes, offset, bytes.byteLength - offset, null);
34790
+ const count = readSync8(fd, bytes, offset, bytes.byteLength - offset, null);
34642
34791
  pluginNeed(count > 0, "Plugin file changed while being read");
34643
34792
  offset += count;
34644
34793
  }
34645
- pluginNeed(readSync7(fd, new Uint8Array(1), 0, 1, null) === 0, "Plugin file grew while being read");
34646
- 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 }));
34647
34796
  same3(opened, stat(path));
34648
34797
  verifyAncestors(chain);
34649
34798
  return bytes;
@@ -34653,7 +34802,7 @@ function readBytes(path, maximum, kind) {
34653
34802
  return pluginRefusal("Cannot safely read plugin file");
34654
34803
  } finally {
34655
34804
  if (fd !== undefined)
34656
- closeSync12(fd);
34805
+ closeSync13(fd);
34657
34806
  }
34658
34807
  }
34659
34808
  function exactPaths(entries) {
@@ -34693,7 +34842,7 @@ function snapshotPluginTree(root, options = {}) {
34693
34842
  pluginNeed(++visited <= PLUGIN_PROJECTION_LIMITS.files * 50, "Plugin tree membership exceeds its limit");
34694
34843
  const path = relative6 ? `${relative6}/${name}` : name;
34695
34844
  pluginNeed(new TextEncoder().encode(path).byteLength <= 100 && !/[\\:\x00-\x1f\x7f]/u.test(path), "Plugin entry path exceeds its limit or is unsafe");
34696
- const absolute = join24(directory, name), entryStat = stat(absolute);
34845
+ const absolute = join25(directory, name), entryStat = stat(absolute);
34697
34846
  pluginNeed(entryStat, "Plugin tree member disappeared");
34698
34847
  if (relative6 === "" && name === ".orphaned_at" && (options.nativeRuntime === "claude-2.1.274" || options.nativeRuntime === "claude-2.1.276")) {
34699
34848
  const bytes2 = readBytes(absolute, 32, "native-pin");
@@ -34710,7 +34859,7 @@ function snapshotPluginTree(root, options = {}) {
34710
34859
  directories.push({ path: absolute, stat: entryStat, names: pins });
34711
34860
  for (const pin of pins) {
34712
34861
  pluginNeed(/^[1-9][0-9]{0,9}$/.test(pin) && Number(pin) <= 2147483647, "Unrecognized native plugin pin name");
34713
- const pinPath = join24(absolute, pin), pinStat = stat(pinPath);
34862
+ const pinPath = join25(absolute, pin), pinStat = stat(pinPath);
34714
34863
  pluginNeed(pinStat, "Native plugin pin disappeared");
34715
34864
  const bytes2 = readBytes(pinPath, 4096, "native-pin");
34716
34865
  let value;
@@ -34776,8 +34925,8 @@ function readPluginJson(path) {
34776
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");
34777
34926
  var init_plugin_projection_store = __esm(() => {
34778
34927
  init_plugin_projection();
34779
- READ_FLAGS = constants10.O_RDONLY | constants10.O_NOFOLLOW | constants10.O_NONBLOCK;
34780
- 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;
34781
34930
  });
34782
34931
 
34783
34932
  // src/lib/selected-manifest.ts
@@ -34807,7 +34956,7 @@ var init_selected_manifest = __esm(() => {
34807
34956
  });
34808
34957
 
34809
34958
  // src/lib/plugin-admission.ts
34810
- 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";
34811
34960
  function validatePluginTarget(value) {
34812
34961
  pluginKeys(value, ["schemaVersion", "pluginId", "registrations", "native", "resolver"]);
34813
34962
  pluginNeed(value.schemaVersion === 1, "Invalid plugin admission target");
@@ -34817,7 +34966,7 @@ function validatePluginTarget(value) {
34817
34966
  for (const registration of value.registrations) {
34818
34967
  pluginKeys(registration, ["scope", "projectPath"]);
34819
34968
  pluginNeed(registration.scope === "user" || registration.scope === "project", "Unsupported plugin registration scope");
34820
- 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");
34821
34970
  const key = JSON.stringify([registration.scope, registration.projectPath]);
34822
34971
  pluginNeed(!scopes.has(key), "Duplicate plugin registration scope");
34823
34972
  scopes.add(key);
@@ -34825,7 +34974,7 @@ function validatePluginTarget(value) {
34825
34974
  for (const key of ["native", "resolver"]) {
34826
34975
  pluginKeys(value[key], key === "native" ? ["version", "executable", "digest"] : ["executable", "digest"]);
34827
34976
  pluginText(value[key].executable);
34828
- 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");
34829
34978
  pluginDigest(value[key].digest);
34830
34979
  }
34831
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)");
@@ -34968,12 +35117,12 @@ function pluginResolverCommand(binding) {
34968
35117
  }
34969
35118
  function pluginBindingPath(storeRoot, id) {
34970
35119
  pluginNeed(/^[a-f0-9]{64}$/.test(id), "Invalid plugin binding identifier");
34971
- return join25(storeRoot, "bindings", `${id}.json`);
35120
+ return join26(storeRoot, "bindings", `${id}.json`);
34972
35121
  }
34973
35122
  function pluginReceiptPath(storeRoot, id, digest) {
34974
35123
  pluginNeed(/^[a-f0-9]{64}$/.test(id), "Invalid plugin binding identifier");
34975
35124
  pluginDigest(digest);
34976
- return join25(storeRoot, "receipts", id, `${digest.slice(7)}.json`);
35125
+ return join26(storeRoot, "receipts", id, `${digest.slice(7)}.json`);
34977
35126
  }
34978
35127
  function readPluginBinding(storeRoot, id) {
34979
35128
  const value = readPluginJson(pluginBindingPath(storeRoot, id));
@@ -34993,7 +35142,7 @@ function readPluginAdmissionReceipt(storeRoot, id, digest) {
34993
35142
  pluginNeed(receipt.plan.bindingId === id && receipt.plan.planDigest === digest, "Plugin receipt identity differs from its filename");
34994
35143
  const binding = readPluginBinding(storeRoot, id);
34995
35144
  pluginNeed(canonicalJson(binding) === canonicalJson(receipt.plan.binding) && receipt.plan.sourceCommand === pluginResolverCommand(binding), "Plugin receipt binding changed");
34996
- 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");
34997
35146
  pluginText(receipt.admittedAt, 64);
34998
35147
  pluginNeed(Number.isFinite(Date.parse(receipt.admittedAt)), "Invalid plugin admission time");
34999
35148
  return receipt;
@@ -35010,8 +35159,8 @@ var init_plugin_admission = __esm(() => {
35010
35159
  });
35011
35160
 
35012
35161
  // src/lib/plugin-discovery.ts
35013
- import { closeSync as closeSync13, constants as constants11, fstatSync as fstatSync13, lstatSync as lstatSync17, openSync as openSync13, opendirSync as opendirSync3, readSync as readSync8 } from "fs";
35014
- 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";
35015
35164
  function validateManagedPluginWitnesses(value) {
35016
35165
  pluginNeed(Array.isArray(value) && value.length > 0 && value.length <= PLUGIN_PROJECTION_LIMITS.registrations, "Invalid managed plugin witness collection");
35017
35166
  const seen = new Set;
@@ -35020,36 +35169,36 @@ function validateManagedPluginWitnesses(value) {
35020
35169
  pluginNeed(typeof item.bindingId === "string" && /^[a-f0-9]{64}$/.test(item.bindingId) && !seen.has(item.bindingId), "Invalid or duplicate managed plugin witness");
35021
35170
  seen.add(item.bindingId);
35022
35171
  pluginText(item.storeRoot);
35023
- 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");
35024
35173
  }
35025
35174
  }
35026
- function safe3(path) {
35175
+ function safe4(path) {
35027
35176
  pluginText(path);
35028
- pluginNeed(isAbsolute14(path) && resolve16(path) === path, "Invalid plugin registry path");
35029
- for (let at = path;; at = dirname15(at)) {
35030
- pluginNeed(!lstatSync17(at, { throwIfNoEntry: false })?.isSymbolicLink(), "Plugin registry path traverses a symlink");
35031
- 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))
35032
35181
  break;
35033
35182
  }
35034
35183
  }
35035
35184
  function readRegistry(path) {
35036
- safe3(path);
35037
- const initial = lstatSync17(path);
35185
+ safe4(path);
35186
+ const initial = lstatSync18(path);
35038
35187
  pluginNeed(initial.isFile() && initial.size <= 1024 * 1024, "Plugin registry is not a bounded regular file");
35039
- 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);
35040
35189
  try {
35041
- const opened = fstatSync13(fd);
35190
+ const opened = fstatSync14(fd);
35042
35191
  pluginNeed(opened.isFile() && opened.ino === initial.ino && opened.dev === initial.dev, "Plugin registry changed during open");
35043
35192
  const bytes = Buffer.alloc(1024 * 1024 + 1);
35044
35193
  let length = 0;
35045
35194
  while (length < bytes.length) {
35046
- const count = readSync8(fd, bytes, length, bytes.length - length, null);
35195
+ const count = readSync9(fd, bytes, length, bytes.length - length, null);
35047
35196
  if (!count)
35048
35197
  break;
35049
35198
  length += count;
35050
35199
  }
35051
- const after = fstatSync13(fd), current = lstatSync17(path);
35052
- safe3(path);
35200
+ const after = fstatSync14(fd), current = lstatSync18(path);
35201
+ safe4(path);
35053
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");
35054
35203
  let value;
35055
35204
  try {
@@ -35060,7 +35209,7 @@ function readRegistry(path) {
35060
35209
  pluginNeed(pluginObject(value) && value.version === 2 && pluginObject(value.plugins), "Unsupported native plugin registry schema");
35061
35210
  return { value, rawDigest: pluginHash(bytes.subarray(0, length)) };
35062
35211
  } finally {
35063
- closeSync13(fd);
35212
+ closeSync14(fd);
35064
35213
  }
35065
35214
  }
35066
35215
  function nativeVersionMatches(version2, receipt) {
@@ -35078,7 +35227,7 @@ function hashManagedPluginRegistry(path, managed) {
35078
35227
  seen.add(target.pluginId);
35079
35228
  const rows = plugins[target.pluginId];
35080
35229
  pluginNeed(Array.isArray(rows) && rows.length === target.registrations.length, "Managed plugin registration membership changed");
35081
- 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);
35082
35231
  const scopes = new Set, approvals = new Map, currentFiles = new Map;
35083
35232
  plugins[target.pluginId] = rows.map((row) => {
35084
35233
  pluginNeed(pluginObject(row), "Invalid managed plugin registration");
@@ -35091,7 +35240,7 @@ function hashManagedPluginRegistry(path, managed) {
35091
35240
  pluginText(row.sourceProducerPath);
35092
35241
  pluginText(row.lastUpdated, 64);
35093
35242
  pluginNeed(Number.isFinite(Date.parse(row.lastUpdated)), "Invalid managed plugin update timestamp");
35094
- 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");
35095
35244
  const approval = (producer) => {
35096
35245
  pluginText(producer);
35097
35246
  const digest = `sha256:${basename7(producer)}`;
@@ -35120,8 +35269,8 @@ function hashManagedPluginRegistry(path, managed) {
35120
35269
  }
35121
35270
  return Object.fromEntries(Object.entries(row).filter(([key]) => !["version", "installPath", "sourceProducerPath", "previousProducerPaths", "lastUpdated"].includes(key)));
35122
35271
  });
35123
- safe3(cacheRoot);
35124
- const before = lstatSync17(cacheRoot);
35272
+ safe4(cacheRoot);
35273
+ const before = lstatSync18(cacheRoot);
35125
35274
  pluginNeed(before.isDirectory(), "Invalid managed plugin cache root");
35126
35275
  const directory = opendirSync3(cacheRoot), names = [];
35127
35276
  try {
@@ -35134,18 +35283,18 @@ function hashManagedPluginRegistry(path, managed) {
35134
35283
  directory.closeSync();
35135
35284
  }
35136
35285
  for (const version2 of names.sort()) {
35137
- 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}` }));
35138
35287
  verifiedBytes += files.reduce((total, file2) => total + file2.size, 0);
35139
35288
  pluginNeed(verifiedBytes <= 256 * 1024 * 1024, "Managed plugin verification exceeds its aggregate byte budget");
35140
35289
  const serialized = JSON.stringify(files);
35141
- const expected = currentFiles.get(join26(cacheRoot, version2));
35290
+ const expected = currentFiles.get(join27(cacheRoot, version2));
35142
35291
  pluginNeed(expected === undefined || serialized === expected, "Current native cache differs from its exact registered producer receipt");
35143
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");
35144
35293
  }
35145
35294
  for (const row of rows)
35146
35295
  pluginNeed(names.includes(row.version), "Managed native plugin installation is missing");
35147
- const after = lstatSync17(cacheRoot);
35148
- safe3(cacheRoot);
35296
+ const after = lstatSync18(cacheRoot);
35297
+ safe4(cacheRoot);
35149
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");
35150
35299
  }
35151
35300
  pluginNeed(readRegistry(path).rawDigest === snapshot2.rawDigest, "Native plugin registry changed during content verification");
@@ -35158,50 +35307,50 @@ var init_plugin_discovery = __esm(() => {
35158
35307
  });
35159
35308
 
35160
35309
  // src/lib/claude-marketplace-registry.ts
35161
- import { createHash as createHash17 } from "crypto";
35162
- import { closeSync as closeSync14, constants as constants12, fstatSync as fstatSync14, lstatSync as lstatSync18, openSync as openSync14, readSync as readSync9 } from "fs";
35163
- import { basename as basename8, dirname as dirname16, isAbsolute as isAbsolute15, resolve as resolve17 } from "path";
35164
- 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) {
35165
35314
  if (!value)
35166
35315
  throw new Error(`Claude marketplace registry ${reason2}`);
35167
35316
  }
35168
- function absolutePath3(value) {
35169
- 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");
35170
35319
  }
35171
35320
  function parents2(path) {
35172
35321
  const result = [];
35173
- for (let at = dirname16(path);; at = dirname16(at)) {
35174
- const stat2 = lstatSync18(at, { bigint: true });
35175
- 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");
35176
35325
  result.push([at, stat2]);
35177
- if (at === dirname16(at))
35326
+ if (at === dirname17(at))
35178
35327
  return result;
35179
35328
  }
35180
35329
  }
35181
35330
  function readRegistry2(path, budget2) {
35182
- absolutePath3(path);
35183
- need7(basename8(path) === "known_marketplaces.json", "requires known_marketplaces.json");
35184
- need7(Number.isSafeInteger(budget2.remaining) && budget2.remaining >= 0, "has an invalid byte budget");
35185
- const ancestors2 = parents2(path), initial = lstatSync18(path, { bigint: true });
35186
- need7(initial.isFile() && !initial.isSymbolicLink() && initial.size <= BigInt(CLAUDE_MARKETPLACE_REGISTRY_LIMITS.bytes), "is not a bounded regular file");
35187
- need7(initial.size <= BigInt(budget2.remaining), "exceeds its aggregate byte limit");
35188
- 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);
35189
35338
  try {
35190
- const opened = fstatSync14(fd, { bigint: true });
35191
- 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");
35192
35341
  const bytes = Buffer.alloc(Number(opened.size) + 1);
35193
35342
  let length = 0;
35194
35343
  while (length < bytes.length) {
35195
- const count = readSync9(fd, bytes, length, bytes.length - length, null);
35344
+ const count = readSync10(fd, bytes, length, bytes.length - length, null);
35196
35345
  if (!count)
35197
35346
  break;
35198
35347
  length += count;
35199
35348
  }
35200
- const after = fstatSync14(fd, { bigint: true }), current = lstatSync18(path, { bigint: true });
35201
- 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");
35202
35351
  for (const [ancestor, before] of ancestors2) {
35203
- const now = lstatSync18(ancestor, { bigint: true });
35204
- 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");
35205
35354
  }
35206
35355
  budget2.remaining -= length;
35207
35356
  try {
@@ -35210,7 +35359,7 @@ function readRegistry2(path, budget2) {
35210
35359
  throw new Error("Claude marketplace registry is not strict UTF-8");
35211
35360
  }
35212
35361
  } finally {
35213
- closeSync14(fd);
35362
+ closeSync15(fd);
35214
35363
  }
35215
35364
  }
35216
35365
  function parse11(text2) {
@@ -35221,7 +35370,7 @@ function parse11(text2) {
35221
35370
  at++;
35222
35371
  };
35223
35372
  function string4() {
35224
- need7(text2[at] === '"', "contains invalid JSON");
35373
+ need8(text2[at] === '"', "contains invalid JSON");
35225
35374
  const start = at++;
35226
35375
  while (at < text2.length) {
35227
35376
  const character = text2[at++];
@@ -35232,7 +35381,7 @@ function parse11(text2) {
35232
35381
  } catch {
35233
35382
  throw new Error("Claude marketplace registry contains invalid JSON string");
35234
35383
  }
35235
- 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");
35236
35385
  return value2;
35237
35386
  }
35238
35387
  if (character === "\\")
@@ -35241,7 +35390,7 @@ function parse11(text2) {
35241
35390
  throw new Error("Claude marketplace registry contains an unterminated JSON string");
35242
35391
  }
35243
35392
  function value(depth) {
35244
- 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");
35245
35394
  space();
35246
35395
  const character = text2[at];
35247
35396
  if (character === '"')
@@ -35249,26 +35398,26 @@ function parse11(text2) {
35249
35398
  if (character === "{" || character === "[") {
35250
35399
  at++;
35251
35400
  space();
35252
- const object5 = character === "{", end = object5 ? "}" : "]", entries = [], items = [], keys = new Set;
35401
+ const object6 = character === "{", end = object6 ? "}" : "]", entries = [], items = [], keys2 = new Set;
35253
35402
  if (text2[at] !== end)
35254
35403
  while (true) {
35255
- if (object5) {
35404
+ if (object6) {
35256
35405
  space();
35257
35406
  const key = string4();
35258
- need7(!keys.has(key), "contains a duplicate JSON key");
35259
- keys.add(key);
35407
+ need8(!keys2.has(key), "contains a duplicate JSON key");
35408
+ keys2.add(key);
35260
35409
  space();
35261
- need7(text2[at++] === ":", "contains invalid JSON");
35410
+ need8(text2[at++] === ":", "contains invalid JSON");
35262
35411
  entries.push([key, value(depth + 1)]);
35263
35412
  } else
35264
35413
  items.push(value(depth + 1));
35265
35414
  space();
35266
35415
  if (text2[at] === end)
35267
35416
  break;
35268
- need7(text2[at++] === ",", "contains invalid JSON");
35417
+ need8(text2[at++] === ",", "contains invalid JSON");
35269
35418
  }
35270
35419
  at++;
35271
- return object5 ? { kind: "object", entries } : { kind: "array", items };
35420
+ return object6 ? { kind: "object", entries } : { kind: "array", items };
35272
35421
  }
35273
35422
  for (const literal2 of ["true", "false", "null"])
35274
35423
  if (text2.startsWith(literal2, at)) {
@@ -35277,21 +35426,21 @@ function parse11(text2) {
35277
35426
  }
35278
35427
  numberPattern.lastIndex = at;
35279
35428
  const number4 = numberPattern.exec(text2);
35280
- need7(number4, "contains invalid JSON");
35429
+ need8(number4, "contains invalid JSON");
35281
35430
  at += number4[0].length;
35282
35431
  return { kind: "number", value: number4[0] };
35283
35432
  }
35284
35433
  const root = value(0);
35285
35434
  space();
35286
- need7(at === text2.length && root.kind === "object", "requires a JSON object without trailing content");
35287
- 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");
35288
35437
  return root;
35289
35438
  }
35290
- function exactKeys(value, keys) {
35291
- 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));
35292
35441
  }
35293
35442
  function textField(value) {
35294
- 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");
35295
35444
  return value.value;
35296
35445
  }
35297
35446
  function normalizeRow(row, version2 = 1) {
@@ -35299,7 +35448,7 @@ function normalizeRow(row, version2 = 1) {
35299
35448
  if (version2 !== 2 || !exactKeys(row, ["source", "installLocation", "lastUpdated", "autoUpdate"]))
35300
35449
  return;
35301
35450
  const autoUpdate = field2(row, "autoUpdate");
35302
- 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");
35303
35452
  }
35304
35453
  const source = field2(row, "source");
35305
35454
  if (source?.kind !== "object")
@@ -35312,29 +35461,29 @@ function normalizeRow(row, version2 = 1) {
35312
35461
  return;
35313
35462
  const sourceLocation = textField(field2(source, location));
35314
35463
  if (type.value === "directory")
35315
- absolutePath3(sourceLocation);
35316
- absolutePath3(textField(field2(row, "installLocation")));
35464
+ absolutePath4(sourceLocation);
35465
+ absolutePath4(textField(field2(row, "installLocation")));
35317
35466
  const updated = textField(field2(row, "lastUpdated"));
35318
- 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");
35319
35468
  const millis = Date.parse(updated);
35320
- 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");
35321
35470
  row.entries = row.entries.map(([key, value]) => [key, key === "lastUpdated" ? { kind: "validated-update-time" } : value]);
35322
35471
  }
35323
35472
  function captureClaudeMarketplaceRegistry(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
35324
35473
  const value = parse11(readRegistry2(path, budget2));
35325
35474
  for (const [, row] of value.entries)
35326
35475
  normalizeRow(row);
35327
- 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");
35328
35477
  return { path, hashMode: "claude-marketplace-registry", sha256: sha2562 };
35329
35478
  }
35330
35479
  function captureClaudeMarketplaceRegistryV2(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
35331
35480
  const value = parse11(readRegistry2(path, budget2));
35332
35481
  for (const [, row] of value.entries)
35333
35482
  normalizeRow(row, 2);
35334
- 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");
35335
35484
  return { path, hashMode: "claude-marketplace-registry-v2", sha256: sha2562 };
35336
35485
  }
35337
- 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];
35338
35487
  var init_claude_marketplace_registry = __esm(() => {
35339
35488
  CLAUDE_MARKETPLACE_REGISTRY_LIMITS = Object.freeze({ bytes: 1024 * 1024, rows: 1024, depth: 32, nodes: 65536, stringCharacters: 16384, pathCharacters: 4096 });
35340
35489
  });
@@ -35353,7 +35502,7 @@ var init_codex_hook_additions_review = __esm(() => {
35353
35502
  });
35354
35503
 
35355
35504
  // src/lib/codex-hook-discovery-recovery.ts
35356
- import { createHash as createHash18 } from "crypto";
35505
+ import { createHash as createHash19 } from "crypto";
35357
35506
  function assertCodexHookDiscoveryRecovery(binding, witness) {
35358
35507
  const proof = proofs2.get(witness);
35359
35508
  need6(!!proof && binding.agent === "codex" && witness.discoverySha256 === discoveryDigest(binding), "RECONCILE_DISCOVERY_RECOVERY_CHANGED");
@@ -35368,13 +35517,13 @@ function verifiesCodexHookDiscoverySource(binding, source, currentDigest, witnes
35368
35517
  need6(source.sha256 === witness.beforeSha256 && currentDigest === witness.currentSha256, "RECONCILE_DISCOVERY_RECOVERY_CHANGED");
35369
35518
  return true;
35370
35519
  }
35371
- 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) => {
35372
35521
  const controls = binding.codexDisabledPluginSkills;
35373
35522
  if (!Object.hasOwn(binding, "codexDisabledPluginSkills") || Array.isArray(controls) && controls.length === 0) {
35374
35523
  const { codexDisabledPluginSkills: _controls, ...withoutControls } = binding;
35375
- return sha3(JSON.stringify({ ...withoutControls, codexDisabledPluginSkills: [] }));
35524
+ return sha4(JSON.stringify({ ...withoutControls, codexDisabledPluginSkills: [] }));
35376
35525
  }
35377
- return sha3(JSON.stringify(binding));
35526
+ return sha4(JSON.stringify(binding));
35378
35527
  }, proofs2;
35379
35528
  var init_codex_hook_discovery_recovery = __esm(() => {
35380
35529
  init_codex_hook_trust_files();
@@ -35386,16 +35535,16 @@ var init_codex_hook_discovery_recovery = __esm(() => {
35386
35535
  });
35387
35536
 
35388
35537
  // src/lib/agent-discovery.ts
35389
- import { createHash as createHash19 } from "crypto";
35390
- import { lstatSync as lstatSync19, readFileSync as readFileSync16, readdirSync as readdirSync7, realpathSync as realpathSync6 } from "fs";
35391
- 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";
35392
35541
  import { isDeepStrictEqual as isDeepStrictEqual4 } from "util";
35393
35542
  function discoveryExecutable(agent) {
35394
35543
  const command = DISCOVERY_RUNTIME_COMMANDS[agent];
35395
35544
  const found = command ? Bun.which(command) : null;
35396
35545
  if (!command || !found)
35397
35546
  return null;
35398
- const path = resolve18(found), target = realpathOrNull(path);
35547
+ const path = resolve19(found), target = realpathOrNull(path);
35399
35548
  return target === null ? null : { command, path, target };
35400
35549
  }
35401
35550
  function parseConfig(text2, path, toml = false) {
@@ -35408,21 +35557,21 @@ function parseConfig(text2, path, toml = false) {
35408
35557
  throw new Error(`Invalid native discovery configuration: ${path}`);
35409
35558
  }
35410
35559
  }
35411
- function safe4(path) {
35412
- if (!isAbsolute16(path) || path.includes("\x00"))
35560
+ function safe5(path) {
35561
+ if (!isAbsolute18(path) || path.includes("\x00"))
35413
35562
  throw new Error("Expected an absolute native discovery path");
35414
- for (let cursor = path;; cursor = dirname17(cursor)) {
35415
- if (lstatSync19(cursor, { throwIfNoEntry: false })?.isSymbolicLink())
35563
+ for (let cursor = path;; cursor = dirname18(cursor)) {
35564
+ if (lstatSync20(cursor, { throwIfNoEntry: false })?.isSymbolicLink())
35416
35565
  throw new Error(`Refusing symlink native discovery input: ${cursor}`);
35417
- if (dirname17(cursor) === cursor)
35566
+ if (dirname18(cursor) === cursor)
35418
35567
  break;
35419
35568
  }
35420
35569
  }
35421
35570
  function read(path, changes) {
35422
- safe4(path);
35571
+ safe5(path);
35423
35572
  if (changes?.has(path))
35424
35573
  return changes.get(path);
35425
- const stat2 = lstatSync19(path, { throwIfNoEntry: false });
35574
+ const stat2 = lstatSync20(path, { throwIfNoEntry: false });
35426
35575
  if (!stat2)
35427
35576
  return null;
35428
35577
  if (!stat2.isFile() || stat2.size > 16 * 1024 * 1024)
@@ -35433,8 +35582,8 @@ function assertReviewedClaudeCacheClosures(home, config2, review, canonical8) {
35433
35582
  const enabledIds = Object.entries(config2.enabledPlugins ?? {}).filter(([, enabled]) => enabled === true).map(([id]) => id);
35434
35583
  if (enabledIds.length === 0)
35435
35584
  return;
35436
- const registryPath = canonical8(join27(home, ".claude/plugins/installed_plugins.json"));
35437
- 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");
35438
35587
  const cacheRoot = canonical8(cacheAliasRoot);
35439
35588
  const registryText = read(registryPath);
35440
35589
  if (registryText === null)
@@ -35442,7 +35591,7 @@ function assertReviewedClaudeCacheClosures(home, config2, review, canonical8) {
35442
35591
  const registry2 = parseConfig(registryText, registryPath);
35443
35592
  if (registry2.version !== 2 || !registry2.plugins || typeof registry2.plugins !== "object" || Array.isArray(registry2.plugins))
35444
35593
  throw new Error("Reviewed Claude installed plugin registrations are invalid");
35445
- 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));
35446
35595
  const activeRoots = new Set;
35447
35596
  for (const id of enabledIds) {
35448
35597
  const rows = registry2.plugins[id];
@@ -35454,11 +35603,11 @@ function assertReviewedClaudeCacheClosures(home, config2, review, canonical8) {
35454
35603
  if (!row || typeof row !== "object" || Array.isArray(row) || typeof row.installPath !== "string") {
35455
35604
  throw new Error("Reviewed Claude enabled plugin registration requires an object with an installPath string");
35456
35605
  }
35457
- 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))) {
35458
35607
  if (!cachePath(row.installPath) || row.installPath.length > AGENT_POLICY_LIMITS.pathCharacters || row.version !== undefined && (typeof row.version !== "string" || basename9(row.installPath) !== row.version)) {
35459
35608
  throw new Error("Reviewed Claude discovery has a malformed active cache registration");
35460
35609
  }
35461
- 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
35462
35611
  throw new Error("Reviewed Claude discovery has an unsupported active cache registration scope");
35463
35612
  activeRoots.add(canonical8(row.installPath));
35464
35613
  }
@@ -35475,12 +35624,12 @@ function assertReviewedClaudeCacheClosures(home, config2, review, canonical8) {
35475
35624
  throw new Error(`Reviewed active Claude cache plugin ${description} is not bound`);
35476
35625
  };
35477
35626
  for (const root of activeRoots) {
35478
- safe4(root);
35479
- const rootStat = lstatSync19(root, { throwIfNoEntry: false });
35627
+ safe5(root);
35628
+ const rootStat = lstatSync20(root, { throwIfNoEntry: false });
35480
35629
  if (!rootStat?.isDirectory() || realpathSync6(root) !== root)
35481
35630
  throw new Error("Reviewed Claude active cache plugin root is missing or unsafe");
35482
- const manifestPath = join27(root, ".claude-plugin/plugin.json");
35483
- const manifestStat = lstatSync19(manifestPath, { throwIfNoEntry: false });
35631
+ const manifestPath = join28(root, ".claude-plugin/plugin.json");
35632
+ const manifestStat = lstatSync20(manifestPath, { throwIfNoEntry: false });
35484
35633
  let manifest;
35485
35634
  if (manifestStat) {
35486
35635
  if (!manifestStat.isFile())
@@ -35495,37 +35644,37 @@ function assertReviewedClaudeCacheClosures(home, config2, review, canonical8) {
35495
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)) {
35496
35645
  throw new Error("Reviewed Claude active cache plugin manifest absence requires a path-bytes witness");
35497
35646
  }
35498
- const roots = new Set([join27(root, "skills")]);
35499
- 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())
35500
35649
  roots.add(root);
35501
35650
  const declared = manifest?.skills === undefined ? ["./skills"] : typeof manifest.skills === "string" ? [manifest.skills] : manifest.skills;
35502
35651
  if (!Array.isArray(declared) || declared.some((path) => typeof path !== "string"))
35503
35652
  throw new Error("Reviewed Claude active cache plugin has unsupported skill paths");
35504
35653
  for (const value of declared) {
35505
- const path = resolve18(root, value);
35506
- if (path !== root && !path.startsWith(root + sep7))
35654
+ const path = resolve19(root, value);
35655
+ if (path !== root && !path.startsWith(root + sep8))
35507
35656
  throw new Error("Reviewed Claude active cache plugin skill path escapes its root");
35508
- roots.add(path.endsWith(`${sep7}SKILL.md`) ? dirname17(path) : path);
35657
+ roots.add(path.endsWith(`${sep8}SKILL.md`) ? dirname18(path) : path);
35509
35658
  }
35510
35659
  for (const skillRoot of roots)
35511
35660
  if (!review.roots.includes(skillRoot))
35512
35661
  throw new Error("Reviewed Claude active cache plugin skill root is not covered");
35513
- const hooksPath = join27(root, "hooks/hooks.json");
35514
- const hooksStat = lstatSync19(hooksPath, { throwIfNoEntry: false });
35662
+ const hooksPath = join28(root, "hooks/hooks.json");
35663
+ const hooksStat = lstatSync20(hooksPath, { throwIfNoEntry: false });
35515
35664
  if (hooksStat) {
35516
35665
  if (!hooksStat.isFile())
35517
35666
  throw new Error("Reviewed Claude plugin hook manifest is unsupported");
35518
35667
  requireSource(hooksPath, "hook manifest");
35519
35668
  }
35520
35669
  if (typeof manifest?.hooks === "string")
35521
- requireSource(resolve18(root, manifest.hooks), "manifest-declared hook source");
35670
+ requireSource(resolve19(root, manifest.hooks), "manifest-declared hook source");
35522
35671
  }
35523
35672
  }
35524
35673
  function projectNativeDiscoveryFields(text2, format, fields2, path) {
35525
- const object5 = format === "yaml" ? parseHermesConfig(text2) : parseConfig(text2, path, format === "toml");
35526
- 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))
35527
35676
  throw new Error("Expected native discovery configuration object");
35528
- 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]))));
35529
35678
  }
35530
35679
  function isSupersededSettingsProjection(agent, configPath, source) {
35531
35680
  if (agent === "sumi")
@@ -35538,6 +35687,8 @@ function supersedesSettingsProjection(agent, sources, configPath) {
35538
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")));
35539
35688
  }
35540
35689
  function projected(source, changes, budget2 = discoveryByteBudget()) {
35690
+ if (source.reviewArtifact !== undefined)
35691
+ verifyRetainedReviewArtifact(source);
35541
35692
  if (source.hashMode === "sumi-settings-v1") {
35542
35693
  if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
35543
35694
  throw new Error("Sumi settings witnesses require exact typed metadata");
@@ -35613,9 +35764,9 @@ function absentCodexSkillRoots(binding) {
35613
35764
  return [];
35614
35765
  if (binding.agent !== "codex" || !Array.isArray(controls) || controls.length > 4096)
35615
35766
  throw new Error("Invalid disabled Codex discovery proof");
35616
- 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 })))
35617
35768
  return [];
35618
- 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");
35619
35770
  const source = binding.sources.find((source2) => source2.path === config2 && source2.sha256 !== null && source2.format === undefined && source2.fields === undefined);
35620
35771
  if (!source || projected(source) !== source.sha256)
35621
35772
  throw new Error("Missing current disabled Codex configuration witness");
@@ -35623,8 +35774,8 @@ function absentCodexSkillRoots(binding) {
35623
35774
  return [...new Set(controls.map((control) => control.pluginParent))].filter((parent) => !codexDirectHookSelects(cache, parent) && absentDisabledCodexPluginParent(cache, parent, controls, rules));
35624
35775
  }
35625
35776
  function codexDirectHookSelects(cache, root) {
35626
- const codex = dirname17(dirname17(cache)), config2 = Bun.TOML.parse(read(join27(codex, "config.toml")) ?? "");
35627
- 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"));
35628
35779
  if (hooks !== null)
35629
35780
  hashNativeJsonControls(hooks);
35630
35781
  return JSON.stringify(config2.hooks ?? {}).includes(root) || hooks !== null && JSON.stringify(JSON.parse(hooks)).includes(root);
@@ -35636,7 +35787,7 @@ function retiredCodexRoots(binding) {
35636
35787
  const controls = binding.codexDisabledPluginSkills;
35637
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)
35638
35789
  throw new Error("Invalid retired Codex materialization proof");
35639
- 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");
35640
35791
  const source = binding.sources.find((source2) => source2.path === config2 && source2.sha256 !== null && source2.format === undefined && source2.fields === undefined);
35641
35792
  if (!source || projected(source) !== source.sha256)
35642
35793
  throw new Error("Missing current retired Codex configuration witness");
@@ -35644,7 +35795,7 @@ function retiredCodexRoots(binding) {
35644
35795
  if ((proof.parents ?? []).some((parent) => codexDirectHookSelects(cache, parent) || !reviewedDisabledCodexPluginParent(cache, parent, controls, rules)) || !reviewedCodexPluginCapabilitiesUnchanged(cache, controls, (path) => read(path), rules))
35645
35796
  throw new Error("Retired Codex parent capabilities changed");
35646
35797
  for (const root of proof.roots) {
35647
- 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));
35648
35799
  if (!manifest || codexDirectHookSelects(cache, root) || !reviewedRetiredCodexRoot(cache, root, controls, rules, (path) => read(path), true))
35649
35800
  throw new Error("Retired Codex materialization changed");
35650
35801
  }
@@ -35653,7 +35804,7 @@ function retiredCodexRoots(binding) {
35653
35804
  function retainableAbsentSource(source) {
35654
35805
  if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined)
35655
35806
  return false;
35656
- 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"));
35657
35808
  }
35658
35809
  function absentRetiredClaudeRoots(binding) {
35659
35810
  if (binding.agent !== "claude" || binding.method !== "reviewed")
@@ -35662,17 +35813,17 @@ function absentRetiredClaudeRoots(binding) {
35662
35813
  for (const source of binding.sources) {
35663
35814
  if (!retainableAbsentSource(source) || source.sha256 === null)
35664
35815
  continue;
35665
- 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);
35666
35817
  if (at < 0 || source.path.indexOf(marker, at + 1) >= 0)
35667
35818
  continue;
35668
- 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);
35669
35820
  if (parts.length < 4 || parts.slice(0, 3).some((part) => !part || part === "." || part === ".."))
35670
35821
  continue;
35671
- const root = join27(cache, ...parts.slice(0, 3));
35672
- safe4(root);
35673
- if (lstatSync19(root, { throwIfNoEntry: false }))
35822
+ const root = join28(cache, ...parts.slice(0, 3));
35823
+ safe5(root);
35824
+ if (lstatSync20(root, { throwIfNoEntry: false }))
35674
35825
  continue;
35675
- 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");
35676
35827
  const full = (path) => binding.sources.find((item) => item.path === path && item.sha256 !== null && item.format === undefined && item.fields === undefined);
35677
35828
  const configSource = full(settings), registrySource = full(registry2);
35678
35829
  if (!configSource || !registrySource || projected(configSource) !== configSource.sha256 || projected(registrySource) !== registrySource.sha256)
@@ -35689,15 +35840,15 @@ function absentRetiredClaudeRoots(binding) {
35689
35840
  if (!row || typeof row !== "object" || Array.isArray(row))
35690
35841
  return null;
35691
35842
  const value = row;
35692
- 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)
35693
35844
  return null;
35694
35845
  if (value.scope === "user")
35695
35846
  return value.projectPath === undefined || value.projectPath === null ? "user\x00" : null;
35696
35847
  if (value.scope === "project")
35697
- 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;
35698
35849
  return null;
35699
35850
  };
35700
- 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))))
35701
35852
  continue;
35702
35853
  const rows = installed.plugins[id];
35703
35854
  if (!Array.isArray(rows) || rows.length < 1)
@@ -35715,9 +35866,9 @@ function absentRetiredClaudeRoots(binding) {
35715
35866
  if (!targetValid || !targetScopes.has("user\x00"))
35716
35867
  continue;
35717
35868
  const active = rows[0]?.installPath;
35718
- 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)
35719
35870
  continue;
35720
- const activeManifest = full(join27(active, ".claude-plugin/plugin.json"));
35871
+ const activeManifest = full(join28(active, ".claude-plugin/plugin.json"));
35721
35872
  if (!activeManifest || projected(activeManifest) !== activeManifest.sha256)
35722
35873
  continue;
35723
35874
  result.add(root);
@@ -35733,10 +35884,10 @@ function verifyAgentDiscovery(binding, codexRecovery) {
35733
35884
  throw new Error("Hermes discovery requires directory membership coverage; run skills hook install with a fresh discovery review");
35734
35885
  const installationRoots = codexInstallationRoots(binding);
35735
35886
  const retiredRoots = retiredCodexRoots(binding);
35736
- 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));
35737
35888
  if (binding.directories !== undefined) {
35738
35889
  const projected2 = binding.codexInstallationInputs?.directories ?? [];
35739
- 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)));
35740
35891
  if (projected2.length !== ancestors2.length || projected2.some((directory) => !ancestors2.some((original) => original.path === directory.path)))
35741
35892
  throw new Error("Missing installation input directory projection");
35742
35893
  const ordinary = binding.directories.filter((directory) => !installationInput(directory.path) && !ancestors2.includes(directory));
@@ -35744,7 +35895,7 @@ function verifyAgentDiscovery(binding, codexRecovery) {
35744
35895
  const projection = binding.codexRetiredMaterializations.directories;
35745
35896
  if (projection.length !== ordinary.length || projection.some((item, index) => item.path !== ordinary[index]?.path))
35746
35897
  throw new Error("Missing retired Codex directory projection");
35747
- 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 }))];
35748
35899
  if (projection.every((item) => Array.isArray(item.entries)))
35749
35900
  verifyDiscoveryDirectoryProjection(projection, omitted);
35750
35901
  else {
@@ -35758,7 +35909,7 @@ function verifyAgentDiscovery(binding, codexRecovery) {
35758
35909
  verifyDiscoveryDirectories(ordinary);
35759
35910
  verifyDiscoveryDirectories(projected2, installationRoots);
35760
35911
  }
35761
- 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 }))];
35762
35913
  const budget2 = discoveryByteBudget();
35763
35914
  for (const source of binding.sources) {
35764
35915
  assertMarketplaceBinding(binding, source);
@@ -35769,11 +35920,11 @@ function verifyAgentDiscovery(binding, codexRecovery) {
35769
35920
  if (source.sha256 !== null && !/^[a-f0-9]{64}$/.test(source.sha256))
35770
35921
  throw new Error("Invalid native discovery digest");
35771
35922
  if (installationInput(source.path)) {
35772
- safe4(source.path);
35923
+ safe5(source.path);
35773
35924
  continue;
35774
35925
  }
35775
- if (absentRoots.some((root) => source.path.startsWith(root + sep7)) && retainableAbsentSource(source)) {
35776
- safe4(source.path);
35926
+ if (absentRoots.some((root) => source.path.startsWith(root + sep8)) && retainableAbsentSource(source)) {
35927
+ safe5(source.path);
35777
35928
  continue;
35778
35929
  }
35779
35930
  const current = projected(source, undefined, budget2);
@@ -35781,10 +35932,10 @@ function verifyAgentDiscovery(binding, codexRecovery) {
35781
35932
  throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
35782
35933
  }
35783
35934
  for (const root of binding.roots)
35784
- safe4(root);
35935
+ safe5(root);
35785
35936
  for (const root of absentRoots) {
35786
- safe4(root);
35787
- if (lstatSync19(root, { throwIfNoEntry: false }))
35937
+ safe5(root);
35938
+ if (lstatSync20(root, { throwIfNoEntry: false }))
35788
35939
  throw new Error("Retired native materialization changed during discovery verification");
35789
35940
  }
35790
35941
  }
@@ -35794,13 +35945,13 @@ function codexInstallationRoots(binding) {
35794
35945
  return [];
35795
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)
35796
35947
  throw new Error("Invalid native installation input proof");
35797
- const cache = dirname17(dirname17(proof.plugins[0].pluginParent));
35798
- 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)));
35799
35950
  const configSource = binding.sources.find((source) => source.path === config2 && source.sha256 !== null && (!source.format || source.format === "toml" && source.fields?.includes("plugins")));
35800
- const nativeRoots = NATIVE_SKILL_ROOTS.filter(([agent]) => agent === "codex").map(([, path]) => join27(home, path));
35801
- 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)))))
35802
35953
  throw new Error("Native installation input overlaps configuration or loading roots");
35803
- 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)))
35804
35955
  throw new Error("Missing native installation input source witness");
35805
35956
  return reviewedCodexPluginSourceRoots(cache, proof.plugins, (path) => {
35806
35957
  const text2 = read(path);
@@ -35810,7 +35961,7 @@ function codexInstallationRoots(binding) {
35810
35961
  });
35811
35962
  }
35812
35963
  function assertMarketplaceBinding(binding, source) {
35813
- 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"))))
35814
35965
  throw new Error("Claude plugin manifest witnesses require Claude plugin discovery");
35815
35966
  if (source.hashMode === "sumi-settings-v1" && (binding.agent !== "sumi" || binding.method !== "reviewed" || basename9(source.path) !== "sumi.json"))
35816
35967
  throw new Error("Sumi settings witnesses require explicit reviewed Sumi configuration");
@@ -35826,10 +35977,10 @@ function assertMarketplaceBinding(binding, source) {
35826
35977
  function agentDiscoveryConfigPath(home, agent) {
35827
35978
  if (agent === "sumi")
35828
35979
  return sumiConfigPath(home);
35829
- 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"}`);
35830
35981
  }
35831
35982
  function resolveAgentDiscovery(options) {
35832
- 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;
35833
35984
  const sources = [], roots = new Set, builtinNames = [];
35834
35985
  const witness = (path, format, fields2, hashMode) => {
35835
35986
  const source = { path: canonical8(path), sha256: null, ...format ? { format, fields: fields2 } : {}, ...hashMode ? { hashMode } : {} };
@@ -35850,42 +36001,42 @@ function resolveAgentDiscovery(options) {
35850
36001
  const review = options.reviewed?.agents.find((item) => item.agent === agent);
35851
36002
  if (agent === "sumi") {
35852
36003
  const directory = sumiConfigDirectory(home);
35853
- if (witness(join27(directory, "sumi.jsonc")) !== null)
36004
+ if (witness(join28(directory, "sumi.jsonc")) !== null)
35854
36005
  unresolved("JSONC configuration requires a supported format adapter");
35855
- for (const root of [directory, join27(home, ".claude"), join27(home, ".agents")])
36006
+ for (const root of [directory, join28(home, ".claude"), join28(home, ".agents")])
35856
36007
  for (const name of ["skill", "skills"])
35857
- roots.add(canonical8(join27(root, name)));
36008
+ roots.add(canonical8(join28(root, name)));
35858
36009
  if (config2.skills !== undefined && (!Array.isArray(config2.skills) || config2.skills.some((path) => typeof path !== "string")))
35859
36010
  unresolved("skills must be a string array");
35860
36011
  for (const value of config2.skills ?? []) {
35861
- 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("~/")))
35862
36013
  unresolved("remote or relative skill sources need a dedicated discovery adapter");
35863
- roots.add(canonical8(value.startsWith("~/") ? join27(home, value.slice(2)) : value));
36014
+ roots.add(canonical8(value.startsWith("~/") ? join28(home, value.slice(2)) : value));
35864
36015
  }
35865
36016
  for (const key of ["plugin", "plugins"])
35866
36017
  if (config2[key] !== undefined && !Array.isArray(config2[key]))
35867
36018
  unresolved(`${key} must be an array`);
35868
- const plugins = [join27(directory, "plugin"), join27(directory, "plugins")];
36019
+ const plugins = [join28(directory, "plugin"), join28(directory, "plugins")];
35869
36020
  for (const path of plugins) {
35870
- safe4(path);
35871
- if (lstatSync19(path, { throwIfNoEntry: false })?.isDirectory())
36021
+ safe5(path);
36022
+ if (lstatSync20(path, { throwIfNoEntry: false })?.isDirectory())
35872
36023
  for (const name of readdirSync7(path).sort()) {
35873
36024
  if (name === "skills-cli.js" && path === plugins[1])
35874
36025
  continue;
35875
- const target = join27(path, name);
35876
- if (!lstatSync19(target).isFile())
36026
+ const target = join28(path, name);
36027
+ if (!lstatSync20(target).isFile())
35877
36028
  unresolved("local plugin packages need a dedicated discovery adapter");
35878
36029
  witness(target);
35879
36030
  }
35880
36031
  }
35881
36032
  for (const root of roots) {
35882
- safe4(root);
35883
- 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")))
35884
36035
  unresolved("flat markdown skills require a dedicated native migration adapter");
35885
36036
  }
35886
36037
  }
35887
36038
  if (agent === "hermes") {
35888
- const profile = witness(join27(home, ".hermes/active_profile"));
36039
+ const profile = witness(join28(home, ".hermes/active_profile"));
35889
36040
  if (profile?.trim() && profile.trim() !== "default")
35890
36041
  unresolved("a non-default profile is active");
35891
36042
  const declared = config2.skills?.external_dirs ?? [], paths = typeof declared === "string" ? [declared] : declared;
@@ -35899,8 +36050,8 @@ function resolveAgentDiscovery(options) {
35899
36050
  continue;
35900
36051
  if (normalized.startsWith("~") && normalized !== "~" && !normalized.startsWith("~/"))
35901
36052
  unresolved("user-specific tilde expansion requires a separate discovery adapter");
35902
- const path = normalized === "~" ? home : normalized.startsWith("~/") ? join27(home, normalized.slice(2)) : resolve18(home, ".hermes", normalized);
35903
- safe4(path);
36053
+ const path = normalized === "~" ? home : normalized.startsWith("~/") ? join28(home, normalized.slice(2)) : resolve19(home, ".hermes", normalized);
36054
+ safe5(path);
35904
36055
  roots.add(path);
35905
36056
  }
35906
36057
  }
@@ -35908,24 +36059,24 @@ function resolveAgentDiscovery(options) {
35908
36059
  const executable = options.executable === undefined ? discoveryExecutable(agent) : options.executable;
35909
36060
  if (executable) {
35910
36061
  let packageRoot;
35911
- for (let directory = dirname17(executable.target), depth = 0;depth < 8; directory = dirname17(directory), depth++) {
35912
- 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);
35913
36064
  if (raw !== null && parseConfig(raw, path).name === "@google/gemini-cli") {
35914
36065
  packageRoot = directory;
35915
36066
  witness(path);
35916
36067
  break;
35917
36068
  }
35918
- if (dirname17(directory) === directory)
36069
+ if (dirname18(directory) === directory)
35919
36070
  break;
35920
36071
  }
35921
36072
  if (!packageRoot)
35922
36073
  unresolved("installed Gemini package layout is not recognized");
35923
- const builtinRoot = join27(packageRoot, "bundle/builtin");
35924
- safe4(builtinRoot);
35925
- if (!lstatSync19(builtinRoot, { throwIfNoEntry: false })?.isDirectory())
36074
+ const builtinRoot = join28(packageRoot, "bundle/builtin");
36075
+ safe5(builtinRoot);
36076
+ if (!lstatSync20(builtinRoot, { throwIfNoEntry: false })?.isDirectory())
35926
36077
  unresolved("installed Gemini builtin root is missing");
35927
36078
  for (const name of readdirSync7(builtinRoot).sort()) {
35928
- const text2 = witness(join27(builtinRoot, name, "SKILL.md"));
36079
+ const text2 = witness(join28(builtinRoot, name, "SKILL.md"));
35929
36080
  const match = text2?.match(/^---\r?\n[\s\S]*?^name:\s*([a-z0-9][a-z0-9-]*)\s*$/m);
35930
36081
  if (!match?.[1] || builtinNames.includes(match[1]))
35931
36082
  unresolved("installed Gemini builtin name is missing or ambiguous");
@@ -35960,10 +36111,10 @@ function resolveAgentDiscovery(options) {
35960
36111
  throw new Error("Discovery review must include the agent configuration source");
35961
36112
  const reviewedSources = supersedesSettingsProjection(agent, review.sources, canonical8(configPath)) ? sources.filter((source) => !isSupersededSettingsProjection(agent, canonical8(configPath), source)) : sources;
35962
36113
  const reviewedSourcesWithManifestProjection = review.sources.map((source) => {
35963
- 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")))
35964
36115
  return source;
35965
- const pluginRoot = dirname17(dirname17(source.path)), hooksPath = join27(pluginRoot, "hooks/hooks.json");
35966
- 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 });
35967
36118
  const text2 = read(source.path);
35968
36119
  if (text2 === null)
35969
36120
  throw new Error("Reviewed Claude plugin manifest is missing");
@@ -35977,8 +36128,8 @@ function resolveAgentDiscovery(options) {
35977
36128
  if (manifest.hooks !== undefined) {
35978
36129
  if (typeof manifest.hooks !== "string")
35979
36130
  throw new Error("Reviewed Claude plugin manifest has an unsupported hooks target");
35980
- const declaredHookPath = resolve18(pluginRoot, manifest.hooks);
35981
- if (!declaredHookPath.startsWith(pluginRoot + sep7))
36131
+ const declaredHookPath = resolve19(pluginRoot, manifest.hooks);
36132
+ if (!declaredHookPath.startsWith(pluginRoot + sep8))
35982
36133
  throw new Error("Reviewed Claude plugin hooks target escapes its root");
35983
36134
  reviewedHookPaths.add(declaredHookPath);
35984
36135
  }
@@ -35995,40 +36146,40 @@ function resolveAgentDiscovery(options) {
35995
36146
  }
35996
36147
  function plugin(root) {
35997
36148
  root = canonical8(root);
35998
- safe4(root);
35999
- 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");
36000
36151
  const raw = witness(manifestPath, undefined, undefined, agent === "claude" ? "claude-plugin-manifest-v1" : undefined);
36001
36152
  if (raw === null)
36002
36153
  unresolved("plugin manifest missing");
36003
36154
  const manifest = parseConfig(raw, manifestPath);
36004
- const hooks = witness(join27(root, "hooks/hooks.json"));
36155
+ const hooks = witness(join28(root, "hooks/hooks.json"));
36005
36156
  if (manifest.hooks !== undefined || hooks !== null)
36006
36157
  unresolved("plugin hooks require a separate no-skill-injection review");
36007
- const commands = join27(root, "commands");
36008
- safe4(commands);
36009
- 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))
36010
36161
  unresolved("legacy command discovery requires retirement or a dedicated format adapter");
36011
- const rootSkill = witness(join27(root, "SKILL.md"));
36162
+ const rootSkill = witness(join28(root, "SKILL.md"));
36012
36163
  if (rootSkill !== null)
36013
36164
  roots.add(root);
36014
36165
  const declared = manifest.skills === undefined ? ["./skills"] : typeof manifest.skills === "string" ? [manifest.skills] : manifest.skills;
36015
36166
  if (!Array.isArray(declared) || declared.some((path) => typeof path !== "string"))
36016
36167
  unresolved("unsupported plugin skill paths");
36017
36168
  if (agent === "claude")
36018
- roots.add(join27(root, "skills"));
36169
+ roots.add(join28(root, "skills"));
36019
36170
  for (const value of declared) {
36020
- const path = resolve18(root, value);
36021
- if (path !== root && !path.startsWith(root + sep7))
36171
+ const path = resolve19(root, value);
36172
+ if (path !== root && !path.startsWith(root + sep8))
36022
36173
  unresolved("plugin skill path escapes its root");
36023
- roots.add(path.endsWith(`${sep7}SKILL.md`) ? dirname17(path) : path);
36174
+ roots.add(path.endsWith(`${sep8}SKILL.md`) ? dirname18(path) : path);
36024
36175
  }
36025
36176
  }
36026
36177
  if (agent === "claude") {
36027
- const registrations = witness(join27(home, ".claude/plugins/installed_plugins.json"));
36028
- const installed = registrations === null ? {} : parseConfig(registrations, join27(home, ".claude/plugins/installed_plugins.json")).plugins;
36029
- const commands = canonical8(join27(home, ".claude/commands"));
36030
- safe4(commands);
36031
- 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)
36032
36183
  unresolved("legacy home command discovery requires a dedicated format adapter");
36033
36184
  for (const [id, enabled] of Object.entries(config2.enabledPlugins ?? {})) {
36034
36185
  if (enabled === false)
@@ -36048,37 +36199,37 @@ function resolveAgentDiscovery(options) {
36048
36199
  unresolved("unsupported plugin enablement");
36049
36200
  const split = id.lastIndexOf("@"), name = id.slice(0, split), marketplace = id.slice(split + 1);
36050
36201
  const market = config2.marketplaces?.[marketplace] ?? (marketplace === "personal" ? { source_type: "local", source: home } : undefined);
36051
- 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))
36052
36203
  unresolved("enabled plugin marketplace is not an explicit local source");
36053
- const catalogText = witness(join27(market.source, ".agents/plugins/marketplace.json"));
36204
+ const catalogText = witness(join28(market.source, ".agents/plugins/marketplace.json"));
36054
36205
  if (catalogText === null)
36055
36206
  unresolved("marketplace catalog missing");
36056
- 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) : [];
36057
36208
  if (matches.length !== 1 || matches[0]?.source?.source !== "local" || typeof matches[0]?.source?.path !== "string")
36058
36209
  unresolved("plugin catalog source is missing or ambiguous");
36059
- plugin(resolve18(market.source, matches[0].source.path));
36210
+ plugin(resolve19(market.source, matches[0].source.path));
36060
36211
  }
36061
36212
  } else if (agent === "opencode") {
36062
- 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)
36063
36214
  unresolved("additional config layers require review");
36064
36215
  if ((config2.plugin?.length ?? 0) > 0 || config2.skills?.urls?.length)
36065
36216
  unresolved("external plugin or remote skill source");
36066
36217
  for (const path of config2.skills?.paths ?? []) {
36067
- if (typeof path !== "string" || !isAbsolute16(path))
36218
+ if (typeof path !== "string" || !isAbsolute18(path))
36068
36219
  unresolved("relative or malformed added skill root");
36069
36220
  roots.add(path);
36070
36221
  }
36071
- const localPlugins = join27(home, ".config/opencode/plugins");
36072
- safe4(localPlugins);
36073
- 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"))
36074
36225
  unresolved("additional local plugin hooks require review");
36075
36226
  } else if (agent === "sumi") {
36076
- 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))
36077
36228
  unresolved("external or foreign local plugins require review");
36078
36229
  } else if (agent === "hermes") {
36079
- for (const directory of [join27(home, ".hermes/plugins"), join27(home, ".hermes/hermes-agent")]) {
36080
- safe4(directory);
36081
- 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 }))
36082
36233
  unresolved("installed runtime/plugin discovery requires reviewed source bindings");
36083
36234
  }
36084
36235
  if (Bun.which("hermes") || Object.keys(config2.plugins ?? {}).length)
@@ -36086,24 +36237,24 @@ function resolveAgentDiscovery(options) {
36086
36237
  } else if (agent === "gemini") {
36087
36238
  if (Object.keys(config2.extensions ?? {}).length || config2.skills?.paths?.length)
36088
36239
  unresolved("custom extension or skill paths");
36089
- const directory = join27(home, ".gemini/extensions");
36090
- safe4(directory);
36091
- if (lstatSync19(directory, { throwIfNoEntry: false }))
36240
+ const directory = join28(home, ".gemini/extensions");
36241
+ safe5(directory);
36242
+ if (lstatSync20(directory, { throwIfNoEntry: false }))
36092
36243
  for (const name of readdirSync7(directory)) {
36093
- const root = join27(directory, name);
36094
- safe4(root);
36095
- if (!lstatSync19(root)?.isDirectory())
36244
+ const root = join28(directory, name);
36245
+ safe5(root);
36246
+ if (!lstatSync20(root)?.isDirectory())
36096
36247
  continue;
36097
- const raw = witness(join27(root, "gemini-extension.json"));
36248
+ const raw = witness(join28(root, "gemini-extension.json"));
36098
36249
  if (raw === null)
36099
36250
  unresolved("extension registration missing");
36100
- const manifest = parseConfig(raw, join27(root, "gemini-extension.json"));
36101
- 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)
36102
36253
  unresolved("extension hooks or linked registration require review");
36103
- roots.add(join27(root, "skills"));
36254
+ roots.add(join28(root, "skills"));
36104
36255
  }
36105
36256
  }
36106
- 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))) } : {} };
36107
36258
  }
36108
36259
  var DISCOVERY_RUNTIME_COMMANDS, realpathOrNull = (path) => {
36109
36260
  try {
@@ -36111,7 +36262,7 @@ var DISCOVERY_RUNTIME_COMMANDS, realpathOrNull = (path) => {
36111
36262
  } catch {
36112
36263
  return null;
36113
36264
  }
36114
- }, digest = (text2) => createHash19("sha256").update(text2).digest("hex");
36265
+ }, digest = (text2) => createHash20("sha256").update(text2).digest("hex");
36115
36266
  var init_agent_discovery = __esm(() => {
36116
36267
  init_sumi_settings_witness();
36117
36268
  init_agent_policy_limits();
@@ -36131,16 +36282,17 @@ var init_agent_discovery = __esm(() => {
36131
36282
  init_agent_sumi();
36132
36283
  init_native_discovery_roots();
36133
36284
  init_codex_native_compatibility();
36285
+ init_retained_review_artifacts();
36134
36286
  init_agent_discovery_directories();
36135
36287
  DISCOVERY_RUNTIME_COMMANDS = Object.freeze({ gemini: "gemini" });
36136
36288
  });
36137
36289
 
36138
36290
  // src/lib/authoring-path.ts
36139
- import { lstatSync as lstatSync20, realpathSync as realpathSync7 } from "fs";
36291
+ import { lstatSync as lstatSync21, realpathSync as realpathSync7 } from "fs";
36140
36292
  import { homedir as homedir3 } from "os";
36141
- 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";
36142
36294
  function pathParts(path) {
36143
- return resolve19(path).split(sep8).filter(Boolean);
36295
+ return resolve20(path).split(sep9).filter(Boolean);
36144
36296
  }
36145
36297
  function nativeRootMatch(path) {
36146
36298
  const parts = pathParts(path);
@@ -36154,24 +36306,24 @@ function nativeRootMatch(path) {
36154
36306
  return;
36155
36307
  }
36156
36308
  function physicalPath(path) {
36157
- let cursor = resolve19(path);
36309
+ let cursor = resolve20(path);
36158
36310
  const suffix = [];
36159
- while (!lstatSync20(cursor, { throwIfNoEntry: false })) {
36311
+ while (!lstatSync21(cursor, { throwIfNoEntry: false })) {
36160
36312
  suffix.unshift(basename10(cursor));
36161
- const parent = dirname18(cursor);
36313
+ const parent = dirname19(cursor);
36162
36314
  if (parent === cursor)
36163
- return resolve19(path);
36315
+ return resolve20(path);
36164
36316
  cursor = parent;
36165
36317
  }
36166
- return resolve19(realpathSync7(cursor), ...suffix);
36318
+ return resolve20(realpathSync7(cursor), ...suffix);
36167
36319
  }
36168
36320
  function contains(root, path) {
36169
- return path === root || path.startsWith(root + sep8);
36321
+ return path === root || path.startsWith(root + sep9);
36170
36322
  }
36171
36323
  function configuredRoots(home, explicitHome) {
36172
- const homeData = join28(home, ".hasna", "skills");
36324
+ const homeData = join29(home, ".hasna", "skills");
36173
36325
  const homePolicy = readManagedSkillPolicySnapshot(homeData);
36174
- const configuredPolicy = !explicitHome && resolve19(getDataDirReadOnly()) !== resolve19(homeData) ? readManagedSkillPolicySnapshot(getDataDirReadOnly()) : null;
36326
+ const configuredPolicy = !explicitHome && resolve20(getDataDirReadOnly()) !== resolve20(homeData) ? readManagedSkillPolicySnapshot(getDataDirReadOnly()) : null;
36175
36327
  const policy = homePolicy ?? configuredPolicy;
36176
36328
  const bridge = policy?.value.bridge;
36177
36329
  if (bridge && (typeof bridge.home !== "string" || physicalPath(bridge.home) !== physicalPath(home))) {
@@ -36200,8 +36352,8 @@ function configuredRoots(home, explicitHome) {
36200
36352
  admitBinding(binding);
36201
36353
  continue;
36202
36354
  }
36203
- const nativeHome = join28(home, agent === "opencode" ? ".config/opencode" : `.${agent}`);
36204
- if (!lstatSync20(nativeHome, { throwIfNoEntry: false }))
36355
+ const nativeHome = join29(home, agent === "opencode" ? ".config/opencode" : `.${agent}`);
36356
+ if (!lstatSync21(nativeHome, { throwIfNoEntry: false }))
36205
36357
  continue;
36206
36358
  roots.push(...resolveAgentDiscovery({ home, agent, canonical: physicalPath }).roots);
36207
36359
  }
@@ -36210,22 +36362,22 @@ function configuredRoots(home, explicitHome) {
36210
36362
  function assertPortableAuthoringPath(path, options = {}) {
36211
36363
  if (typeof path !== "string" || !path || path.includes("\x00"))
36212
36364
  throw new Error("Invalid portable authoring path");
36213
- const lexical = resolve19(path);
36365
+ const lexical = resolve20(path);
36214
36366
  const physical = physicalPath(lexical);
36215
36367
  const candidates = [lexical, physical];
36216
36368
  let native = candidates.map(nativeRootMatch).find(Boolean);
36217
- const home = resolve19(options.homeDir ?? homedir3());
36218
- const defaults = NATIVE_DISCOVERY_ROOTS.map((parts) => join28(home, ...parts));
36219
- 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"));
36220
36372
  for (const root of defaults) {
36221
- 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)))
36222
36374
  native ??= root;
36223
36375
  }
36224
36376
  if (native) {
36225
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.`);
36226
36378
  }
36227
36379
  for (const root of configuredRoots(home, options.homeDir !== undefined)) {
36228
- 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))) {
36229
36381
  throw new Error(`Refusing portable Skills authoring below configured native discovery root: ${lexical}`);
36230
36382
  }
36231
36383
  }
@@ -36243,7 +36395,7 @@ var init_authoring_path = __esm(() => {
36243
36395
  // src/lib/portable-skills.ts
36244
36396
  import {
36245
36397
  existsSync as existsSync12,
36246
- mkdirSync as mkdirSync7,
36398
+ mkdirSync as mkdirSync8,
36247
36399
  mkdtempSync,
36248
36400
  readdirSync as readdirSync8,
36249
36401
  realpathSync as realpathSync8,
@@ -36252,22 +36404,22 @@ import {
36252
36404
  statSync as statSync8,
36253
36405
  writeFileSync as writeFileSync6
36254
36406
  } from "fs";
36255
- 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";
36256
36408
  function getPortableSkillsRoot(options = {}) {
36257
36409
  return resolvePortableSkillsRoot(options, true);
36258
36410
  }
36259
36411
  function resolvePortableSkillsRoot(options, migrate) {
36260
36412
  if (options.rootDir)
36261
36413
  return options.rootDir;
36262
- const appDir = options.homeDir ? join29(options.homeDir, ".hasna", "skills") : migrate ? getDataDir() : getDataDirReadOnly();
36263
- 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);
36264
36416
  if (isOwnerLayoutMigrated(appDir) && safeIsDirectory(cache))
36265
36417
  return cache;
36266
- const installed = join29(appDir, INSTALLED_SKILLS_DIRNAME);
36418
+ const installed = join30(appDir, INSTALLED_SKILLS_DIRNAME);
36267
36419
  return installed;
36268
36420
  }
36269
36421
  function getPortableSkillPath(name, options = {}) {
36270
- return join29(getPortableSkillsRoot(options), normalizePortableSkillName(name));
36422
+ return join30(getPortableSkillsRoot(options), normalizePortableSkillName(name));
36271
36423
  }
36272
36424
  function findPortableSkill(name, options = {}) {
36273
36425
  let normalized;
@@ -36293,7 +36445,7 @@ function listPortableSkills(options = {}) {
36293
36445
  for (const entry of readdirSync8(root).sort()) {
36294
36446
  if (entry.startsWith("."))
36295
36447
  continue;
36296
- const path = join29(root, entry);
36448
+ const path = join30(root, entry);
36297
36449
  if (!safeIsDirectory(path))
36298
36450
  continue;
36299
36451
  try {
@@ -36326,9 +36478,9 @@ function isOfficialSkillName(name) {
36326
36478
  function scaffoldPortableSkill(name, options = {}) {
36327
36479
  const skillName = normalizeNewPortableSkillName(name);
36328
36480
  const readOnlyRoot = resolvePortableSkillsRoot(options, false);
36329
- assertPortableAuthoringPath(join29(readOnlyRoot, skillName), options);
36481
+ assertPortableAuthoringPath(join30(readOnlyRoot, skillName), options);
36330
36482
  const root = getPortableSkillsRoot(options);
36331
- const skillPath = join29(root, skillName);
36483
+ const skillPath = join30(root, skillName);
36332
36484
  assertPortableAuthoringPath(skillPath, options);
36333
36485
  if (existsSync12(skillPath)) {
36334
36486
  if (!options.overwrite)
@@ -36347,27 +36499,27 @@ function scaffoldPortableSkill(name, options = {}) {
36347
36499
  return { name: skillName, path: skillPath, manifest, created: true };
36348
36500
  }
36349
36501
  function physicalImportPath(path) {
36350
- let ancestor = resolve20(path);
36502
+ let ancestor = resolve21(path);
36351
36503
  const suffix = [];
36352
36504
  while (!existsSync12(ancestor)) {
36353
36505
  suffix.unshift(basename11(ancestor));
36354
- ancestor = dirname19(ancestor);
36506
+ ancestor = dirname20(ancestor);
36355
36507
  }
36356
- return join29(realpathSync8(ancestor), ...suffix);
36508
+ return join30(realpathSync8(ancestor), ...suffix);
36357
36509
  }
36358
36510
  function assertDisjointImportPaths(source, destination) {
36359
36511
  const sourcePath = realpathSync8(source);
36360
36512
  const destinationPath = physicalImportPath(destination);
36361
36513
  const contains2 = (parent, child2) => {
36362
36514
  const path = relative6(parent, child2);
36363
- return path === "" || !isAbsolute17(path) && path !== ".." && !path.startsWith(`..${sep9}`);
36515
+ return path === "" || !isAbsolute19(path) && path !== ".." && !path.startsWith(`..${sep10}`);
36364
36516
  };
36365
36517
  if (contains2(sourcePath, destinationPath) || contains2(destinationPath, sourcePath)) {
36366
36518
  throw new Error("Source and destination skill directories must not overlap");
36367
36519
  }
36368
36520
  }
36369
36521
  function portPortableSkill(sourcePath, options = {}) {
36370
- const absoluteSource = normalize3(sourcePath);
36522
+ const absoluteSource = normalize4(sourcePath);
36371
36523
  if (!existsSync12(absoluteSource) || !statSync8(absoluteSource).isDirectory()) {
36372
36524
  throw new Error(`Skill source directory not found: ${sourcePath}`);
36373
36525
  }
@@ -36379,11 +36531,11 @@ function portPortableSkill(sourcePath, options = {}) {
36379
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.`;
36380
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.`);
36381
36533
  }
36382
- const readOnlyDestination = join29(resolvePortableSkillsRoot(options, false), skillName);
36534
+ const readOnlyDestination = join30(resolvePortableSkillsRoot(options, false), skillName);
36383
36535
  assertPortableAuthoringPath(readOnlyDestination, options);
36384
36536
  assertDisjointImportPaths(absoluteSource, readOnlyDestination);
36385
36537
  const root = getPortableSkillsRoot(options);
36386
- const destination = join29(root, skillName);
36538
+ const destination = join30(root, skillName);
36387
36539
  assertPortableAuthoringPath(destination, options);
36388
36540
  assertDisjointImportPaths(absoluteSource, destination);
36389
36541
  if (existsSync12(destination)) {
@@ -36391,7 +36543,7 @@ function portPortableSkill(sourcePath, options = {}) {
36391
36543
  throw new Error(`Skill '${skillName}' already exists at ${destination}`);
36392
36544
  rmSync3(destination, { recursive: true, force: true });
36393
36545
  }
36394
- mkdirSync7(dirname19(destination), { recursive: true });
36546
+ mkdirSync8(dirname20(destination), { recursive: true });
36395
36547
  copySkillDirectory(absoluteSource, destination);
36396
36548
  const base = {
36397
36549
  ...inferred,
@@ -36415,8 +36567,8 @@ function validatePortableSkillDirectory(name, skillPath) {
36415
36567
  const warnings = [...base.warnings];
36416
36568
  let manifest;
36417
36569
  if (existsSync12(skillPath)) {
36418
- const skillJsonPath = join29(skillPath, "skill.json");
36419
- const skillMdPath = join29(skillPath, "SKILL.md");
36570
+ const skillJsonPath = join30(skillPath, "skill.json");
36571
+ const skillMdPath = join30(skillPath, "SKILL.md");
36420
36572
  if (!existsSync12(skillJsonPath) && !existsSync12(skillMdPath)) {
36421
36573
  add3(issues, "portable.manifest_missing", "Missing portable manifest: expected SKILL.md frontmatter and/or skill.json");
36422
36574
  }
@@ -36436,7 +36588,7 @@ function validatePortableSkillDirectory(name, skillPath) {
36436
36588
  add3(issues, "portable.version_missing", "Portable manifest missing version");
36437
36589
  }
36438
36590
  const contractIssues = validatePortableManifestContract(manifest, {
36439
- strict: existsSync12(join29(skillPath, "skill.json")),
36591
+ strict: existsSync12(join30(skillPath, "skill.json")),
36440
36592
  skillPath
36441
36593
  });
36442
36594
  for (const issue2 of contractIssues)
@@ -36476,7 +36628,7 @@ function validatePortableSkillDirectory(name, skillPath) {
36476
36628
  add3(issues, "portable.command_entry_unsafe", `Command '${command.name}' entry '${command.entry}' must stay inside the skill directory`);
36477
36629
  continue;
36478
36630
  }
36479
- const entryPath = join29(skillPath, command.entry);
36631
+ const entryPath = join30(skillPath, command.entry);
36480
36632
  if (!existsSync12(entryPath))
36481
36633
  add3(issues, "portable.command_entry_missing", `Command '${command.name}' entry '${command.entry}' is missing`);
36482
36634
  else if (statSync8(entryPath).isDirectory())
@@ -36487,7 +36639,7 @@ function validatePortableSkillDirectory(name, skillPath) {
36487
36639
  } catch (error61) {
36488
36640
  add3(issues, "portable.manifest_invalid", error61.message);
36489
36641
  }
36490
- if (manifest?.kind !== "instruction" && !existsSync12(join29(skillPath, "AGENTS.md"))) {
36642
+ if (manifest?.kind !== "instruction" && !existsSync12(join30(skillPath, "AGENTS.md"))) {
36491
36643
  add3(issues, "portable.agents_missing", "Missing AGENTS.md with build-out instructions for coding agents");
36492
36644
  }
36493
36645
  }
@@ -36525,9 +36677,9 @@ function safeIsDirectory(path) {
36525
36677
  }
36526
36678
  }
36527
36679
  function isSafeRelativePath2(value) {
36528
- if (!value.trim() || isAbsolute17(value))
36680
+ if (!value.trim() || isAbsolute19(value))
36529
36681
  return false;
36530
- const normalized = normalize3(value).replace(/\\/g, "/");
36682
+ const normalized = normalize4(value).replace(/\\/g, "/");
36531
36683
  return normalized !== ".." && !normalized.startsWith("../") && !normalized.includes("/../");
36532
36684
  }
36533
36685
  function add3(target, code, message) {
@@ -36715,7 +36867,7 @@ var init_search = __esm(() => {
36715
36867
 
36716
36868
  // src/lib/registry.ts
36717
36869
  import { existsSync as existsSync13, readFileSync as readFileSync17, readdirSync as readdirSync9 } from "fs";
36718
- import { join as join30 } from "path";
36870
+ import { join as join31 } from "path";
36719
36871
  function parseSkillMdFrontmatter(content) {
36720
36872
  const match = content.match(/^---\n([\s\S]*?)\n---/);
36721
36873
  if (!match)
@@ -36756,7 +36908,7 @@ function discoverSkillsInDir(dir, source = "custom") {
36756
36908
  for (const entry of entries) {
36757
36909
  if (!entry.isDirectory())
36758
36910
  continue;
36759
- const skillMdPath = join30(dir, entry.name, "SKILL.md");
36911
+ const skillMdPath = join31(dir, entry.name, "SKILL.md");
36760
36912
  if (!existsSync13(skillMdPath))
36761
36913
  continue;
36762
36914
  let content;
@@ -36776,7 +36928,7 @@ function discoverSkillsInDir(dir, source = "custom") {
36776
36928
  category: fm.category || "Development Tools",
36777
36929
  tags: fm.tags || [],
36778
36930
  ...fm.kind ? { kind: fm.kind } : {},
36779
- ...isHostedMetadataSkillDir(join30(dir, entry.name)) ? { serverOwned: true } : {},
36931
+ ...isHostedMetadataSkillDir(join31(dir, entry.name)) ? { serverOwned: true } : {},
36780
36932
  source
36781
36933
  });
36782
36934
  }
@@ -36792,8 +36944,8 @@ function findExtensionSkillPath(name) {
36792
36944
  for (const entry of entries) {
36793
36945
  if (!entry.isDirectory())
36794
36946
  continue;
36795
- const skillDir = join30(config2.extensionsDir, entry.name);
36796
- const skillMdPath = join30(skillDir, "SKILL.md");
36947
+ const skillDir = join31(config2.extensionsDir, entry.name);
36948
+ const skillMdPath = join31(skillDir, "SKILL.md");
36797
36949
  if (!existsSync13(skillMdPath))
36798
36950
  continue;
36799
36951
  let content;
@@ -37210,7 +37362,7 @@ var init_v4 = __esm(() => {
37210
37362
  });
37211
37363
 
37212
37364
  // src/lib/canonical-json.ts
37213
- import { createHash as createHash20 } from "crypto";
37365
+ import { createHash as createHash21 } from "crypto";
37214
37366
  function canonicalJson2(value, maximumBytes = 2 * 1024 * 1024) {
37215
37367
  return canonicalJsonAtDepth(value, maximumBytes, 64);
37216
37368
  }
@@ -37254,7 +37406,7 @@ function canonicalJsonAtDepth(value, maximumBytes, maximumDepth) {
37254
37406
  return visit3(value, 0);
37255
37407
  }
37256
37408
  function canonicalJsonSha256(value, maximumBytes) {
37257
- return createHash20("sha256").update(canonicalJson2(value, maximumBytes)).digest("hex");
37409
+ return createHash21("sha256").update(canonicalJson2(value, maximumBytes)).digest("hex");
37258
37410
  }
37259
37411
  var init_canonical_json = () => {};
37260
37412
 
@@ -37597,7 +37749,7 @@ function invitationFailure(value, status) {
37597
37749
  function invitationInput(action, input2) {
37598
37750
  if (!record4(input2))
37599
37751
  return inputFailure();
37600
- const keys = {
37752
+ const keys2 = {
37601
37753
  list: ["after"],
37602
37754
  get: ["invitationId"],
37603
37755
  issue: ["email", "role", "idempotencyKey", "confirm"],
@@ -37605,7 +37757,7 @@ function invitationInput(action, input2) {
37605
37757
  revoke: ["invitationId", "expectedGeneration", "confirm"],
37606
37758
  accept: ["invitationId", "token", "confirm"]
37607
37759
  };
37608
- 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)))
37609
37761
  return inputFailure();
37610
37762
  const value = { ...input2 };
37611
37763
  if (action === "list") {
@@ -38004,14 +38156,14 @@ var init_remote_workspace_leave = __esm(() => {
38004
38156
  });
38005
38157
 
38006
38158
  // src/lib/auth-store.ts
38007
- 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";
38008
- 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";
38009
38161
  function getAuthFilePath(env = process.env) {
38010
38162
  return skillsCredentialFilePath(env);
38011
38163
  }
38012
38164
  function getIdentityFilePath(env = process.env) {
38013
38165
  const file2 = skillsCredentialFilePath(env);
38014
- return join31(dirname20(file2), basename12(file2).replace(/^credentials/, "identity") + ".json");
38166
+ return join32(dirname21(file2), basename12(file2).replace(/^credentials/, "identity") + ".json");
38015
38167
  }
38016
38168
  function getApiUrl(action, env = process.env, options = {}) {
38017
38169
  return requireSkillsApiOrigin(action, env, options);
@@ -38093,15 +38245,15 @@ function runQuoteReceipt(value) {
38093
38245
  return value;
38094
38246
  }
38095
38247
  function parseRemoteRunQuote(value) {
38096
- const quote3 = object5(value);
38248
+ const quote3 = object6(value);
38097
38249
  runQuoteReceipt(quote3.quoteReceipt);
38098
- const pricing = object5(quote3.pricing);
38250
+ const pricing = object6(quote3.pricing);
38099
38251
  if (typeof quote3.skill !== "string" || !/^[a-z0-9][a-z0-9-]*$/.test(quote3.skill))
38100
38252
  throw new Error("Invalid quoted skill");
38101
38253
  const costCents = creditCount(pricing.costCredits ?? pricing.costCents);
38102
38254
  if (pricing.costCredits !== undefined && pricing.costCents !== undefined && pricing.costCents !== costCents)
38103
38255
  throw new Error("Inconsistent quoted credit count");
38104
- if (quote3.availability && object5(quote3.availability).status !== "available")
38256
+ if (quote3.availability && object6(quote3.availability).status !== "available")
38105
38257
  throw new Error("This skill is unavailable for remote execution");
38106
38258
  return { ...quote3, skill: quote3.skill, pricing: { ...pricing, costCredits: costCents, costCents, formattedCost: `${costCents} credits` } };
38107
38259
  }
@@ -38110,7 +38262,7 @@ function parseRemoteCreditPacks(value) {
38110
38262
  throw new Error("Invalid credit pack response");
38111
38263
  const ids = new Set;
38112
38264
  return value.map((value2) => {
38113
- const row = object5(value2);
38265
+ const row = object6(value2);
38114
38266
  const counts = [row.credits, row.creditsCents, row.amountCents].filter((value3) => value3 !== undefined).map(creditCount);
38115
38267
  if (!counts.length || counts[0] === 0 || counts.some((count) => count !== counts[0]))
38116
38268
  throw new Error("Inconsistent credit pack counts");
@@ -38125,7 +38277,7 @@ function parseRemoteCreditPacks(value) {
38125
38277
  });
38126
38278
  }
38127
38279
  function parseRemoteBillingStatus(value) {
38128
- const row = object5(value);
38280
+ const row = object6(value);
38129
38281
  const counts = [row.creditBalance, row.balanceCents].filter((value2) => value2 !== undefined).map(creditCount);
38130
38282
  if (!counts.length || counts.some((count) => count !== counts[0]))
38131
38283
  throw new Error("Inconsistent credit balance");
@@ -38137,7 +38289,7 @@ function parseRemoteBillingStatus(value) {
38137
38289
  };
38138
38290
  }
38139
38291
  function parseRemoteCheckout(value) {
38140
- const row = object5(value);
38292
+ const row = object6(value);
38141
38293
  if (typeof row.url !== "string")
38142
38294
  throw new Error("Invalid checkout URL");
38143
38295
  const url2 = new URL(row.url);
@@ -38145,7 +38297,7 @@ function parseRemoteCheckout(value) {
38145
38297
  throw new Error("Invalid checkout URL");
38146
38298
  return { url: row.url };
38147
38299
  }
38148
- function object5(value) {
38300
+ function object6(value) {
38149
38301
  if (!value || typeof value !== "object" || Array.isArray(value))
38150
38302
  throw new Error("Invalid Skills server response");
38151
38303
  return value;
@@ -38239,10 +38391,10 @@ async function readQuoteUnavailableCode(response) {
38239
38391
  let timer;
38240
38392
  let deadlineExceeded = false;
38241
38393
  const expired = Symbol("quote body deadline");
38242
- const deadline = new Promise((resolve21) => {
38394
+ const deadline = new Promise((resolve22) => {
38243
38395
  timer = setTimeout(() => {
38244
38396
  deadlineExceeded = true;
38245
- resolve21(expired);
38397
+ resolve22(expired);
38246
38398
  reader.cancel().catch(() => {});
38247
38399
  }, 1500);
38248
38400
  });
@@ -39385,8 +39537,8 @@ function invitationEmailIds(invitationId, challengeId) {
39385
39537
  return { invitationId, challengeId };
39386
39538
  }
39387
39539
  function invitationEmailInput(action, input2) {
39388
- const keys = ["invitationId", "token", "challengeId", "confirm", ...action === "accept" ? ["code"] : []];
39389
- 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)))
39390
39542
  throw new InvitationEmailInputError;
39391
39543
  const value = { ...input2 };
39392
39544
  const ids = invitationEmailIds(value.invitationId, value.challengeId);
@@ -39480,7 +39632,7 @@ var init_remote_invitation_recovery = __esm(() => {
39480
39632
  });
39481
39633
 
39482
39634
  // src/lib/remote-private-publications.ts
39483
- import { createHash as createHash21 } from "crypto";
39635
+ import { createHash as createHash22 } from "crypto";
39484
39636
  function checkedPublicationDeclaration(value) {
39485
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)
39486
39638
  return bad();
@@ -39725,12 +39877,12 @@ class RemotePrivatePublicationsClient {
39725
39877
  previous = view;
39726
39878
  if (!["queued", "verifying"].includes(view.state) || Date.now() >= until)
39727
39879
  return view;
39728
- await new Promise((resolve21) => {
39880
+ await new Promise((resolve22) => {
39729
39881
  const timer = setTimeout(done, Math.min(1000, until - Date.now()));
39730
39882
  function done() {
39731
39883
  clearTimeout(timer);
39732
39884
  options.signal?.removeEventListener("abort", done);
39733
- resolve21();
39885
+ resolve22();
39734
39886
  }
39735
39887
  options.signal?.addEventListener("abort", done, { once: true });
39736
39888
  });
@@ -39741,7 +39893,7 @@ var PRIVATE_PUBLICATION_MAX_BYTES, failures2, PrivatePublicationError, bad = ()
39741
39893
  throw new PrivatePublicationError("INVALID_PUBLICATION_INPUT", "Invalid publication input or recovery data.");
39742
39894
  }, invalid4 = () => {
39743
39895
  throw new PrivatePublicationError("INVALID_PUBLICATION_RESPONSE", "The server returned an invalid publication result.");
39744
- }, 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");
39745
39897
  var init_remote_private_publications = __esm(() => {
39746
39898
  init_fleet_credentials();
39747
39899
  init_remote_workspace_selection();
@@ -40018,10 +40170,10 @@ var init_remote_auth = __esm(() => {
40018
40170
  });
40019
40171
 
40020
40172
  // src/lib/workspace-profile.ts
40021
- 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";
40022
40174
  function stat2(path) {
40023
40175
  try {
40024
- return lstatSync21(path);
40176
+ return lstatSync22(path);
40025
40177
  } catch (error61) {
40026
40178
  if (error61.code === "ENOENT")
40027
40179
  return null;
@@ -40031,14 +40183,14 @@ function stat2(path) {
40031
40183
  function safeText(file2) {
40032
40184
  if (stat2(file2) === null)
40033
40185
  return null;
40034
- 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);
40035
40187
  try {
40036
- const s = fstatSync15(fd);
40188
+ const s = fstatSync16(fd);
40037
40189
  if (!s.isFile() || s.size > 65536 || ![256, 384].includes(s.mode & 4095) || process.getuid && s.uid !== process.getuid())
40038
40190
  return fail("The selected profile must use bounded owner-only regular files.");
40039
40191
  return readFileSync19(fd, "utf8");
40040
40192
  } finally {
40041
- closeSync15(fd);
40193
+ closeSync16(fd);
40042
40194
  }
40043
40195
  }
40044
40196
  function checkIdentityMetadata(file2, identity3) {
@@ -40250,8 +40402,8 @@ var init_recurring_customer = __esm(() => {
40250
40402
  });
40251
40403
 
40252
40404
  // src/lib/recurring-recovery.ts
40253
- 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";
40254
- 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";
40255
40407
  import { randomUUID as randomUUID2 } from "crypto";
40256
40408
 
40257
40409
  class RecoveryOwner {
@@ -40259,14 +40411,14 @@ class RecoveryOwner {
40259
40411
  parents = [];
40260
40412
  constructor(directory) {
40261
40413
  this.directory = directory;
40262
- if (!isAbsolute18(directory) || resolve21(directory) !== directory || realpathSync9(directory) !== directory)
40414
+ if (!isAbsolute20(directory) || resolve22(directory) !== directory || realpathSync9(directory) !== directory)
40263
40415
  invalid5();
40264
- for (let path = directory;; path = dirname21(path)) {
40265
- const stat3 = lstatSync22(path);
40416
+ for (let path = directory;; path = dirname22(path)) {
40417
+ const stat3 = lstatSync23(path);
40266
40418
  if (!stat3.isDirectory() || stat3.isSymbolicLink())
40267
40419
  invalid5();
40268
40420
  this.parents.push({ path, dev: stat3.dev, ino: stat3.ino });
40269
- if (path === dirname21(path))
40421
+ if (path === dirname22(path))
40270
40422
  break;
40271
40423
  }
40272
40424
  this.assert();
@@ -40275,59 +40427,59 @@ class RecoveryOwner {
40275
40427
  if (realpathSync9(this.directory) !== this.directory)
40276
40428
  invalid5();
40277
40429
  for (const prior of this.parents) {
40278
- const now = lstatSync22(prior.path);
40430
+ const now = lstatSync23(prior.path);
40279
40431
  if (!now.isDirectory() || now.isSymbolicLink() || now.dev !== prior.dev || now.ino !== prior.ino)
40280
40432
  invalid5();
40281
40433
  }
40282
- const own2 = lstatSync22(this.directory);
40434
+ const own2 = lstatSync23(this.directory);
40283
40435
  if ((own2.mode & 511) !== 448 || (own2.mode & 3584) !== 0 || process.getuid && own2.uid !== process.getuid())
40284
40436
  invalid5();
40285
40437
  }
40286
40438
  read(name) {
40287
40439
  this.assert();
40288
- 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);
40289
40441
  try {
40290
- const before = fstatSync16(fd);
40442
+ const before = fstatSync17(fd);
40291
40443
  if (!before.isFile() || before.nlink !== 1 || (before.mode & 4095) !== 384 || before.size < 1 || before.size > 8192 || process.getuid && before.uid !== process.getuid())
40292
40444
  invalid5();
40293
40445
  const bytes = Buffer.alloc(before.size + 1);
40294
40446
  let size = 0;
40295
40447
  while (size < bytes.length) {
40296
- const n2 = readSync10(fd, bytes, size, bytes.length - size, size);
40448
+ const n2 = readSync11(fd, bytes, size, bytes.length - size, size);
40297
40449
  if (!n2)
40298
40450
  break;
40299
40451
  size += n2;
40300
40452
  }
40301
- const after = fstatSync16(fd), path = lstatSync22(join32(this.directory, name));
40453
+ const after = fstatSync17(fd), path = lstatSync23(join33(this.directory, name));
40302
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())
40303
40455
  invalid5();
40304
40456
  this.assert();
40305
40457
  return new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(0, size));
40306
40458
  } finally {
40307
- closeSync16(fd);
40459
+ closeSync17(fd);
40308
40460
  }
40309
40461
  }
40310
40462
  write(name, value) {
40311
40463
  this.assert();
40312
40464
  const bytes = canonicalJson2(value, 8192) + `
40313
40465
  `;
40314
- 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);
40315
40467
  try {
40316
40468
  writeFileSync9(fd, bytes);
40317
- fsyncSync4(fd);
40469
+ fsyncSync5(fd);
40318
40470
  } finally {
40319
- closeSync16(fd);
40471
+ closeSync17(fd);
40320
40472
  }
40321
40473
  this.assert();
40322
40474
  this.sync();
40323
40475
  }
40324
40476
  sync() {
40325
40477
  this.assert();
40326
- const fd = openSync16(this.directory, constants14.O_RDONLY | constants14.O_NOFOLLOW);
40478
+ const fd = openSync17(this.directory, constants15.O_RDONLY | constants15.O_NOFOLLOW);
40327
40479
  try {
40328
- fsyncSync4(fd);
40480
+ fsyncSync5(fd);
40329
40481
  } finally {
40330
- closeSync16(fd);
40482
+ closeSync17(fd);
40331
40483
  }
40332
40484
  }
40333
40485
  saveState(state, expected) {
@@ -40338,30 +40490,30 @@ class RecoveryOwner {
40338
40490
  if (this.read("state.json") !== expected)
40339
40491
  invalid5();
40340
40492
  this.assert();
40341
- renameSync6(join32(this.directory, name), join32(this.directory, "state.json"));
40493
+ renameSync6(join33(this.directory, name), join33(this.directory, "state.json"));
40342
40494
  this.sync();
40343
40495
  }
40344
40496
  async locked(action) {
40345
40497
  this.assert();
40346
40498
  let fd;
40347
40499
  try {
40348
- 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);
40349
40501
  } catch {
40350
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.");
40351
40503
  }
40352
- const owner2 = fstatSync16(fd);
40504
+ const owner2 = fstatSync17(fd);
40353
40505
  try {
40354
40506
  writeFileSync9(fd, JSON.stringify({ pid: process.pid }));
40355
- fsyncSync4(fd);
40507
+ fsyncSync5(fd);
40356
40508
  this.sync();
40357
40509
  return await action();
40358
40510
  } finally {
40359
- closeSync16(fd);
40511
+ closeSync17(fd);
40360
40512
  this.assert();
40361
- const now = lstatSync22(join32(this.directory, "operation.lock"));
40513
+ const now = lstatSync23(join33(this.directory, "operation.lock"));
40362
40514
  if (owner2.dev !== now.dev || owner2.ino !== now.ino || !now.isFile() || now.isSymbolicLink())
40363
40515
  invalid5();
40364
- unlinkSync5(join32(this.directory, "operation.lock"));
40516
+ unlinkSync5(join33(this.directory, "operation.lock"));
40365
40517
  this.sync();
40366
40518
  }
40367
40519
  }
@@ -40394,9 +40546,9 @@ function base(customer, organizationId) {
40394
40546
  };
40395
40547
  }
40396
40548
  function create(directory, intent) {
40397
- if (!isAbsolute18(directory) || resolve21(directory) !== directory || realpathSync9(dirname21(directory)) !== dirname21(directory))
40549
+ if (!isAbsolute20(directory) || resolve22(directory) !== directory || realpathSync9(dirname22(directory)) !== dirname22(directory))
40398
40550
  invalid5();
40399
- mkdirSync10(directory, { mode: 448 });
40551
+ mkdirSync11(directory, { mode: 448 });
40400
40552
  const owner2 = new RecoveryOwner(directory), checked = intentSchema.parse(intent), intentSha256 = canonicalJsonSha256(checked);
40401
40553
  owner2.write(`intent-${intentSha256}.json`, checked);
40402
40554
  owner2.write("state.json", { contractVersion: 1, intentSha256, phase: "prepared", consentId: null });
@@ -40519,7 +40671,7 @@ async function continueRecurringRecovery(customer, directory, options) {
40519
40671
  throw error61;
40520
40672
  }
40521
40673
  }
40522
- var uuid12, sha4, common, intentSchema, stateSchema, invalid5 = () => {
40674
+ var uuid12, sha5, common, intentSchema, stateSchema, invalid5 = () => {
40523
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.");
40524
40676
  };
40525
40677
  var init_recurring_recovery = __esm(() => {
@@ -40529,7 +40681,7 @@ var init_recurring_recovery = __esm(() => {
40529
40681
  init_remote_recurring();
40530
40682
  init_recurring_customer();
40531
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}$/);
40532
- sha4 = exports_external.string().regex(/^[a-f0-9]{64}$/);
40684
+ sha5 = exports_external.string().regex(/^[a-f0-9]{64}$/);
40533
40685
  common = exports_external.object({
40534
40686
  contractVersion: exports_external.literal(1),
40535
40687
  apiOrigin: exports_external.string().min(1).max(4096),
@@ -40542,7 +40694,7 @@ var init_recurring_recovery = __esm(() => {
40542
40694
  common.extend({
40543
40695
  operation: exports_external.literal("activate"),
40544
40696
  draftId: uuid12,
40545
- termsSha256: sha4,
40697
+ termsSha256: sha5,
40546
40698
  approvalDeadline: exports_external.string().datetime(),
40547
40699
  approval: recurringActivationSchema
40548
40700
  }).strict(),
@@ -40550,14 +40702,14 @@ var init_recurring_recovery = __esm(() => {
40550
40702
  ]);
40551
40703
  stateSchema = exports_external.object({
40552
40704
  contractVersion: exports_external.literal(1),
40553
- intentSha256: sha4,
40705
+ intentSha256: sha5,
40554
40706
  phase: exports_external.enum(["prepared", "pending", "observed"]),
40555
40707
  consentId: uuid12.nullable()
40556
40708
  }).strict();
40557
40709
  });
40558
40710
 
40559
40711
  // src/lib/recurring-surface.ts
40560
- import { isAbsolute as isAbsolute19 } from "path";
40712
+ import { isAbsolute as isAbsolute21 } from "path";
40561
40713
  function recurringMcpSchema(action) {
40562
40714
  return action === "activate" ? recurringSurfaceSchemas.activate.extend({ code, confirm: exports_external.literal(true) }) : recurringSurfaceSchemas[action];
40563
40715
  }
@@ -40662,7 +40814,7 @@ var init_recurring_surface = __esm(() => {
40662
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}$/);
40663
40815
  context = { userId: uuid13.optional(), membershipId: uuid13.optional() };
40664
40816
  page2 = { limit: exports_external.number().int().min(1).max(100).optional(), cursor: exports_external.string().min(1).max(2048).optional() };
40665
- 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");
40666
40818
  email4 = exports_external.string().trim().toLowerCase().email().max(254);
40667
40819
  code = exports_external.string().regex(/^\d{6}$/);
40668
40820
  recurringSurfaceSchemas = {
@@ -42491,21 +42643,21 @@ var init_credential_state = __esm(() => {
42491
42643
  });
42492
42644
 
42493
42645
  // src/lib/run-state.ts
42494
- import { createHash as createHash22, randomBytes } from "crypto";
42495
- import { existsSync as existsSync15, mkdirSync as mkdirSync11, readFileSync as readFileSync20, readdirSync as readdirSync10, statSync as statSync10, writeFileSync as writeFileSync10 } from "fs";
42496
- 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";
42497
42649
  function createSkillRun(params, targetDir = process.cwd()) {
42498
42650
  const now = new Date;
42499
42651
  const id = createRunId(now);
42500
42652
  const day = now.toISOString().slice(0, 10);
42501
42653
  const skillName = normalizeSkillName(params.skill);
42502
42654
  const root = getProjectStateDir(targetDir);
42503
- const runDir = join33(root, "runs", day, id);
42504
- const logsDir = join33(runDir, "logs");
42505
- const exportDir = join33(root, "exports", skillName, id);
42506
- mkdirSync11(logsDir, { recursive: true });
42507
- mkdirSync11(exportDir, { recursive: true });
42508
- 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 });
42509
42661
  const record10 = {
42510
42662
  id,
42511
42663
  skill: skillName,
@@ -42557,22 +42709,22 @@ function updateSkillRun(context2, patch) {
42557
42709
  return context2.record;
42558
42710
  }
42559
42711
  function writeRunLogs(context2, stdout = "", stderr = "") {
42560
- writeFileSync10(join33(context2.logsDir, "stdout.log"), stdout);
42561
- writeFileSync10(join33(context2.logsDir, "stderr.log"), stderr);
42712
+ writeFileSync10(join34(context2.logsDir, "stdout.log"), stdout);
42713
+ writeFileSync10(join34(context2.logsDir, "stderr.log"), stderr);
42562
42714
  }
42563
42715
  function appendRunEvent(context2, event, data = {}) {
42564
42716
  const line = JSON.stringify({ ts: new Date().toISOString(), event, ...data }) + `
42565
42717
  `;
42566
- const path = join33(context2.runDir, "events.ndjson");
42718
+ const path = join34(context2.runDir, "events.ndjson");
42567
42719
  const previous = existsSync15(path) ? readFileSync20(path, "utf-8") : "";
42568
42720
  writeFileSync10(path, previous + line);
42569
42721
  }
42570
42722
  function findSkillRun(runId, targetDir = process.cwd()) {
42571
- const runsRoot = join33(getProjectStateDir(targetDir), "runs");
42723
+ const runsRoot = join34(getProjectStateDir(targetDir), "runs");
42572
42724
  if (!existsSync15(runsRoot))
42573
42725
  return null;
42574
42726
  for (const day of readdirSync10(runsRoot)) {
42575
- const record10 = readRunRecord(join33(runsRoot, day, runId));
42727
+ const record10 = readRunRecord(join34(runsRoot, day, runId));
42576
42728
  if (record10)
42577
42729
  return record10;
42578
42730
  }
@@ -42589,11 +42741,11 @@ function skillRunEnv(context2) {
42589
42741
  };
42590
42742
  }
42591
42743
  function writeRunRecord(context2) {
42592
- 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) + `
42593
42745
  `);
42594
42746
  }
42595
42747
  function writeArtifactsManifest(context2, artifacts) {
42596
- 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) + `
42597
42749
  `);
42598
42750
  }
42599
42751
  function collectRunArtifacts(context2) {
@@ -42606,14 +42758,14 @@ function collectRunArtifacts(context2) {
42606
42758
  artifacts.push({
42607
42759
  path: toProjectRelative(context2.targetDir, path),
42608
42760
  mime: mimeForPath(path),
42609
- sha256: createHash22("sha256").update(bytes).digest("hex"),
42761
+ sha256: createHash23("sha256").update(bytes).digest("hex"),
42610
42762
  sizeBytes: stat3.size
42611
42763
  });
42612
42764
  }
42613
42765
  return artifacts.sort((a, b) => a.path.localeCompare(b.path));
42614
42766
  }
42615
42767
  function readRunRecord(runDir) {
42616
- const path = join33(runDir, "run.json");
42768
+ const path = join34(runDir, "run.json");
42617
42769
  if (!existsSync15(path))
42618
42770
  return null;
42619
42771
  try {
@@ -42625,7 +42777,7 @@ function readRunRecord(runDir) {
42625
42777
  function walkFiles(dir) {
42626
42778
  const files = [];
42627
42779
  for (const entry of readdirSync10(dir)) {
42628
- const full = join33(dir, entry);
42780
+ const full = join34(dir, entry);
42629
42781
  if (statSync10(full).isDirectory())
42630
42782
  files.push(...walkFiles(full));
42631
42783
  else
@@ -42878,11 +43030,11 @@ var init_cloud_executions = __esm(() => {
42878
43030
  // node_modules/@hasna/secrets/dist/sdk.js
42879
43031
  import { isIP as isIP2 } from "net";
42880
43032
  import { spawnSync as spawnSync5 } from "child_process";
42881
- 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";
42882
43034
  import { O_NOFOLLOW as O_NOFOLLOW3, O_NONBLOCK as O_NONBLOCK3, O_RDONLY as O_RDONLY3 } from "constants";
42883
43035
  import { createRequire as createRequire2 } from "module";
42884
43036
  import { hostname as osHostname2 } from "os";
42885
- import { isAbsolute as isAbsolute20, join as join34 } from "path";
43037
+ import { isAbsolute as isAbsolute22, join as join35 } from "path";
42886
43038
  import { createRequire as createRequire22 } from "module";
42887
43039
  function envToken2(name) {
42888
43040
  return name.toUpperCase().replace(/-/g, "_");
@@ -42906,21 +43058,21 @@ function homeDir2(env) {
42906
43058
  }
42907
43059
  function absoluteOverride2(env, key) {
42908
43060
  const value = env[key]?.trim();
42909
- return value && isAbsolute20(value) ? value : null;
43061
+ return value && isAbsolute22(value) ? value : null;
42910
43062
  }
42911
43063
  function hasnaHomeDir2(env) {
42912
43064
  const override = absoluteOverride2(env, HASNA_HOME_ENV_KEY2);
42913
43065
  if (override)
42914
43066
  return override;
42915
43067
  const home = homeDir2(env);
42916
- return home ? join34(home, HASNA_HOME_DIR2) : null;
43068
+ return home ? join35(home, HASNA_HOME_DIR2) : null;
42917
43069
  }
42918
43070
  function appConfigDir2(name, env) {
42919
43071
  const configRoot = absoluteOverride2(env, HASNA_CONFIG_HOME_ENV_KEY2);
42920
43072
  if (configRoot)
42921
- return join34(configRoot, name);
43073
+ return join35(configRoot, name);
42922
43074
  const root = hasnaHomeDir2(env);
42923
- return root ? join34(root, name, CONFIG_SUBDIR2) : null;
43075
+ return root ? join35(root, name, CONFIG_SUBDIR2) : null;
42924
43076
  }
42925
43077
  function credentialDiskSourceList2(name, env, profile = null) {
42926
43078
  if (!SAFE_APP_SLUG2.test(name))
@@ -42929,7 +43081,7 @@ function credentialDiskSourceList2(name, env, profile = null) {
42929
43081
  if (!directory2)
42930
43082
  return [];
42931
43083
  const file2 = profile ? `${CREDENTIALS_FILE2}-${profile}` : CREDENTIALS_FILE2;
42932
- return [{ path: join34(directory2, file2), tier: "disk" }];
43084
+ return [{ path: join35(directory2, file2), tier: "disk" }];
42933
43085
  }
42934
43086
  function credentialDiskSources2(name, env) {
42935
43087
  return credentialDiskSourceList2(name, env, null).map((s) => s.path);
@@ -42983,7 +43135,7 @@ function readAppConfigFile2(path) {
42983
43135
  };
42984
43136
  let fd = -1;
42985
43137
  try {
42986
- fd = openSync17(path, O_RDONLY3 | O_NOFOLLOW3 | O_NONBLOCK3);
43138
+ fd = openSync18(path, O_RDONLY3 | O_NOFOLLOW3 | O_NONBLOCK3);
42987
43139
  } catch (error61) {
42988
43140
  const code2 = error61.code;
42989
43141
  if (code2 === "ENOENT" || code2 === "ENOTDIR")
@@ -42993,7 +43145,7 @@ function readAppConfigFile2(path) {
42993
43145
  unsafe(`the path could not be opened (${code2 ?? "unknown error"})`);
42994
43146
  }
42995
43147
  try {
42996
- const before = fstatSync17(fd);
43148
+ const before = fstatSync18(fd);
42997
43149
  if (!before.isFile())
42998
43150
  unsafe("the path is not a regular file");
42999
43151
  if (!configFileModeAllowed2(before.mode)) {
@@ -43005,14 +43157,14 @@ function readAppConfigFile2(path) {
43005
43157
  if (before.size > MAX_CREDENTIAL_FILE_BYTES2)
43006
43158
  unsafe("the file exceeds the size limit");
43007
43159
  const bytes = readFileSync21(fd);
43008
- const after = fstatSync17(fd);
43160
+ const after = fstatSync18(fd);
43009
43161
  if (!configFileReadsCoherent2(before, after)) {
43010
43162
  unsafe("the file changed while being read");
43011
43163
  }
43012
43164
  return parseEnvFile2(bytes.toString("utf8"));
43013
43165
  } finally {
43014
43166
  if (fd !== -1)
43015
- closeSync17(fd);
43167
+ closeSync18(fd);
43016
43168
  }
43017
43169
  }
43018
43170
  function readCredentialFile2(path, apiKeyKeys) {
@@ -43030,8 +43182,8 @@ function readCredentialFile2(path, apiKeyKeys) {
43030
43182
  }
43031
43183
  return values[0] ?? null;
43032
43184
  }
43033
- function appConfigDiskValue2(name, env, keys) {
43034
- 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));
43035
43187
  if (wanted.length === 0)
43036
43188
  return null;
43037
43189
  for (const path of credentialDiskSources2(name, env)) {
@@ -43138,8 +43290,8 @@ function validateAndSealResolvedCredential(appName, credential) {
43138
43290
  ...credential.pointerVaultKey !== undefined ? { pointerVaultKey: credential.pointerVaultKey } : {}
43139
43291
  });
43140
43292
  }
43141
- function firstEnvValue2(env, keys) {
43142
- for (const key of keys) {
43293
+ function firstEnvValue2(env, keys2) {
43294
+ for (const key of keys2) {
43143
43295
  if (!Object.prototype.hasOwnProperty.call(env, key))
43144
43296
  continue;
43145
43297
  const value = env[key]?.trim();
@@ -43216,12 +43368,12 @@ function keychainConfigValue2(name, env, options = {}) {
43216
43368
  return readKeychainItem2(name, env, "api-url", options);
43217
43369
  }
43218
43370
  function snapshotClientEnvironment2(name, env) {
43219
- const keys = clientTransportEnvKeys2(name);
43371
+ const keys2 = clientTransportEnvKeys2(name);
43220
43372
  const ambient = isAmbientEnvironment2(env);
43221
43373
  const snapshot2 = Object.create(null);
43222
43374
  for (const key of [
43223
- ...keys.apiUrlKeys,
43224
- ...keys.apiKeyKeys,
43375
+ ...keys2.apiUrlKeys,
43376
+ ...keys2.apiKeyKeys,
43225
43377
  credentialOverrideEnvKey2(name),
43226
43378
  credentialPointerEnvKey2(name),
43227
43379
  CREDENTIAL_PROFILE_ENV_KEY2,
@@ -43548,8 +43700,8 @@ function toV1BaseUrl2(apiUrl) {
43548
43700
  }
43549
43701
  function resolveClientTransportSnapshot(name, env = process.env, options = {}) {
43550
43702
  env = snapshotClientEnvironment2(name, env);
43551
- const keys = clientTransportEnvKeys2(name);
43552
- 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]) }));
43553
43705
  const blankUrl = definedUrlEntries.find((entry) => entry.raw.trim().length === 0);
43554
43706
  if (blankUrl) {
43555
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]);
@@ -43564,7 +43716,7 @@ function resolveClientTransportSnapshot(name, env = process.env, options = {}) {
43564
43716
  }
43565
43717
  const envUrlHit = usableUrlEntries[0] ?? null;
43566
43718
  const keychainUrlHit = keychainConfigValue2(name, env, options.credentials?.keychain);
43567
- const diskConfigUrlHit = appConfigDiskValue2(name, env, keys.apiUrlKeys);
43719
+ const diskConfigUrlHit = appConfigDiskValue2(name, env, keys2.apiUrlKeys);
43568
43720
  if (diskConfigUrlHit?.unusable) {
43569
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]);
43570
43722
  }
@@ -43580,14 +43732,14 @@ function resolveClientTransportSnapshot(name, env = process.env, options = {}) {
43580
43732
  }
43581
43733
  const warnings = [];
43582
43734
  if (configuredUrl && !envUrlHit) {
43583
- 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.`);
43584
43736
  }
43585
43737
  const credential = resolveCredential2(name, env, options.credentials);
43586
43738
  if (!credential) {
43587
43739
  const diskHint = credentialDiskSourcesForMessage(name, env);
43588
- 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`;
43589
- 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.`);
43590
- 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]]);
43591
43743
  }
43592
43744
  if (credential.warning)
43593
43745
  warnings.push(credential.warning);
@@ -43599,7 +43751,7 @@ function resolveClientTransportSnapshot(name, env = process.env, options = {}) {
43599
43751
  urlHit = { key: DEFAULT_AUTHORITY_SOURCE, value: defaultFleetGatewayBaseUrl2(name) };
43600
43752
  } catch (error61) {
43601
43753
  const message = error61 instanceof Error ? error61.message : String(error61);
43602
- 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]]);
43603
43755
  }
43604
43756
  }
43605
43757
  const apiUrlSource = urlHit.key;
@@ -44043,7 +44195,7 @@ function createSecretsClientFromEnv(env = process.env, overrides = {}) {
44043
44195
  });
44044
44196
  return new SecretsClient({ ...clientOverrides, baseUrl, apiKey });
44045
44197
  }
44046
- 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;
44047
44199
  var init_sdk = __esm(() => {
44048
44200
  init_transport2 = __esm2(() => {
44049
44201
  CredentialResolutionError2 = class CredentialResolutionError3 extends Error {
@@ -44178,14 +44330,14 @@ var init_sdk = __esm(() => {
44178
44330
  });
44179
44331
 
44180
44332
  // src/lib/execution-secrets.ts
44181
- 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";
44182
44334
  import { hostname as stationHostname } from "os";
44183
44335
  function selectedSecretBindingsTemplate(scope, names, createClient = createSecretsClientFromEnv) {
44184
44336
  let secretsAuthority;
44185
44337
  try {
44186
44338
  secretsAuthority = createClient().baseUrl;
44187
44339
  } catch {
44188
- 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.");
44189
44341
  }
44190
44342
  const { authority, workspaceId, profileRevision, slug: slug2, version: version2, bundleDigest } = scope.selection;
44191
44343
  return {
@@ -44196,14 +44348,14 @@ function selectedSecretBindingsTemplate(scope, names, createClient = createSecre
44196
44348
  bindings: Object.fromEntries(names.map((name) => [name, ""]))
44197
44349
  };
44198
44350
  }
44199
- function refuse2(code2, message) {
44351
+ function refuse4(code2, message) {
44200
44352
  throw new SkillSelectionError(code2, message);
44201
44353
  }
44202
44354
  function record10(value) {
44203
44355
  return !!value && typeof value === "object" && !Array.isArray(value);
44204
44356
  }
44205
- function exactKeys2(value, keys) {
44206
- 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));
44207
44359
  }
44208
44360
  function identifier3(value) {
44209
44361
  return typeof value === "string" && value.length > 0 && value.length <= 2048 && !/[\x00-\x20\x7f]/.test(value);
@@ -44212,29 +44364,29 @@ function declaredSecretNames(value) {
44212
44364
  if (value === undefined)
44213
44365
  return [];
44214
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) {
44215
- 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).");
44216
44368
  }
44217
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))) {
44218
- 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.");
44219
44371
  }
44220
44372
  return value;
44221
44373
  }
44222
44374
  function validateSelectedSecretBindings(value, scope, names) {
44223
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)) {
44224
- 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.");
44225
44377
  }
44226
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 })) {
44227
44379
  if (value.selection[key] !== expected)
44228
- 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.");
44229
44381
  }
44230
44382
  let workspaceDirectory;
44231
44383
  try {
44232
44384
  workspaceDirectory = realpathSync10(scope.cwd);
44233
44385
  } catch {
44234
- 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.");
44235
44387
  }
44236
44388
  if (value.consumer.stationId !== (process.env.HASNA_STATION || stationHostname()) || value.consumer.workspaceDirectory !== workspaceDirectory) {
44237
- 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.");
44238
44390
  }
44239
44391
  try {
44240
44392
  if (!identifier3(value.secretsAuthority))
@@ -44243,10 +44395,10 @@ function validateSelectedSecretBindings(value, scope, names) {
44243
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)
44244
44396
  throw new Error;
44245
44397
  } catch {
44246
- 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).");
44247
44399
  }
44248
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 === ".."))) {
44249
- 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.");
44250
44402
  }
44251
44403
  return structuredClone(value);
44252
44404
  }
@@ -44257,10 +44409,10 @@ async function resolveSelectedSecrets(bindings, createClient = createSecretsClie
44257
44409
  try {
44258
44410
  client = createClient();
44259
44411
  } catch {
44260
- 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.");
44261
44413
  }
44262
44414
  if (client.baseUrl !== bindings.secretsAuthority)
44263
- 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.");
44264
44416
  const env = {};
44265
44417
  const signal = AbortSignal.timeout(15000);
44266
44418
  try {
@@ -44272,7 +44424,7 @@ async function resolveSelectedSecrets(bindings, createClient = createSecretsClie
44272
44424
  }
44273
44425
  return env;
44274
44426
  } catch {
44275
- 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.");
44276
44428
  }
44277
44429
  }
44278
44430
  function redactExecutionSecrets(text3, env) {
@@ -44300,7 +44452,7 @@ function grantIdentifier(v) {
44300
44452
  function grantRecord(v) {
44301
44453
  return !!v && typeof v === "object" && !Array.isArray(v);
44302
44454
  }
44303
- function keys(v, required2, optional2 = []) {
44455
+ function keys2(v, required2, optional2 = []) {
44304
44456
  return required2.every((k) => Object.hasOwn(v, k)) && Object.keys(v).every((k) => required2.includes(k) || optional2.includes(k));
44305
44457
  }
44306
44458
  function invalid6() {
@@ -44328,10 +44480,10 @@ function grantWorkspace(v) {
44328
44480
  return flavor.isAbsolute(v) && flavor.normalize(v) === v;
44329
44481
  }
44330
44482
  function selection(v) {
44331
- 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);
44332
44484
  }
44333
44485
  function validateExecutionGrantRequest(value) {
44334
- 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, [
44335
44487
  "authority",
44336
44488
  "workspaceId",
44337
44489
  "profileId",
@@ -44339,7 +44491,7 @@ function validateExecutionGrantRequest(value) {
44339
44491
  "slug",
44340
44492
  "version",
44341
44493
  "bundleDigest"
44342
- ]) || !grantRecord(value.consumer) || !keys(value.consumer, ["stationId", "workspaceDirectory"]))
44494
+ ]) || !grantRecord(value.consumer) || !keys2(value.consumer, ["stationId", "workspaceDirectory"]))
44343
44495
  invalid6();
44344
44496
  const { selection: s, consumer: c } = value;
44345
44497
  if (!selection({
@@ -44420,10 +44572,10 @@ __export(exports_selected_run, {
44420
44572
  prepareSelectedSecretBindings: () => prepareSelectedSecretBindings,
44421
44573
  executeSelectedLocal: () => executeSelectedLocal
44422
44574
  });
44423
- import { createHash as createHash23 } from "crypto";
44575
+ import { createHash as createHash24 } from "crypto";
44424
44576
  import { spawn as spawn2 } from "child_process";
44425
- import { mkdirSync as mkdirSync12, mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync11, realpathSync as realpathSync11 } from "fs";
44426
- 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";
44427
44579
  import { tmpdir, hostname as stationHostname2 } from "os";
44428
44580
  async function resolveSelectedRun(spec, profileId, options = {}) {
44429
44581
  const context2 = await resolveSelectionContext(profileId, options);
@@ -44503,7 +44655,7 @@ async function executeSelectedLocal(selected, options = {}) {
44503
44655
  throw new SkillSelectionError("INVALID_SECRET_BINDINGS", "Explicit environment values must be bounded strings without NUL bytes.");
44504
44656
  secretEnv[name] = value;
44505
44657
  }
44506
- const runDirectory = mkdtempSync3(join35(tmpdir(), "skills-execution-"));
44658
+ const runDirectory = mkdtempSync3(join36(tmpdir(), "skills-execution-"));
44507
44659
  const paths = new SkillEntryPaths;
44508
44660
  for (const entry of entries) {
44509
44661
  paths.add(entry.path, 100, () => {
@@ -44511,12 +44663,12 @@ async function executeSelectedLocal(selected, options = {}) {
44511
44663
  }, () => {
44512
44664
  throw new SkillSelectionError("INVALID_BUNDLE_PATH", "The execution bundle path exceeds its limit.");
44513
44665
  });
44514
- const destination = join35(runDirectory, entry.path);
44515
- mkdirSync12(dirname22(destination), { recursive: true, mode: 448 });
44666
+ const destination = join36(runDirectory, entry.path);
44667
+ mkdirSync13(dirname23(destination), { recursive: true, mode: 448 });
44516
44668
  writeFileSync11(destination, entry.bytes, { flag: "wx", mode: entry.mode & 511 });
44517
44669
  }
44518
44670
  env.SKILLS_INPUT_JSON = input2;
44519
- env.SKILLS_WORKSPACE_DIR = resolve22(options.cwd ?? process.cwd());
44671
+ env.SKILLS_WORKSPACE_DIR = resolve23(options.cwd ?? process.cwd());
44520
44672
  env.SKILLS_RUN_DIR = runDirectory;
44521
44673
  if (runtime.version) {
44522
44674
  const version2 = await subprocess([executable, ...runtimeName === "bun" ? ["--no-env-file"] : [], "--version"], runDirectory, env, "", Math.min(timeoutMs, 5000));
@@ -44539,20 +44691,20 @@ async function executeSelectedLocal(selected, options = {}) {
44539
44691
  }
44540
44692
  if (bindings)
44541
44693
  secretEnv = await resolveSelectedSecrets(bindings, options.createSecretsClient);
44542
- 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);
44543
44695
  result.stdout = redactExecutionSecrets(result.stdout, secretEnv);
44544
44696
  result.stderr = redactExecutionSecrets(result.stderr, secretEnv);
44545
44697
  const receipt = {
44546
44698
  selection: selection2,
44547
44699
  target: "local",
44548
44700
  runtime: runtimeName,
44549
- inputDigest: `sha256:${createHash23("sha256").update(input2).digest("hex")}`,
44701
+ inputDigest: `sha256:${createHash24("sha256").update(input2).digest("hex")}`,
44550
44702
  runDirectory,
44551
44703
  ...executionGrant ? { executionGrant } : {},
44552
44704
  ...bindings ? { secretBinding: { schema: bindings.schema, selection: bindings.selection, consumer: bindings.consumer, secretsAuthority: bindings.secretsAuthority, bindings: bindings.bindings } } : {},
44553
44705
  ...result
44554
44706
  };
44555
- 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 });
44556
44708
  return receipt;
44557
44709
  }
44558
44710
  async function subprocess(command, cwd, env, input2, timeoutMs) {
@@ -44742,7 +44894,7 @@ var init_blog_article = __esm(() => {
44742
44894
 
44743
44895
  // src/mcp/operation-tools.ts
44744
44896
  import { existsSync as existsSync16, readdirSync as readdirSync11, statSync as statSync11 } from "fs";
44745
- import { join as join36 } from "path";
44897
+ import { join as join37 } from "path";
44746
44898
  function registerOperationTools(server) {
44747
44899
  server.registerTool("cloud_skill_eligibility", {
44748
44900
  title: "Cloud Skill Eligibility",
@@ -45219,7 +45371,7 @@ function registerOperationTools(server) {
45219
45371
  if (exists) {
45220
45372
  try {
45221
45373
  skillCount = readdirSync11(agentSkillsPath).filter((f) => {
45222
- const full = join36(agentSkillsPath, f);
45374
+ const full = join37(agentSkillsPath, f);
45223
45375
  return !f.startsWith(".") && statSync11(full).isDirectory();
45224
45376
  }).length;
45225
45377
  } catch {}
@@ -45286,17 +45438,17 @@ var init_operation_tools = __esm(() => {
45286
45438
  });
45287
45439
 
45288
45440
  // src/lib/feedback.ts
45289
- import { appendFileSync, existsSync as existsSync17, mkdirSync as mkdirSync13 } from "fs";
45290
- 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";
45291
45443
  import { Database } from "bun:sqlite";
45292
45444
  function getFeedbackDbPath() {
45293
- return join37(getDataDir(), "skills.db");
45445
+ return join38(getDataDir(), "skills.db");
45294
45446
  }
45295
45447
  function getFeedbackDb() {
45296
45448
  const dbPath = getFeedbackDbPath();
45297
- const dir = dirname23(dbPath);
45449
+ const dir = dirname24(dbPath);
45298
45450
  if (!existsSync17(dir))
45299
- mkdirSync13(dir, { recursive: true });
45451
+ mkdirSync14(dir, { recursive: true });
45300
45452
  const db = new Database(dbPath);
45301
45453
  db.exec("PRAGMA journal_mode = WAL");
45302
45454
  db.exec([
@@ -45322,10 +45474,10 @@ function saveFeedback(input2) {
45322
45474
  throw new Error("Feedback message is required");
45323
45475
  const category = input2.category ?? "general";
45324
45476
  if (isApiMode()) {
45325
- const path = join37(getDataDir(), "feedback.jsonl");
45326
- const dir = dirname23(path);
45477
+ const path = join38(getDataDir(), "feedback.jsonl");
45478
+ const dir = dirname24(path);
45327
45479
  if (!existsSync17(dir))
45328
- mkdirSync13(dir, { recursive: true });
45480
+ mkdirSync14(dir, { recursive: true });
45329
45481
  appendFileSync(path, JSON.stringify({ message, category, email: input2.email ?? null, agent: input2.agent ?? null, version: input2.version ?? null, createdAt: new Date().toISOString() }) + `
45330
45482
  `);
45331
45483
  return { saved: true, category, path };
@@ -45486,10 +45638,10 @@ var init_resource_meta_tools = __esm(() => {
45486
45638
  });
45487
45639
 
45488
45640
  // src/lib/scheduler.ts
45489
- import { existsSync as existsSync18, readFileSync as readFileSync22, writeFileSync as writeFileSync12, mkdirSync as mkdirSync14 } from "fs";
45490
- 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";
45491
45643
  function getSchedulesPath(targetDir = process.cwd()) {
45492
- return join38(targetDir, ".skills", "schedules.json");
45644
+ return join39(targetDir, ".skills", "schedules.json");
45493
45645
  }
45494
45646
  function loadSchedules(targetDir = process.cwd()) {
45495
45647
  const path = getSchedulesPath(targetDir);
@@ -45502,9 +45654,9 @@ function loadSchedules(targetDir = process.cwd()) {
45502
45654
  }
45503
45655
  function saveSchedules(data, targetDir = process.cwd()) {
45504
45656
  const path = getSchedulesPath(targetDir);
45505
- const dir = join38(targetDir, ".skills");
45657
+ const dir = join39(targetDir, ".skills");
45506
45658
  if (!existsSync18(dir))
45507
- mkdirSync14(dir, { recursive: true });
45659
+ mkdirSync15(dir, { recursive: true });
45508
45660
  writeFileSync12(path, JSON.stringify(data, null, 2));
45509
45661
  }
45510
45662
  function validateCronField(expr, min, max, label) {
@@ -45774,16 +45926,16 @@ var init_schedule_tools = __esm(() => {
45774
45926
  });
45775
45927
 
45776
45928
  // src/lib/native-storage.ts
45777
- import { createHash as createHash24, createHmac } from "crypto";
45929
+ import { createHash as createHash25, createHmac } from "crypto";
45778
45930
  import {
45779
45931
  existsSync as existsSync19,
45780
- mkdirSync as mkdirSync15,
45932
+ mkdirSync as mkdirSync16,
45781
45933
  readFileSync as readFileSync23,
45782
45934
  readdirSync as readdirSync12,
45783
45935
  statSync as statSync12,
45784
45936
  writeFileSync as writeFileSync13
45785
45937
  } from "fs";
45786
- 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";
45787
45939
  function resolveSkillsNativeStorageConfig(env = process.env) {
45788
45940
  assertNoRetiredModeEnvVars(env, {
45789
45941
  app: SKILLS_ENV_NAMESPACE,
@@ -45824,7 +45976,7 @@ function getSkillsNativeStorageStatus(options = {}) {
45824
45976
  local: {
45825
45977
  dataDir: getDataDir(),
45826
45978
  projectStateDir: getProjectStateDir(targetDir),
45827
- feedbackDbPath: join39(getDataDir(), "skills.db")
45979
+ feedbackDbPath: join40(getDataDir(), "skills.db")
45828
45980
  },
45829
45981
  remote: {
45830
45982
  databaseConfigured: Boolean(config2.databaseUrl),
@@ -45851,7 +46003,7 @@ function exportSkillsLocalSnapshot(targetDir = process.cwd(), options = {}) {
45851
46003
  files.push({
45852
46004
  path: relativePath,
45853
46005
  sizeBytes: bytes.byteLength,
45854
- sha256: createHash24("sha256").update(bytes).digest("hex"),
46006
+ sha256: createHash25("sha256").update(bytes).digest("hex"),
45855
46007
  ...options.includeFileContents ? { contentBase64: Buffer.from(bytes).toString("base64") } : {}
45856
46008
  });
45857
46009
  }
@@ -45905,7 +46057,7 @@ function parsePositiveInteger(value) {
45905
46057
  function walkFiles2(dir) {
45906
46058
  const files = [];
45907
46059
  for (const entry of readdirSync12(dir)) {
45908
- const full = join39(dir, entry);
46060
+ const full = join40(dir, entry);
45909
46061
  const stats = statSync12(full);
45910
46062
  if (stats.isDirectory())
45911
46063
  files.push(...walkFiles2(full));
@@ -46143,20 +46295,20 @@ var init_private_publication_customer = __esm(() => {
46143
46295
  });
46144
46296
 
46145
46297
  // src/lib/private-publication-recovery.ts
46146
- 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";
46147
- 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";
46148
46300
  import { randomUUID as randomUUID3 } from "crypto";
46149
46301
  function safeDirectory(directory2) {
46150
- if (!isAbsolute21(directory2) || directory2 !== resolve23(directory2) || realpathSync12(directory2) !== directory2)
46302
+ if (!isAbsolute23(directory2) || directory2 !== resolve24(directory2) || realpathSync12(directory2) !== directory2)
46151
46303
  return fail2();
46152
- for (let path = directory2;; path = dirname25(path)) {
46153
- const stat3 = lstatSync23(path);
46304
+ for (let path = directory2;; path = dirname26(path)) {
46305
+ const stat3 = lstatSync24(path);
46154
46306
  if (!stat3.isDirectory() || stat3.isSymbolicLink())
46155
46307
  return fail2();
46156
- if (path === dirname25(path))
46308
+ if (path === dirname26(path))
46157
46309
  break;
46158
46310
  }
46159
- const own2 = lstatSync23(directory2);
46311
+ const own2 = lstatSync24(directory2);
46160
46312
  if ((own2.mode & 63) !== 0 || process.getuid && own2.uid !== process.getuid())
46161
46313
  return fail2();
46162
46314
  return { dev: own2.dev, ino: own2.ino };
@@ -46167,36 +46319,36 @@ function unchangedDirectory(directory2, identity3) {
46167
46319
  return fail2();
46168
46320
  }
46169
46321
  function readOwned(directory2, name, max) {
46170
- const identity3 = safeDirectory(directory2), file2 = join40(directory2, name);
46171
- 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);
46172
46324
  try {
46173
- const stat3 = fstatSync19(fd);
46325
+ const stat3 = fstatSync20(fd);
46174
46326
  if (!stat3.isFile() || stat3.nlink !== 1 || stat3.size > max || stat3.size < 1 || (stat3.mode & 63) !== 0 || process.getuid && stat3.uid !== process.getuid())
46175
46327
  return fail2();
46176
46328
  const buffer = Buffer.alloc(Math.min(max, stat3.size) + 1);
46177
46329
  let length = 0;
46178
46330
  while (length < buffer.length) {
46179
- const count = readSync12(fd, buffer, length, buffer.length - length, length);
46331
+ const count = readSync13(fd, buffer, length, buffer.length - length, length);
46180
46332
  if (count === 0)
46181
46333
  break;
46182
46334
  length += count;
46183
46335
  }
46184
- const bytes = buffer.subarray(0, length), after = fstatSync19(fd);
46336
+ const bytes = buffer.subarray(0, length), after = fstatSync20(fd);
46185
46337
  unchangedDirectory(directory2, identity3);
46186
46338
  if (bytes.length !== stat3.size || stat3.size !== after.size || stat3.mtimeMs !== after.mtimeMs || stat3.ctimeMs !== after.ctimeMs)
46187
46339
  return fail2();
46188
46340
  return bytes;
46189
46341
  } finally {
46190
- closeSync19(fd);
46342
+ closeSync20(fd);
46191
46343
  }
46192
46344
  }
46193
46345
  function writeOwned(directory2, name, bytes) {
46194
- 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);
46195
46347
  try {
46196
46348
  writeFileSync14(fd, bytes);
46197
- fsyncSync5(fd);
46349
+ fsyncSync6(fd);
46198
46350
  } finally {
46199
- closeSync19(fd);
46351
+ closeSync20(fd);
46200
46352
  }
46201
46353
  }
46202
46354
  function save(directory2, value) {
@@ -46204,12 +46356,12 @@ function save(directory2, value) {
46204
46356
  writeOwned(directory2, temporary, JSON.stringify(value) + `
46205
46357
  `);
46206
46358
  unchangedDirectory(directory2, identity3);
46207
- renameSync7(join40(directory2, temporary), join40(directory2, "receipt.json"));
46208
- 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);
46209
46361
  try {
46210
- fsyncSync5(fd);
46362
+ fsyncSync6(fd);
46211
46363
  } finally {
46212
- closeSync19(fd);
46364
+ closeSync20(fd);
46213
46365
  }
46214
46366
  }
46215
46367
  function bind(client, receipt) {
@@ -46217,23 +46369,23 @@ function bind(client, receipt) {
46217
46369
  throw new PrivatePublicationError("PUBLICATION_IDENTITY_CHANGED", "The fresh session does not match the recovery directory's server, account and membership.");
46218
46370
  }
46219
46371
  async function locked(directory2, action) {
46220
- const identity3 = safeDirectory(directory2), file2 = join40(directory2, "operation.lock");
46372
+ const identity3 = safeDirectory(directory2), file2 = join41(directory2, "operation.lock");
46221
46373
  let fd;
46222
46374
  try {
46223
- 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);
46224
46376
  } catch {
46225
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.");
46226
46378
  }
46227
- const lock = fstatSync19(fd);
46379
+ const lock = fstatSync20(fd);
46228
46380
  try {
46229
46381
  writeFileSync14(fd, JSON.stringify({ pid: process.pid }) + `
46230
46382
  `);
46231
- fsyncSync5(fd);
46383
+ fsyncSync6(fd);
46232
46384
  return await action();
46233
46385
  } finally {
46234
- closeSync19(fd);
46386
+ closeSync20(fd);
46235
46387
  unchangedDirectory(directory2, identity3);
46236
- const now = lstatSync23(file2);
46388
+ const now = lstatSync24(file2);
46237
46389
  if (now.dev !== lock.dev || now.ino !== lock.ino || !now.isFile() || now.isSymbolicLink())
46238
46390
  fail2();
46239
46391
  unlinkSync6(file2);
@@ -46285,15 +46437,15 @@ async function preparePrivatePublication(client, sourceDirectory, recoveryDirect
46285
46437
  phase: "prepared",
46286
46438
  intent: null
46287
46439
  };
46288
- if (!isAbsolute21(recoveryDirectory) || resolve23(recoveryDirectory) !== recoveryDirectory || realpathSync12(dirname25(recoveryDirectory)) !== dirname25(recoveryDirectory))
46440
+ if (!isAbsolute23(recoveryDirectory) || resolve24(recoveryDirectory) !== recoveryDirectory || realpathSync12(dirname26(recoveryDirectory)) !== dirname26(recoveryDirectory))
46289
46441
  return fail2();
46290
- mkdirSync16(recoveryDirectory, { mode: 448 });
46442
+ mkdirSync17(recoveryDirectory, { mode: 448 });
46291
46443
  safeDirectory(recoveryDirectory);
46292
- const parent = openSync19(dirname25(recoveryDirectory), constants16.O_RDONLY | constants16.O_NOFOLLOW);
46444
+ const parent = openSync20(dirname26(recoveryDirectory), constants17.O_RDONLY | constants17.O_NOFOLLOW);
46293
46445
  try {
46294
- fsyncSync5(parent);
46446
+ fsyncSync6(parent);
46295
46447
  } finally {
46296
- closeSync19(parent);
46448
+ closeSync20(parent);
46297
46449
  }
46298
46450
  writeOwned(recoveryDirectory, "bundle.tgz", packed.bytes);
46299
46451
  save(recoveryDirectory, receipt);
@@ -46386,10 +46538,10 @@ var init_private_publication_recovery = __esm(() => {
46386
46538
  });
46387
46539
 
46388
46540
  // src/mcp/private-publication-tools.ts
46389
- import { isAbsolute as isAbsolute22 } from "path";
46541
+ import { isAbsolute as isAbsolute24 } from "path";
46390
46542
  function registerPrivatePublicationTools(server) {
46391
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}$/);
46392
- 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");
46393
46545
  const verification2 = { email: exports_external.string().email().max(254), code: exports_external.string().regex(/^\d{6}$/), userId: uuid9, membershipId: uuid9, recoveryDirectory: directory2 };
46394
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.";
46395
46547
  const handler = (action) => async (value) => {
@@ -46822,19 +46974,19 @@ async function connectMcpForNode() {
46822
46974
  return { server: server2, transport };
46823
46975
  }
46824
46976
  function readBody(req) {
46825
- return new Promise((resolve24, reject) => {
46977
+ return new Promise((resolve25, reject) => {
46826
46978
  const chunks = [];
46827
46979
  req.on("data", (chunk) => chunks.push(Buffer.from(chunk)));
46828
46980
  req.on("end", () => {
46829
46981
  const raw = Buffer.concat(chunks).toString("utf-8");
46830
46982
  if (!raw.trim()) {
46831
- resolve24(undefined);
46983
+ resolve25(undefined);
46832
46984
  return;
46833
46985
  }
46834
46986
  try {
46835
- resolve24(JSON.parse(raw));
46987
+ resolve25(JSON.parse(raw));
46836
46988
  } catch {
46837
- resolve24(undefined);
46989
+ resolve25(undefined);
46838
46990
  }
46839
46991
  });
46840
46992
  req.on("error", reject);
@@ -46876,9 +47028,9 @@ async function startSkillsMcpHttpServer(options = {}) {
46876
47028
  }
46877
47029
  }
46878
47030
  });
46879
- await new Promise((resolve24, reject) => {
47031
+ await new Promise((resolve25, reject) => {
46880
47032
  httpServer.once("error", reject);
46881
- httpServer.listen(port, hostname4, () => resolve24());
47033
+ httpServer.listen(port, hostname4, () => resolve25());
46882
47034
  });
46883
47035
  const address = httpServer.address();
46884
47036
  const listenPort = typeof address === "object" && address ? address.port : port;