@hasna/skills 0.10.19 → 0.10.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/sdk/index.js CHANGED
@@ -9004,7 +9004,7 @@ var require_client = __commonJS((exports) => {
9004
9004
  var require_config = __commonJS((exports) => {
9005
9005
  var { homedir: homedir7 } = __require("os");
9006
9006
  var { sep: sep9, join: join4 } = __require("path");
9007
- var { createHash: createHash20 } = __require("crypto");
9007
+ var { createHash: createHash21 } = __require("crypto");
9008
9008
  var { readFile: readFile$1 } = __require("fs/promises");
9009
9009
  var { IniSectionType } = require_dist_cjs();
9010
9010
  var { normalizeProvider } = require_client();
@@ -9159,7 +9159,7 @@ var require_config = __commonJS((exports) => {
9159
9159
  var DEFAULT_PROFILE = "default";
9160
9160
  var getProfileName = (init) => init.profile || process.env[ENV_PROFILE] || DEFAULT_PROFILE;
9161
9161
  var getSSOTokenFilepath = (id2) => {
9162
- const hasher = createHash20("sha1");
9162
+ const hasher = createHash21("sha1");
9163
9163
  const cacheName = hasher.update(id2).digest("hex");
9164
9164
  return join4(getHomeDir(), ".aws", "sso", "cache", `${cacheName}.json`);
9165
9165
  };
@@ -10511,7 +10511,7 @@ var require_endpoints = __commonJS((exports) => {
10511
10511
 
10512
10512
  // node_modules/@smithy/core/dist-cjs/submodules/serde/index.js
10513
10513
  var require_serde = __commonJS((exports) => {
10514
- var { createHmac: createHmac2, createHash: createHash20, getRandomValues } = __require("crypto");
10514
+ var { createHmac: createHmac2, createHash: createHash21, getRandomValues } = __require("crypto");
10515
10515
  var { hasOwn: hasOwn2, HttpResponse } = require_transport();
10516
10516
  exports.hasOwn = hasOwn2;
10517
10517
  var { ReadStream, lstatSync: lstatSync23, fstatSync: fstatSync4 } = __require("fs");
@@ -11416,7 +11416,7 @@ var require_serde = __commonJS((exports) => {
11416
11416
  return Promise.resolve(this.hash.digest());
11417
11417
  }
11418
11418
  reset() {
11419
- this.hash = this.secret ? createHmac2(this.algorithmIdentifier, castSourceData(this.secret)) : createHash20(this.algorithmIdentifier);
11419
+ this.hash = this.secret ? createHmac2(this.algorithmIdentifier, castSourceData(this.secret)) : createHash21(this.algorithmIdentifier);
11420
11420
  }
11421
11421
  }
11422
11422
  function castSourceData(toCast, encoding) {
@@ -12155,7 +12155,7 @@ var require_checksum = __commonJS((exports) => {
12155
12155
  var { createReadStream } = __require("fs");
12156
12156
  var { Writable } = __require("stream");
12157
12157
  var { toUint8Array, concatBytes } = require_serde();
12158
- var { createHash: createHash20, createHmac: createHmac2 } = __require("crypto");
12158
+ var { createHash: createHash21, createHmac: createHmac2 } = __require("crypto");
12159
12159
  var zlib = __require("zlib");
12160
12160
  async function blobReader(blob, onChunk, chunkSize = 1024 * 1024) {
12161
12161
  const size = blob.size;
@@ -12320,7 +12320,7 @@ var require_checksum = __commonJS((exports) => {
12320
12320
  }
12321
12321
  var hasNativeCrypto$1 = (() => {
12322
12322
  try {
12323
- createHash20("md5");
12323
+ createHash21("md5");
12324
12324
  return true;
12325
12325
  } catch {
12326
12326
  return false;
@@ -12330,7 +12330,7 @@ var require_checksum = __commonJS((exports) => {
12330
12330
  function buildNativeClass$2() {
12331
12331
  return class Md5Node2 {
12332
12332
  digestLength = 16;
12333
- hash = createHash20("md5");
12333
+ hash = createHash21("md5");
12334
12334
  update(data) {
12335
12335
  this.hash.update(toUint8Array(data));
12336
12336
  }
@@ -12339,7 +12339,7 @@ var require_checksum = __commonJS((exports) => {
12339
12339
  return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
12340
12340
  }
12341
12341
  reset() {
12342
- this.hash = createHash20("md5");
12342
+ this.hash = createHash21("md5");
12343
12343
  }
12344
12344
  };
12345
12345
  }
@@ -12629,7 +12629,7 @@ var require_checksum = __commonJS((exports) => {
12629
12629
  ]);
12630
12630
  var hasNativeCrypto = (() => {
12631
12631
  try {
12632
- createHash20("sha256");
12632
+ createHash21("sha256");
12633
12633
  return true;
12634
12634
  } catch {
12635
12635
  return false;
@@ -12669,7 +12669,7 @@ var require_checksum = __commonJS((exports) => {
12669
12669
  this.finished = false;
12670
12670
  }
12671
12671
  createHash() {
12672
- return this.secret ? createHmac2("sha256", toBuffer(this.secret)) : createHash20("sha256");
12672
+ return this.secret ? createHmac2("sha256", toBuffer(this.secret)) : createHash21("sha256");
12673
12673
  }
12674
12674
  };
12675
12675
  }
@@ -14538,8 +14538,8 @@ var require_protocols = __commonJS((exports) => {
14538
14538
  class Fields {
14539
14539
  entries = {};
14540
14540
  encoding;
14541
- constructor({ fields = [], encoding = "utf-8" }) {
14542
- fields.forEach(this.setField.bind(this));
14541
+ constructor({ fields: fields2 = [], encoding = "utf-8" }) {
14542
+ fields2.forEach(this.setField.bind(this));
14543
14543
  this.encoding = encoding;
14544
14544
  }
14545
14545
  setField(field2) {
@@ -18166,7 +18166,7 @@ ${toHex(hashedRequest)}`;
18166
18166
  return hash2.digest();
18167
18167
  };
18168
18168
  var getCanonicalHeaders = ({ headers }, unsignableHeaders, signableHeaders) => {
18169
- const canonical5 = {};
18169
+ const canonical6 = {};
18170
18170
  for (const headerName of Object.keys(headers).sort()) {
18171
18171
  if (headers[headerName] == undefined) {
18172
18172
  continue;
@@ -18177,9 +18177,9 @@ ${toHex(hashedRequest)}`;
18177
18177
  continue;
18178
18178
  }
18179
18179
  }
18180
- canonical5[canonicalHeaderName] = headers[headerName].trim().replace(/\s+/g, " ");
18180
+ canonical6[canonicalHeaderName] = headers[headerName].trim().replace(/\s+/g, " ");
18181
18181
  }
18182
- return canonical5;
18182
+ return canonical6;
18183
18183
  };
18184
18184
  var getPayloadHash = async ({ headers, body }, hashConstructor) => {
18185
18185
  for (const headerName in headers) {
@@ -21700,12 +21700,12 @@ var require_protocols2 = __commonJS((exports) => {
21700
21700
  return expandToDecimal(numericString) === expandToDecimal(String(value));
21701
21701
  }
21702
21702
  const normalized = numericString.replace(/(\.\d*?)0+$/, "$1").replace(/\.$/, "");
21703
- const canonical5 = String(value);
21704
- if (normalized === canonical5) {
21703
+ const canonical6 = String(value);
21704
+ if (normalized === canonical6) {
21705
21705
  return true;
21706
21706
  }
21707
- if (/[eE]/.test(canonical5)) {
21708
- return normalized === expandToDecimal(canonical5);
21707
+ if (/[eE]/.test(canonical6)) {
21708
+ return normalized === expandToDecimal(canonical6);
21709
21709
  }
21710
21710
  return false;
21711
21711
  }
@@ -25954,12 +25954,12 @@ import fs from "fs/promises";
25954
25954
  var import_client9, import_config17, import_node_http_handler, AWS_CONTAINER_CREDENTIALS_RELATIVE_URI = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI", DEFAULT_LINK_LOCAL_HOST = "http://169.254.170.2", AWS_CONTAINER_CREDENTIALS_FULL_URI = "AWS_CONTAINER_CREDENTIALS_FULL_URI", AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE = "AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE", AWS_CONTAINER_AUTHORIZATION_TOKEN = "AWS_CONTAINER_AUTHORIZATION_TOKEN", fromHttp = (options = {}) => {
25955
25955
  options.logger?.debug("@aws-sdk/credential-provider-http - fromHttp");
25956
25956
  let host;
25957
- const relative6 = options.awsContainerCredentialsRelativeUri ?? process.env[AWS_CONTAINER_CREDENTIALS_RELATIVE_URI];
25957
+ const relative7 = options.awsContainerCredentialsRelativeUri ?? process.env[AWS_CONTAINER_CREDENTIALS_RELATIVE_URI];
25958
25958
  const full = options.awsContainerCredentialsFullUri ?? process.env[AWS_CONTAINER_CREDENTIALS_FULL_URI];
25959
25959
  const token = options.awsContainerAuthorizationToken ?? process.env[AWS_CONTAINER_AUTHORIZATION_TOKEN];
25960
25960
  const tokenFile = options.awsContainerAuthorizationTokenFile ?? process.env[AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE];
25961
25961
  const warn = options.logger?.constructor?.name === "NoOpLogger" || !options.logger?.warn ? console.warn : options.logger.warn.bind(options.logger);
25962
- if (relative6 && full) {
25962
+ if (relative7 && full) {
25963
25963
  warn("@aws-sdk/credential-provider-http: " + "you have set both awsContainerCredentialsRelativeUri and awsContainerCredentialsFullUri.");
25964
25964
  warn("awsContainerCredentialsRelativeUri will take precedence.");
25965
25965
  }
@@ -25967,8 +25967,8 @@ var import_client9, import_config17, import_node_http_handler, AWS_CONTAINER_CRE
25967
25967
  warn("@aws-sdk/credential-provider-http: " + "you have set both awsContainerAuthorizationToken and awsContainerAuthorizationTokenFile.");
25968
25968
  warn("awsContainerAuthorizationTokenFile will take precedence.");
25969
25969
  }
25970
- if (relative6) {
25971
- host = `${DEFAULT_LINK_LOCAL_HOST}${relative6}`;
25970
+ if (relative7) {
25971
+ host = `${DEFAULT_LINK_LOCAL_HOST}${relative7}`;
25972
25972
  } else if (full) {
25973
25973
  host = full;
25974
25974
  } else {
@@ -29443,7 +29443,7 @@ var require_signin = __commonJS((exports) => {
29443
29443
  });
29444
29444
 
29445
29445
  // node_modules/@aws-sdk/credential-provider-ini/node_modules/@aws-sdk/credential-provider-login/dist-es/LoginCredentialsFetcher.js
29446
- import { createHash as createHash20, createPrivateKey, createPublicKey, sign } from "crypto";
29446
+ import { createHash as createHash21, createPrivateKey, createPublicKey, sign } from "crypto";
29447
29447
  import { promises as fs2 } from "fs";
29448
29448
  import { homedir as homedir7 } from "os";
29449
29449
  import { dirname as dirname21, join as join33 } from "path";
@@ -29615,7 +29615,7 @@ var init_LoginCredentialsFetcher = __esm(() => {
29615
29615
  getTokenFilePath() {
29616
29616
  const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ?? join33(homedir7(), ".aws", "login", "cache");
29617
29617
  const loginSessionBytes = Buffer.from(this.loginSession, "utf8");
29618
- const loginSessionSha256 = createHash20("sha256").update(loginSessionBytes).digest("hex");
29618
+ const loginSessionSha256 = createHash21("sha256").update(loginSessionBytes).digest("hex");
29619
29619
  return join33(directory, `${loginSessionSha256}.json`);
29620
29620
  }
29621
29621
  derToRawSignature(derSignature) {
@@ -32373,7 +32373,7 @@ var init_event_sink = __esm(() => {
32373
32373
  // package.json
32374
32374
  var package_default = {
32375
32375
  name: "@hasna/skills",
32376
- version: "0.10.19",
32376
+ version: "0.10.22",
32377
32377
  description: "Skills library for AI coding agents",
32378
32378
  type: "module",
32379
32379
  bin: {
@@ -37455,7 +37455,7 @@ async function reconcileSkillSession(input, options = {}) {
37455
37455
  return { applied: true, plan, planDigest, ...result };
37456
37456
  }
37457
37457
  // src/lib/selected-run.ts
37458
- import { createHash as createHash19 } from "crypto";
37458
+ import { createHash as createHash20 } from "crypto";
37459
37459
  import { spawn as spawn2 } from "child_process";
37460
37460
  import { mkdirSync as mkdirSync10, mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync9, realpathSync as realpathSync11 } from "fs";
37461
37461
  import { dirname as dirname20, join as join32, resolve as resolve18 } from "path";
@@ -37692,7 +37692,7 @@ import {
37692
37692
  writeFileSync as writeFileSync7
37693
37693
  } from "fs";
37694
37694
  import { homedir as homedir5 } from "os";
37695
- import { basename as basename10, dirname as dirname19, join as join27 } from "path";
37695
+ import { basename as basename11, dirname as dirname19, join as join27 } from "path";
37696
37696
 
37697
37697
  // src/lib/claude-settings-witness.ts
37698
37698
  import { createHash as createHash5 } from "crypto";
@@ -38006,9 +38006,28 @@ function hashNativeJsonControls(text, excludedMetadata) {
38006
38006
  }
38007
38007
 
38008
38008
  // src/lib/codex-plugin-skill-controls.ts
38009
- import { dirname as dirname5, join as join10, resolve as resolve4, sep as sep2 } from "path";
38009
+ import { basename as basename3, dirname as dirname5, join as join10, relative as relative3, resolve as resolve4, sep as sep2 } from "path";
38010
38010
  import { lstatSync as lstatSync6, readdirSync as readdirSync3, readlinkSync as readlinkSync2, realpathSync as realpathSync5 } from "fs";
38011
38011
 
38012
+ // src/lib/codex-native-compatibility.ts
38013
+ var MEASURED_CODEX_CAPABILITIES = {
38014
+ "codex-cli 0.153.0": ["hooks"],
38015
+ "codex-cli 0.154.0": ["hooks"],
38016
+ "codex-cli 0.155.0": ["hooks"],
38017
+ "codex-cli 0.155.1": ["hooks"],
38018
+ "codex-cli 0.156.1": ["hooks"],
38019
+ "codex-cli 0.157.0": ["hooks"],
38020
+ "codex-cli 0.157.1": ["hooks"],
38021
+ "codex-cli 0.158.0": ["hooks"],
38022
+ "codex-cli 0.159.0": ["hooks"],
38023
+ "codex-cli 0.159.2": ["hooks", "qualified-skill-catalog"],
38024
+ "codex-cli 0.160.0": ["hooks", "qualified-skill-catalog"]
38025
+ };
38026
+ function supportsCodexNativeCapability(version, capability) {
38027
+ return typeof version === "string" && Object.hasOwn(MEASURED_CODEX_CAPABILITIES, version) && MEASURED_CODEX_CAPABILITIES[version].includes(capability);
38028
+ }
38029
+ var SUPPORTED_CODEX_HOOK_VERSIONS = Object.freeze(Object.keys(MEASURED_CODEX_CAPABILITIES).filter((version) => supportsCodexNativeCapability(version, "hooks")));
38030
+
38012
38031
  // src/lib/codex-native-skill-catalog.ts
38013
38032
  import { realpathSync as realpathSync4 } from "fs";
38014
38033
  import { isAbsolute as isAbsolute5, normalize } from "path";
@@ -38018,7 +38037,6 @@ import { execFile, spawn } from "child_process";
38018
38037
  import { realpathSync as realpathSync3, statSync as statSync3 } from "fs";
38019
38038
  import { isAbsolute as isAbsolute4 } from "path";
38020
38039
  import { promisify } from "util";
38021
- var SUPPORTED_CODEX_HOOK_VERSIONS = ["codex-cli 0.153.0", "codex-cli 0.154.0", "codex-cli 0.155.0", "codex-cli 0.155.1", "codex-cli 0.156.1", "codex-cli 0.157.0", "codex-cli 0.157.1", "codex-cli 0.158.0", "codex-cli 0.159.0", "codex-cli 0.159.2"];
38022
38040
  async function connectCodexHookRpc(options) {
38023
38041
  const timeoutMs = options.timeoutMs ?? 20000;
38024
38042
  if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 100 || timeoutMs > 20000)
@@ -38036,7 +38054,7 @@ async function connectCodexHookRpc(options) {
38036
38054
  } catch {
38037
38055
  throw new Error("CODEX_HOOK_TRUST_NATIVE_UNAVAILABLE");
38038
38056
  }
38039
- if (!SUPPORTED_CODEX_HOOK_VERSIONS.includes(version))
38057
+ if (!supportsCodexNativeCapability(version, "hooks"))
38040
38058
  throw new Error("CODEX_HOOK_TRUST_NATIVE_UNSUPPORTED_VERSION");
38041
38059
  const current = statSync3(binary);
38042
38060
  if (realpathSync3(found) !== binary || ["dev", "ino", "size", "mtimeMs", "ctimeMs"].some((k) => stat[k] !== current[k]))
@@ -38160,12 +38178,13 @@ async function connectCodexHookRpc(options) {
38160
38178
  var MAX_SKILLS = 4096;
38161
38179
  var MAX_NAME_BYTES = 1024;
38162
38180
  var MAX_PATH_BYTES = 16384;
38163
- var SUPPORTED_NAME_CONTROL_VERSIONS = new Set(["codex-cli 0.159.2"]);
38181
+ var MAX_PLUGIN_ID_BYTES = 1024;
38164
38182
  function refuse2() {
38165
38183
  throw new Error("CODEX_NATIVE_SKILL_CATALOG_INVALID");
38166
38184
  }
38167
38185
  var object2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
38168
38186
  var scalar = (value, max) => typeof value === "string" && value.length > 0 && value.trim() === value && Buffer.byteLength(value, "utf8") <= max && !/[\u0000-\u001f\u007f]/u.test(value);
38187
+ var remotePluginIdentifier = (value) => typeof value === "string" && /^[A-Za-z0-9_~-]{1,1024}$/.test(value);
38169
38188
  var absolutePath2 = (value) => scalar(value, MAX_PATH_BYTES) && isAbsolute5(value);
38170
38189
  function projectCodexNativeSkillCatalog(response, cwd) {
38171
38190
  if (!absolutePath2(cwd) || !object2(response) || !Array.isArray(response.data) || response.data.length !== 1)
@@ -38183,6 +38202,47 @@ function projectCodexNativeSkillCatalog(response, cwd) {
38183
38202
  return { name: value.name, path: value.path, enabled: value.enabled, pluginId: value.pluginId ?? null };
38184
38203
  });
38185
38204
  }
38205
+ function projectCodexInstalledPlugins(response) {
38206
+ if (!object2(response) || !Array.isArray(response.marketplaces) || !Array.isArray(response.marketplaceLoadErrors) || response.marketplaceLoadErrors.length !== 0 || response.marketplaces.length > MAX_SKILLS)
38207
+ refuse2();
38208
+ const plugins = [];
38209
+ for (const marketplace of response.marketplaces) {
38210
+ if (!object2(marketplace) || !scalar(marketplace.name, MAX_NAME_BYTES) || !Array.isArray(marketplace.plugins) || marketplace.plugins.length > MAX_SKILLS)
38211
+ refuse2();
38212
+ for (const value of marketplace.plugins) {
38213
+ if (!object2(value) || !scalar(value.id, MAX_PLUGIN_ID_BYTES) || !scalar(value.name, MAX_NAME_BYTES) || value.id !== `${value.name}@${marketplace.name}`)
38214
+ refuse2();
38215
+ plugins.push({
38216
+ ...value,
38217
+ marketplace: marketplace.name,
38218
+ sourceType: object2(value.source) && value.source.type === "remote" ? "remote" : undefined
38219
+ });
38220
+ }
38221
+ }
38222
+ return projectCodexInstalledPluginEntries(plugins);
38223
+ }
38224
+ function projectCodexInstalledPluginEntries(value) {
38225
+ if (!Array.isArray(value) || value.length > MAX_SKILLS)
38226
+ refuse2();
38227
+ const ids = new Set;
38228
+ return value.map((item) => {
38229
+ if (!object2(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 && item.sourceType !== "remote")
38230
+ refuse2();
38231
+ const at = item.id.lastIndexOf("@");
38232
+ if (at < 1 || item.id.slice(0, at) !== item.name || at === item.id.length - 1 || ids.has(item.id))
38233
+ refuse2();
38234
+ ids.add(item.id);
38235
+ return {
38236
+ id: item.id,
38237
+ name: item.name,
38238
+ installed: item.installed,
38239
+ enabled: item.enabled,
38240
+ localVersion: item.localVersion ?? null,
38241
+ ...item.sourceType === "remote" ? { sourceType: "remote" } : {},
38242
+ ...item.remotePluginId == null ? {} : { remotePluginId: item.remotePluginId }
38243
+ };
38244
+ });
38245
+ }
38186
38246
  async function captureCodexNativeSkillCatalog(options, connect = connectCodexHookRpc) {
38187
38247
  if (!absolutePath2(options.cwd) || !absolutePath2(options.home))
38188
38248
  refuse2();
@@ -38193,10 +38253,16 @@ async function captureCodexNativeSkillCatalog(options, connect = connectCodexHoo
38193
38253
  ...options.timeoutMs === undefined ? {} : { timeoutMs: options.timeoutMs }
38194
38254
  });
38195
38255
  try {
38196
- if (!SUPPORTED_NAME_CONTROL_VERSIONS.has(rpc.version))
38256
+ if (!supportsCodexNativeCapability(rpc.version, "qualified-skill-catalog"))
38197
38257
  throw new Error("CODEX_NATIVE_SKILL_CATALOG_UNSUPPORTED_VERSION");
38198
38258
  const response = await rpc.request("skills/list", { cwds: [options.cwd], forceReload: true });
38199
- return { version: rpc.version, cwd: options.cwd, skills: projectCodexNativeSkillCatalog(response, options.cwd) };
38259
+ const installed = await rpc.request("plugin/installed", { cwds: [options.cwd] });
38260
+ return {
38261
+ version: rpc.version,
38262
+ cwd: options.cwd,
38263
+ skills: projectCodexNativeSkillCatalog(response, options.cwd),
38264
+ plugins: projectCodexInstalledPlugins(installed)
38265
+ };
38200
38266
  } finally {
38201
38267
  await rpc.close();
38202
38268
  }
@@ -38241,9 +38307,25 @@ function isCodexNativeSkillDisabled(skill, rules) {
38241
38307
 
38242
38308
  // src/lib/codex-plugin-skill-controls.ts
38243
38309
  var identifier3 = (v) => typeof v === "string" && /^[A-Za-z0-9_-]{1,64}$/.test(v);
38310
+ var CODEX_DEFAULT_AGENT_PLUGIN_VERSION = "1.0.0";
38244
38311
  function refuse3() {
38245
38312
  throw new Error("CODEX_NATIVE_SKILL_IDENTITY_UNSUPPORTED: review native plugin names and hook controls");
38246
38313
  }
38314
+ function remoteInstallationMatches(parent, remotePluginId, read) {
38315
+ try {
38316
+ if (!remotePluginIdentifier(remotePluginId) || !lstatSync6(parent).isDirectory() || realpathSync5(parent) !== parent)
38317
+ return false;
38318
+ const path = join10(parent, ".codex-remote-plugin-install.json"), stat = lstatSync6(path, { throwIfNoEntry: false });
38319
+ if (!stat?.isFile() || stat.isSymbolicLink() || stat.size > 16384)
38320
+ return false;
38321
+ const text = read(path);
38322
+ hashNativeJsonControls(text);
38323
+ const value = JSON.parse(text);
38324
+ return Boolean(value && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 2 && value.schema_version === 1 && value.remote_plugin_id === remotePluginId);
38325
+ } catch {
38326
+ return false;
38327
+ }
38328
+ }
38247
38329
  function appControls(path, read) {
38248
38330
  const text = read(path);
38249
38331
  let value, sha2562;
@@ -38279,6 +38361,9 @@ function rootControls(root, read) {
38279
38361
  }
38280
38362
  if (!manifest || typeof manifest !== "object" || Array.isArray(manifest) || !identifier3(manifest.name))
38281
38363
  refuse3();
38364
+ const cacheVersion = basename3(root), declaredVersion = manifest.version === undefined ? "" : typeof manifest.version === "string" ? manifest.version.trim() : null;
38365
+ if (declaredVersion === null || (declaredVersion ? declaredVersion !== cacheVersion : cacheVersion !== CODEX_DEFAULT_AGENT_PLUGIN_VERSION))
38366
+ refuse3();
38282
38367
  if (manifest.hooks !== undefined || manifest.mcpServers !== undefined || manifest.commands !== undefined || manifest.apps !== undefined && manifest.apps !== "./.app.json" || ["hooks", ".mcp.json"].some((path) => lstatSync6(join10(root, path), { throwIfNoEntry: false })))
38283
38368
  refuse3();
38284
38369
  const app = join10(root, ".app.json"), present = lstatSync6(app, { throwIfNoEntry: false });
@@ -38330,6 +38415,10 @@ function reviewedCodexPluginCapabilitiesUnchanged(cache, controls, read) {
38330
38415
  for (const parent of new Set(controls.map((control) => control.pluginParent))) {
38331
38416
  if (!parent.startsWith(cache + sep2) || !lstatSync6(parent, { throwIfNoEntry: false })?.isDirectory())
38332
38417
  return false;
38418
+ for (const control of controls.filter((control2) => control2.pluginParent === parent)) {
38419
+ if (control.remotePluginId !== undefined && !remoteInstallationMatches(parent, control.remotePluginId, read))
38420
+ return false;
38421
+ }
38333
38422
  const names = readdirSync3(parent);
38334
38423
  entries += names.length;
38335
38424
  if (entries > 4096)
@@ -38355,22 +38444,56 @@ function reviewedCodexPluginCapabilitiesUnchanged(cache, controls, read) {
38355
38444
  return false;
38356
38445
  }
38357
38446
  }
38358
- function reviewCodexPluginSkillControls(catalog, documents, cache, cwd, read) {
38359
- if (catalog?.version !== "codex-cli 0.159.2" || catalog.cwd !== cwd)
38447
+ function reviewCodexPluginSkillControls(catalog, documents, cache, cwd, read, rules) {
38448
+ if (!supportsCodexNativeCapability(catalog?.version, "qualified-skill-catalog") || catalog.cwd !== cwd)
38360
38449
  refuse3();
38361
38450
  const skills = projectCodexNativeSkillCatalog({ data: [{ cwd, errors: [], skills: catalog.skills }] }, cwd);
38362
38451
  const allowed = new Set(documents), result = [];
38363
- for (const skill of skills) {
38364
- if (!allowed.has(skill.path) || !skill.path.startsWith(cache + sep2))
38452
+ let installedPlugins;
38453
+ try {
38454
+ installedPlugins = projectCodexInstalledPluginEntries(catalog.plugins ?? []);
38455
+ } catch {
38456
+ refuse3();
38457
+ }
38458
+ const candidates = catalog.plugins === undefined ? skills.map((skill) => skill.path).filter((path) => allowed.has(path)) : allowed;
38459
+ for (const document of candidates) {
38460
+ if (!document.startsWith(cache + sep2))
38365
38461
  continue;
38366
- if (skills.filter((other) => other.name === skill.name).length !== 1)
38462
+ const parsed = identity(document, cache, read);
38463
+ if (parsed.name === "skills-cli" || parsed.name.endsWith(":skills-cli"))
38367
38464
  refuse3();
38368
- if (!skill.pluginId || skill.name === "skills-cli" || skill.name.endsWith(":skills-cli"))
38465
+ const cacheParts = relative3(cache, parsed.pluginParent).split(sep2);
38466
+ if (cacheParts.length !== 2 || cacheParts.some((part) => !identifier3(part)))
38369
38467
  refuse3();
38370
- const parsed = identity(skill.path, cache, read);
38371
- if (parsed.name !== skill.name)
38468
+ const [marketplace, pluginName] = cacheParts;
38469
+ if (pluginName !== parsed.namespace)
38372
38470
  refuse3();
38373
- result.push({ ...parsed, pluginId: skill.pluginId });
38471
+ const expectedPluginId = `${pluginName}@${marketplace}`;
38472
+ const listed = skills.filter((skill) => skill.path === document);
38473
+ if (listed.length > 1)
38474
+ refuse3();
38475
+ let remotePluginId;
38476
+ if (listed.length === 1) {
38477
+ if (listed[0].name !== parsed.name || listed[0].pluginId !== expectedPluginId)
38478
+ refuse3();
38479
+ } else {
38480
+ const installed = installedPlugins.filter((plugin2) => plugin2.id === expectedPluginId && plugin2.name === pluginName);
38481
+ if (installed.length !== 1 || !installed[0].installed || !installed[0].enabled)
38482
+ refuse3();
38483
+ const plugin = installed[0];
38484
+ if (plugin.localVersion !== null) {
38485
+ if (plugin.localVersion !== basename3(dirname5(dirname5(dirname5(document)))))
38486
+ continue;
38487
+ } else {
38488
+ if (plugin.sourceType !== "remote" || !plugin.remotePluginId || !remoteInstallationMatches(parsed.pluginParent, plugin.remotePluginId, read) || !lstatSync6(document).isFile() || realpathSync5(document) !== document)
38489
+ refuse3();
38490
+ remotePluginId = plugin.remotePluginId;
38491
+ }
38492
+ const exactPathDeny = Array.isArray(rules) && rules.some((rule) => rule?.path === document && rule?.enabled === false);
38493
+ if (!exactPathDeny || !isCodexNativeSkillDisabled({ name: parsed.name, path: document, pluginId: expectedPluginId, enabled: true }, rules))
38494
+ refuse3();
38495
+ }
38496
+ result.push({ ...parsed, pluginId: expectedPluginId, ...remotePluginId ? { remotePluginId } : {} });
38374
38497
  }
38375
38498
  if (!result.length || new Set(result.map((item) => item.name)).size !== result.length)
38376
38499
  refuse3();
@@ -38386,7 +38509,7 @@ function isReviewedCodexPluginSkillDisabled(document, cache, controls, rules, re
38386
38509
  return false;
38387
38510
  }
38388
38511
  const reviewed = controls.find((item) => item.name === parsed.name && item.namespace === parsed.namespace && item.pluginParent === parsed.pluginParent && item.manifestSha256 === parsed.manifestSha256 && item.appSha256 === parsed.appSha256);
38389
- if (!reviewed)
38512
+ if (!reviewed || reviewed.remotePluginId !== undefined && !remoteInstallationMatches(reviewed.pluginParent, reviewed.remotePluginId, read))
38390
38513
  return false;
38391
38514
  return isCodexNativeSkillDisabled({ name: parsed.name, path: document, pluginId: reviewed.pluginId, enabled: true }, rules);
38392
38515
  }
@@ -38405,7 +38528,7 @@ enabled = false
38405
38528
  return text;
38406
38529
  }
38407
38530
 
38408
- // src/lib/codex-settings-witness.ts
38531
+ // src/lib/codex-settings-witness-v1.ts
38409
38532
  import { createHash as createHash6 } from "crypto";
38410
38533
  var sha = (text) => createHash6("sha256").update(text).digest("hex");
38411
38534
  var EFFORT = new Set(["none", "minimal", "low", "medium", "high", "xhigh"]);
@@ -38499,15 +38622,162 @@ function captureCodexSettings(path, budget = { remaining: 256 * 1024 * 1024 }) {
38499
38622
  const text = readNativeSettingsWitnessFile(path, budget, "config.toml");
38500
38623
  return { path, hashMode: "codex-settings-v1", sha256: hashCodexSettingsReplacement(text) };
38501
38624
  }
38625
+
38626
+ // src/lib/codex-settings-witness.ts
38627
+ import { createHash as createHash7 } from "crypto";
38628
+ var sha2 = (text) => createHash7("sha256").update(text).digest("hex");
38629
+ var EFFORT2 = new Set(["none", "minimal", "low", "medium", "high", "xhigh"]);
38630
+ var VERBOSITY2 = new Set(["low", "medium", "high"]);
38631
+ var MODEL = /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$/;
38632
+ var CODEX_DISCOVERY_PROJECTION_FIELDS = ["plugins", "marketplaces", "skills"];
38633
+ var INFERENCE = ["model", "model_reasoning_effort", "model_verbosity"];
38634
+ function need3(value) {
38635
+ if (!value)
38636
+ throw new Error("Invalid Codex settings witness");
38637
+ }
38638
+ function isRecord(value) {
38639
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
38640
+ }
38641
+ function isDate(value) {
38642
+ return value instanceof Date;
38643
+ }
38644
+ function numericTokens2(text) {
38645
+ const result = [];
38646
+ for (let at = 0;at < text.length; ) {
38647
+ const char = text[at];
38648
+ if (char === "#") {
38649
+ while (at < text.length && text[at] !== `
38650
+ `)
38651
+ at++;
38652
+ continue;
38653
+ }
38654
+ if (char === '"' || char === "'") {
38655
+ const quote = char, triple = text.slice(at, at + 3) === quote.repeat(3);
38656
+ at += triple ? 3 : 1;
38657
+ while (at < text.length) {
38658
+ if (quote === '"' && text[at] === "\\") {
38659
+ at += 2;
38660
+ continue;
38661
+ }
38662
+ if (text.slice(at, at + (triple ? 3 : 1)) === quote.repeat(triple ? 3 : 1)) {
38663
+ at += triple ? 3 : 1;
38664
+ break;
38665
+ }
38666
+ at++;
38667
+ }
38668
+ continue;
38669
+ }
38670
+ if (/[0-9+-]/.test(char)) {
38671
+ const start = at;
38672
+ while (at < text.length && !/[\s,\]{}#=]/.test(text[at]))
38673
+ at++;
38674
+ if (at > start) {
38675
+ result.push(text.slice(start, at));
38676
+ continue;
38677
+ }
38678
+ }
38679
+ at++;
38680
+ }
38681
+ return result.sort();
38682
+ }
38683
+ function canonical3(value, depth = 0, budget = { remaining: 65536 }) {
38684
+ need3(depth <= 32 && --budget.remaining >= 0);
38685
+ if (value === null)
38686
+ return ["null"];
38687
+ if (typeof value === "string")
38688
+ return ["string", value];
38689
+ if (typeof value === "boolean")
38690
+ return ["boolean", value];
38691
+ if (typeof value === "number") {
38692
+ need3(Number.isFinite(value));
38693
+ return ["number", String(value)];
38694
+ }
38695
+ if (isDate(value)) {
38696
+ need3(Number.isFinite(value.getTime()));
38697
+ return ["date", value.toISOString()];
38698
+ }
38699
+ if (Array.isArray(value))
38700
+ return ["array", value.map((child) => canonical3(child, depth + 1, budget))];
38701
+ need3(isRecord(value));
38702
+ return ["object", Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, child]) => [key, canonical3(child, depth + 1, budget)])];
38703
+ }
38704
+ function normalize2(config) {
38705
+ if (isRecord(config.hooks)) {
38706
+ delete config.hooks.state;
38707
+ if (!Object.keys(config.hooks).length)
38708
+ delete config.hooks;
38709
+ }
38710
+ if (isRecord(config.skills) && Array.isArray(config.skills.config)) {
38711
+ const skills = config.skills;
38712
+ const retained = skills.config.filter((entry) => !disablesOneSkill(entry));
38713
+ if (retained.length !== skills.config.length) {
38714
+ if (retained.length)
38715
+ skills.config = retained;
38716
+ else
38717
+ delete skills.config;
38718
+ }
38719
+ if (!Object.keys(skills).length)
38720
+ delete config.skills;
38721
+ }
38722
+ inference(config);
38723
+ if (isRecord(config.profiles)) {
38724
+ for (const profile of Object.values(config.profiles))
38725
+ if (isRecord(profile))
38726
+ inference(profile);
38727
+ }
38728
+ }
38729
+ function disablesOneSkill(entry) {
38730
+ if (!isRecord(entry) || entry.enabled !== false)
38731
+ return false;
38732
+ const keys2 = Object.keys(entry);
38733
+ if (!keys2.every((key) => key === "path" || key === "name" || key === "enabled"))
38734
+ return false;
38735
+ const selector = ["path", "name"].filter((key) => Object.hasOwn(entry, key));
38736
+ return selector.length === 1 && typeof entry[selector[0]] === "string" && entry[selector[0]].length > 0;
38737
+ }
38738
+ function inference(target) {
38739
+ for (const key of INFERENCE)
38740
+ if (Object.hasOwn(target, key)) {
38741
+ const value = target[key];
38742
+ if (key === "model")
38743
+ need3(typeof value === "string" && MODEL.test(value));
38744
+ else
38745
+ need3(typeof value === "string" && (key === "model_reasoning_effort" ? EFFORT2.has(value) : VERBOSITY2.has(value)));
38746
+ delete target[key];
38747
+ }
38748
+ }
38749
+ function settingsDigest2(text) {
38750
+ let config;
38751
+ try {
38752
+ config = Bun.TOML.parse(text);
38753
+ } catch {
38754
+ throw new Error("Invalid Codex settings witness");
38755
+ }
38756
+ need3(isRecord(config));
38757
+ normalize2(config);
38758
+ return sha2(`hasna.skills.codex-settings.v2\x00${JSON.stringify([canonical3(config), numericTokens2(text)])}`);
38759
+ }
38760
+ function hashCodexSettingsReplacementV2(text, budget = { remaining: 256 * 1024 * 1024 }) {
38761
+ need3(Buffer.byteLength(text) <= 1024 * 1024 && budget.remaining >= Buffer.byteLength(text));
38762
+ budget.remaining -= Buffer.byteLength(text);
38763
+ return settingsDigest2(text);
38764
+ }
38765
+ function captureCodexSettingsV2(path, budget = { remaining: 256 * 1024 * 1024 }) {
38766
+ const text = readNativeSettingsWitnessFile(path, budget, "config.toml");
38767
+ return { path, hashMode: "codex-settings-v2", sha256: settingsDigest2(text) };
38768
+ }
38769
+ function readCodexSettingsPreimage(path, budget = { remaining: 2 * 1024 * 1024 }) {
38770
+ return readNativeSettingsWitnessFile(path, budget, "config.toml");
38771
+ }
38502
38772
  function upgradeCodexSettingsWitness(previous, reviewedSettingsPath) {
38503
- need2(previous && Object.keys(previous).every((key) => ["path", "hashMode", "sha256"].includes(key)) && (previous.hashMode === undefined || previous.hashMode === "bytes") && /^[a-f0-9]{64}$/.test(previous.sha256));
38773
+ need3(previous && Object.keys(previous).every((key) => ["path", "hashMode", "sha256"].includes(key)) && (previous.hashMode === undefined || previous.hashMode === "bytes" || previous.hashMode === "codex-settings-v1") && /^[a-f0-9]{64}$/.test(previous.sha256));
38504
38774
  const budget = { remaining: 2 * 1024 * 1024 };
38505
38775
  const before = readNativeSettingsWitnessFile(reviewedSettingsPath, budget, "config.toml"), current = readNativeSettingsWitnessFile(previous.path, budget, "config.toml");
38506
- need2(sha(before) === previous.sha256);
38507
- const sha2562 = hashCodexSettingsReplacement(current);
38508
- if (hashCodexSettingsReplacement(before) !== sha2562)
38776
+ need3((previous.hashMode === "codex-settings-v1" ? hashCodexSettingsReplacement(before) : sha2(before)) === previous.sha256);
38777
+ const sha2562 = settingsDigest2(current);
38778
+ if (settingsDigest2(before) !== sha2562)
38509
38779
  throw new Error("Codex non-preference settings changed; explicit discovery review required");
38510
- return { path: previous.path, hashMode: "codex-settings-v1", sha256: sha2562 };
38780
+ return { path: previous.path, hashMode: "codex-settings-v2", sha256: sha2562 };
38511
38781
  }
38512
38782
 
38513
38783
  // src/lib/native-discovery-roots.ts
@@ -38530,9 +38800,10 @@ var NATIVE_SKILL_ROOTS = [
38530
38800
  ];
38531
38801
 
38532
38802
  // src/lib/agent-integration.ts
38533
- import { createHash as createHash17, randomUUID as randomUUID3 } from "crypto";
38803
+ import { createHash as createHash18, randomUUID as randomUUID3 } from "crypto";
38804
+ import { isDeepStrictEqual as isDeepStrictEqual5 } from "util";
38534
38805
  import { existsSync as existsSync6, lstatSync as lstatSync19, statSync as statSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync14, readdirSync as readdirSync8, opendirSync as opendirSync5, readlinkSync as readlinkSync4, realpathSync as realpathSync7, renameSync as renameSync3, rmdirSync as rmdirSync3, writeFileSync as writeFileSync4, unlinkSync as unlinkSync4, chmodSync, openSync as openSync16, closeSync as closeSync16, fsyncSync as fsyncSync4, fstatSync as fstatSync16, readSync as readSync11, constants as constants12, linkSync as linkSync2 } from "fs";
38535
- import { dirname as dirname15, join as join22, resolve as resolve15, relative as relative3, isAbsolute as isAbsolute17, sep as sep5 } from "path";
38806
+ import { dirname as dirname15, join as join22, resolve as resolve15, relative as relative4, isAbsolute as isAbsolute17, sep as sep5 } from "path";
38536
38807
  import { homedir as homedir3 } from "os";
38537
38808
 
38538
38809
  // src/lib/managed-policy.ts
@@ -38540,7 +38811,7 @@ import { closeSync as closeSync10, constants as constants6, fstatSync as fstatSy
38540
38811
  import { join as join11 } from "path";
38541
38812
 
38542
38813
  // src/lib/agent-policy-limits.ts
38543
- import { basename as basename3, isAbsolute as isAbsolute6, resolve as resolve5 } from "path";
38814
+ import { basename as basename4, isAbsolute as isAbsolute6, resolve as resolve5 } from "path";
38544
38815
  var AGENT_POLICY_LIMITS = Object.freeze({ bytes: 1024 * 1024, agents: 16, discoverySources: 2048, discoveryRawSourceBytes: 64 * 1024 * 1024, discoveryRawTotalBytes: 256 * 1024 * 1024, discoveryPathLinks: 40, discoveryPathSteps: 256, discoveryPathSourceMetadataBytes: 64 * 1024, discoveryPathTotalMetadataBytes: 8 * 1024 * 1024, discoveryRoots: 512, discoveryDirectories: 64, discoveryDirectoryEntries: 20000, discoveryDirectoryBytes: 8 * 1024 * 1024, builtinNames: 2048, rootAliases: 2, fields: 64, pathCharacters: 4096 });
38545
38816
  function object3(value) {
38546
38817
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
@@ -38589,12 +38860,14 @@ function assertAgentPolicyCollections(policy) {
38589
38860
  }
38590
38861
  if (bridge.codexPluginSkills !== undefined)
38591
38862
  for (const control of array(bridge.codexPluginSkills, 4096)) {
38592
- requireBound(object3(control) && Object.keys(control).every((key) => ["name", "pluginId", "namespace", "pluginParent", "manifestSha256", "appSha256"].includes(key)));
38863
+ requireBound(object3(control) && Object.keys(control).every((key) => ["name", "pluginId", "namespace", "pluginParent", "manifestSha256", "appSha256", "remotePluginId"].includes(key)));
38593
38864
  text(control.name, 129);
38594
38865
  text(control.pluginId, 1024);
38595
38866
  text(control.namespace, 64);
38596
38867
  text(control.pluginParent);
38597
38868
  requireBound(isAbsolute6(control.pluginParent) && resolve5(control.pluginParent) === control.pluginParent && /^[a-f0-9]{64}$/.test(control.manifestSha256));
38869
+ if (control.remotePluginId !== undefined)
38870
+ requireBound(typeof control.remotePluginId === "string" && /^[A-Za-z0-9_~-]{1,1024}$/.test(control.remotePluginId));
38598
38871
  if (control.appSha256 !== undefined)
38599
38872
  requireBound(typeof control.appSha256 === "string" && /^[a-f0-9]{64}$/.test(control.appSha256));
38600
38873
  }
@@ -38617,13 +38890,13 @@ function assertAgentPolicyCollections(policy) {
38617
38890
  text(source.path);
38618
38891
  requireBound(source.sha256 === null || typeof source.sha256 === "string" && /^[a-f0-9]{64}$/.test(source.sha256));
38619
38892
  if (source.hashMode !== undefined)
38620
- requireBound(["bytes", "path-bytes", "claude-plugin-registry", "claude-marketplace-registry", "claude-settings-v1", "claude-settings-v2", "claude-settings-v3", "claude-marketplace-registry-v2", "codex-settings-v1"].includes(source.hashMode) && source.format === undefined && source.fields === undefined && (source.hashMode === "bytes" || source.sha256 !== null));
38621
- if (source.hashMode === "codex-settings-v1")
38622
- requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute6(source.path) && resolve5(source.path) === source.path && basename3(source.path) === "config.toml");
38893
+ requireBound(["bytes", "path-bytes", "claude-plugin-registry", "claude-marketplace-registry", "claude-settings-v1", "claude-settings-v2", "claude-settings-v3", "claude-marketplace-registry-v2", "codex-settings-v1", "codex-settings-v2"].includes(source.hashMode) && source.format === undefined && source.fields === undefined && (source.hashMode === "bytes" || source.sha256 !== null));
38894
+ if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2")
38895
+ requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute6(source.path) && resolve5(source.path) === source.path && basename4(source.path) === "config.toml");
38623
38896
  if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3")
38624
- requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute6(source.path) && resolve5(source.path) === source.path && basename3(source.path) === "settings.json");
38897
+ requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute6(source.path) && resolve5(source.path) === source.path && basename4(source.path) === "settings.json");
38625
38898
  if (source.hashMode === "claude-marketplace-registry" || source.hashMode === "claude-marketplace-registry-v2")
38626
- requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute6(source.path) && resolve5(source.path) === source.path && basename3(source.path) === "known_marketplaces.json");
38899
+ requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute6(source.path) && resolve5(source.path) === source.path && basename4(source.path) === "known_marketplaces.json");
38627
38900
  if (source.hashMode === "claude-plugin-registry") {
38628
38901
  requireBound(agent === "claude");
38629
38902
  const managed = array(source.managedPlugins, 64);
@@ -38732,7 +39005,7 @@ function requiresCliSkillLoading(dataDir2 = getDataDirReadOnly()) {
38732
39005
  }
38733
39006
 
38734
39007
  // src/lib/agent-bridge.ts
38735
- import { createHash as createHash7 } from "crypto";
39008
+ import { createHash as createHash8 } from "crypto";
38736
39009
  import { lstatSync as lstatSync8, readFileSync as readFileSync9, readdirSync as readdirSync4 } from "fs";
38737
39010
  import { join as join12 } from "path";
38738
39011
  var CLI_BRIDGE_NAME = "skills-cli";
@@ -38751,7 +39024,7 @@ Use the Skills CLI as the skill authority for this station.
38751
39024
 
38752
39025
  This bridge contains no skill payloads. Do not copy skill content into agent-native skill directories or load other native skill copies. If a Skills command refuses authority, selection, integrity, or native drift, report that refusal and use its repair guidance; do not substitute bundled or stale local content. Explicit local draft authoring remains available.
38753
39026
  `;
38754
- var CLI_BRIDGE_DIGEST = createHash7("sha256").update(markdown).digest("hex");
39027
+ var CLI_BRIDGE_DIGEST = createHash8("sha256").update(markdown).digest("hex");
38755
39028
  var CLI_BRIDGE_FILES = Object.freeze({
38756
39029
  "SKILL.md": markdown,
38757
39030
  ".hasna-skills.json": `${JSON.stringify({ managedBy: "@hasna/skills", kind: "cli-bridge", version: CLI_BRIDGE_VERSION, protocol: "selection-v1", contentSha256: CLI_BRIDGE_DIGEST }, null, 2)}
@@ -38775,9 +39048,9 @@ function isOwnedCliBridge(path, expectedPaths) {
38775
39048
  }
38776
39049
 
38777
39050
  // src/lib/agent-discovery.ts
38778
- import { createHash as createHash16 } from "crypto";
39051
+ import { createHash as createHash17 } from "crypto";
38779
39052
  import { lstatSync as lstatSync18, readFileSync as readFileSync13, readdirSync as readdirSync7, realpathSync as realpathSync6 } from "fs";
38780
- import { basename as basename6, dirname as dirname14, isAbsolute as isAbsolute16, join as join21, resolve as resolve14, sep as sep4 } from "path";
39053
+ import { basename as basename7, dirname as dirname14, isAbsolute as isAbsolute16, join as join21, resolve as resolve14, sep as sep4 } from "path";
38781
39054
  import { isDeepStrictEqual as isDeepStrictEqual3 } from "util";
38782
39055
 
38783
39056
  // node_modules/yaml/dist/index.js
@@ -39034,17 +39307,17 @@ if (failed) process.exitCode = 2;
39034
39307
  }
39035
39308
 
39036
39309
  // src/lib/agent-discovery-directories.ts
39037
- import { createHash as createHash8 } from "crypto";
39310
+ import { createHash as createHash9 } from "crypto";
39038
39311
  import { lstatSync as lstatSync10, opendirSync as opendirSync2 } from "fs";
39039
39312
  import { dirname as dirname7, isAbsolute as isAbsolute8, join as join14, resolve as resolve7 } from "path";
39040
- function need3(value, message) {
39313
+ function need4(value, message) {
39041
39314
  if (!value)
39042
39315
  throw new Error(message);
39043
39316
  }
39044
39317
  function safe(path) {
39045
- need3(typeof path === "string" && path.length <= AGENT_POLICY_LIMITS.pathCharacters && isAbsolute8(path) && resolve7(path) === path && !path.includes("\x00"), "Expected a canonical absolute discovery directory path");
39318
+ need4(typeof path === "string" && path.length <= AGENT_POLICY_LIMITS.pathCharacters && isAbsolute8(path) && resolve7(path) === path && !path.includes("\x00"), "Expected a canonical absolute discovery directory path");
39046
39319
  for (let cursor = path;; cursor = dirname7(cursor)) {
39047
- need3(!lstatSync10(cursor, { throwIfNoEntry: false })?.isSymbolicLink(), "Refusing symlink native discovery directory");
39320
+ need4(!lstatSync10(cursor, { throwIfNoEntry: false })?.isSymbolicLink(), "Refusing symlink native discovery directory");
39048
39321
  if (dirname7(cursor) === cursor)
39049
39322
  break;
39050
39323
  }
@@ -39057,55 +39330,55 @@ function capture(path, budget) {
39057
39330
  const root = lstatSync10(path, { throwIfNoEntry: false });
39058
39331
  if (!root)
39059
39332
  return { path, sha256: null };
39060
- need3(root.isDirectory(), "Unsupported native discovery directory input");
39061
- const hash2 = createHash8("sha256");
39062
- function walk2(current, relative3, before, depth) {
39063
- need3(depth <= 64, "Native discovery directory depth limit exceeded");
39333
+ need4(root.isDirectory(), "Unsupported native discovery directory input");
39334
+ const hash2 = createHash9("sha256");
39335
+ function walk2(current, relative4, before, depth) {
39336
+ need4(depth <= 64, "Native discovery directory depth limit exceeded");
39064
39337
  const names = [], directory = opendirSync2(current);
39065
39338
  try {
39066
39339
  for (let entry = directory.readSync();entry; entry = directory.readSync()) {
39067
- need3(++budget.entries <= AGENT_POLICY_LIMITS.discoveryDirectoryEntries, "Native discovery directory entry limit exceeded");
39340
+ need4(++budget.entries <= AGENT_POLICY_LIMITS.discoveryDirectoryEntries, "Native discovery directory entry limit exceeded");
39068
39341
  names.push(entry.name);
39069
39342
  }
39070
39343
  } finally {
39071
39344
  directory.closeSync();
39072
39345
  }
39073
- need3(new Set(names).size === names.length, "Ambiguous native discovery directory names");
39346
+ need4(new Set(names).size === names.length, "Ambiguous native discovery directory names");
39074
39347
  for (const name of names.sort()) {
39075
- const child = join14(current, name), childRelative = relative3 ? `${relative3}/${name}` : name;
39076
- need3(child.length <= AGENT_POLICY_LIMITS.pathCharacters, "Native discovery directory path limit exceeded");
39348
+ const child = join14(current, name), childRelative = relative4 ? `${relative4}/${name}` : name;
39349
+ need4(child.length <= AGENT_POLICY_LIMITS.pathCharacters, "Native discovery directory path limit exceeded");
39077
39350
  const stat = lstatSync10(child);
39078
- need3(stat.isFile() || stat.isDirectory(), "Refusing symlink or special native discovery directory member");
39351
+ need4(stat.isFile() || stat.isDirectory(), "Refusing symlink or special native discovery directory member");
39079
39352
  const row = JSON.stringify([childRelative, stat.isDirectory() ? "directory" : "file"]) + `
39080
39353
  `;
39081
39354
  budget.bytes += Buffer.byteLength(row);
39082
- need3(budget.bytes <= AGENT_POLICY_LIMITS.discoveryDirectoryBytes, "Native discovery directory metadata limit exceeded");
39355
+ need4(budget.bytes <= AGENT_POLICY_LIMITS.discoveryDirectoryBytes, "Native discovery directory metadata limit exceeded");
39083
39356
  hash2.update(row);
39084
39357
  if (stat.isDirectory())
39085
39358
  walk2(child, childRelative, stat, depth + 1);
39086
39359
  }
39087
- need3(same(before, lstatSync10(current, { throwIfNoEntry: false })), "Native discovery directory changed while reading");
39360
+ need4(same(before, lstatSync10(current, { throwIfNoEntry: false })), "Native discovery directory changed while reading");
39088
39361
  }
39089
39362
  walk2(path, "", root, 0);
39090
39363
  safe(path);
39091
39364
  return { path, sha256: hash2.digest("hex") };
39092
39365
  }
39093
39366
  function captureDiscoveryDirectories(paths) {
39094
- need3(Array.isArray(paths) && paths.length <= AGENT_POLICY_LIMITS.discoveryDirectories && new Set(paths).size === paths.length, "Invalid native discovery directory collection");
39367
+ need4(Array.isArray(paths) && paths.length <= AGENT_POLICY_LIMITS.discoveryDirectories && new Set(paths).size === paths.length, "Invalid native discovery directory collection");
39095
39368
  const budget = { entries: 0, bytes: 0 };
39096
39369
  return paths.map((path) => capture(path, budget));
39097
39370
  }
39098
39371
  function verifyDiscoveryDirectories(directories) {
39099
- need3(Array.isArray(directories) && directories.length <= AGENT_POLICY_LIMITS.discoveryDirectories, "Invalid native discovery directory collection");
39372
+ need4(Array.isArray(directories) && directories.length <= AGENT_POLICY_LIMITS.discoveryDirectories, "Invalid native discovery directory collection");
39100
39373
  for (const directory of directories)
39101
- need3(directory && typeof directory === "object" && (directory.sha256 === null || typeof directory.sha256 === "string" && /^[a-f0-9]{64}$/.test(directory.sha256)), "Invalid native discovery directory digest");
39374
+ need4(directory && typeof directory === "object" && (directory.sha256 === null || typeof directory.sha256 === "string" && /^[a-f0-9]{64}$/.test(directory.sha256)), "Invalid native discovery directory digest");
39102
39375
  const current = captureDiscoveryDirectories(directories.map((directory) => directory.path));
39103
39376
  for (let i = 0;i < directories.length; i++)
39104
- need3(current[i].sha256 === directories[i].sha256, `Native discovery directory membership changed; run skills hook install with a fresh discovery review: ${directories[i].path}`);
39377
+ need4(current[i].sha256 === directories[i].sha256, `Native discovery directory membership changed; run skills hook install with a fresh discovery review: ${directories[i].path}`);
39105
39378
  }
39106
39379
 
39107
39380
  // src/lib/agent-discovery-bytes.ts
39108
- import { createHash as createHash9 } from "crypto";
39381
+ import { createHash as createHash10 } from "crypto";
39109
39382
  import { closeSync as closeSync11, constants as constants7, fstatSync as fstatSync11, lstatSync as lstatSync11, openSync as openSync11, readSync as readSync6 } from "fs";
39110
39383
  import { dirname as dirname8, isAbsolute as isAbsolute9, resolve as resolve8 } from "path";
39111
39384
  function discoveryByteBudget() {
@@ -39136,7 +39409,7 @@ function hashRawDiscoveryFile(path, budget, changes) {
39136
39409
  if (bytes > AGENT_POLICY_LIMITS.discoveryRawSourceBytes)
39137
39410
  throw new Error("Raw discovery file byte limit exceeded");
39138
39411
  consume(budget, bytes);
39139
- return createHash9("sha256").update(text2).digest("hex");
39412
+ return createHash10("sha256").update(text2).digest("hex");
39140
39413
  }
39141
39414
  const initial = lstatSync11(path, { throwIfNoEntry: false });
39142
39415
  if (!initial)
@@ -39150,7 +39423,7 @@ function hashRawDiscoveryFile(path, budget, changes) {
39150
39423
  const opened = fstatSync11(fd);
39151
39424
  if (!opened.isFile() || !same2(initial, opened))
39152
39425
  throw new Error("Raw discovery input changed during open");
39153
- const hash2 = createHash9("sha256"), buffer = Buffer.alloc(64 * 1024);
39426
+ const hash2 = createHash10("sha256"), buffer = Buffer.alloc(64 * 1024);
39154
39427
  let bytes = 0;
39155
39428
  while (true) {
39156
39429
  const count = readSync6(fd, buffer, 0, Math.min(buffer.length, AGENT_POLICY_LIMITS.discoveryRawSourceBytes - bytes + 1), null);
@@ -39173,7 +39446,7 @@ function hashRawDiscoveryFile(path, budget, changes) {
39173
39446
  }
39174
39447
 
39175
39448
  // src/lib/agent-discovery-path-bytes.ts
39176
- import { createHash as createHash10 } from "crypto";
39449
+ import { createHash as createHash11 } from "crypto";
39177
39450
  import { lstatSync as lstatSync12, readlinkSync as readlinkSync3 } from "fs";
39178
39451
  import { dirname as dirname9, isAbsolute as isAbsolute10, join as join15, parse as parse3, resolve as resolve9, sep as sep3 } from "path";
39179
39452
  function identity3(stat, mutable = false) {
@@ -39186,12 +39459,12 @@ function identity3(stat, mutable = false) {
39186
39459
  ...mutable ? { size: String(stat.size), mtimeNs: String(stat.mtimeNs), ctimeNs: String(stat.ctimeNs) } : {}
39187
39460
  };
39188
39461
  }
39189
- function canonical3(path) {
39462
+ function canonical4(path) {
39190
39463
  if (typeof path !== "string" || !isAbsolute10(path) || path !== resolve9(path) || path.length > AGENT_POLICY_LIMITS.pathCharacters || path.includes("\x00") || Buffer.from(path).toString("utf8") !== path)
39191
39464
  throw new Error("Expected a canonical absolute discovery path");
39192
39465
  }
39193
39466
  function trace(path) {
39194
- canonical3(path);
39467
+ canonical4(path);
39195
39468
  const rows = [], paths = [];
39196
39469
  let metadataBytes = 0, steps = 0, links = 0, cursor = parse3(path).root, pending = path.slice(cursor.length).split(sep3);
39197
39470
  function record3(path2, row) {
@@ -39283,19 +39556,19 @@ function hashDiscoveryPathFile(path, budget, changes) {
39283
39556
  const after = trace(path);
39284
39557
  if (JSON.stringify(before.rows) !== JSON.stringify(after.rows) || before.file !== after.file)
39285
39558
  throw new Error("Discovery path input changed during read");
39286
- return createHash10("sha256").update(JSON.stringify({ version: 1, path, rows: before.rows, content })).digest("hex");
39559
+ return createHash11("sha256").update(JSON.stringify({ version: 1, path, rows: before.rows, content })).digest("hex");
39287
39560
  }
39288
39561
 
39289
39562
  // src/lib/plugin-discovery.ts
39290
39563
  import { closeSync as closeSync13, constants as constants9, fstatSync as fstatSync13, lstatSync as lstatSync15, openSync as openSync13, opendirSync as opendirSync4, readSync as readSync8 } from "fs";
39291
- import { basename as basename4, dirname as dirname11, isAbsolute as isAbsolute14, join as join20, resolve as resolve12 } from "path";
39564
+ import { basename as basename5, dirname as dirname11, isAbsolute as isAbsolute14, join as join20, resolve as resolve12 } from "path";
39292
39565
 
39293
39566
  // src/lib/plugin-admission.ts
39294
39567
  import { homedir as homedir2 } from "os";
39295
39568
  import { isAbsolute as isAbsolute13, join as join19, resolve as resolve11 } from "path";
39296
39569
 
39297
39570
  // src/lib/plugin-projection.ts
39298
- import { createHash as createHash11 } from "crypto";
39571
+ import { createHash as createHash12 } from "crypto";
39299
39572
  import { posix as posix2 } from "path";
39300
39573
  var PLUGIN_PROJECTION_MANIFEST = "plugin-projection.json";
39301
39574
  var PLUGIN_PROJECTION_LIMITS = Object.freeze({ files: 1024, bytes: 64 * 1024 * 1024, fileBytes: 16 * 1024 * 1024, metadataBytes: 512 * 1024, registrations: 64, history: 128 });
@@ -39306,7 +39579,7 @@ function pluginNeed(value, message) {
39306
39579
  if (!value)
39307
39580
  pluginRefusal(message);
39308
39581
  }
39309
- var pluginHash = (bytes) => createHash11("sha256").update(bytes).digest("hex");
39582
+ var pluginHash = (bytes) => createHash12("sha256").update(bytes).digest("hex");
39310
39583
  function pluginObject(value) {
39311
39584
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
39312
39585
  }
@@ -39494,7 +39767,7 @@ function buildPluginProjection(entries) {
39494
39767
  }
39495
39768
 
39496
39769
  // src/lib/plugin-projection-store.ts
39497
- import { createHash as createHash12, randomUUID as randomUUID2 } from "crypto";
39770
+ import { createHash as createHash13, randomUUID as randomUUID2 } from "crypto";
39498
39771
  import { constants as constants8, closeSync as closeSync12, fchmodSync, fstatSync as fstatSync12, fsyncSync as fsyncSync2, linkSync, lstatSync as lstatSync13, mkdirSync as mkdirSync4, openSync as openSync12, opendirSync as opendirSync3, readSync as readSync7, renameSync as renameSync2, rmdirSync as rmdirSync2, rmSync, unlinkSync as unlinkSync3, writeSync as writeSync2 } from "fs";
39499
39772
  import { dirname as dirname10, isAbsolute as isAbsolute11, join as join16, parse as parse5, resolve as resolve10 } from "path";
39500
39773
  var READ_FLAGS = constants8.O_RDONLY | constants8.O_NOFOLLOW | constants8.O_NONBLOCK;
@@ -39510,7 +39783,7 @@ function stat(path) {
39510
39783
  return pluginRefusal("Cannot inspect plugin filesystem entry");
39511
39784
  }
39512
39785
  }
39513
- function canonical4(path) {
39786
+ function canonical5(path) {
39514
39787
  pluginNeed(typeof path === "string" && path.length <= 8192 && isAbsolute11(path) && resolve10(path) === path && !/[\x00-\x1f\x7f]/.test(path), "Plugin storage paths must be canonical absolute paths");
39515
39788
  }
39516
39789
  function owner(stats, system = false) {
@@ -39521,7 +39794,7 @@ function same3(left, right, identityOnly = false) {
39521
39794
  pluginNeed(right && left.dev === right.dev && left.ino === right.ino && left.mode === right.mode && left.uid === right.uid && left.gid === right.gid && (identityOnly || left.size === right.size && left.nlink === right.nlink && left.mtimeNs === right.mtimeNs && left.ctimeNs === right.ctimeNs), "Plugin filesystem entry changed during access");
39522
39795
  }
39523
39796
  function ancestors(path, create = false) {
39524
- canonical4(path);
39797
+ canonical5(path);
39525
39798
  const result = [], parent = dirname10(path), filesystemRoot = parse5(parent).root;
39526
39799
  let current = filesystemRoot;
39527
39800
  for (const segment of ["", ...parent.slice(filesystemRoot.length).split("/").filter(Boolean)]) {
@@ -39631,7 +39904,7 @@ function directoryNames(path) {
39631
39904
  function snapshotPluginTree(root, options = {}) {
39632
39905
  const chain = ancestors(root), entries = [], files = [], directories = [];
39633
39906
  let bytes = 0, visited = 0;
39634
- const visit2 = (directory, relative3) => {
39907
+ const visit2 = (directory, relative4) => {
39635
39908
  const before = stat(directory);
39636
39909
  pluginNeed(before && before.isDirectory() && !before.isSymbolicLink(), "Plugin tree must contain real directories");
39637
39910
  const names = directoryNames(directory);
@@ -39639,18 +39912,18 @@ function snapshotPluginTree(root, options = {}) {
39639
39912
  directories.push({ path: directory, stat: before, names });
39640
39913
  for (const name of names) {
39641
39914
  pluginNeed(++visited <= PLUGIN_PROJECTION_LIMITS.files * 50, "Plugin tree membership exceeds its limit");
39642
- const path = relative3 ? `${relative3}/${name}` : name;
39915
+ const path = relative4 ? `${relative4}/${name}` : name;
39643
39916
  pluginNeed(new TextEncoder().encode(path).byteLength <= 100 && !/[\\:\x00-\x1f\x7f]/u.test(path), "Plugin entry path exceeds its limit or is unsafe");
39644
39917
  const absolute = join16(directory, name), entryStat = stat(absolute);
39645
39918
  pluginNeed(entryStat, "Plugin tree member disappeared");
39646
- if (relative3 === "" && name === ".orphaned_at" && (options.nativeRuntime === "claude-2.1.274" || options.nativeRuntime === "claude-2.1.276")) {
39919
+ if (relative4 === "" && name === ".orphaned_at" && (options.nativeRuntime === "claude-2.1.274" || options.nativeRuntime === "claude-2.1.276")) {
39647
39920
  const bytes2 = readBytes(absolute, 32, "native-pin");
39648
39921
  pluginNeed(/^[1-9][0-9]{12}$/.test(new TextDecoder().decode(bytes2)), "Malformed native orphan timestamp");
39649
39922
  same3(entryStat, stat(absolute));
39650
39923
  files.push({ path: absolute, stat: entryStat });
39651
39924
  continue;
39652
39925
  }
39653
- if (relative3 === "" && name === ".in_use" && (options.nativeRuntime === "claude-2.1.274" || options.nativeRuntime === "claude-2.1.276")) {
39926
+ if (relative4 === "" && name === ".in_use" && (options.nativeRuntime === "claude-2.1.274" || options.nativeRuntime === "claude-2.1.276")) {
39654
39927
  pluginNeed(entryStat.isDirectory() && !entryStat.isSymbolicLink(), "Native plugin pins require a real directory");
39655
39928
  owner(entryStat);
39656
39929
  const pins = directoryNames(absolute);
@@ -39836,7 +40109,7 @@ function pluginExecutableDigest(path) {
39836
40109
  const opened = fstatSync12(fd, { bigint: true });
39837
40110
  same3(before, opened);
39838
40111
  fileShape(opened, maximum, "executable");
39839
- const hash2 = createHash12("sha256"), buffer = new Uint8Array(64 * 1024);
40112
+ const hash2 = createHash13("sha256"), buffer = new Uint8Array(64 * 1024);
39840
40113
  let remaining = Number(opened.size);
39841
40114
  while (remaining > 0) {
39842
40115
  const count = readSync7(fd, buffer, 0, Math.min(buffer.byteLength, remaining), null);
@@ -39861,7 +40134,7 @@ function pluginExecutableDigest(path) {
39861
40134
 
39862
40135
  // src/lib/skill-validation.ts
39863
40136
  import { existsSync as existsSync5, lstatSync as lstatSync14, readFileSync as readFileSync12, readdirSync as readdirSync6, statSync as statSync5 } from "fs";
39864
- import { isAbsolute as isAbsolute12, join as join18, normalize as normalize2 } from "path";
40137
+ import { isAbsolute as isAbsolute12, join as join18, normalize as normalize3 } from "path";
39865
40138
 
39866
40139
  // src/lib/hosted-skill-set.ts
39867
40140
  import { existsSync as existsSync4, readFileSync as readFileSync11, readdirSync as readdirSync5, statSync as statSync4 } from "fs";
@@ -39967,7 +40240,7 @@ function sortMessages(messages) {
39967
40240
  function isSafeRelativePath(value) {
39968
40241
  if (!value.trim() || isAbsolute12(value))
39969
40242
  return false;
39970
- const normalized = normalize2(value).replace(/\\/g, "/");
40243
+ const normalized = normalize3(value).replace(/\\/g, "/");
39971
40244
  return normalized !== ".." && !normalized.startsWith("../") && !normalized.includes("/../");
39972
40245
  }
39973
40246
  function validateRuntimeEntry(skillPath, entrypoint, issues, warnings) {
@@ -40769,7 +41042,7 @@ function hashManagedPluginRegistry(path, managed) {
40769
41042
  pluginNeed(/^(?:[A-Za-z0-9][A-Za-z0-9._+-]*-)?[a-f0-9]{12}$/.test(row.version) && row.installPath === join20(cacheRoot, row.version), "Managed plugin cache path or version is outside its registration");
40770
41043
  const approval = (producer) => {
40771
41044
  pluginText(producer);
40772
- const digest2 = `sha256:${basename4(producer)}`;
41045
+ const digest2 = `sha256:${basename5(producer)}`;
40773
41046
  const receipt2 = readPluginAdmissionReceipt(witness.storeRoot, witness.bindingId, digest2);
40774
41047
  pluginNeed(receipt2.materializedPath === producer, "Managed producer path is not an approved immutable projection");
40775
41048
  if (!verified.has(producer)) {
@@ -40831,23 +41104,23 @@ function captureManagedPluginRegistry(path, managedPlugins) {
40831
41104
  }
40832
41105
 
40833
41106
  // src/lib/claude-marketplace-registry.ts
40834
- import { createHash as createHash13 } from "crypto";
41107
+ import { createHash as createHash14 } from "crypto";
40835
41108
  import { closeSync as closeSync14, constants as constants10, fstatSync as fstatSync14, lstatSync as lstatSync16, openSync as openSync14, readSync as readSync9 } from "fs";
40836
- import { basename as basename5, dirname as dirname12, isAbsolute as isAbsolute15, resolve as resolve13 } from "path";
41109
+ import { basename as basename6, dirname as dirname12, isAbsolute as isAbsolute15, resolve as resolve13 } from "path";
40837
41110
  var CLAUDE_MARKETPLACE_REGISTRY_LIMITS = Object.freeze({ bytes: 1024 * 1024, rows: 1024, depth: 32, nodes: 65536, stringCharacters: 16384, pathCharacters: 4096 });
40838
- function need4(value, reason) {
41111
+ function need5(value, reason) {
40839
41112
  if (!value)
40840
41113
  throw new Error(`Claude marketplace registry ${reason}`);
40841
41114
  }
40842
41115
  function absolutePath3(value) {
40843
- need4(typeof value === "string" && value.length > 0 && value.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.pathCharacters && !/[\x00-\x1f\x7f]/.test(value) && isAbsolute15(value) && resolve13(value) === value, "requires a normalized absolute path");
41116
+ need5(typeof value === "string" && value.length > 0 && value.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.pathCharacters && !/[\x00-\x1f\x7f]/.test(value) && isAbsolute15(value) && resolve13(value) === value, "requires a normalized absolute path");
40844
41117
  }
40845
41118
  var 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;
40846
41119
  function parents2(path) {
40847
41120
  const result = [];
40848
41121
  for (let at = dirname12(path);; at = dirname12(at)) {
40849
41122
  const stat2 = lstatSync16(at, { bigint: true });
40850
- need4(stat2.isDirectory() && !stat2.isSymbolicLink(), "path traverses a symlink or non-directory");
41123
+ need5(stat2.isDirectory() && !stat2.isSymbolicLink(), "path traverses a symlink or non-directory");
40851
41124
  result.push([at, stat2]);
40852
41125
  if (at === dirname12(at))
40853
41126
  return result;
@@ -40855,15 +41128,15 @@ function parents2(path) {
40855
41128
  }
40856
41129
  function readRegistry2(path, budget) {
40857
41130
  absolutePath3(path);
40858
- need4(basename5(path) === "known_marketplaces.json", "requires known_marketplaces.json");
40859
- need4(Number.isSafeInteger(budget.remaining) && budget.remaining >= 0, "has an invalid byte budget");
41131
+ need5(basename6(path) === "known_marketplaces.json", "requires known_marketplaces.json");
41132
+ need5(Number.isSafeInteger(budget.remaining) && budget.remaining >= 0, "has an invalid byte budget");
40860
41133
  const ancestors2 = parents2(path), initial = lstatSync16(path, { bigint: true });
40861
- need4(initial.isFile() && !initial.isSymbolicLink() && initial.size <= BigInt(CLAUDE_MARKETPLACE_REGISTRY_LIMITS.bytes), "is not a bounded regular file");
40862
- need4(initial.size <= BigInt(budget.remaining), "exceeds its aggregate byte limit");
41134
+ need5(initial.isFile() && !initial.isSymbolicLink() && initial.size <= BigInt(CLAUDE_MARKETPLACE_REGISTRY_LIMITS.bytes), "is not a bounded regular file");
41135
+ need5(initial.size <= BigInt(budget.remaining), "exceeds its aggregate byte limit");
40863
41136
  const fd = openSync14(path, constants10.O_RDONLY | constants10.O_NOFOLLOW | constants10.O_NONBLOCK);
40864
41137
  try {
40865
41138
  const opened = fstatSync14(fd, { bigint: true });
40866
- need4(opened.isFile() && sameFile2(initial, opened), "changed during open");
41139
+ need5(opened.isFile() && sameFile2(initial, opened), "changed during open");
40867
41140
  const bytes = Buffer.alloc(Number(opened.size) + 1);
40868
41141
  let length = 0;
40869
41142
  while (length < bytes.length) {
@@ -40873,10 +41146,10 @@ function readRegistry2(path, budget) {
40873
41146
  length += count;
40874
41147
  }
40875
41148
  const after = fstatSync14(fd, { bigint: true }), current = lstatSync16(path, { bigint: true });
40876
- need4(current.isFile() && sameFile2(opened, after) && sameFile2(after, current) && BigInt(length) === opened.size, "changed during read");
41149
+ need5(current.isFile() && sameFile2(opened, after) && sameFile2(after, current) && BigInt(length) === opened.size, "changed during read");
40877
41150
  for (const [ancestor, before] of ancestors2) {
40878
41151
  const now = lstatSync16(ancestor, { bigint: true });
40879
- need4(now.isDirectory() && before.dev === now.dev && before.ino === now.ino && before.mode === now.mode, "parent changed during read");
41152
+ need5(now.isDirectory() && before.dev === now.dev && before.ino === now.ino && before.mode === now.mode, "parent changed during read");
40880
41153
  }
40881
41154
  budget.remaining -= length;
40882
41155
  try {
@@ -40896,7 +41169,7 @@ function parse6(text2) {
40896
41169
  at++;
40897
41170
  };
40898
41171
  function string() {
40899
- need4(text2[at] === '"', "contains invalid JSON");
41172
+ need5(text2[at] === '"', "contains invalid JSON");
40900
41173
  const start = at++;
40901
41174
  while (at < text2.length) {
40902
41175
  const character = text2[at++];
@@ -40907,7 +41180,7 @@ function parse6(text2) {
40907
41180
  } catch {
40908
41181
  throw new Error("Claude marketplace registry contains invalid JSON string");
40909
41182
  }
40910
- need4(value2.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.stringCharacters, "exceeds its string limit");
41183
+ need5(value2.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.stringCharacters, "exceeds its string limit");
40911
41184
  return value2;
40912
41185
  }
40913
41186
  if (character === "\\")
@@ -40916,7 +41189,7 @@ function parse6(text2) {
40916
41189
  throw new Error("Claude marketplace registry contains an unterminated JSON string");
40917
41190
  }
40918
41191
  function value(depth) {
40919
- need4(depth <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.depth && ++nodes <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.nodes, "exceeds its nesting or node limit");
41192
+ need5(depth <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.depth && ++nodes <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.nodes, "exceeds its nesting or node limit");
40920
41193
  space();
40921
41194
  const character = text2[at];
40922
41195
  if (character === '"')
@@ -40930,17 +41203,17 @@ function parse6(text2) {
40930
41203
  if (object5) {
40931
41204
  space();
40932
41205
  const key = string();
40933
- need4(!keys2.has(key), "contains a duplicate JSON key");
41206
+ need5(!keys2.has(key), "contains a duplicate JSON key");
40934
41207
  keys2.add(key);
40935
41208
  space();
40936
- need4(text2[at++] === ":", "contains invalid JSON");
41209
+ need5(text2[at++] === ":", "contains invalid JSON");
40937
41210
  entries.push([key, value(depth + 1)]);
40938
41211
  } else
40939
41212
  items.push(value(depth + 1));
40940
41213
  space();
40941
41214
  if (text2[at] === end)
40942
41215
  break;
40943
- need4(text2[at++] === ",", "contains invalid JSON");
41216
+ need5(text2[at++] === ",", "contains invalid JSON");
40944
41217
  }
40945
41218
  at++;
40946
41219
  return object5 ? { kind: "object", entries } : { kind: "array", items };
@@ -40952,14 +41225,14 @@ function parse6(text2) {
40952
41225
  }
40953
41226
  numberPattern.lastIndex = at;
40954
41227
  const number = numberPattern.exec(text2);
40955
- need4(number, "contains invalid JSON");
41228
+ need5(number, "contains invalid JSON");
40956
41229
  at += number[0].length;
40957
41230
  return { kind: "number", value: number[0] };
40958
41231
  }
40959
41232
  const root2 = value(0);
40960
41233
  space();
40961
- need4(at === text2.length && root2.kind === "object", "requires a JSON object without trailing content");
40962
- need4(root2.entries.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.rows, "exceeds its marketplace row limit");
41234
+ need5(at === text2.length && root2.kind === "object", "requires a JSON object without trailing content");
41235
+ need5(root2.entries.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.rows, "exceeds its marketplace row limit");
40963
41236
  return root2;
40964
41237
  }
40965
41238
  function exactKeys2(value, keys2) {
@@ -40967,7 +41240,7 @@ function exactKeys2(value, keys2) {
40967
41240
  }
40968
41241
  var field = (object5, key) => object5.entries.find(([name]) => name === key)?.[1];
40969
41242
  function textField(value) {
40970
- need4(value?.kind === "string" && value.value.length > 0 && !/[\x00-\x1f\x7f]/.test(value.value), "contains an invalid recognized field");
41243
+ need5(value?.kind === "string" && value.value.length > 0 && !/[\x00-\x1f\x7f]/.test(value.value), "contains an invalid recognized field");
40971
41244
  return value.value;
40972
41245
  }
40973
41246
  function normalizeRow(row, version = 1) {
@@ -40975,7 +41248,7 @@ function normalizeRow(row, version = 1) {
40975
41248
  if (version !== 2 || !exactKeys2(row, ["source", "installLocation", "lastUpdated", "autoUpdate"]))
40976
41249
  return;
40977
41250
  const autoUpdate = field(row, "autoUpdate");
40978
- need4(autoUpdate?.kind === "literal" && (autoUpdate.value === "true" || autoUpdate.value === "false"), "contains an invalid automatic-update preference");
41251
+ need5(autoUpdate?.kind === "literal" && (autoUpdate.value === "true" || autoUpdate.value === "false"), "contains an invalid automatic-update preference");
40979
41252
  }
40980
41253
  const source = field(row, "source");
40981
41254
  if (source?.kind !== "object")
@@ -40991,34 +41264,34 @@ function normalizeRow(row, version = 1) {
40991
41264
  absolutePath3(sourceLocation);
40992
41265
  absolutePath3(textField(field(row, "installLocation")));
40993
41266
  const updated = textField(field(row, "lastUpdated"));
40994
- need4(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(updated), "contains an invalid recognized update timestamp");
41267
+ need5(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(updated), "contains an invalid recognized update timestamp");
40995
41268
  const millis = Date.parse(updated);
40996
- need4(Number.isFinite(millis) && new Date(millis).toISOString() === updated, "contains an invalid recognized update timestamp");
41269
+ need5(Number.isFinite(millis) && new Date(millis).toISOString() === updated, "contains an invalid recognized update timestamp");
40997
41270
  row.entries = row.entries.map(([key, value]) => [key, key === "lastUpdated" ? { kind: "validated-update-time" } : value]);
40998
41271
  }
40999
41272
  function captureClaudeMarketplaceRegistry(path, budget = { remaining: 256 * 1024 * 1024 }) {
41000
41273
  const value = parse6(readRegistry2(path, budget));
41001
41274
  for (const [, row] of value.entries)
41002
41275
  normalizeRow(row);
41003
- const sha2562 = createHash13("sha256").update("hasna.skills.claude-marketplace-registry.v1\x00").update(JSON.stringify(value)).digest("hex");
41276
+ const sha2562 = createHash14("sha256").update("hasna.skills.claude-marketplace-registry.v1\x00").update(JSON.stringify(value)).digest("hex");
41004
41277
  return { path, hashMode: "claude-marketplace-registry", sha256: sha2562 };
41005
41278
  }
41006
41279
  function captureClaudeMarketplaceRegistryV2(path, budget = { remaining: 256 * 1024 * 1024 }) {
41007
41280
  const value = parse6(readRegistry2(path, budget));
41008
41281
  for (const [, row] of value.entries)
41009
41282
  normalizeRow(row, 2);
41010
- const sha2562 = createHash13("sha256").update("hasna.skills.claude-marketplace-registry.v2\x00").update(JSON.stringify(value)).digest("hex");
41283
+ const sha2562 = createHash14("sha256").update("hasna.skills.claude-marketplace-registry.v2\x00").update(JSON.stringify(value)).digest("hex");
41011
41284
  return { path, hashMode: "claude-marketplace-registry-v2", sha256: sha2562 };
41012
41285
  }
41013
41286
 
41014
41287
  // src/lib/codex-hook-discovery-recovery.ts
41015
- import { createHash as createHash15 } from "crypto";
41288
+ import { createHash as createHash16 } from "crypto";
41016
41289
 
41017
41290
  // src/lib/codex-hook-trust-files.ts
41018
41291
  import { closeSync as closeSync15, constants as constants11, fstatSync as fstatSync15, fsyncSync as fsyncSync3, lstatSync as lstatSync17, openSync as openSync15, readSync as readSync10, writeFileSync as writeFileSync3 } from "fs";
41019
- import { createHash as createHash14 } from "crypto";
41292
+ import { createHash as createHash15 } from "crypto";
41020
41293
  import { dirname as dirname13 } from "path";
41021
- function need5(value, code) {
41294
+ function need6(value, code) {
41022
41295
  if (!value)
41023
41296
  throw new Error(`CODEX_HOOK_TRUST_${code}`);
41024
41297
  }
@@ -41026,8 +41299,8 @@ var sameStat = (a, b) => ["dev", "ino", "uid", "nlink", "mode", "size", "mtimeNs
41026
41299
  function safeParents(file) {
41027
41300
  for (let p = dirname13(file);; p = dirname13(p)) {
41028
41301
  const s = lstatSync17(p);
41029
- need5(s.isDirectory() && !s.isSymbolicLink(), "UNSAFE_PARENT");
41030
- need5((s.mode & 18) === 0 || s.uid === 0 && (s.mode & 512) !== 0, "UNSAFE_PARENT");
41302
+ need6(s.isDirectory() && !s.isSymbolicLink(), "UNSAFE_PARENT");
41303
+ need6((s.mode & 18) === 0 || s.uid === 0 && (s.mode & 512) !== 0, "UNSAFE_PARENT");
41031
41304
  if (dirname13(p) === p)
41032
41305
  break;
41033
41306
  }
@@ -41036,12 +41309,12 @@ function snapshot(file, privateFile = false, options = {}) {
41036
41309
  const readOnlyPackage = options.readOnlyPackage === true && !privateFile;
41037
41310
  safeParents(file);
41038
41311
  const initial = lstatSync17(file, { bigint: true });
41039
- need5(initial.isFile() && initial.uid === BigInt(process.getuid()) && (initial.nlink === 1n || readOnlyPackage && initial.nlink > 1n) && (initial.mode & 0o022n) === 0n && (!privateFile || (initial.mode & 0o777n) === 0o600n), "UNSAFE_FILE");
41040
- need5(initial.size <= 8n * 1024n * 1024n, "FILE_BOUND");
41312
+ need6(initial.isFile() && initial.uid === BigInt(process.getuid()) && (initial.nlink === 1n || readOnlyPackage && initial.nlink > 1n) && (initial.mode & 0o022n) === 0n && (!privateFile || (initial.mode & 0o777n) === 0o600n), "UNSAFE_FILE");
41313
+ need6(initial.size <= 8n * 1024n * 1024n, "FILE_BOUND");
41041
41314
  const fd = openSync15(file, constants11.O_RDONLY | constants11.O_NOFOLLOW | constants11.O_NONBLOCK);
41042
41315
  try {
41043
41316
  const before = fstatSync15(fd, { bigint: true });
41044
- need5(sameStat(initial, before), "INPUT_CHANGED");
41317
+ need6(sameStat(initial, before), "INPUT_CHANGED");
41045
41318
  const bytes = Buffer.alloc(Number(before.size) + 1);
41046
41319
  let length = 0;
41047
41320
  while (length < bytes.length) {
@@ -41050,16 +41323,16 @@ function snapshot(file, privateFile = false, options = {}) {
41050
41323
  break;
41051
41324
  length += n2;
41052
41325
  }
41053
- need5(length === Number(before.size) && sameStat(before, fstatSync15(fd, { bigint: true })) && sameStat(before, lstatSync17(file, { bigint: true })), "INPUT_CHANGED");
41326
+ need6(length === Number(before.size) && sameStat(before, fstatSync15(fd, { bigint: true })) && sameStat(before, lstatSync17(file, { bigint: true })), "INPUT_CHANGED");
41054
41327
  const content = bytes.subarray(0, length), text2 = new TextDecoder("utf-8", { fatal: true }).decode(content);
41055
- return { file, privateFile, readOnlyPackage, text: text2, bytes: content, stat: before, sha256: createHash14("sha256").update(content).digest("hex") };
41328
+ return { file, privateFile, readOnlyPackage, text: text2, bytes: content, stat: before, sha256: createHash15("sha256").update(content).digest("hex") };
41056
41329
  } finally {
41057
41330
  closeSync15(fd);
41058
41331
  }
41059
41332
  }
41060
41333
  function unchanged2(before) {
41061
41334
  const after = snapshot(before.file, before.privateFile, before.readOnlyPackage ? { readOnlyPackage: true } : {});
41062
- need5(sameStat(before.stat, after.stat) && after.sha256 === before.sha256, "INPUT_CHANGED");
41335
+ need6(sameStat(before.stat, after.stat) && after.sha256 === before.sha256, "INPUT_CHANGED");
41063
41336
  }
41064
41337
 
41065
41338
  // src/lib/codex-hook-additions-review.ts
@@ -41068,11 +41341,12 @@ var matchedEvents = { ...events, PreToolUse: ["preToolUse", "pre_tool_use"] };
41068
41341
  var proofs = new WeakMap;
41069
41342
 
41070
41343
  // src/lib/codex-hook-discovery-recovery.ts
41071
- var sha2 = (text2) => createHash15("sha256").update(text2).digest("hex");
41344
+ var sha3 = (text2) => createHash16("sha256").update(text2).digest("hex");
41345
+ var fields = [...CODEX_DISCOVERY_PROJECTION_FIELDS];
41072
41346
  var proofs2 = new WeakMap;
41073
41347
  function assertCodexHookDiscoveryRecovery(binding, witness) {
41074
41348
  const proof = proofs2.get(witness);
41075
- need5(!!proof && binding.agent === "codex" && witness.discoverySha256 === sha2(JSON.stringify(binding)), "RECONCILE_DISCOVERY_RECOVERY_CHANGED");
41349
+ need6(!!proof && binding.agent === "codex" && witness.discoverySha256 === sha3(JSON.stringify(binding)), "RECONCILE_DISCOVERY_RECOVERY_CHANGED");
41076
41350
  unchanged2(proof.before);
41077
41351
  unchanged2(proof.current);
41078
41352
  proof.recheckAdditions();
@@ -41081,12 +41355,12 @@ function verifiesCodexHookDiscoverySource(binding, source, currentDigest, witnes
41081
41355
  if (!witness || source.path !== witness.configPath || source.hashMode !== "bytes")
41082
41356
  return false;
41083
41357
  assertCodexHookDiscoveryRecovery(binding, witness);
41084
- need5(source.sha256 === witness.beforeSha256 && currentDigest === witness.currentSha256, "RECONCILE_DISCOVERY_RECOVERY_CHANGED");
41358
+ need6(source.sha256 === witness.beforeSha256 && currentDigest === witness.currentSha256, "RECONCILE_DISCOVERY_RECOVERY_CHANGED");
41085
41359
  return true;
41086
41360
  }
41087
41361
 
41088
41362
  // src/lib/agent-discovery.ts
41089
- var digest2 = (text2) => createHash16("sha256").update(text2).digest("hex");
41363
+ var digest2 = (text2) => createHash17("sha256").update(text2).digest("hex");
41090
41364
  function parseConfig(text2, path, toml = false) {
41091
41365
  try {
41092
41366
  const value = toml ? Bun.TOML.parse(text2) : JSON.parse(text2);
@@ -41118,14 +41392,26 @@ function read2(path, changes) {
41118
41392
  throw new Error(`Unsupported or oversized native discovery input: ${path}`);
41119
41393
  return readFileSync13(path, "utf8");
41120
41394
  }
41395
+ function projectNativeDiscoveryFields(text2, format, fields2, path) {
41396
+ const object5 = format === "yaml" ? parseHermesConfig(text2) : parseConfig(text2, path, format === "toml");
41397
+ if (!object5 || typeof object5 !== "object" || Array.isArray(object5))
41398
+ throw new Error("Expected native discovery configuration object");
41399
+ return digest2(JSON.stringify(Object.fromEntries(fields2.map((field2) => [field2, object5[field2] ?? null]))));
41400
+ }
41401
+ function isSupersededCodexProjection(agent, configPath, source) {
41402
+ return agent === "codex" && source.path === configPath && source.format === "toml" && isDeepStrictEqual3(source.fields, [...CODEX_DISCOVERY_PROJECTION_FIELDS]);
41403
+ }
41404
+ function supersedesCodexProjection(sources, configPath) {
41405
+ return sources.some((source) => source.path === configPath && source.hashMode === "codex-settings-v2");
41406
+ }
41121
41407
  function projected(source, changes, budget = discoveryByteBudget()) {
41122
- if (source.hashMode === "codex-settings-v1") {
41408
+ if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2") {
41123
41409
  if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
41124
41410
  throw new Error("Codex settings witnesses require exact typed metadata");
41125
- const current = captureCodexSettings(source.path, budget).sha256;
41411
+ const current = (source.hashMode === "codex-settings-v2" ? captureCodexSettingsV2 : captureCodexSettings)(source.path, budget).sha256;
41126
41412
  if (current !== source.sha256)
41127
41413
  throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
41128
- return changes?.has(source.path) ? hashCodexSettingsReplacement(changes.get(source.path), budget) : current;
41414
+ return changes?.has(source.path) ? (source.hashMode === "codex-settings-v2" ? hashCodexSettingsReplacementV2 : hashCodexSettingsReplacement)(changes.get(source.path), budget) : current;
41129
41415
  }
41130
41416
  if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") {
41131
41417
  if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
@@ -41164,10 +41450,7 @@ function projected(source, changes, budget = discoveryByteBudget()) {
41164
41450
  return null;
41165
41451
  if (!source.format)
41166
41452
  return digest2(text2);
41167
- const object5 = source.format === "yaml" ? parseHermesConfig(text2) : parseConfig(text2, source.path, source.format === "toml");
41168
- if (!object5 || typeof object5 !== "object" || Array.isArray(object5))
41169
- throw new Error("Expected native discovery configuration object");
41170
- return digest2(JSON.stringify(Object.fromEntries((source.fields ?? []).map((field2) => [field2, object5[field2] ?? null]))));
41453
+ return projectNativeDiscoveryFields(text2, source.format, source.fields ?? [], source.path);
41171
41454
  }
41172
41455
  function verifyAgentDiscovery(binding, codexRecovery) {
41173
41456
  if (codexRecovery)
@@ -41195,9 +41478,9 @@ function verifyAgentDiscovery(binding, codexRecovery) {
41195
41478
  safe4(root2);
41196
41479
  }
41197
41480
  function assertMarketplaceBinding(binding, source) {
41198
- if (source.hashMode === "codex-settings-v1" && (binding.agent !== "codex" || binding.method !== "reviewed" || basename6(source.path) !== "config.toml"))
41481
+ if ((source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2") && (binding.agent !== "codex" || binding.method !== "reviewed" || basename7(source.path) !== "config.toml"))
41199
41482
  throw new Error("Codex settings witnesses require explicit reviewed Codex configuration");
41200
- if ((source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") && (binding.agent !== "claude" || binding.method !== "reviewed" || basename6(source.path) !== "settings.json"))
41483
+ if ((source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") && (binding.agent !== "claude" || binding.method !== "reviewed" || basename7(source.path) !== "settings.json"))
41201
41484
  throw new Error("Claude settings witnesses require explicit reviewed Claude configuration");
41202
41485
  if ((source.hashMode === "claude-marketplace-registry" || source.hashMode === "claude-marketplace-registry-v2") && (binding.agent !== "claude" || binding.method !== "reviewed"))
41203
41486
  throw new Error("Claude marketplace witnesses require explicit reviewed Claude discovery");
@@ -41224,8 +41507,8 @@ function captureDiscoveryPathSources(paths) {
41224
41507
  const budget = discoveryByteBudget();
41225
41508
  return paths.map((path) => ({ path, hashMode: "path-bytes", sha256: hashDiscoveryPathFile(path, budget) }));
41226
41509
  }
41227
- function assertProjectDiscovery(agent, directories, home, canonical5 = resolve14, reviewed) {
41228
- const homeConfigPath = canonical5(agentDiscoveryConfigPath(home, agent));
41510
+ function assertProjectDiscovery(agent, directories, home, canonical6 = resolve14, reviewed) {
41511
+ const homeConfigPath = canonical6(agentDiscoveryConfigPath(home, agent));
41229
41512
  for (const directory of directories) {
41230
41513
  const isHome = resolve14(directory) === resolve14(home);
41231
41514
  if (agent === "hermes") {
@@ -41236,7 +41519,7 @@ function assertProjectDiscovery(agent, directories, home, canonical5 = resolve14
41236
41519
  continue;
41237
41520
  const paths = agent === "claude" ? [...isHome ? [] : [".claude/settings.json"], ".claude/settings.local.json"] : agent === "codex" ? [".codex/config.toml"] : agent === "gemini" ? [".gemini/settings.json"] : agent === "opencode" ? ["opencode.json", "opencode.jsonc", ".opencode/opencode.json", ".opencode/opencode.jsonc"] : [".cursor/hooks.json"];
41238
41521
  for (const suffix of paths) {
41239
- const path = canonical5(join21(directory, suffix)), raw = read2(path);
41522
+ const path = canonical6(join21(directory, suffix)), raw = read2(path);
41240
41523
  if (raw === null)
41241
41524
  continue;
41242
41525
  const isRootAliasedHomeConfig = agent === "claude" && suffix === ".claude/settings.json" || agent === "codex" && suffix === ".codex/config.toml";
@@ -41252,14 +41535,14 @@ function assertProjectDiscovery(agent, directories, home, canonical5 = resolve14
41252
41535
  const managed = reviewed.sources.flatMap((source) => source.hashMode === "claude-plugin-registry" ? source.managedPlugins ?? [] : []);
41253
41536
  if (exact && projected(exact) === exact.sha256 && managed.length) {
41254
41537
  const bindings = managed.map((item) => readPluginBinding(item.storeRoot, item.bindingId));
41255
- admittedPlugins = Object.entries(config.enabledPlugins).every(([id2, enabled]) => typeof enabled === "boolean" && bindings.some((binding) => binding.target.pluginId === id2 && binding.target.registrations.some((scope) => scope.scope === "project" && scope.projectPath === canonical5(directory))));
41538
+ admittedPlugins = Object.entries(config.enabledPlugins).every(([id2, enabled]) => typeof enabled === "boolean" && bindings.some((binding) => binding.target.pluginId === id2 && binding.target.registrations.some((scope) => scope.scope === "project" && scope.projectPath === canonical6(directory))));
41256
41539
  }
41257
41540
  }
41258
41541
  if (keys2.some((key) => config[key] !== undefined && !(key === "enabledPlugins" && admittedPlugins)) || config.disableAllHooks === true || config.disableBundledSkills === false || config.hooksConfig?.enabled === false || config.permission?.skill !== undefined || config.permissions?.deny?.some((rule) => typeof rule === "string" && /^Skill(?:\(|$)/.test(rule)))
41259
41542
  throw new Error(`NATIVE_SKILL_DRIFT: higher-precedence project skill or hook configuration requires review: ${path}`);
41260
41543
  }
41261
41544
  if (agent === "claude") {
41262
- const commands = canonical5(join21(directory, ".claude/commands"));
41545
+ const commands = canonical6(join21(directory, ".claude/commands"));
41263
41546
  safe4(commands);
41264
41547
  if (lstatSync18(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync7(commands).length)
41265
41548
  throw new Error("NATIVE_SKILL_DRIFT: legacy project command discovery requires a dedicated format adapter");
@@ -41270,10 +41553,10 @@ function agentDiscoveryConfigPath(home, agent) {
41270
41553
  return join21(home, agent === "hermes" ? ".hermes/config.yaml" : agent === "opencode" ? ".config/opencode/opencode.json" : `.${agent}/${agent === "codex" ? "config.toml" : agent === "cursor" ? "hooks.json" : "settings.json"}`);
41271
41554
  }
41272
41555
  function resolveAgentDiscovery(options) {
41273
- const canonical5 = options.canonical ?? resolve14, home = resolve14(options.home), agent = options.agent;
41556
+ const canonical6 = options.canonical ?? resolve14, home = resolve14(options.home), agent = options.agent;
41274
41557
  const sources = [], roots = new Set, builtinNames = [];
41275
- const witness = (path, format, fields) => {
41276
- const source = { path: canonical5(path), sha256: null, ...format ? { format, fields } : {} };
41558
+ const witness = (path, format, fields2) => {
41559
+ const source = { path: canonical6(path), sha256: null, ...format ? { format, fields: fields2 } : {} };
41277
41560
  source.sha256 = projected(source);
41278
41561
  sources.push(source);
41279
41562
  return read2(source.path);
@@ -41281,7 +41564,7 @@ function resolveAgentDiscovery(options) {
41281
41564
  if (agent === "hermes")
41282
41565
  assertHermesEnvironment(home);
41283
41566
  const configPath = agentDiscoveryConfigPath(home, agent);
41284
- const configText = witness(configPath, agent === "hermes" ? "yaml" : agent === "codex" ? "toml" : "json", agent === "hermes" ? ["skills", "plugins", "hooks"] : agent === "claude" ? ["enabledPlugins", "extraKnownMarketplaces"] : agent === "codex" ? ["plugins", "marketplaces", "skills"] : agent === "gemini" ? ["skills", "extensions", "security"] : agent === "opencode" ? ["plugin", "skills"] : ["version"]);
41567
+ const configText = witness(configPath, agent === "hermes" ? "yaml" : agent === "codex" ? "toml" : "json", agent === "hermes" ? ["skills", "plugins", "hooks"] : agent === "claude" ? ["enabledPlugins", "extraKnownMarketplaces"] : agent === "codex" ? [...CODEX_DISCOVERY_PROJECTION_FIELDS] : agent === "gemini" ? ["skills", "extensions", "security"] : agent === "opencode" ? ["plugin", "skills"] : ["version"]);
41285
41568
  const config = configText === null ? {} : agent === "hermes" ? parseHermesConfig(configText) : parseConfig(configText, configPath, agent === "codex");
41286
41569
  const unresolved = (detail) => {
41287
41570
  throw new Error(`Native discovery is unresolved (${agent}: ${detail}); provide a reviewed --discovery-inputs file`);
@@ -41340,11 +41623,12 @@ function resolveAgentDiscovery(options) {
41340
41623
  if (retained.agent !== agent || retained.method !== "reviewed")
41341
41624
  unresolved("invalid retained review");
41342
41625
  verifyAgentDiscovery(retained);
41343
- if (!retained.sources.some((source) => source.path === canonical5(configPath) && source.format === undefined && source.fields === undefined))
41626
+ if (!retained.sources.some((source) => source.path === canonical6(configPath) && source.format === undefined && source.fields === undefined))
41344
41627
  unresolved("retained review is missing the full agent configuration source");
41345
- if (retained.sources.some((source) => (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "codex-settings-v1")) && source.path !== canonical5(configPath)))
41628
+ if (retained.sources.some((source) => (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2"))) && source.path !== canonical6(configPath)))
41346
41629
  unresolved("retained settings witness names another configuration source");
41347
- if (sources.some((source) => !retained.sources.some((saved) => isDeepStrictEqual3(saved, source))) || [...roots].some((root2) => !retained.roots.includes(root2)) || agent === "gemini" && JSON.stringify(retained.builtinNames) !== JSON.stringify(builtinNames))
41630
+ const covered = supersedesCodexProjection(retained.sources, canonical6(configPath)) ? sources.filter((source) => !isSupersededCodexProjection(agent, canonical6(configPath), source)) : sources;
41631
+ if (covered.some((source) => !retained.sources.some((saved) => isDeepStrictEqual3(saved, source))) || [...roots].some((root2) => !retained.roots.includes(root2)) || agent === "gemini" && JSON.stringify(retained.builtinNames) !== JSON.stringify(builtinNames))
41348
41632
  unresolved("retained review is missing current runtime discovery coverage");
41349
41633
  return retained;
41350
41634
  }
@@ -41358,14 +41642,15 @@ function resolveAgentDiscovery(options) {
41358
41642
  if (review.sources.some((source) => source.format !== undefined || source.fields !== undefined))
41359
41643
  throw new Error("Explicit discovery reviews require full source-file hashes");
41360
41644
  verifyAgentDiscovery(supplied);
41361
- if (review.sources.some((source) => (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "codex-settings-v1")) && source.path !== canonical5(configPath)))
41645
+ if (review.sources.some((source) => (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2"))) && source.path !== canonical6(configPath)))
41362
41646
  throw new Error("Semantic settings witnesses must name the configured Claude configuration source");
41363
- if (!review.sources.some((source) => source.path === canonical5(configPath)))
41647
+ if (!review.sources.some((source) => source.path === canonical6(configPath)))
41364
41648
  throw new Error("Discovery review must include the agent configuration source");
41365
- return { ...supplied, roots: [...new Set([...roots, ...supplied.roots])].sort(), sources: [...sources, ...review.sources], ...agent === "gemini" ? { builtinNames } : {} };
41649
+ const reviewedSources = supersedesCodexProjection(review.sources, canonical6(configPath)) ? sources.filter((source) => !isSupersededCodexProjection(agent, canonical6(configPath), source)) : sources;
41650
+ return { ...supplied, roots: [...new Set([...roots, ...supplied.roots])].sort(), sources: [...reviewedSources, ...review.sources], ...agent === "gemini" ? { builtinNames } : {} };
41366
41651
  }
41367
41652
  function plugin(root2) {
41368
- root2 = canonical5(root2);
41653
+ root2 = canonical6(root2);
41369
41654
  safe4(root2);
41370
41655
  const manifestPath = join21(root2, agent === "claude" ? ".claude-plugin/plugin.json" : ".codex-plugin/plugin.json");
41371
41656
  const raw = witness(manifestPath);
@@ -41397,7 +41682,7 @@ function resolveAgentDiscovery(options) {
41397
41682
  if (agent === "claude") {
41398
41683
  const registrations = witness(join21(home, ".claude/plugins/installed_plugins.json"));
41399
41684
  const installed = registrations === null ? {} : parseConfig(registrations, join21(home, ".claude/plugins/installed_plugins.json")).plugins;
41400
- const commands = canonical5(join21(home, ".claude/commands"));
41685
+ const commands = canonical6(join21(home, ".claude/commands"));
41401
41686
  safe4(commands);
41402
41687
  if (lstatSync18(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync7(commands).length)
41403
41688
  unresolved("legacy home command discovery requires a dedicated format adapter");
@@ -41471,7 +41756,7 @@ function resolveAgentDiscovery(options) {
41471
41756
  roots.add(join21(root2, "skills"));
41472
41757
  }
41473
41758
  }
41474
- return { agent, roots: [...roots].sort(), sources, method: "automatic", ...agent === "gemini" ? { builtinNames } : {}, ...agent === "hermes" ? { directories: captureDiscoveryDirectories([join21(home, ".hermes/plugins"), join21(home, ".hermes/hermes-agent")].map((path) => canonical5(path))) } : {} };
41759
+ return { agent, roots: [...roots].sort(), sources, method: "automatic", ...agent === "gemini" ? { builtinNames } : {}, ...agent === "hermes" ? { directories: captureDiscoveryDirectories([join21(home, ".hermes/plugins"), join21(home, ".hermes/hermes-agent")].map((path) => canonical6(path))) } : {} };
41475
41760
  }
41476
41761
 
41477
41762
  // src/lib/agent-adapters.ts
@@ -41650,10 +41935,10 @@ function inlineRowsAsTables(value, newline) {
41650
41935
  for (const row of rows) {
41651
41936
  if (!row.startsWith("{") || !row.endsWith("}"))
41652
41937
  return null;
41653
- const fields = splitTopLevel(row.slice(1, -1), ",");
41654
- if (!fields)
41938
+ const fields2 = splitTopLevel(row.slice(1, -1), ",");
41939
+ if (!fields2)
41655
41940
  return null;
41656
- const lines = fields.map((field2) => field2.trim()).filter(Boolean);
41941
+ const lines = fields2.map((field2) => field2.trim()).filter(Boolean);
41657
41942
  if (lines.some((line) => !/^(?:path|name|enabled)\s*=/.test(line)))
41658
41943
  return null;
41659
41944
  const keys2 = lines.map((line) => line.slice(0, line.indexOf("=")).trim());
@@ -41809,7 +42094,7 @@ function disableCodexBundledSkills(text2) {
41809
42094
  }
41810
42095
 
41811
42096
  // src/lib/agent-integration.ts
41812
- var sha3 = (data) => createHash17("sha256").update(data).digest("hex");
42097
+ var sha4 = (data) => createHash18("sha256").update(data).digest("hex");
41813
42098
  var ROOTS = NATIVE_SKILL_ROOTS;
41814
42099
  function assertSafePath(path) {
41815
42100
  let cursor = resolve15(path);
@@ -41833,7 +42118,7 @@ function readRootAlias(home, agent) {
41833
42118
  const targetStat = lstatSync19(targetPath, { throwIfNoEntry: false });
41834
42119
  if (!targetStat?.isDirectory())
41835
42120
  throw new Error(`Agent root alias must target an existing directory: ${alias}`);
41836
- const target = realpathSync7(targetPath), inside = relative3(realHome, target);
42121
+ const target = realpathSync7(targetPath), inside = relative4(realHome, target);
41837
42122
  if (!inside || inside === ".." || inside.startsWith(`..${sep5}`) || isAbsolute17(inside))
41838
42123
  throw new Error(`Agent root alias target must be inside the real home: ${alias}`);
41839
42124
  return { agent, home: realHome, alias, target, link, aliasIdentity: `${stat2.dev}:${stat2.ino}:${stat2.ctimeNs}`, targetIdentity: `${targetStat.dev}:${targetStat.ino}` };
@@ -41851,7 +42136,7 @@ function rootAliases(home, allowed = false) {
41851
42136
  }
41852
42137
  function canonicalAgentPath(path, aliases) {
41853
42138
  const absolute = resolve15(path), binding = aliases.find((item) => absolute === item.alias || absolute.startsWith(item.alias + sep5));
41854
- return binding ? join22(binding.target, relative3(binding.alias, absolute)) : absolute;
42139
+ return binding ? join22(binding.target, relative4(binding.alias, absolute)) : absolute;
41855
42140
  }
41856
42141
  function disabledCodexSkillPaths(config, aliases) {
41857
42142
  const skills = config.skills;
@@ -41916,13 +42201,13 @@ function readNativeBytes(path, maximum = 64 * 1024 * 1024) {
41916
42201
  }
41917
42202
  }
41918
42203
  function treeHash(root2) {
41919
- const hash2 = createHash17("sha256");
42204
+ const hash2 = createHash18("sha256");
41920
42205
  let bytes = 0, files = 0;
41921
42206
  function visit2(path) {
41922
42207
  const stat2 = lstatSync19(path);
41923
42208
  if (stat2.isSymbolicLink())
41924
42209
  throw new Error(`Refusing symlink in skill: ${path}`);
41925
- const rel = relative3(root2, path);
42210
+ const rel = relative4(root2, path);
41926
42211
  if (stat2.isDirectory()) {
41927
42212
  hash2.update(`d\x00${rel}\x00`);
41928
42213
  for (const name of readdirSync8(path).sort())
@@ -41948,7 +42233,7 @@ function selectNativeMigrationTargets(inventory, manifest) {
41948
42233
  const identities = new Set;
41949
42234
  const selected = [];
41950
42235
  for (const target of manifest.targets) {
41951
- const projectRoot = resolve15(target.projectRoot), normalized = relative3(projectRoot, resolve15(projectRoot, target.path));
42236
+ const projectRoot = resolve15(target.projectRoot), normalized = relative4(projectRoot, resolve15(projectRoot, target.path));
41952
42237
  if (!isAbsolute17(target.projectRoot) || projectRoot !== target.projectRoot || !existsSync6(projectRoot) || !lstatSync19(projectRoot).isDirectory())
41953
42238
  throw new Error(`Native migration target project root must be an existing absolute directory: ${target.projectRoot}`);
41954
42239
  assertSafePath(projectRoot);
@@ -42301,9 +42586,9 @@ function planAgentIntegration(options) {
42301
42586
  const observedNativeSources = [];
42302
42587
  const codexPluginSkills = options.codexNativeCatalog ? reviewCodexPluginSkillControls(options.codexNativeCatalog, nativeSkills.filter((entry) => entry.agent === "codex" && entry.vendor).map((entry) => join22(entry.path, "SKILL.md")), canonicalAgentPath(join22(home, ".codex/plugins/cache"), aliases), resolve15(options.projectDir ?? home), (path) => {
42303
42588
  const bytes = readNativeBytes(path, 1024 * 1024);
42304
- observedNativeSources.push({ path, sha256: sha3(bytes) });
42589
+ observedNativeSources.push({ path, sha256: sha4(bytes) });
42305
42590
  return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
42306
- }) : policy.bridge?.codexPluginSkills ?? [];
42591
+ }, codexConfig.skills?.config ?? []) : policy.bridge?.codexPluginSkills ?? [];
42307
42592
  const changes = [];
42308
42593
  for (const agent of [...new Set(options.agents)]) {
42309
42594
  if (!INTEGRATION_AGENTS.includes(agent))
@@ -42329,7 +42614,7 @@ function planAgentIntegration(options) {
42329
42614
  throw new Error("Refusing to overwrite an unrecognized Hermes supervisor");
42330
42615
  if (supervisorBefore !== supervisorAfter)
42331
42616
  changes.push({ path: supervisorPath, before: supervisorBefore, after: supervisorAfter });
42332
- const supervisor = { path: supervisorPath, runtime: process.execPath, sha256: sha3(supervisorAfter) };
42617
+ const supervisor = { path: supervisorPath, runtime: process.execPath, sha256: sha4(supervisorAfter) };
42333
42618
  const after2 = configureHermesHooks(before, supervisor, previous);
42334
42619
  if (before !== after2)
42335
42620
  changes.push({ path, before, after: after2 });
@@ -42376,12 +42661,12 @@ function planAgentIntegration(options) {
42376
42661
  agents: [...new Set([...priorAgents, ...options.agents])].sort(),
42377
42662
  home: resolve15(home),
42378
42663
  includeVendor: true,
42379
- ...options.agents.includes("hermes") ? { supervisors: { ...policy.bridge?.supervisors, hermes: { path: join22(dataDir2, "agent-hooks", "hermes.js"), runtime: process.execPath, sha256: sha3(renderHermesSupervisor(bindings.get("hermes").command, bindings.get("hermes").profileId)) } } } : {},
42664
+ ...options.agents.includes("hermes") ? { supervisors: { ...policy.bridge?.supervisors, hermes: { path: join22(dataDir2, "agent-hooks", "hermes.js"), runtime: process.execPath, sha256: sha4(renderHermesSupervisor(bindings.get("hermes").command, bindings.get("hermes").profileId)) } } } : {},
42380
42665
  commands: { ...policy.bridge?.commands, ...Object.fromEntries([...bindings].map(([agent, binding]) => [agent, binding.command])) },
42381
42666
  profiles: Object.fromEntries([...new Set([...priorAgents, ...options.agents])].sort().map((agent) => [agent, bindings.get(agent)?.profileId ?? policy.bridge?.profiles?.[agent] ?? policy.profileId])),
42382
42667
  disabledBuiltins: options.agents.includes("codex") ? nativeSkills.filter((entry) => entry.agent === "codex" && entry.vendor && entry.path.startsWith(canonicalAgentPath(join22(home, ".codex", "skills", ".system"), aliases) + sep5)).map((entry) => ({ path: entry.path, hash: entry.hash })) : policy.bridge?.disabledBuiltins ?? [],
42383
42668
  rootAliases: aliases,
42384
- ...codexPluginSkills.length ? { codexPluginSkills, codexPluginSkillReview: options.codexNativeCatalog ? { version: options.codexNativeCatalog.version, cwd: options.codexNativeCatalog.cwd, catalogSha256: sha3(JSON.stringify({ version: options.codexNativeCatalog.version, cwd: options.codexNativeCatalog.cwd, skills: projectCodexNativeSkillCatalog({ data: [{ cwd: options.codexNativeCatalog.cwd, errors: [], skills: options.codexNativeCatalog.skills }] }, options.codexNativeCatalog.cwd) })), configSha256: changes.find((change) => change.path === canonicalAgentPath(join22(home, ".codex/config.toml"), aliases))?.before === null ? null : sha3(readOptional(canonicalAgentPath(join22(home, ".codex/config.toml"), aliases)) ?? "") } : policy.bridge?.codexPluginSkillReview } : {},
42669
+ ...codexPluginSkills.length ? { codexPluginSkills, codexPluginSkillReview: options.codexNativeCatalog ? { version: options.codexNativeCatalog.version, cwd: options.codexNativeCatalog.cwd, catalogSha256: sha4(JSON.stringify({ version: options.codexNativeCatalog.version, cwd: options.codexNativeCatalog.cwd, skills: projectCodexNativeSkillCatalog({ data: [{ cwd: options.codexNativeCatalog.cwd, errors: [], skills: options.codexNativeCatalog.skills }] }, options.codexNativeCatalog.cwd), ...options.codexNativeCatalog.plugins === undefined ? {} : { plugins: projectCodexInstalledPluginEntries(options.codexNativeCatalog.plugins) } })), configSha256: changes.find((change) => change.path === canonicalAgentPath(join22(home, ".codex/config.toml"), aliases))?.before === null ? null : sha4(readOptional(canonicalAgentPath(join22(home, ".codex/config.toml"), aliases)) ?? "") } : policy.bridge?.codexPluginSkillReview } : {},
42385
42670
  discovery: { ...policy.bridge?.discovery, ...Object.fromEntries(discoveryAfter.map((binding) => [binding.agent, binding])) }
42386
42671
  } };
42387
42672
  const serializedPolicy = serializeManagedSkillPolicy(nextPolicy);
@@ -42397,12 +42682,12 @@ function planClaudePreToolUseHookUpdate(options) {
42397
42682
  return planClaudeHookEventsUpdate({ ...options, events: ["PreToolUse"] });
42398
42683
  }
42399
42684
  function claudeSettingsConsumers(home, path, discoveries, aliases) {
42400
- const canonical5 = (value) => canonicalAgentPath(value, aliases);
42685
+ const canonical6 = (value) => canonicalAgentPath(value, aliases);
42401
42686
  const containsSettings = (root2) => {
42402
- const distance = relative3(canonical5(root2), path);
42687
+ const distance = relative4(canonical6(root2), path);
42403
42688
  return distance === "" || distance !== ".." && !distance.startsWith(`..${sep5}`) && !isAbsolute17(distance);
42404
42689
  };
42405
- return discoveries.filter((binding) => binding.agent === "claude" || binding.agent === "opencode" || canonical5(join22(home, AGENT_ADAPTERS[binding.agent].config)) === path || binding.sources.some((source) => canonical5(source.path) === path) || binding.roots.some(containsSettings) || binding.directories?.some((directory) => containsSettings(directory.path))).map((binding) => binding.agent);
42690
+ return discoveries.filter((binding) => binding.agent === "claude" || binding.agent === "opencode" || canonical6(join22(home, AGENT_ADAPTERS[binding.agent].config)) === path || binding.sources.some((source) => canonical6(source.path) === path) || binding.roots.some(containsSettings) || binding.directories?.some((directory) => containsSettings(directory.path))).map((binding) => binding.agent);
42406
42691
  }
42407
42692
  function verifyCoordinatedDiscovery(binding, home, aliases) {
42408
42693
  try {
@@ -42434,7 +42719,7 @@ function planClaudeHookEventsUpdate(options) {
42434
42719
  const path = canonicalAgentPath(join22(home, ".claude", "settings.json"), aliases);
42435
42720
  assertSafePath(path);
42436
42721
  const before = lstatSync19(path, { throwIfNoEntry: false }) ? new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(readNativeBytes(path, 1024 * 1024)) : null;
42437
- if ((before === null ? "absent" : sha3(before)) !== options.expectedSettingsSha256)
42722
+ if ((before === null ? "absent" : sha4(before)) !== options.expectedSettingsSha256)
42438
42723
  throw new Error("Claude settings preimage changed");
42439
42724
  assertClaudeHookEventsReplacement(before, options.replacement, options.events);
42440
42725
  const agents = bridge.agents;
@@ -42500,7 +42785,7 @@ function atomicWrite2(path, content) {
42500
42785
  function planAgentSettingsWitnessUpgrade(options) {
42501
42786
  const home = resolve15(options.home ?? homedir3()), dataDir2 = options.dataDir ?? getDataDirReadOnly();
42502
42787
  const snapshot2 = readManagedSkillPolicySnapshot(dataDir2);
42503
- if (!snapshot2 || sha3(snapshot2.text) !== options.expectedPolicySha256)
42788
+ if (!snapshot2 || sha4(snapshot2.text) !== options.expectedPolicySha256)
42504
42789
  throw new Error("Managed policy preimage changed");
42505
42790
  const policy = snapshot2.value, aliases = policy.bridge?.rootAliases ?? [];
42506
42791
  recheckRootAliases(aliases);
@@ -42509,7 +42794,7 @@ function planAgentSettingsWitnessUpgrade(options) {
42509
42794
  throw new Error("Settings witness upgrade requires an existing reviewed native binding");
42510
42795
  const configPath = canonicalAgentPath(join22(home, options.agent === "claude" ? ".claude/settings.json" : ".codex/config.toml"), aliases);
42511
42796
  const settings = readOptional(configPath);
42512
- if (settings === null || sha3(settings) !== options.expectedSettingsSha256)
42797
+ if (settings === null || sha4(settings) !== options.expectedSettingsSha256)
42513
42798
  throw new Error("Native settings preimage changed");
42514
42799
  const sources = binding.sources.filter((source) => source.path === configPath && source.format === undefined && source.fields === undefined);
42515
42800
  if (sources.length !== 1)
@@ -42517,15 +42802,40 @@ function planAgentSettingsWitnessUpgrade(options) {
42517
42802
  const previous = sources[0];
42518
42803
  if (typeof previous.sha256 !== "string")
42519
42804
  throw new Error("Settings witness upgrade requires a preserved settings preimage");
42805
+ const replaced = [previous];
42806
+ if (options.agent === "codex") {
42807
+ if (previous.hashMode !== undefined && previous.hashMode !== "bytes" && previous.hashMode !== "codex-settings-v1")
42808
+ throw new Error("Codex settings witness upgrade requires a preserved raw or codex-settings-v1 configuration witness");
42809
+ const preimage = readCodexSettingsPreimage(options.reviewedPreimage);
42810
+ for (const source of binding.sources) {
42811
+ if (source === previous || source.path !== configPath)
42812
+ continue;
42813
+ const fields2 = source.fields;
42814
+ if (source.hashMode !== undefined || source.format !== "toml" || !Array.isArray(fields2) || !isDeepStrictEqual5(fields2, [...CODEX_DISCOVERY_PROJECTION_FIELDS]) || typeof source.sha256 !== "string")
42815
+ throw new Error("Codex settings witness upgrade found an unrecognized configuration witness");
42816
+ if (projectNativeDiscoveryFields(preimage, "toml", fields2, configPath) !== source.sha256)
42817
+ throw new Error("Reviewed preimage does not explain the Codex discovery projection witness");
42818
+ replaced.push(source);
42819
+ }
42820
+ }
42520
42821
  const next = options.agent === "claude" ? upgradeClaudeSettingsWitness(previous, options.reviewedPreimage) : upgradeCodexSettingsWitness(previous, options.reviewedPreimage);
42521
- const replacement = { ...binding, sources: binding.sources.map((source) => source === previous ? next : source) };
42822
+ const rebound = [];
42823
+ for (const source of binding.sources) {
42824
+ if (!replaced.includes(source)) {
42825
+ rebound.push(source);
42826
+ continue;
42827
+ }
42828
+ if (source === replaced[0])
42829
+ rebound.push(next);
42830
+ }
42831
+ const replacement = { ...binding, sources: rebound };
42522
42832
  verifyAgentDiscovery(replacement);
42523
42833
  const after = serializeManagedSkillPolicy({ ...policy, bridge: { ...policy.bridge, discovery: { ...policy.bridge.discovery, [options.agent]: replacement } } });
42524
- return { dataDir: dataDir2, profileId: policy.profileId, changes: [{ path: join22(dataDir2, "agent-policy.json"), before: snapshot2.text, after }], nativeSkills: [], observedPolicy: { path: join22(dataDir2, "agent-policy.json"), before: snapshot2.text }, observedSettings: { path: configPath, before: settings }, discoveryBefore: [replacement], discoveryAfter: [replacement], rootAliases: aliases, managedAgentChecks: { home, agents: [options.agent] }, settingsWitnessUpgrade: { agent: options.agent, path: configPath, fromHashMode: previous.hashMode ?? "bytes", fromSha256: previous.sha256, toHashMode: next.hashMode, toSha256: next.sha256, reviewedPreimage: options.reviewedPreimage, currentSettingsSha256: options.expectedSettingsSha256 } };
42834
+ return { dataDir: dataDir2, profileId: policy.profileId, changes: [{ path: join22(dataDir2, "agent-policy.json"), before: snapshot2.text, after }], nativeSkills: [], observedPolicy: { path: join22(dataDir2, "agent-policy.json"), before: snapshot2.text }, observedSettings: { path: configPath, before: settings }, discoveryBefore: [replacement], discoveryAfter: [replacement], rootAliases: aliases, managedAgentChecks: { home, agents: [options.agent] }, settingsWitnessUpgrade: { agent: options.agent, path: configPath, fromHashMode: previous.hashMode ?? "bytes", fromSha256: previous.sha256, toHashMode: next.hashMode, toSha256: next.sha256, reviewedPreimage: options.reviewedPreimage, currentSettingsSha256: options.expectedSettingsSha256, replacedWitnesses: replaced.map((source) => ({ hashMode: source.hashMode ?? "bytes", sha256: source.sha256 })) } };
42525
42835
  }
42526
42836
  function applyAgentIntegration(plan) {
42527
42837
  for (const source of plan.observedNativeSources ?? [])
42528
- if (sha3(readNativeBytes(source.path, 1024 * 1024)) !== source.sha256)
42838
+ if (sha4(readNativeBytes(source.path, 1024 * 1024)) !== source.sha256)
42529
42839
  throw new Error("Native identity source changed after planning");
42530
42840
  if (plan.observedSettings && readOptional(plan.observedSettings.path) !== plan.observedSettings.before)
42531
42841
  throw new Error("Native settings changed after witness planning");
@@ -42545,7 +42855,7 @@ function applyAgentIntegration(plan) {
42545
42855
  const upgrade = plan.settingsWitnessUpgrade;
42546
42856
  if (!plan.managedAgentChecks || !plan.observedPolicy?.before)
42547
42857
  throw new Error("Invalid settings witness upgrade plan");
42548
- const verified = planAgentSettingsWitnessUpgrade({ agent: upgrade.agent, reviewedPreimage: upgrade.reviewedPreimage, home: plan.managedAgentChecks.home, dataDir: plan.dataDir, expectedPolicySha256: sha3(plan.observedPolicy.before), expectedSettingsSha256: upgrade.currentSettingsSha256 });
42858
+ const verified = planAgentSettingsWitnessUpgrade({ agent: upgrade.agent, reviewedPreimage: upgrade.reviewedPreimage, home: plan.managedAgentChecks.home, dataDir: plan.dataDir, expectedPolicySha256: sha4(plan.observedPolicy.before), expectedSettingsSha256: upgrade.currentSettingsSha256 });
42549
42859
  if (JSON.stringify(verified.changes) !== JSON.stringify(plan.changes) || JSON.stringify(verified.settingsWitnessUpgrade) !== JSON.stringify(upgrade))
42550
42860
  throw new Error("Settings witness upgrade plan changed");
42551
42861
  provenDiscovery = verified.discoveryBefore[0];
@@ -42573,7 +42883,7 @@ function applyAgentIntegration(plan) {
42573
42883
  chmodSync(backupRoot, 448);
42574
42884
  for (const [index, change] of plan.changes.entries())
42575
42885
  if (change.before !== null) {
42576
- const backup = join22(backupRoot, `${index}-${sha3(change.path).slice(0, 12)}.backup`);
42886
+ const backup = join22(backupRoot, `${index}-${sha4(change.path).slice(0, 12)}.backup`);
42577
42887
  writeFileSync4(backup, change.before, { mode: 384, flag: "wx" });
42578
42888
  if (readFileSync14(backup, "utf8") !== change.before)
42579
42889
  throw new Error("Native configuration preservation readback failed");
@@ -42592,7 +42902,7 @@ function applyAgentIntegration(plan) {
42592
42902
  }
42593
42903
  recheckRootAliases(aliases);
42594
42904
  for (const source of plan.observedNativeSources ?? [])
42595
- if (sha3(readNativeBytes(source.path, 1024 * 1024)) !== source.sha256)
42905
+ if (sha4(readNativeBytes(source.path, 1024 * 1024)) !== source.sha256)
42596
42906
  throw new Error("Native identity source changed during application");
42597
42907
  if (plan.observedSettings && readOptional(plan.observedSettings.path) !== plan.observedSettings.before)
42598
42908
  throw new Error("Native settings changed during witness application");
@@ -42604,7 +42914,7 @@ function applyAgentIntegration(plan) {
42604
42914
  }
42605
42915
  for (const agent of plan.managedAgentChecks?.agents ?? [])
42606
42916
  assertManagedAgentBridge(agent, { home: plan.managedAgentChecks.home, dataDir: plan.dataDir, projectDir: plan.managedAgentChecks.home });
42607
- atomicWrite2(join22(backupRoot, "receipt.json"), JSON.stringify({ version: 1, changes: written.map((change) => ({ path: change.path, beforeHash: change.before === null ? null : sha3(change.before), afterHash: sha3(change.after) })), backups, ...aliases.length ? { rootAliases: aliases } : {} }) + `
42917
+ atomicWrite2(join22(backupRoot, "receipt.json"), JSON.stringify({ version: 1, changes: written.map((change) => ({ path: change.path, beforeHash: change.before === null ? null : sha4(change.before), afterHash: sha4(change.after) })), backups, ...aliases.length ? { rootAliases: aliases } : {} }) + `
42608
42918
  `);
42609
42919
  } catch (error) {
42610
42920
  for (const change of written.reverse()) {
@@ -42683,8 +42993,8 @@ function archiveNativeSkills(inventory, options) {
42683
42993
  const operationId = randomUUID3(), archiveRoot = join22(options.dataDir ?? getDataDir(), "migration", operationId, "native"), receiptPath = join22(archiveRoot, "receipt.json");
42684
42994
  const entries = selected.map((entry, index) => ({
42685
42995
  source: entry.vendor ? join22(entry.path, "SKILL.md") : entry.path,
42686
- archive: join22(archiveRoot, `${index}-${sha3(entry.path).slice(0, 12)}`),
42687
- hash: entry.vendor ? sha3(readNativeBytes(join22(entry.path, "SKILL.md"))) : entry.hash,
42996
+ archive: join22(archiveRoot, `${index}-${sha4(entry.path).slice(0, 12)}`),
42997
+ hash: entry.vendor ? sha4(readNativeBytes(join22(entry.path, "SKILL.md"))) : entry.hash,
42688
42998
  ...entry.vendor ? { discoveryOnly: true } : {},
42689
42999
  status: "planned"
42690
43000
  }));
@@ -42695,7 +43005,7 @@ function archiveNativeSkills(inventory, options) {
42695
43005
  const stat2 = lstatSync19(entry.archive);
42696
43006
  if (entry.discoveryOnly ? !stat2.isFile() : !stat2.isDirectory())
42697
43007
  throw new Error("Archive type changed");
42698
- if ((entry.discoveryOnly ? sha3(readNativeBytes(entry.archive)) : treeHash(entry.archive)) !== entry.hash)
43008
+ if ((entry.discoveryOnly ? sha4(readNativeBytes(entry.archive)) : treeHash(entry.archive)) !== entry.hash)
42699
43009
  throw new Error("Archive bytes changed");
42700
43010
  };
42701
43011
  assertSafePath(archiveRoot);
@@ -42815,7 +43125,7 @@ function assertManagedAgentBridgeWithDiscovery(agent, options = {}, provenDiscov
42815
43125
  throw new Error("NATIVE_SKILL_DRIFT: the hook selection profile differs from its managed binding; restart the native client after reviewing skills hook install");
42816
43126
  if (agent === "hermes") {
42817
43127
  const supervisor = binding.supervisors?.hermes;
42818
- if (supervisor?.path !== join22(dataDir2, "agent-hooks", "hermes.js") || supervisor?.sha256 !== sha3(renderHermesSupervisor(command, profile)))
43128
+ if (supervisor?.path !== join22(dataDir2, "agent-hooks", "hermes.js") || supervisor?.sha256 !== sha4(renderHermesSupervisor(command, profile)))
42819
43129
  throw new Error("NATIVE_SKILL_DRIFT: Hermes supervisor binding changed; run skills hook install");
42820
43130
  assertHermesProtection(home, config, command, profile, supervisor);
42821
43131
  } else if (agent === "opencode") {
@@ -42913,13 +43223,13 @@ import {
42913
43223
  statSync as statSync9,
42914
43224
  writeFileSync as writeFileSync6
42915
43225
  } from "fs";
42916
- import { basename as basename9, dirname as dirname18, isAbsolute as isAbsolute18, join as join26, normalize as normalize3, relative as relative5, resolve as resolve17, sep as sep8 } from "path";
43226
+ import { basename as basename10, dirname as dirname18, isAbsolute as isAbsolute18, join as join26, normalize as normalize4, relative as relative6, resolve as resolve17, sep as sep8 } from "path";
42917
43227
 
42918
43228
  // src/lib/registry-data/index.ts
42919
43229
  var SKILLS = [];
42920
43230
 
42921
43231
  // src/lib/skill-hash.ts
42922
- import { createHash as createHash18 } from "crypto";
43232
+ import { createHash as createHash19 } from "crypto";
42923
43233
  import { existsSync as existsSync7, readdirSync as readdirSync9, readFileSync as readFileSync15, statSync as statSync7 } from "fs";
42924
43234
  import { join as join23, sep as sep6 } from "path";
42925
43235
  var CONTENT_HASH_ALGORITHM = "sha256";
@@ -43043,13 +43353,13 @@ function* bundleHashParts(files) {
43043
43353
  yield new TextEncoder().encode("\x00");
43044
43354
  }
43045
43355
  function hashBundleFiles(files) {
43046
- const hash2 = createHash18(CONTENT_HASH_ALGORITHM);
43356
+ const hash2 = createHash19(CONTENT_HASH_ALGORITHM);
43047
43357
  for (const part of bundleHashParts(files))
43048
43358
  hash2.update(part);
43049
43359
  return hash2.digest("hex");
43050
43360
  }
43051
43361
  async function hashBundleFilesCooperatively(files, check) {
43052
- const hash2 = createHash18(CONTENT_HASH_ALGORITHM);
43362
+ const hash2 = createHash19(CONTENT_HASH_ALGORITHM);
43053
43363
  let bytesSinceYield = 0;
43054
43364
  for (const part of bundleHashParts(files)) {
43055
43365
  for (let offset = 0;offset < part.byteLength; offset += 64 * 1024) {
@@ -43307,7 +43617,7 @@ var MAX_RUNTIME_TIMEOUT_SECONDS = 900;
43307
43617
  function add2(target, code, message) {
43308
43618
  target.push({ code, message });
43309
43619
  }
43310
- function isRecord(value) {
43620
+ function isRecord2(value) {
43311
43621
  return typeof value === "object" && value !== null && !Array.isArray(value);
43312
43622
  }
43313
43623
  function isNonEmptyString(value) {
@@ -43335,7 +43645,7 @@ function validatePortableManifestContract(manifest, options = {}) {
43335
43645
  }
43336
43646
  validateRuntimeContract(manifest, issues, options.strict === true);
43337
43647
  const provenance = manifest.provenance;
43338
- if (provenance && !isRecord(provenance)) {
43648
+ if (provenance && !isRecord2(provenance)) {
43339
43649
  add2(issues, "contract.provenance_invalid", "provenance must be an object");
43340
43650
  } else {
43341
43651
  const sourceCommit = provenance?.source_commit;
@@ -43368,7 +43678,7 @@ function validateRuntimeContract(manifest, issues, strict) {
43368
43678
  }
43369
43679
  return;
43370
43680
  }
43371
- if (!isRecord(runtime)) {
43681
+ if (!isRecord2(runtime)) {
43372
43682
  add2(issues, "contract.runtime_invalid", "runtime must be an object");
43373
43683
  return;
43374
43684
  }
@@ -43438,7 +43748,7 @@ import {
43438
43748
  realpathSync as realpathSync8,
43439
43749
  writeFileSync as writeFileSync5
43440
43750
  } from "fs";
43441
- import { basename as basename7, dirname as dirname16, join as join24, relative as relative4 } from "path";
43751
+ import { basename as basename8, dirname as dirname16, join as join24, relative as relative5 } from "path";
43442
43752
  var ANY_SEGMENT_COPY_EXCLUDES = new Set([
43443
43753
  ".git",
43444
43754
  ".DS_Store",
@@ -43488,11 +43798,11 @@ function normalizeNewPortableSkillName(name) {
43488
43798
  throw new Error(`Invalid skill name '${name}'. Include letters or numbers.`);
43489
43799
  return normalized;
43490
43800
  }
43491
- function readPortableSkillManifest(skillPath, fallbackName = basename7(skillPath)) {
43801
+ function readPortableSkillManifest(skillPath, fallbackName = basename8(skillPath)) {
43492
43802
  return readManifest(skillPath, fallbackName, normalizePortableSkillName);
43493
43803
  }
43494
43804
  function readPortableSkillManifestForImport(skillPath) {
43495
- return readManifest(skillPath, basename7(skillPath), normalizeNewPortableSkillName);
43805
+ return readManifest(skillPath, basename8(skillPath), normalizeNewPortableSkillName);
43496
43806
  }
43497
43807
  function readManifest(skillPath, fallbackName, normalizeName) {
43498
43808
  const skillJsonPath = join24(skillPath, "skill.json");
@@ -43655,7 +43965,7 @@ function readExistingSkillJson(skillPath) {
43655
43965
  return {};
43656
43966
  try {
43657
43967
  const parsed = JSON.parse(readFileSync16(path, "utf-8"));
43658
- return isRecord2(parsed) ? parsed : {};
43968
+ return isRecord3(parsed) ? parsed : {};
43659
43969
  } catch {
43660
43970
  return {};
43661
43971
  }
@@ -43711,7 +44021,7 @@ function ensurePackageJson(skillPath, manifest) {
43711
44021
  }
43712
44022
  const existing = readJsonObject(pkgPath);
43713
44023
  const bin = {};
43714
- if (isRecord2(existing.bin)) {
44024
+ if (isRecord3(existing.bin)) {
43715
44025
  for (const [name, value] of Object.entries(existing.bin)) {
43716
44026
  if (typeof value === "string" && value.trim())
43717
44027
  bin[normalizePortableSkillName(name)] = value.replace(/^\.\//, "");
@@ -43722,7 +44032,7 @@ function ensurePackageJson(skillPath, manifest) {
43722
44032
  bin[manifest.name] = binEntry.replace(/^\.\//, "");
43723
44033
  }
43724
44034
  bin[commandName] = entry;
43725
- const scripts = isRecord2(existing.scripts) ? { ...existing.scripts } : {};
44035
+ const scripts = isRecord3(existing.scripts) ? { ...existing.scripts } : {};
43726
44036
  if (!stringValue(scripts.dev))
43727
44037
  scripts.dev = `bun run ${entry}`;
43728
44038
  writeFileSync5(pkgPath, `${JSON.stringify({
@@ -43795,7 +44105,7 @@ function copySkillDirectory(source, destination) {
43795
44105
  cpSync(resolvedSource, destination, {
43796
44106
  recursive: true,
43797
44107
  filter: (src) => {
43798
- const rel = relative4(resolvedSource, src);
44108
+ const rel = relative5(resolvedSource, src);
43799
44109
  if (!rel)
43800
44110
  return true;
43801
44111
  const segments = rel.split(/[\\/]/);
@@ -43943,7 +44253,7 @@ function parseManifestCommands(value) {
43943
44253
  if (!Array.isArray(raw))
43944
44254
  return;
43945
44255
  const commands = raw.map((item) => {
43946
- if (!isRecord2(item))
44256
+ if (!isRecord3(item))
43947
44257
  return null;
43948
44258
  const name = stringValue(item.name);
43949
44259
  if (!name)
@@ -43960,7 +44270,7 @@ function parseManifestCommands(value) {
43960
44270
  }
43961
44271
  function parseManifestRuntime(value) {
43962
44272
  const raw = value?.runtime;
43963
- if (!isRecord2(raw))
44273
+ if (!isRecord3(raw))
43964
44274
  return;
43965
44275
  const runtimeName = stringValue(raw.runtime);
43966
44276
  if (!runtimeName)
@@ -43986,7 +44296,7 @@ function parseManifestRuntime(value) {
43986
44296
  }
43987
44297
  function parseManifestProvenance(value) {
43988
44298
  const raw = value?.provenance;
43989
- if (!isRecord2(raw))
44299
+ if (!isRecord3(raw))
43990
44300
  return;
43991
44301
  const parsed = {};
43992
44302
  if (stringValue(raw.source_commit))
@@ -44002,7 +44312,7 @@ function parseManifestInputs(value) {
44002
44312
  if (!Array.isArray(raw))
44003
44313
  return;
44004
44314
  const inputs = raw.map((item) => {
44005
- if (!isRecord2(item))
44315
+ if (!isRecord3(item))
44006
44316
  return null;
44007
44317
  const name = stringValue(item.name);
44008
44318
  const type = stringValue(item.type);
@@ -44020,7 +44330,7 @@ function parseManifestInputs(value) {
44020
44330
  function inferPackageCommands(pkg, fallbackName) {
44021
44331
  if (!pkg)
44022
44332
  return;
44023
- if (isRecord2(pkg.bin)) {
44333
+ if (isRecord3(pkg.bin)) {
44024
44334
  const commands = Object.entries(pkg.bin).filter((entry) => typeof entry[1] === "string" && entry[1].trim().length > 0).map(([name, entry]) => ({
44025
44335
  name: normalizePortableSkillName(name),
44026
44336
  entry: entry.replace(/^\.\//, ""),
@@ -44029,7 +44339,7 @@ function inferPackageCommands(pkg, fallbackName) {
44029
44339
  if (commands.length)
44030
44340
  return commands;
44031
44341
  }
44032
- const scripts = isRecord2(pkg.scripts) ? pkg.scripts : undefined;
44342
+ const scripts = isRecord3(pkg.scripts) ? pkg.scripts : undefined;
44033
44343
  const dev = stringValue(scripts?.dev);
44034
44344
  const match = dev?.match(/(?:bun\s+run\s+|bun\s+)([^ ]+)/);
44035
44345
  if (match?.[1]) {
@@ -44045,20 +44355,20 @@ function inferRuntimeFromCommands(commands) {
44045
44355
  }
44046
44356
  function readJsonObject(path) {
44047
44357
  const parsed = JSON.parse(readFileSync16(path, "utf-8"));
44048
- if (!isRecord2(parsed))
44049
- throw new Error(`${basename7(path)} must contain a JSON object`);
44358
+ if (!isRecord3(parsed))
44359
+ throw new Error(`${basename8(path)} must contain a JSON object`);
44050
44360
  return parsed;
44051
44361
  }
44052
44362
  function hasPackageDependencies(pkgPath) {
44053
44363
  try {
44054
44364
  const pkg = readJsonObject(pkgPath);
44055
- const deps = isRecord2(pkg.dependencies) ? Object.keys(pkg.dependencies) : [];
44365
+ const deps = isRecord3(pkg.dependencies) ? Object.keys(pkg.dependencies) : [];
44056
44366
  return deps.length > 0;
44057
44367
  } catch {
44058
44368
  return false;
44059
44369
  }
44060
44370
  }
44061
- function isRecord2(value) {
44371
+ function isRecord3(value) {
44062
44372
  return typeof value === "object" && value !== null && !Array.isArray(value);
44063
44373
  }
44064
44374
  function stringField(value, key) {
@@ -44084,7 +44394,7 @@ function escapeJsString(value) {
44084
44394
  // src/lib/authoring-path.ts
44085
44395
  import { lstatSync as lstatSync21, realpathSync as realpathSync9 } from "fs";
44086
44396
  import { homedir as homedir4 } from "os";
44087
- import { basename as basename8, dirname as dirname17, join as join25, resolve as resolve16, sep as sep7 } from "path";
44397
+ import { basename as basename9, dirname as dirname17, join as join25, resolve as resolve16, sep as sep7 } from "path";
44088
44398
  var NATIVE_DISCOVERY_ROOTS = NATIVE_SKILL_ROOTS.map(([, path]) => path.split("/"));
44089
44399
  function pathParts(path) {
44090
44400
  return resolve16(path).split(sep7).filter(Boolean);
@@ -44104,7 +44414,7 @@ function physicalPath(path) {
44104
44414
  let cursor = resolve16(path);
44105
44415
  const suffix = [];
44106
44416
  while (!lstatSync21(cursor, { throwIfNoEntry: false })) {
44107
- suffix.unshift(basename8(cursor));
44417
+ suffix.unshift(basename9(cursor));
44108
44418
  const parent = dirname17(cursor);
44109
44419
  if (parent === cursor)
44110
44420
  return resolve16(path);
@@ -44273,7 +44583,7 @@ function scaffoldPortableSkill(name, options = {}) {
44273
44583
  return { name: skillName, path: skillPath, manifest, created: true };
44274
44584
  }
44275
44585
  function portPortableSkillDirectory(sourceDir, options = {}) {
44276
- const absoluteSource = normalize3(sourceDir);
44586
+ const absoluteSource = normalize4(sourceDir);
44277
44587
  if (!existsSync9(absoluteSource) || !statSync9(absoluteSource).isDirectory()) {
44278
44588
  throw new Error(`Import directory not found: ${sourceDir}`);
44279
44589
  }
@@ -44323,7 +44633,7 @@ function physicalImportPath(path) {
44323
44633
  let ancestor = resolve17(path);
44324
44634
  const suffix = [];
44325
44635
  while (!existsSync9(ancestor)) {
44326
- suffix.unshift(basename9(ancestor));
44636
+ suffix.unshift(basename10(ancestor));
44327
44637
  ancestor = dirname18(ancestor);
44328
44638
  }
44329
44639
  return join26(realpathSync10(ancestor), ...suffix);
@@ -44332,7 +44642,7 @@ function assertDisjointImportPaths(source, destination) {
44332
44642
  const sourcePath = realpathSync10(source);
44333
44643
  const destinationPath = physicalImportPath(destination);
44334
44644
  const contains2 = (parent, child) => {
44335
- const path = relative5(parent, child);
44645
+ const path = relative6(parent, child);
44336
44646
  return path === "" || !isAbsolute18(path) && path !== ".." && !path.startsWith(`..${sep8}`);
44337
44647
  };
44338
44648
  if (contains2(sourcePath, destinationPath) || contains2(destinationPath, sourcePath)) {
@@ -44340,7 +44650,7 @@ function assertDisjointImportPaths(source, destination) {
44340
44650
  }
44341
44651
  }
44342
44652
  function portPortableSkill(sourcePath, options = {}) {
44343
- const absoluteSource = normalize3(sourcePath);
44653
+ const absoluteSource = normalize4(sourcePath);
44344
44654
  if (!existsSync9(absoluteSource) || !statSync9(absoluteSource).isDirectory()) {
44345
44655
  throw new Error(`Skill source directory not found: ${sourcePath}`);
44346
44656
  }
@@ -44348,8 +44658,8 @@ function portPortableSkill(sourcePath, options = {}) {
44348
44658
  const explicitName = options.name != null;
44349
44659
  const skillName = normalizeNewPortableSkillName(options.name ?? inferred.name);
44350
44660
  if (isOfficialSkillName(skillName) && !options.allowShadow) {
44351
- const sourceSlug = safeNormalizeName(basename9(absoluteSource));
44352
- const via = explicitName ? `Name '${skillName}' matches a bundled official skill.` : `Inferred name '${skillName}'${sourceSlug && sourceSlug !== skillName ? ` (from source folder '${basename9(absoluteSource)}')` : ""} matches a bundled official skill.`;
44661
+ const sourceSlug = safeNormalizeName(basename10(absoluteSource));
44662
+ const via = explicitName ? `Name '${skillName}' matches a bundled official skill.` : `Inferred name '${skillName}'${sourceSlug && sourceSlug !== skillName ? ` (from source folder '${basename10(absoluteSource)}')` : ""} matches a bundled official skill.`;
44353
44663
  throw new Error(`${via} Importing it would shadow the official '${skillName}'. ` + `Pass --name to choose a different name, or --allow-shadow to override deliberately.`);
44354
44664
  }
44355
44665
  const readOnlyDestination = join26(resolvePortableSkillsRoot(options, false), skillName);
@@ -44616,7 +44926,7 @@ function safeIsDirectory(path) {
44616
44926
  function isSafeRelativePath2(value) {
44617
44927
  if (!value.trim() || isAbsolute18(value))
44618
44928
  return false;
44619
- const normalized = normalize3(value).replace(/\\/g, "/");
44929
+ const normalized = normalize4(value).replace(/\\/g, "/");
44620
44930
  return normalized !== ".." && !normalized.startsWith("../") && !normalized.includes("/../");
44621
44931
  }
44622
44932
  function add3(target, code, message) {
@@ -44869,7 +45179,7 @@ function writeManagedSkillDir(dir, skillMd, options) {
44869
45179
  return { action, path: skillMdPath };
44870
45180
  const parentDir = dirname19(dir);
44871
45181
  mkdirSync8(parentDir, { recursive: true });
44872
- const transactionDir = mkdtempSync2(join27(parentDir, `.hasna-skills-write-${basename10(dir)}-`));
45182
+ const transactionDir = mkdtempSync2(join27(parentDir, `.hasna-skills-write-${basename11(dir)}-`));
44873
45183
  const candidateDir = join27(transactionDir, "candidate");
44874
45184
  const backupDir = join27(transactionDir, "backup");
44875
45185
  const candidateSkillMdPath = join27(candidateDir, "SKILL.md");
@@ -46267,7 +46577,7 @@ async function executeSelectedLocal(selected, options = {}) {
46267
46577
  selection: selection2,
46268
46578
  target: "local",
46269
46579
  runtime: runtimeName,
46270
- inputDigest: `sha256:${createHash19("sha256").update(input).digest("hex")}`,
46580
+ inputDigest: `sha256:${createHash20("sha256").update(input).digest("hex")}`,
46271
46581
  runDirectory,
46272
46582
  ...executionGrant ? { executionGrant } : {},
46273
46583
  ...bindings ? { secretBinding: { schema: bindings.schema, selection: bindings.selection, consumer: bindings.consumer, secretsAuthority: bindings.secretsAuthority, bindings: bindings.bindings } } : {},
@@ -46325,7 +46635,7 @@ async function subprocess(command, cwd, env, input, timeoutMs) {
46325
46635
  // src/lib/remote-run-contract.ts
46326
46636
  var REMOTE_SKILL_RUN_CONTRACT_VERSION = 1;
46327
46637
  function normalizeRemoteSkillRunContract(payload, fallbackSkill) {
46328
- const record3 = isRecord3(payload) ? payload : {};
46638
+ const record3 = isRecord4(payload) ? payload : {};
46329
46639
  return {
46330
46640
  contractVersion: REMOTE_SKILL_RUN_CONTRACT_VERSION,
46331
46641
  ...pickString(record3, "id"),
@@ -46347,7 +46657,7 @@ function normalizeRemoteSkillRunContract(payload, fallbackSkill) {
46347
46657
  ...hasOwn(record3, "details") ? { details: record3.details } : {}
46348
46658
  };
46349
46659
  }
46350
- function isRecord3(value) {
46660
+ function isRecord4(value) {
46351
46661
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
46352
46662
  }
46353
46663
  function hasOwn(record3, key) {
@@ -55557,7 +55867,7 @@ var import_node_http_handler2 = __toESM(require_dist_cjs6(), 1);
55557
55867
 
55558
55868
  // node_modules/@aws-sdk/checksums/dist-cjs/submodules/sha/index.js
55559
55869
  var { toUint8Array: toUint8Array2, concatBytes } = require_serde();
55560
- var { createHmac: createHmac2, createHash: createHash21 } = __require("crypto");
55870
+ var { createHmac: createHmac2, createHash: createHash22 } = __require("crypto");
55561
55871
  var { Sha256: Sha2562, Sha256Js, Sha256Node } = require_checksum();
55562
55872
  var BLOCK2 = 64;
55563
55873
  var DIGEST_LENGTH = 20;
@@ -55726,7 +56036,7 @@ class Sha1Js {
55726
56036
  }
55727
56037
  var hasNativeCrypto = (() => {
55728
56038
  try {
55729
- createHash21("sha1");
56039
+ createHash22("sha1");
55730
56040
  return true;
55731
56041
  } catch {
55732
56042
  return false;
@@ -55766,7 +56076,7 @@ function buildNativeClass() {
55766
56076
  this.finished = false;
55767
56077
  }
55768
56078
  createHash() {
55769
- return this.secret ? createHmac2("sha1", toBuffer(this.secret)) : createHash21("sha1");
56079
+ return this.secret ? createHmac2("sha1", toBuffer(this.secret)) : createHash22("sha1");
55770
56080
  }
55771
56081
  };
55772
56082
  }
@@ -56634,9 +56944,9 @@ import { mkdirSync as mkdirSync11, readFileSync as readFileSync23, readdirSync a
56634
56944
  import { dirname as dirname23, join as join36 } from "path";
56635
56945
 
56636
56946
  // src/server/auth.ts
56637
- import { createHash as createHash22 } from "crypto";
56947
+ import { createHash as createHash23 } from "crypto";
56638
56948
  function hashApiKey(token) {
56639
- return createHash22("sha256").update(token).digest("hex");
56949
+ return createHash23("sha256").update(token).digest("hex");
56640
56950
  }
56641
56951
  function bearerToken(request2) {
56642
56952
  const header = request2.headers.get("authorization") || "";
@@ -56958,7 +57268,7 @@ function validOperatorScopeEnrollmentInput(input) {
56958
57268
  }
56959
57269
 
56960
57270
  // src/lib/revision.ts
56961
- import { createHash as createHash23 } from "crypto";
57271
+ import { createHash as createHash24 } from "crypto";
56962
57272
  var REVISION_ID_PATTERN = /^[0-9a-f]{64}$/;
56963
57273
  function revisionIdOf(content) {
56964
57274
  const canonicalContent = {
@@ -56979,8 +57289,8 @@ function revisionIdOf(content) {
56979
57289
  canonicalContent.archiveReason = content.archiveReason ?? null;
56980
57290
  canonicalContent.replacementSlug = content.replacementSlug ?? null;
56981
57291
  }
56982
- const canonical5 = JSON.stringify(canonicalContent);
56983
- return createHash23("sha256").update(canonical5).digest("hex");
57292
+ const canonical6 = JSON.stringify(canonicalContent);
57293
+ return createHash24("sha256").update(canonical6).digest("hex");
56984
57294
  }
56985
57295
  function revisionIdOfRecord(record3) {
56986
57296
  return revisionIdOf(record3);
@@ -58064,7 +58374,7 @@ function nextMonthPrefix(monthPrefix) {
58064
58374
  }
58065
58375
 
58066
58376
  // src/server/skills-api.ts
58067
- import { createHash as createHash24 } from "crypto";
58377
+ import { createHash as createHash25 } from "crypto";
58068
58378
  var SLUG_PATTERN = /^[a-z0-9][a-z0-9._-]*$/;
58069
58379
  var SHA256_HEX2 = /^[0-9a-f]{64}$/;
58070
58380
  var MAX_SLUG_LENGTH = 128;
@@ -58254,7 +58564,7 @@ async function parsePublishRequest(request2, config) {
58254
58564
  if (bundleBytes.byteLength === 0) {
58255
58565
  throw new SkillRequestError(400, "BUNDLE_EMPTY", "the uploaded bundle is empty");
58256
58566
  }
58257
- const sha2562 = createHash24("sha256").update(bundleBytes).digest("hex");
58567
+ const sha2562 = createHash25("sha256").update(bundleBytes).digest("hex");
58258
58568
  const claimed = optionalString(manifest.bundleSha256);
58259
58569
  if (claimed)
58260
58570
  assertSha2562(claimed);
@@ -58369,7 +58679,7 @@ async function readPublishedBundle(store, artifactStorage, principal, slug) {
58369
58679
  if (!bytes) {
58370
58680
  throw new SkillRequestError(503, "BUNDLE_BACKEND_UNAVAILABLE", "bundle storage backend unavailable");
58371
58681
  }
58372
- const actual = createHash24("sha256").update(bytes).digest("hex");
58682
+ const actual = createHash25("sha256").update(bytes).digest("hex");
58373
58683
  if (actual !== record3.bundleSha256) {
58374
58684
  throw new SkillRequestError(500, "BUNDLE_DIGEST_DRIFT", `stored bundle for '${slug}' hashes to ${actual} but was published as ${record3.bundleSha256}`);
58375
58685
  }
@@ -58517,7 +58827,7 @@ async function readSkillVersionBundle(store, artifactStorage, principal, slug, v
58517
58827
  const bytes = await artifactStorage.readBundle(bundle2);
58518
58828
  if (!bytes)
58519
58829
  throw new SkillRequestError(503, "BUNDLE_BACKEND_UNAVAILABLE", "bundle storage backend unavailable");
58520
- const actual = createHash24("sha256").update(bytes).digest("hex");
58830
+ const actual = createHash25("sha256").update(bytes).digest("hex");
58521
58831
  if (actual !== found.bundleSha256) {
58522
58832
  throw new SkillRequestError(500, "BUNDLE_DIGEST_DRIFT", `stored bundle for '${slug}@${version2}' hashes to ${actual} but was published as ${found.bundleSha256}`);
58523
58833
  }
@@ -59220,7 +59530,7 @@ class RuntimeExecutionStore {
59220
59530
  }
59221
59531
 
59222
59532
  // src/sdk/execution/admission.ts
59223
- import { createHash as createHash26 } from "crypto";
59533
+ import { createHash as createHash27 } from "crypto";
59224
59534
 
59225
59535
  // src/sdk/execution/image-profile.ts
59226
59536
  class ImageProfileResolutionError extends Error {
@@ -59832,11 +60142,11 @@ function ownedAdmission(admission) {
59832
60142
  };
59833
60143
  }
59834
60144
  function digestInput(input) {
59835
- return createHash26("sha256").update(canonicalJson2(input)).digest("hex");
60145
+ return createHash27("sha256").update(canonicalJson2(input)).digest("hex");
59836
60146
  }
59837
60147
 
59838
60148
  // src/sdk/execution/dispatchers/ecs.ts
59839
- import { createHash as createHash27 } from "crypto";
60149
+ import { createHash as createHash28 } from "crypto";
59840
60150
 
59841
60151
  // src/sdk/execution/state-machine.ts
59842
60152
  var LEGAL_TRANSITIONS = {
@@ -63236,13 +63546,13 @@ function observedTask(states, taskArn) {
63236
63546
  return state2.lastStatus === "STOPPED" || LIVE_TASK_STATUSES.has(state2.lastStatus) ? state2 : undefined;
63237
63547
  }
63238
63548
  function clientTokenFor(runId3, attemptId) {
63239
- return createHash27("sha256").update(`${runId3}\x00${attemptId}`).digest("hex").slice(0, CLIENT_TOKEN_BYTES * 2);
63549
+ return createHash28("sha256").update(`${runId3}\x00${attemptId}`).digest("hex").slice(0, CLIENT_TOKEN_BYTES * 2);
63240
63550
  }
63241
63551
  function startedByFor(runId3, attemptNumber) {
63242
63552
  return `skills-exec/${runId3}/a${attemptNumber}`;
63243
63553
  }
63244
63554
  function requestDigestFor(admission, attemptId) {
63245
- return createHash27("sha256").update(canonicalJson2({ admission, attemptId })).digest("hex");
63555
+ return createHash28("sha256").update(canonicalJson2({ admission, attemptId })).digest("hex");
63246
63556
  }
63247
63557
 
63248
63558
  class EcsDispatcher {
@@ -63538,10 +63848,10 @@ function validText(value) {
63538
63848
  }
63539
63849
 
63540
63850
  // src/server/runtime-policy.ts
63541
- import { createHash as createHash29, createHmac as createHmac3, timingSafeEqual as timingSafeEqual2 } from "crypto";
63851
+ import { createHash as createHash30, createHmac as createHmac3, timingSafeEqual as timingSafeEqual2 } from "crypto";
63542
63852
 
63543
63853
  // src/server/runtime-pure-contract.ts
63544
- import { createHash as createHash28 } from "crypto";
63854
+ import { createHash as createHash29 } from "crypto";
63545
63855
  var PURE_DESCRIPTOR = Object.freeze({
63546
63856
  id: "regex-test.v1",
63547
63857
  runtime: "bun",
@@ -63565,7 +63875,7 @@ var PURE_LIMITS = Object.freeze({
63565
63875
  maxArtifactsBytes: 0,
63566
63876
  maxConcurrency: 1
63567
63877
  });
63568
- var hash2 = (bytes) => createHash28("sha256").update(bytes).digest("hex");
63878
+ var hash2 = (bytes) => createHash29("sha256").update(bytes).digest("hex");
63569
63879
  var object6 = (v2) => {
63570
63880
  if (!v2 || typeof v2 !== "object" || Array.isArray(v2))
63571
63881
  throw Error("Pure contract requires an object");
@@ -63794,7 +64104,7 @@ function verifyRuntimeToken(token, key, admission, attempt, now = Date.now()) {
63794
64104
  const actual = Buffer.from(token);
63795
64105
  return actual.length === expected.length && timingSafeEqual2(actual, expected);
63796
64106
  }
63797
- var hashBytes = (bytes) => createHash29("sha256").update(bytes).digest("hex");
64107
+ var hashBytes = (bytes) => createHash30("sha256").update(bytes).digest("hex");
63798
64108
 
63799
64109
  // src/server/runtime-api.ts
63800
64110
  async function createRuntimeService(options) {
@@ -65982,7 +66292,7 @@ async function readJson(request2, limitBytes) {
65982
66292
  if (!text2.trim())
65983
66293
  return {};
65984
66294
  const parsed = JSON.parse(text2);
65985
- return isRecord4(parsed) ? parsed : {};
66295
+ return isRecord5(parsed) ? parsed : {};
65986
66296
  }
65987
66297
  function pathSegments(pathname) {
65988
66298
  return pathname.split("/").filter(Boolean).map(decodeSegment);
@@ -66003,7 +66313,7 @@ function json4(payload, init = {}) {
66003
66313
  headers: { "Cache-Control": "no-store", ...init.headers }
66004
66314
  });
66005
66315
  }
66006
- function isRecord4(value) {
66316
+ function isRecord5(value) {
66007
66317
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
66008
66318
  }
66009
66319
  function clampInt(value, fallback, max) {
@@ -70166,7 +70476,7 @@ var localRunExecutor = {
70166
70476
  // src/sdk/storage.ts
70167
70477
  var artifactStorageSeam = ArtifactStorage;
70168
70478
  // src/sdk/outputs.ts
70169
- import { createHash as createHash30 } from "crypto";
70479
+ import { createHash as createHash31 } from "crypto";
70170
70480
  class DatabaseOnlyObjectStore {
70171
70481
  usesS3 = false;
70172
70482
  async materialize(run, artifact, body4) {
@@ -70213,7 +70523,7 @@ function createGovernedArtifactWriter(options) {
70213
70523
  const stamped = {
70214
70524
  ...meta,
70215
70525
  byteSize: outputBytes,
70216
- sha256: createHash30("sha256").update(persistedBytes).digest("hex"),
70526
+ sha256: createHash31("sha256").update(persistedBytes).digest("hex"),
70217
70527
  visibility: options.visibility ?? config.defaultVisibility,
70218
70528
  ...config.artifactTtlSeconds !== undefined ? { expiresAt: expiresAtFor(createdAt, config.artifactTtlSeconds) } : {}
70219
70529
  };
@@ -73684,15 +73994,15 @@ var $ZodDate = /* @__PURE__ */ $constructor("$ZodDate", (inst, def) => {
73684
73994
  } catch (_err) {}
73685
73995
  }
73686
73996
  const input = payload.value;
73687
- const isDate = input instanceof Date;
73688
- const isValidDate = isDate && !Number.isNaN(input.getTime());
73997
+ const isDate2 = input instanceof Date;
73998
+ const isValidDate = isDate2 && !Number.isNaN(input.getTime());
73689
73999
  if (isValidDate)
73690
74000
  return payload;
73691
74001
  payload.issues.push({
73692
74002
  expected: "date",
73693
74003
  code: "invalid_type",
73694
74004
  input,
73695
- ...isDate ? { received: "Invalid Date" } : {},
74005
+ ...isDate2 ? { received: "Invalid Date" } : {},
73696
74006
  inst
73697
74007
  });
73698
74008
  return payload;
@@ -88980,7 +89290,7 @@ function date4(params) {
88980
89290
  return _coercedDate(ZodDate2, params);
88981
89291
  }
88982
89292
  // src/lib/canonical-json.ts
88983
- import { createHash as createHash31 } from "crypto";
89293
+ import { createHash as createHash32 } from "crypto";
88984
89294
  function canonicalJson3(value, maximumBytes = 2 * 1024 * 1024) {
88985
89295
  return canonicalJsonAtDepth(value, maximumBytes, 64);
88986
89296
  }
@@ -89024,7 +89334,7 @@ function canonicalJsonAtDepth(value, maximumBytes, maximumDepth) {
89024
89334
  return visit3(value, 0);
89025
89335
  }
89026
89336
  function canonicalJsonSha256(value, maximumBytes) {
89027
- return createHash31("sha256").update(canonicalJson3(value, maximumBytes)).digest("hex");
89337
+ return createHash32("sha256").update(canonicalJson3(value, maximumBytes)).digest("hex");
89028
89338
  }
89029
89339
 
89030
89340
  // src/lib/remote-recurring-contract.ts
@@ -89890,7 +90200,7 @@ function creditCheckoutFailure(value, status, key) {
89890
90200
 
89891
90201
  // src/lib/remote-profile.ts
89892
90202
  function customerNamePatch(input2, field2) {
89893
- if (!isRecord5(input2) || Object.keys(input2).length !== 1 || !Object.hasOwn(input2, field2))
90203
+ if (!isRecord6(input2) || Object.keys(input2).length !== 1 || !Object.hasOwn(input2, field2))
89894
90204
  throw new Error("Provide only the requested name field.");
89895
90205
  const value = input2[field2];
89896
90206
  if (typeof value !== "string" || /[\p{Cc}\p{Cs}\u2028\u2029]/u.test(value) || !value.trim() || [...value.trim()].length > 100) {
@@ -89898,22 +90208,22 @@ function customerNamePatch(input2, field2) {
89898
90208
  }
89899
90209
  return { [field2]: value.trim() };
89900
90210
  }
89901
- function isRecord5(value) {
90211
+ function isRecord6(value) {
89902
90212
  return !!value && typeof value === "object" && !Array.isArray(value);
89903
90213
  }
89904
90214
  function string4(value) {
89905
90215
  return typeof value === "string" && value.length > 0;
89906
90216
  }
89907
90217
  function parseUpdatedProfile(value) {
89908
- const user = isRecord5(value) && value.user;
89909
- if (!isRecord5(user) || !string4(user.id) || !string4(user.email) || !(user.displayName === null || typeof user.displayName === "string") || typeof user.role !== "string" || !["owner", "admin", "member", "viewer"].includes(user.role)) {
90218
+ const user = isRecord6(value) && value.user;
90219
+ if (!isRecord6(user) || !string4(user.id) || !string4(user.email) || !(user.displayName === null || typeof user.displayName === "string") || typeof user.role !== "string" || !["owner", "admin", "member", "viewer"].includes(user.role)) {
89910
90220
  throw new Error("The server returned an invalid account profile.");
89911
90221
  }
89912
90222
  return { user: { id: user.id, email: user.email, displayName: user.displayName, role: user.role } };
89913
90223
  }
89914
90224
  function parseUpdatedWorkspace(value) {
89915
- const organization2 = isRecord5(value) && value.organization;
89916
- if (!isRecord5(organization2) || !string4(organization2.id) || !string4(organization2.slug) || !string4(organization2.name)) {
90225
+ const organization2 = isRecord6(value) && value.organization;
90226
+ if (!isRecord6(organization2) || !string4(organization2.id) || !string4(organization2.slug) || !string4(organization2.name)) {
89917
90227
  throw new Error("The server returned an invalid workspace.");
89918
90228
  }
89919
90229
  return { organization: { id: organization2.id, slug: organization2.slug, name: organization2.name } };
@@ -91138,7 +91448,7 @@ async function requestInvitationEmail(origin, action, input2) {
91138
91448
  }
91139
91449
 
91140
91450
  // src/lib/remote-private-publications.ts
91141
- import { createHash as createHash32 } from "crypto";
91451
+ import { createHash as createHash33 } from "crypto";
91142
91452
  var PRIVATE_PUBLICATION_MAX_BYTES = 16 * 1024 * 1024;
91143
91453
  var failures2 = {
91144
91454
  INVALID_REQUEST: [400, "The publication request is invalid."],
@@ -91185,7 +91495,7 @@ var hash4 = (v2) => typeof v2 === "string" && /^[a-f0-9]{64}$/.test(v2);
91185
91495
  var record9 = (v2) => !!v2 && typeof v2 === "object" && !Array.isArray(v2);
91186
91496
  var exact = (v2, keys3) => record9(v2) && Object.keys(v2).sort().join(",") === keys3.sort().join(",");
91187
91497
  var date5 = (v2) => typeof v2 === "string" && /^\d{4}-\d\d-\d\dT[0-9:.]+(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(v2) && Number.isFinite(Date.parse(v2));
91188
- var publicationSha256 = (bytes) => createHash32("sha256").update(bytes).digest("hex");
91498
+ var publicationSha256 = (bytes) => createHash33("sha256").update(bytes).digest("hex");
91189
91499
  function checkedPublicationDeclaration(value) {
91190
91500
  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 || !hash4(value.archiveSha256) || !Number.isSafeInteger(value.archiveByteSize) || Number(value.archiveByteSize) < 1 || Number(value.archiveByteSize) > PRIVATE_PUBLICATION_MAX_BYTES)
91191
91501
  return bad();
@@ -91484,7 +91794,7 @@ async function requestAuthApi(instance, path2, options) {
91484
91794
  const text3 = await res.text();
91485
91795
  const body4 = text3 ? parseJsonBody(text3) : {};
91486
91796
  if (!res.ok) {
91487
- const record10 = isRecord6(body4) ? body4 : {};
91797
+ const record10 = isRecord7(body4) ? body4 : {};
91488
91798
  const detail = typeof record10.detail === "string" ? record10.detail : undefined;
91489
91799
  const error61 = typeof record10.error === "string" ? record10.error : undefined;
91490
91800
  const code = typeof record10.code === "string" ? record10.code : undefined;
@@ -91512,7 +91822,7 @@ function condenseErrorBody(text3) {
91512
91822
  return collapsed;
91513
91823
  return `${collapsed.slice(0, MAX_ERROR_DETAIL_LENGTH - 1).trimEnd()}\u2026`;
91514
91824
  }
91515
- function isRecord6(value) {
91825
+ function isRecord7(value) {
91516
91826
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
91517
91827
  }
91518
91828
 
@@ -92020,16 +92330,16 @@ function resultSnapshot(input2, requestId) {
92020
92330
  const value = snapshot2(input2, SKILL_OPERATION_LIMITS.resultBytes).value;
92021
92331
  if (!record10(value) || value.contractVersion !== 1 || value.requestId !== requestId)
92022
92332
  throw Error();
92023
- const fields = ["contractVersion", "requestId", "status"];
92333
+ const fields2 = ["contractVersion", "requestId", "status"];
92024
92334
  if (value.status === "succeeded")
92025
- fields.push("output");
92335
+ fields2.push("output");
92026
92336
  else if (value.status === "refused") {
92027
- fields.push("code");
92337
+ fields2.push("code");
92028
92338
  if (!refusalCodes.has(value.code))
92029
92339
  throw Error();
92030
92340
  } else if (!["not-executed", "pending", "unknown"].includes(value.status))
92031
92341
  throw Error();
92032
- if (!exact2(value, fields))
92342
+ if (!exact2(value, fields2))
92033
92343
  throw Error();
92034
92344
  return value;
92035
92345
  } catch {