@hasna/skills 0.10.45 → 0.10.46

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: sep10, join: join4 } = __require("path");
9007
- var { createHash: createHash24 } = __require("crypto");
9007
+ var { createHash: createHash25 } = __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 = createHash24("sha1");
9162
+ const hasher = createHash25("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: createHash24, getRandomValues } = __require("crypto");
10514
+ var { createHmac: createHmac2, createHash: createHash25, getRandomValues } = __require("crypto");
10515
10515
  var { hasOwn: hasOwn2, HttpResponse } = require_transport();
10516
10516
  exports.hasOwn = hasOwn2;
10517
10517
  var { ReadStream, lstatSync: lstatSync26, 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)) : createHash24(this.algorithmIdentifier);
11419
+ this.hash = this.secret ? createHmac2(this.algorithmIdentifier, castSourceData(this.secret)) : createHash25(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: createHash24, createHmac: createHmac2 } = __require("crypto");
12158
+ var { createHash: createHash25, 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
- createHash24("md5");
12323
+ createHash25("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 = createHash24("md5");
12333
+ hash = createHash25("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 = createHash24("md5");
12342
+ this.hash = createHash25("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
- createHash24("sha256");
12632
+ createHash25("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)) : createHash24("sha256");
12672
+ return this.secret ? createHmac2("sha256", toBuffer(this.secret)) : createHash25("sha256");
12673
12673
  }
12674
12674
  };
12675
12675
  }
@@ -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 createHash24, createPrivateKey, createPublicKey, sign } from "crypto";
29446
+ import { createHash as createHash25, 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 dirname23, join as join37 } from "path";
@@ -29615,7 +29615,7 @@ var init_LoginCredentialsFetcher = __esm(() => {
29615
29615
  getTokenFilePath() {
29616
29616
  const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ?? join37(homedir7(), ".aws", "login", "cache");
29617
29617
  const loginSessionBytes = Buffer.from(this.loginSession, "utf8");
29618
- const loginSessionSha256 = createHash24("sha256").update(loginSessionBytes).digest("hex");
29618
+ const loginSessionSha256 = createHash25("sha256").update(loginSessionBytes).digest("hex");
29619
29619
  return join37(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.45",
32376
+ version: "0.10.46",
32377
32377
  description: "Skills library for AI coding agents",
32378
32378
  type: "module",
32379
32379
  bin: {
@@ -37516,7 +37516,7 @@ async function reconcileSkillSession(input, options = {}) {
37516
37516
  return { applied: true, plan, planDigest, ...result };
37517
37517
  }
37518
37518
  // src/lib/selected-run.ts
37519
- import { createHash as createHash23 } from "crypto";
37519
+ import { createHash as createHash24 } from "crypto";
37520
37520
  import { spawn as spawn2 } from "child_process";
37521
37521
  import { mkdirSync as mkdirSync11, mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync10, realpathSync as realpathSync14 } from "fs";
37522
37522
  import { dirname as dirname22, join as join36, resolve as resolve21 } from "path";
@@ -37916,75 +37916,9 @@ import {
37916
37916
  import { homedir as homedir5 } from "os";
37917
37917
  import { basename as basename12, dirname as dirname21, join as join31 } from "path";
37918
37918
 
37919
- // src/lib/codex-plugin-skill-controls.ts
37919
+ // src/lib/sumi-settings-witness.ts
37920
37920
  import { createHash as createHash7 } from "crypto";
37921
37921
 
37922
- // src/lib/codex-local-mcp-controls.ts
37923
- function isCodexLocalStdioMcpServer(name, server) {
37924
- const identifier3 = (value) => typeof value === "string" && /^[A-Za-z0-9_-]{1,64}$/.test(value);
37925
- const refuse2 = () => {
37926
- throw new Error("Unsupported Codex local stdio MCP controls");
37927
- };
37928
- const object2 = (v) => Boolean(v && typeof v === "object" && !Array.isArray(v) && !(v instanceof Date));
37929
- const textField = (v, empty = false) => typeof v === "string" && (empty || Boolean(v.trim())) && Buffer.byteLength(v) <= 16384 && !/[\x00-\x1f\x7f]/.test(v);
37930
- const envName = (v) => typeof v === "string" && /^[A-Za-z_][A-Za-z0-9_]{0,255}$/.test(v);
37931
- const optional = (v, valid) => v === undefined || v === null || valid(v);
37932
- const stringList = (v) => Array.isArray(v) && v.length <= 256 && v.every((item) => textField(item));
37933
- const approval = (v) => ["auto", "prompt", "writes", "approve"].includes(v);
37934
- const duration = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0;
37935
- const positiveInteger = (v) => Number.isSafeInteger(v) && v > 0;
37936
- const fields = [
37937
- "command",
37938
- "args",
37939
- "cwd",
37940
- "env",
37941
- "env_vars",
37942
- "enabled",
37943
- "required",
37944
- "environment_id",
37945
- "startup_readiness",
37946
- "supports_parallel_tool_calls",
37947
- "tool_input_schema_max_bytes",
37948
- "startup_timeout_sec",
37949
- "startup_timeout_ms",
37950
- "tool_timeout_sec",
37951
- "default_tools_approval_mode",
37952
- "enabled_tools",
37953
- "disabled_tools",
37954
- "omit_tools_from",
37955
- "tools",
37956
- "name"
37957
- ];
37958
- try {
37959
- if (!identifier3(name) || !object2(server) || !Object.keys(server).every((key) => fields.includes(key)) || !textField(server.command) || !optional(server.args, (v) => Array.isArray(v) && v.length <= 256 && v.every((arg) => textField(arg, true))) || !optional(server.cwd, textField) || !optional(server.env, (v) => object2(v) && Object.keys(v).length <= 256 && Object.entries(v).every(([key, value]) => envName(key) && textField(value, true))) || !["enabled", "required", "supports_parallel_tool_calls"].every((key) => optional(server[key], (v) => typeof v === "boolean")) || !optional(server.environment_id, (v) => v === "local") || !optional(server.startup_readiness, (v) => ["connection", "catalog"].includes(v)) || !optional(server.tool_input_schema_max_bytes, positiveInteger) || !["startup_timeout_sec", "tool_timeout_sec"].every((key) => optional(server[key], duration)) || !optional(server.startup_timeout_ms, (v) => Number.isSafeInteger(v) && v >= 0) || !optional(server.default_tools_approval_mode, approval) || !["enabled_tools", "disabled_tools"].every((key) => optional(server[key], stringList)) || !optional(server.omit_tools_from, (v) => Array.isArray(v) && v.length <= 256 && v.every((item) => ["code_mode", "deferred", "direct"].includes(item))) || !optional(server.name, textField))
37960
- refuse2();
37961
- if (server.env_vars !== undefined && server.env_vars !== null) {
37962
- if (!Array.isArray(server.env_vars) || server.env_vars.length > 256)
37963
- refuse2();
37964
- const names = server.env_vars.map((entry) => {
37965
- if (envName(entry))
37966
- return entry;
37967
- if (!object2(entry) || !Object.keys(entry).every((key) => ["name", "source"].includes(key)) || !envName(entry.name) || !optional(entry.source, (v) => v === "local"))
37968
- refuse2();
37969
- return entry.name;
37970
- });
37971
- if (new Set(names).size !== names.length)
37972
- refuse2();
37973
- }
37974
- if (server.tools !== undefined && server.tools !== null) {
37975
- if (!object2(server.tools) || Object.keys(server.tools).length > 256)
37976
- refuse2();
37977
- for (const [tool, config] of Object.entries(server.tools)) {
37978
- if (!textField(tool) || !object2(config) || !Object.keys(config).every((key) => ["approval_mode", "output_token_limit"].includes(key)) || !optional(config.approval_mode, approval) || !optional(config.output_token_limit, positiveInteger))
37979
- refuse2();
37980
- }
37981
- }
37982
- return true;
37983
- } catch {
37984
- return false;
37985
- }
37986
- }
37987
-
37988
37922
  // src/lib/claude-settings-witness.ts
37989
37923
  import { createHash as createHash6 } from "crypto";
37990
37924
  import { closeSync as closeSync9, constants as constants6, fstatSync as fstatSync9, lstatSync as lstatSync6, openSync as openSync9, readSync as readSync4 } from "fs";
@@ -38295,6 +38229,124 @@ function hashNativeJsonControls(text, excludedMetadata) {
38295
38229
  });
38296
38230
  return createHash6("sha256").update("hasna.skills.native-json-controls.v1\x00").update(JSON.stringify(canonical(value))).digest("hex");
38297
38231
  }
38232
+ function hashSumiNativeJsonControls(text) {
38233
+ need(Buffer.byteLength(text) <= CLAUDE_SETTINGS_WITNESS_LIMITS.bytes, "exceeds its byte limit");
38234
+ const value = parse2(text);
38235
+ value.entries = value.entries.filter(([key, child]) => {
38236
+ if (key === "$schema" || key === "username") {
38237
+ need(child.kind === "string", "has invalid Sumi display metadata");
38238
+ return false;
38239
+ }
38240
+ if (key !== "experimental")
38241
+ return true;
38242
+ need(child.kind === "object", "requires Sumi experimental controls to be an object");
38243
+ child.entries = child.entries.filter(([name, option]) => {
38244
+ if (name !== "statusline" && name !== "compact_tools")
38245
+ return true;
38246
+ need(option.kind === "literal" && (option.value === "true" || option.value === "false"), "has invalid Sumi display preference");
38247
+ return false;
38248
+ });
38249
+ return child.entries.length > 0;
38250
+ });
38251
+ return createHash6("sha256").update("hasna.skills.sumi-settings.v1\x00").update(JSON.stringify(value)).digest("hex");
38252
+ }
38253
+
38254
+ // src/lib/sumi-settings-witness.ts
38255
+ var SUMI_DISCOVERY_PROJECTION_FIELDS = ["skills", "plugin", "plugins", "permissions"];
38256
+ var budget = () => ({ remaining: 256 * 1024 * 1024 });
38257
+ function readSumiSettingsPreimage(path) {
38258
+ return readNativeSettingsWitnessFile(path, budget(), "sumi.json");
38259
+ }
38260
+ function hashSumiSettingsReplacement(text, limits) {
38261
+ const bytes = Buffer.byteLength(text);
38262
+ if (bytes > CLAUDE_SETTINGS_WITNESS_LIMITS.bytes || !Number.isSafeInteger(limits.remaining) || limits.remaining < bytes)
38263
+ throw new Error("Sumi settings witness exceeds its byte limit");
38264
+ limits.remaining -= bytes;
38265
+ return hashSumiNativeJsonControls(text);
38266
+ }
38267
+ function captureSumiSettings(path, limits = budget()) {
38268
+ return { path, hashMode: "sumi-settings-v1", sha256: hashSumiNativeJsonControls(readNativeSettingsWitnessFile(path, limits, "sumi.json")) };
38269
+ }
38270
+ function upgradeSumiSettingsWitness(previous, reviewedSettingsPath) {
38271
+ if (!previous || Object.keys(previous).some((key) => !["path", "hashMode", "sha256"].includes(key)) || ![undefined, "bytes"].includes(previous.hashMode) || !/^[a-f0-9]{64}$/.test(previous.sha256))
38272
+ throw new Error("Sumi settings upgrade requires one exact preserved byte witness");
38273
+ const before = readSumiSettingsPreimage(reviewedSettingsPath);
38274
+ if (createHash7("sha256").update(before).digest("hex") !== previous.sha256)
38275
+ throw new Error("Reviewed Sumi preimage does not match its byte witness");
38276
+ const next = captureSumiSettings(previous.path);
38277
+ if (hashSumiNativeJsonControls(before) !== next.sha256)
38278
+ throw new Error("Sumi non-display settings changed; explicit discovery review required");
38279
+ return next;
38280
+ }
38281
+
38282
+ // src/lib/codex-plugin-skill-controls.ts
38283
+ import { createHash as createHash8 } from "crypto";
38284
+
38285
+ // src/lib/codex-local-mcp-controls.ts
38286
+ function isCodexLocalStdioMcpServer(name, server) {
38287
+ const identifier3 = (value) => typeof value === "string" && /^[A-Za-z0-9_-]{1,64}$/.test(value);
38288
+ const refuse2 = () => {
38289
+ throw new Error("Unsupported Codex local stdio MCP controls");
38290
+ };
38291
+ const object2 = (v) => Boolean(v && typeof v === "object" && !Array.isArray(v) && !(v instanceof Date));
38292
+ const textField = (v, empty = false) => typeof v === "string" && (empty || Boolean(v.trim())) && Buffer.byteLength(v) <= 16384 && !/[\x00-\x1f\x7f]/.test(v);
38293
+ const envName = (v) => typeof v === "string" && /^[A-Za-z_][A-Za-z0-9_]{0,255}$/.test(v);
38294
+ const optional = (v, valid) => v === undefined || v === null || valid(v);
38295
+ const stringList = (v) => Array.isArray(v) && v.length <= 256 && v.every((item) => textField(item));
38296
+ const approval = (v) => ["auto", "prompt", "writes", "approve"].includes(v);
38297
+ const duration = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0;
38298
+ const positiveInteger = (v) => Number.isSafeInteger(v) && v > 0;
38299
+ const fields = [
38300
+ "command",
38301
+ "args",
38302
+ "cwd",
38303
+ "env",
38304
+ "env_vars",
38305
+ "enabled",
38306
+ "required",
38307
+ "environment_id",
38308
+ "startup_readiness",
38309
+ "supports_parallel_tool_calls",
38310
+ "tool_input_schema_max_bytes",
38311
+ "startup_timeout_sec",
38312
+ "startup_timeout_ms",
38313
+ "tool_timeout_sec",
38314
+ "default_tools_approval_mode",
38315
+ "enabled_tools",
38316
+ "disabled_tools",
38317
+ "omit_tools_from",
38318
+ "tools",
38319
+ "name"
38320
+ ];
38321
+ try {
38322
+ if (!identifier3(name) || !object2(server) || !Object.keys(server).every((key) => fields.includes(key)) || !textField(server.command) || !optional(server.args, (v) => Array.isArray(v) && v.length <= 256 && v.every((arg) => textField(arg, true))) || !optional(server.cwd, textField) || !optional(server.env, (v) => object2(v) && Object.keys(v).length <= 256 && Object.entries(v).every(([key, value]) => envName(key) && textField(value, true))) || !["enabled", "required", "supports_parallel_tool_calls"].every((key) => optional(server[key], (v) => typeof v === "boolean")) || !optional(server.environment_id, (v) => v === "local") || !optional(server.startup_readiness, (v) => ["connection", "catalog"].includes(v)) || !optional(server.tool_input_schema_max_bytes, positiveInteger) || !["startup_timeout_sec", "tool_timeout_sec"].every((key) => optional(server[key], duration)) || !optional(server.startup_timeout_ms, (v) => Number.isSafeInteger(v) && v >= 0) || !optional(server.default_tools_approval_mode, approval) || !["enabled_tools", "disabled_tools"].every((key) => optional(server[key], stringList)) || !optional(server.omit_tools_from, (v) => Array.isArray(v) && v.length <= 256 && v.every((item) => ["code_mode", "deferred", "direct"].includes(item))) || !optional(server.name, textField))
38323
+ refuse2();
38324
+ if (server.env_vars !== undefined && server.env_vars !== null) {
38325
+ if (!Array.isArray(server.env_vars) || server.env_vars.length > 256)
38326
+ refuse2();
38327
+ const names = server.env_vars.map((entry) => {
38328
+ if (envName(entry))
38329
+ return entry;
38330
+ if (!object2(entry) || !Object.keys(entry).every((key) => ["name", "source"].includes(key)) || !envName(entry.name) || !optional(entry.source, (v) => v === "local"))
38331
+ refuse2();
38332
+ return entry.name;
38333
+ });
38334
+ if (new Set(names).size !== names.length)
38335
+ refuse2();
38336
+ }
38337
+ if (server.tools !== undefined && server.tools !== null) {
38338
+ if (!object2(server.tools) || Object.keys(server.tools).length > 256)
38339
+ refuse2();
38340
+ for (const [tool, config] of Object.entries(server.tools)) {
38341
+ if (!textField(tool) || !object2(config) || !Object.keys(config).every((key) => ["approval_mode", "output_token_limit"].includes(key)) || !optional(config.approval_mode, approval) || !optional(config.output_token_limit, positiveInteger))
38342
+ refuse2();
38343
+ }
38344
+ }
38345
+ return true;
38346
+ } catch {
38347
+ return false;
38348
+ }
38349
+ }
38298
38350
 
38299
38351
  // src/lib/codex-plugin-skill-controls.ts
38300
38352
  import { basename as basename4, dirname as dirname6, join as join12, relative as relative4, resolve as resolve5, sep as sep3 } from "path";
@@ -38986,7 +39038,7 @@ function reviewCodexPluginControls(catalog, documents, cache, cwd, read, rules,
38986
39038
  const exactPathDeny = Array.isArray(rules) && rules.some((rule) => rule?.path === document && rule?.enabled === false);
38987
39039
  const nativeSkill = { name: parsed.name, path: document, pluginId: expectedPluginId, enabled: true };
38988
39040
  const denial = denials.find((item) => item.path === document);
38989
- const explicitDeny = denial !== undefined && remotePluginId !== undefined && catalog.version === "codex-cli 0.160.0" && denial.name === parsed.name && denial.sha256 === createHash7("sha256").update(read(document)).digest("hex") && Array.isArray(rules) && !rules.some((rule) => (rule?.path === document || typeof rule?.name === "string" && rule.name.trim() === parsed.name) && rule.enabled !== false) && Array.isArray(plannedRules) && plannedRules.some((rule) => rule?.path === document && rule.enabled === false);
39041
+ const explicitDeny = denial !== undefined && remotePluginId !== undefined && catalog.version === "codex-cli 0.160.0" && denial.name === parsed.name && denial.sha256 === createHash8("sha256").update(read(document)).digest("hex") && Array.isArray(rules) && !rules.some((rule) => (rule?.path === document || typeof rule?.name === "string" && rule.name.trim() === parsed.name) && rule.enabled !== false) && Array.isArray(plannedRules) && plannedRules.some((rule) => rule?.path === document && rule.enabled === false);
38990
39042
  if (denial && !explicitDeny)
38991
39043
  refuse3();
38992
39044
  if (explicitDeny)
@@ -39073,7 +39125,7 @@ enabled = false
39073
39125
  }
39074
39126
 
39075
39127
  // src/lib/codex-native-skill-policy.ts
39076
- import { createHash as createHash8, randomUUID as randomUUID2 } from "crypto";
39128
+ import { createHash as createHash9, randomUUID as randomUUID2 } from "crypto";
39077
39129
  import { closeSync as closeSync10, constants as constants7, fstatSync as fstatSync10, fsyncSync as fsyncSync2, lstatSync as lstatSync8, mkdirSync as mkdirSync4, openSync as openSync10, readFileSync as readFileSync10, readSync as readSync5, readlinkSync as readlinkSync3, realpathSync as realpathSync7, renameSync as renameSync2, unlinkSync as unlinkSync3, writeFileSync as writeFileSync3 } from "fs";
39078
39130
  import { dirname as dirname7, isAbsolute as isAbsolute7, join as join13, resolve as resolve6 } from "path";
39079
39131
  import { isDeepStrictEqual as isDeepStrictEqual3 } from "util";
@@ -39201,7 +39253,7 @@ function verifyCodexNativeBridgeDocument(path, expectedContent, expectedSha256)
39201
39253
  if (realpathSync7.native(path) !== path)
39202
39254
  refuse4("NATIVE_SKILL_POLICY_BRIDGE_UNVERIFIED", "the bridge document real path differs from its lexical path");
39203
39255
  const bytes = readBounded(path, MAX_BRIDGE_DOCUMENT_BYTES, "the bridge document");
39204
- const sha2562 = createHash8("sha256").update(bytes).digest("hex");
39256
+ const sha2562 = createHash9("sha256").update(bytes).digest("hex");
39205
39257
  if (!bytes.equals(Buffer.from(expectedContent, "utf8")) || sha2562 !== expectedSha256)
39206
39258
  refuse4("NATIVE_SKILL_POLICY_BRIDGE_UNVERIFIED", "the bridge document bytes differ from the managed bridge");
39207
39259
  return { path, sha256: sha2562 };
@@ -39669,8 +39721,8 @@ function recordCodexNativePolicyAcceptance(dataDir2, verification, accepted) {
39669
39721
  }
39670
39722
 
39671
39723
  // src/lib/codex-settings-witness-v1.ts
39672
- import { createHash as createHash9 } from "crypto";
39673
- var sha = (text) => createHash9("sha256").update(text).digest("hex");
39724
+ import { createHash as createHash10 } from "crypto";
39725
+ var sha = (text) => createHash10("sha256").update(text).digest("hex");
39674
39726
  var EFFORT = new Set(["none", "minimal", "low", "medium", "high", "xhigh"]);
39675
39727
  var VERBOSITY = new Set(["low", "medium", "high"]);
39676
39728
  function need2(value) {
@@ -39716,8 +39768,8 @@ function numericTokens(text) {
39716
39768
  }
39717
39769
  return result;
39718
39770
  }
39719
- function canonical2(value, depth = 0, budget = { remaining: 65536 }) {
39720
- need2(depth <= 32 && --budget.remaining >= 0);
39771
+ function canonical2(value, depth = 0, budget2 = { remaining: 65536 }) {
39772
+ need2(depth <= 32 && --budget2.remaining >= 0);
39721
39773
  if (value === null)
39722
39774
  return ["null"];
39723
39775
  if (typeof value === "string")
@@ -39733,13 +39785,13 @@ function canonical2(value, depth = 0, budget = { remaining: 65536 }) {
39733
39785
  return ["date", value.toISOString()];
39734
39786
  }
39735
39787
  if (Array.isArray(value))
39736
- return ["array", value.map((child) => canonical2(child, depth + 1, budget))];
39788
+ return ["array", value.map((child) => canonical2(child, depth + 1, budget2))];
39737
39789
  need2(value && typeof value === "object");
39738
- return ["object", Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, child]) => [key, canonical2(child, depth + 1, budget)])];
39790
+ return ["object", Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, child]) => [key, canonical2(child, depth + 1, budget2)])];
39739
39791
  }
39740
- function hashCodexSettingsReplacement(text, budget = { remaining: 256 * 1024 * 1024 }) {
39741
- need2(Buffer.byteLength(text) <= 1024 * 1024 && budget.remaining >= Buffer.byteLength(text));
39742
- budget.remaining -= Buffer.byteLength(text);
39792
+ function hashCodexSettingsReplacement(text, budget2 = { remaining: 256 * 1024 * 1024 }) {
39793
+ need2(Buffer.byteLength(text) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text));
39794
+ budget2.remaining -= Buffer.byteLength(text);
39743
39795
  let config;
39744
39796
  try {
39745
39797
  config = Bun.TOML.parse(text);
@@ -39758,8 +39810,8 @@ function hashCodexSettingsReplacement(text, budget = { remaining: 256 * 1024 * 1
39758
39810
  }
39759
39811
  return sha(`hasna.skills.codex-settings.v1\x00${JSON.stringify([canonical2(config), numericTokens(text)])}`);
39760
39812
  }
39761
- function captureCodexSettings(path, budget = { remaining: 256 * 1024 * 1024 }) {
39762
- const text = readNativeSettingsWitnessFile(path, budget, "config.toml");
39813
+ function captureCodexSettings(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
39814
+ const text = readNativeSettingsWitnessFile(path, budget2, "config.toml");
39763
39815
  return { path, hashMode: "codex-settings-v1", sha256: hashCodexSettingsReplacement(text) };
39764
39816
  }
39765
39817
  // src/lib/codex-mcp-discovery-projection.ts
@@ -39827,9 +39879,9 @@ function projectRegularCodexMcp(config, source) {
39827
39879
  }
39828
39880
 
39829
39881
  // src/lib/codex-settings-witness.ts
39830
- import { createHash as createHash10 } from "crypto";
39882
+ import { createHash as createHash11 } from "crypto";
39831
39883
  import { isDeepStrictEqual as isDeepStrictEqual5 } from "util";
39832
- var sha2 = (text) => createHash10("sha256").update(text).digest("hex");
39884
+ var sha2 = (text) => createHash11("sha256").update(text).digest("hex");
39833
39885
  var EFFORT2 = new Set(["none", "minimal", "low", "medium", "high", "xhigh"]);
39834
39886
  var VERBOSITY2 = new Set(["low", "medium", "high"]);
39835
39887
  var MODEL = /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,127}$/;
@@ -39884,8 +39936,8 @@ function numericTokens2(text) {
39884
39936
  }
39885
39937
  return result.sort();
39886
39938
  }
39887
- function canonical3(value, depth = 0, budget = { remaining: 65536 }) {
39888
- need3(depth <= 32 && --budget.remaining >= 0);
39939
+ function canonical3(value, depth = 0, budget2 = { remaining: 65536 }) {
39940
+ need3(depth <= 32 && --budget2.remaining >= 0);
39889
39941
  if (value === null)
39890
39942
  return ["null"];
39891
39943
  if (typeof value === "string")
@@ -39901,9 +39953,9 @@ function canonical3(value, depth = 0, budget = { remaining: 65536 }) {
39901
39953
  return ["date", value.toISOString()];
39902
39954
  }
39903
39955
  if (Array.isArray(value))
39904
- return ["array", value.map((child) => canonical3(child, depth + 1, budget))];
39956
+ return ["array", value.map((child) => canonical3(child, depth + 1, budget2))];
39905
39957
  need3(isRecord(value));
39906
- return ["object", Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, child]) => [key, canonical3(child, depth + 1, budget)])];
39958
+ return ["object", Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, child]) => [key, canonical3(child, depth + 1, budget2)])];
39907
39959
  }
39908
39960
  function normalize2(config, version = 2) {
39909
39961
  if (isRecord(config.hooks)) {
@@ -40079,40 +40131,40 @@ function settingsDigest2(text, version = 2) {
40079
40131
  normalize2(projected.config, version);
40080
40132
  return sha2(`hasna.skills.codex-settings.v${version}\x00${JSON.stringify([canonical3(projected.config), numericTokens2(projected.numericSource)])}`);
40081
40133
  }
40082
- function hashCodexSettingsReplacementV2(text, budget = { remaining: 256 * 1024 * 1024 }) {
40083
- need3(Buffer.byteLength(text) <= 1024 * 1024 && budget.remaining >= Buffer.byteLength(text));
40084
- budget.remaining -= Buffer.byteLength(text);
40134
+ function hashCodexSettingsReplacementV2(text, budget2 = { remaining: 256 * 1024 * 1024 }) {
40135
+ need3(Buffer.byteLength(text) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text));
40136
+ budget2.remaining -= Buffer.byteLength(text);
40085
40137
  return settingsDigest2(text);
40086
40138
  }
40087
- function captureCodexSettingsV2(path, budget = { remaining: 256 * 1024 * 1024 }) {
40088
- const text = readNativeSettingsWitnessFile(path, budget, "config.toml");
40139
+ function captureCodexSettingsV2(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
40140
+ const text = readNativeSettingsWitnessFile(path, budget2, "config.toml");
40089
40141
  return { path, hashMode: "codex-settings-v2", sha256: settingsDigest2(text) };
40090
40142
  }
40091
- function readCodexSettingsPreimage(path, budget = { remaining: 2 * 1024 * 1024 }) {
40092
- return readNativeSettingsWitnessFile(path, budget, "config.toml");
40143
+ function readCodexSettingsPreimage(path, budget2 = { remaining: 2 * 1024 * 1024 }) {
40144
+ return readNativeSettingsWitnessFile(path, budget2, "config.toml");
40093
40145
  }
40094
40146
  function upgradeCodexSettingsWitness(previous, reviewedSettingsPath) {
40095
40147
  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));
40096
- const budget = { remaining: 2 * 1024 * 1024 };
40097
- const before = readNativeSettingsWitnessFile(reviewedSettingsPath, budget, "config.toml"), current = readNativeSettingsWitnessFile(previous.path, budget, "config.toml");
40148
+ const budget2 = { remaining: 2 * 1024 * 1024 };
40149
+ const before = readNativeSettingsWitnessFile(reviewedSettingsPath, budget2, "config.toml"), current = readNativeSettingsWitnessFile(previous.path, budget2, "config.toml");
40098
40150
  need3((previous.hashMode === "codex-settings-v1" ? hashCodexSettingsReplacement(before) : sha2(before)) === previous.sha256);
40099
40151
  const sha2562 = settingsDigest2(current);
40100
40152
  if (settingsDigest2(before) !== sha2562)
40101
40153
  throw new Error("Codex non-preference settings changed; explicit discovery review required");
40102
40154
  return { path: previous.path, hashMode: "codex-settings-v2", sha256: sha2562 };
40103
40155
  }
40104
- function hashCodexSettingsReplacementV3(text, budget = { remaining: 256 * 1024 * 1024 }) {
40105
- need3(Buffer.byteLength(text) <= 1024 * 1024 && budget.remaining >= Buffer.byteLength(text));
40106
- budget.remaining -= Buffer.byteLength(text);
40156
+ function hashCodexSettingsReplacementV3(text, budget2 = { remaining: 256 * 1024 * 1024 }) {
40157
+ need3(Buffer.byteLength(text) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text));
40158
+ budget2.remaining -= Buffer.byteLength(text);
40107
40159
  return settingsDigest2(text, 3);
40108
40160
  }
40109
- function captureCodexSettingsV3(path, budget = { remaining: 256 * 1024 * 1024 }) {
40110
- return { path, hashMode: "codex-settings-v3", sha256: settingsDigest2(readNativeSettingsWitnessFile(path, budget, "config.toml"), 3) };
40161
+ function captureCodexSettingsV3(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
40162
+ return { path, hashMode: "codex-settings-v3", sha256: settingsDigest2(readNativeSettingsWitnessFile(path, budget2, "config.toml"), 3) };
40111
40163
  }
40112
40164
  function upgradeCodexSettingsWitnessV3(previous, reviewedSettingsPath) {
40113
40165
  need3(previous && Object.keys(previous).every((key) => ["path", "hashMode", "sha256"].includes(key)) && (previous.hashMode === undefined || ["bytes", "codex-settings-v1", "codex-settings-v2"].includes(previous.hashMode)) && /^[a-f0-9]{64}$/.test(previous.sha256));
40114
- const budget = { remaining: 2 * 1024 * 1024 };
40115
- const before = readNativeSettingsWitnessFile(reviewedSettingsPath, budget, "config.toml"), current = readNativeSettingsWitnessFile(previous.path, budget, "config.toml");
40166
+ const budget2 = { remaining: 2 * 1024 * 1024 };
40167
+ const before = readNativeSettingsWitnessFile(reviewedSettingsPath, budget2, "config.toml"), current = readNativeSettingsWitnessFile(previous.path, budget2, "config.toml");
40116
40168
  const original = previous.hashMode === "codex-settings-v2" ? settingsDigest2(before) : previous.hashMode === "codex-settings-v1" ? hashCodexSettingsReplacement(before) : sha2(before);
40117
40169
  need3(original === previous.sha256);
40118
40170
  const sha2562 = settingsDigest2(current, 3);
@@ -40120,18 +40172,18 @@ function upgradeCodexSettingsWitnessV3(previous, reviewedSettingsPath) {
40120
40172
  throw new Error("Codex settings outside the reviewed V3 contract changed; explicit discovery review required");
40121
40173
  return { path: previous.path, hashMode: "codex-settings-v3", sha256: sha2562 };
40122
40174
  }
40123
- function hashCodexSettingsReplacementV4(text, budget = { remaining: 256 * 1024 * 1024 }) {
40124
- need3(Buffer.byteLength(text) <= 1024 * 1024 && budget.remaining >= Buffer.byteLength(text));
40125
- budget.remaining -= Buffer.byteLength(text);
40175
+ function hashCodexSettingsReplacementV4(text, budget2 = { remaining: 256 * 1024 * 1024 }) {
40176
+ need3(Buffer.byteLength(text) <= 1024 * 1024 && budget2.remaining >= Buffer.byteLength(text));
40177
+ budget2.remaining -= Buffer.byteLength(text);
40126
40178
  return settingsDigest2(text, 4);
40127
40179
  }
40128
- function captureCodexSettingsV4(path, budget = { remaining: 256 * 1024 * 1024 }) {
40129
- return { path, hashMode: "codex-settings-v4", sha256: settingsDigest2(readNativeSettingsWitnessFile(path, budget, "config.toml"), 4) };
40180
+ function captureCodexSettingsV4(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
40181
+ return { path, hashMode: "codex-settings-v4", sha256: settingsDigest2(readNativeSettingsWitnessFile(path, budget2, "config.toml"), 4) };
40130
40182
  }
40131
40183
  function upgradeCodexSettingsWitnessV4(previous, reviewedSettingsPath) {
40132
40184
  need3(previous && Object.keys(previous).every((key) => ["path", "hashMode", "sha256"].includes(key)) && (previous.hashMode === undefined || ["bytes", "codex-settings-v1", "codex-settings-v2", "codex-settings-v3"].includes(previous.hashMode)) && /^[a-f0-9]{64}$/.test(previous.sha256));
40133
- const budget = { remaining: 2 * 1024 * 1024 };
40134
- const before = readNativeSettingsWitnessFile(reviewedSettingsPath, budget, "config.toml"), current = readNativeSettingsWitnessFile(previous.path, budget, "config.toml");
40185
+ const budget2 = { remaining: 2 * 1024 * 1024 };
40186
+ const before = readNativeSettingsWitnessFile(reviewedSettingsPath, budget2, "config.toml"), current = readNativeSettingsWitnessFile(previous.path, budget2, "config.toml");
40135
40187
  const original = previous.hashMode === "codex-settings-v3" ? settingsDigest2(before, 3) : previous.hashMode === "codex-settings-v2" ? settingsDigest2(before, 2) : previous.hashMode === "codex-settings-v1" ? hashCodexSettingsReplacement(before) : sha2(before);
40136
40188
  need3(original === previous.sha256);
40137
40189
  const sha2562 = settingsDigest2(current, 4);
@@ -40162,7 +40214,7 @@ var NATIVE_SKILL_ROOTS = [
40162
40214
  ];
40163
40215
 
40164
40216
  // src/lib/agent-integration.ts
40165
- import { createHash as createHash21, randomUUID as randomUUID4 } from "crypto";
40217
+ import { createHash as createHash22, randomUUID as randomUUID4 } from "crypto";
40166
40218
  import { isDeepStrictEqual as isDeepStrictEqual8 } from "util";
40167
40219
  import { existsSync as existsSync7, lstatSync as lstatSync22, statSync as statSync7, mkdirSync as mkdirSync6, readFileSync as readFileSync16, readdirSync as readdirSync8, opendirSync as opendirSync5, readlinkSync as readlinkSync5, realpathSync as realpathSync10, renameSync as renameSync4, rmdirSync as rmdirSync3, writeFileSync as writeFileSync5, unlinkSync as unlinkSync5, chmodSync, openSync as openSync17, closeSync as closeSync17, fsyncSync as fsyncSync5, fstatSync as fstatSync17, readSync as readSync12, constants as constants14, linkSync as linkSync3 } from "fs";
40168
40220
  import { dirname as dirname17, join as join26, resolve as resolve18, relative as relative5, isAbsolute as isAbsolute19, sep as sep6 } from "path";
@@ -40315,7 +40367,9 @@ function assertAgentPolicyCollections(policy) {
40315
40367
  text(source.path);
40316
40368
  requireBound(source.sha256 === null || typeof source.sha256 === "string" && /^[a-f0-9]{64}$/.test(source.sha256));
40317
40369
  if (source.hashMode !== undefined)
40318
- 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", "codex-settings-v3", "codex-settings-v4"].includes(source.hashMode) && source.format === undefined && source.fields === undefined && (source.hashMode === "bytes" || source.sha256 !== null));
40370
+ 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", "codex-settings-v3", "codex-settings-v4", "sumi-settings-v1"].includes(source.hashMode) && source.format === undefined && source.fields === undefined && (source.hashMode === "bytes" || source.sha256 !== null));
40371
+ if (source.hashMode === "sumi-settings-v1")
40372
+ requireBound(agent === "sumi" && value.agent === "sumi" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute8(source.path) && resolve7(source.path) === source.path && basename5(source.path) === "sumi.json");
40319
40373
  if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4"))
40320
40374
  requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute8(source.path) && resolve7(source.path) === source.path && basename5(source.path) === "config.toml");
40321
40375
  if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3")
@@ -40430,7 +40484,7 @@ function requiresCliSkillLoading(dataDir2 = getDataDirReadOnly()) {
40430
40484
  }
40431
40485
 
40432
40486
  // src/lib/agent-bridge.ts
40433
- import { createHash as createHash11 } from "crypto";
40487
+ import { createHash as createHash12 } from "crypto";
40434
40488
  import { lstatSync as lstatSync10, readFileSync as readFileSync11, readdirSync as readdirSync4 } from "fs";
40435
40489
  import { join as join15 } from "path";
40436
40490
  var CLI_BRIDGE_NAME = "skills-cli";
@@ -40449,7 +40503,7 @@ Use the Skills CLI as the skill authority for this station.
40449
40503
 
40450
40504
  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.
40451
40505
  `;
40452
- var CLI_BRIDGE_DIGEST = createHash11("sha256").update(markdown).digest("hex");
40506
+ var CLI_BRIDGE_DIGEST = createHash12("sha256").update(markdown).digest("hex");
40453
40507
  var CLI_BRIDGE_FILES = Object.freeze({
40454
40508
  "SKILL.md": markdown,
40455
40509
  ".hasna-skills.json": `${JSON.stringify({ managedBy: "@hasna/skills", kind: "cli-bridge", version: CLI_BRIDGE_VERSION, protocol: "selection-v1", contentSha256: CLI_BRIDGE_DIGEST }, null, 2)}
@@ -40473,7 +40527,7 @@ function isOwnedCliBridge(path, expectedPaths) {
40473
40527
  }
40474
40528
 
40475
40529
  // src/lib/agent-discovery.ts
40476
- import { createHash as createHash20 } from "crypto";
40530
+ import { createHash as createHash21 } from "crypto";
40477
40531
  import { lstatSync as lstatSync21, readFileSync as readFileSync15, readdirSync as readdirSync7, realpathSync as realpathSync9 } from "fs";
40478
40532
  import { basename as basename8, dirname as dirname16, isAbsolute as isAbsolute18, join as join25, resolve as resolve17, sep as sep5 } from "path";
40479
40533
  import { isDeepStrictEqual as isDeepStrictEqual6 } from "util";
@@ -40732,7 +40786,7 @@ if (failed) process.exitCode = 2;
40732
40786
  }
40733
40787
 
40734
40788
  // src/lib/agent-discovery-directories.ts
40735
- import { createHash as createHash12 } from "crypto";
40789
+ import { createHash as createHash13 } from "crypto";
40736
40790
  import { lstatSync as lstatSync12, opendirSync as opendirSync2 } from "fs";
40737
40791
  import { dirname as dirname9, isAbsolute as isAbsolute10, join as join17, resolve as resolve9 } from "path";
40738
40792
  function need4(value, message) {
@@ -40750,7 +40804,7 @@ function safe(path) {
40750
40804
  function same(before, after) {
40751
40805
  return Boolean(after && after.isDirectory() && before.dev === after.dev && before.ino === after.ino && before.mtimeMs === after.mtimeMs && before.ctimeMs === after.ctimeMs);
40752
40806
  }
40753
- function capture(path, budget, excludedRoots, omittedRoots = [], rows) {
40807
+ function capture(path, budget2, excludedRoots, omittedRoots = [], rows) {
40754
40808
  safe(path);
40755
40809
  if (omittedRoots.some((root2) => path === root2 || path.startsWith(root2 + "/")))
40756
40810
  return { path, sha256: null };
@@ -40758,13 +40812,13 @@ function capture(path, budget, excludedRoots, omittedRoots = [], rows) {
40758
40812
  if (!root)
40759
40813
  return { path, sha256: null };
40760
40814
  need4(root.isDirectory(), "Unsupported native discovery directory input");
40761
- const hash2 = createHash12("sha256");
40815
+ const hash2 = createHash13("sha256");
40762
40816
  function walk2(current, relative5, before, depth) {
40763
40817
  need4(depth <= 64, "Native discovery directory depth limit exceeded");
40764
40818
  const names = [], directory = opendirSync2(current);
40765
40819
  try {
40766
40820
  for (let entry = directory.readSync();entry; entry = directory.readSync()) {
40767
- need4(++budget.entries <= AGENT_POLICY_LIMITS.discoveryDirectoryEntries, "Native discovery directory entry limit exceeded");
40821
+ need4(++budget2.entries <= AGENT_POLICY_LIMITS.discoveryDirectoryEntries, "Native discovery directory entry limit exceeded");
40768
40822
  names.push(entry.name);
40769
40823
  }
40770
40824
  } finally {
@@ -40780,8 +40834,8 @@ function capture(path, budget, excludedRoots, omittedRoots = [], rows) {
40780
40834
  need4(stat.isFile() || stat.isDirectory(), "Refusing symlink or special native discovery directory member");
40781
40835
  const row = JSON.stringify([childRelative, stat.isDirectory() ? "directory" : "file"]) + `
40782
40836
  `;
40783
- budget.bytes += Buffer.byteLength(row);
40784
- need4(budget.bytes <= AGENT_POLICY_LIMITS.discoveryDirectoryBytes, "Native discovery directory metadata limit exceeded");
40837
+ budget2.bytes += Buffer.byteLength(row);
40838
+ need4(budget2.bytes <= AGENT_POLICY_LIMITS.discoveryDirectoryBytes, "Native discovery directory metadata limit exceeded");
40785
40839
  hash2.update(row);
40786
40840
  rows?.push(row);
40787
40841
  if (stat.isDirectory() && !excludedRoots.includes(child))
@@ -40798,10 +40852,10 @@ function captureDiscoveryDirectoryProjection(paths, omittedRoots) {
40798
40852
  need4(omittedRoots.length <= AGENT_POLICY_LIMITS.discoveryRoots && new Set(omittedRoots).size === omittedRoots.length, "Invalid inactive discovery roots");
40799
40853
  for (const root of omittedRoots)
40800
40854
  safe(root);
40801
- const budget = { entries: 0, bytes: 0 };
40855
+ const budget2 = { entries: 0, bytes: 0 };
40802
40856
  return paths.map((path) => {
40803
40857
  const entries = [];
40804
- return { ...capture(path, budget, [], omittedRoots, entries), entries };
40858
+ return { ...capture(path, budget2, [], omittedRoots, entries), entries };
40805
40859
  });
40806
40860
  }
40807
40861
  function verifyDiscoveryDirectoryProjection(directories, omittedRoots) {
@@ -40810,7 +40864,7 @@ function verifyDiscoveryDirectoryProjection(directories, omittedRoots) {
40810
40864
  const expected = directories.map((directory) => {
40811
40865
  safe(directory.path);
40812
40866
  need4(Array.isArray(directory.entries), "Missing reviewed directory membership inventory");
40813
- const hash2 = createHash12("sha256");
40867
+ const hash2 = createHash13("sha256");
40814
40868
  const kept = [];
40815
40869
  for (const row of directory.entries) {
40816
40870
  need4(typeof row === "string" && ++count <= AGENT_POLICY_LIMITS.discoveryDirectoryEntries, "Invalid reviewed directory membership rows");
@@ -40826,17 +40880,17 @@ function verifyDiscoveryDirectoryProjection(directories, omittedRoots) {
40826
40880
  }
40827
40881
  need4(directory.sha256 === null ? directory.entries.length === 0 : hash2.digest("hex") === directory.sha256, "Reviewed directory inventory does not match its fingerprint");
40828
40882
  const absent = omittedRoots.some((root) => directory.path === root || directory.path.startsWith(root + "/"));
40829
- return { path: directory.path, sha256: absent || directory.sha256 === null ? null : createHash12("sha256").update(kept.join("")).digest("hex") };
40883
+ return { path: directory.path, sha256: absent || directory.sha256 === null ? null : createHash13("sha256").update(kept.join("")).digest("hex") };
40830
40884
  });
40831
40885
  const current = captureDiscoveryDirectoryProjection(directories.map((item) => item.path), omittedRoots);
40832
40886
  need4(current.every((item, index) => item.sha256 === expected[index].sha256), "Native discovery directory membership changed outside retired Codex roots");
40833
40887
  }
40834
40888
  function captureDiscoveryDirectories(paths, excludedRoots = []) {
40835
40889
  need4(Array.isArray(paths) && paths.length <= AGENT_POLICY_LIMITS.discoveryDirectories && new Set(paths).size === paths.length, "Invalid native discovery directory collection");
40836
- const budget = { entries: 0, bytes: 0 };
40890
+ const budget2 = { entries: 0, bytes: 0 };
40837
40891
  for (const root of excludedRoots)
40838
40892
  safe(root);
40839
- return paths.map((path) => capture(path, budget, excludedRoots));
40893
+ return paths.map((path) => capture(path, budget2, excludedRoots));
40840
40894
  }
40841
40895
  function verifyDiscoveryDirectories(directories, excludedRoots = []) {
40842
40896
  need4(Array.isArray(directories) && directories.length <= AGENT_POLICY_LIMITS.discoveryDirectories, "Invalid native discovery directory collection");
@@ -40848,7 +40902,7 @@ function verifyDiscoveryDirectories(directories, excludedRoots = []) {
40848
40902
  }
40849
40903
 
40850
40904
  // src/lib/agent-discovery-bytes.ts
40851
- import { createHash as createHash13 } from "crypto";
40905
+ import { createHash as createHash14 } from "crypto";
40852
40906
  import { closeSync as closeSync12, constants as constants9, fstatSync as fstatSync12, lstatSync as lstatSync13, openSync as openSync12, readSync as readSync7 } from "fs";
40853
40907
  import { dirname as dirname10, isAbsolute as isAbsolute11, resolve as resolve10 } from "path";
40854
40908
  function discoveryByteBudget() {
@@ -40867,33 +40921,33 @@ function safe2(path) {
40867
40921
  function same2(left, right) {
40868
40922
  return left.dev === right.dev && left.ino === right.ino && left.size === right.size && left.mtimeMs === right.mtimeMs && left.ctimeMs === right.ctimeMs;
40869
40923
  }
40870
- function consume(budget, bytes) {
40871
- if (bytes > budget.remaining)
40924
+ function consume(budget2, bytes) {
40925
+ if (bytes > budget2.remaining)
40872
40926
  throw new Error("Raw discovery aggregate byte limit exceeded");
40873
- budget.remaining -= bytes;
40927
+ budget2.remaining -= bytes;
40874
40928
  }
40875
- function hashRawDiscoveryFile(path, budget, changes) {
40929
+ function hashRawDiscoveryFile(path, budget2, changes) {
40876
40930
  safe2(path);
40877
40931
  if (changes?.has(path)) {
40878
40932
  const text2 = changes.get(path), bytes = Buffer.byteLength(text2);
40879
40933
  if (bytes > AGENT_POLICY_LIMITS.discoveryRawSourceBytes)
40880
40934
  throw new Error("Raw discovery file byte limit exceeded");
40881
- consume(budget, bytes);
40882
- return createHash13("sha256").update(text2).digest("hex");
40935
+ consume(budget2, bytes);
40936
+ return createHash14("sha256").update(text2).digest("hex");
40883
40937
  }
40884
40938
  const initial = lstatSync13(path, { throwIfNoEntry: false });
40885
40939
  if (!initial)
40886
40940
  return null;
40887
40941
  if (!initial.isFile() || initial.size > AGENT_POLICY_LIMITS.discoveryRawSourceBytes)
40888
40942
  throw new Error("Unsupported or oversized raw discovery input");
40889
- if (initial.size > budget.remaining)
40943
+ if (initial.size > budget2.remaining)
40890
40944
  throw new Error("Raw discovery aggregate byte limit exceeded");
40891
40945
  const fd = openSync12(path, constants9.O_RDONLY | constants9.O_NOFOLLOW | constants9.O_NONBLOCK);
40892
40946
  try {
40893
40947
  const opened = fstatSync12(fd);
40894
40948
  if (!opened.isFile() || !same2(initial, opened))
40895
40949
  throw new Error("Raw discovery input changed during open");
40896
- const hash2 = createHash13("sha256"), buffer = Buffer.alloc(64 * 1024);
40950
+ const hash2 = createHash14("sha256"), buffer = Buffer.alloc(64 * 1024);
40897
40951
  let bytes = 0;
40898
40952
  while (true) {
40899
40953
  const count = readSync7(fd, buffer, 0, Math.min(buffer.length, AGENT_POLICY_LIMITS.discoveryRawSourceBytes - bytes + 1), null);
@@ -40902,7 +40956,7 @@ function hashRawDiscoveryFile(path, budget, changes) {
40902
40956
  bytes += count;
40903
40957
  if (bytes > AGENT_POLICY_LIMITS.discoveryRawSourceBytes)
40904
40958
  throw new Error("Raw discovery file byte limit exceeded");
40905
- consume(budget, count);
40959
+ consume(budget2, count);
40906
40960
  hash2.update(buffer.subarray(0, count));
40907
40961
  }
40908
40962
  const final = fstatSync12(fd), current = lstatSync13(path, { throwIfNoEntry: false });
@@ -40916,7 +40970,7 @@ function hashRawDiscoveryFile(path, budget, changes) {
40916
40970
  }
40917
40971
 
40918
40972
  // src/lib/agent-discovery-path-bytes.ts
40919
- import { createHash as createHash14 } from "crypto";
40973
+ import { createHash as createHash15 } from "crypto";
40920
40974
  import { lstatSync as lstatSync14, readlinkSync as readlinkSync4 } from "fs";
40921
40975
  import { dirname as dirname11, isAbsolute as isAbsolute12, join as join18, parse as parse3, resolve as resolve11, sep as sep4 } from "path";
40922
40976
  function identity4(stat, mutable = false) {
@@ -41003,7 +41057,7 @@ function trace(path) {
41003
41057
  }
41004
41058
  throw new Error("Unsupported directory discovery path input");
41005
41059
  }
41006
- function hashDiscoveryPathFile(path, budget, changes) {
41060
+ function hashDiscoveryPathFile(path, budget2, changes) {
41007
41061
  const before = trace(path);
41008
41062
  let createsMissingPath = false;
41009
41063
  if (before.missing !== null && changes) {
@@ -41016,17 +41070,17 @@ function hashDiscoveryPathFile(path, budget, changes) {
41016
41070
  }
41017
41071
  if (createsMissingPath || changes?.has(path) || before.paths.some((path2) => changes?.has(path2)))
41018
41072
  throw new Error("Discovery path witness intersects a planned write; use bytes mode for owned configuration");
41019
- const remaining = budget.pathMetadataRemaining ?? AGENT_POLICY_LIMITS.discoveryPathTotalMetadataBytes;
41073
+ const remaining = budget2.pathMetadataRemaining ?? AGENT_POLICY_LIMITS.discoveryPathTotalMetadataBytes;
41020
41074
  if (before.metadataBytes > remaining)
41021
41075
  throw new Error("Discovery path aggregate metadata limit exceeded");
41022
- budget.pathMetadataRemaining = remaining - before.metadataBytes;
41023
- const content = before.file === null ? null : hashRawDiscoveryFile(before.file, budget);
41076
+ budget2.pathMetadataRemaining = remaining - before.metadataBytes;
41077
+ const content = before.file === null ? null : hashRawDiscoveryFile(before.file, budget2);
41024
41078
  if (before.file !== null && content === null)
41025
41079
  throw new Error("Discovery path input changed during read");
41026
41080
  const after = trace(path);
41027
41081
  if (JSON.stringify(before.rows) !== JSON.stringify(after.rows) || before.file !== after.file)
41028
41082
  throw new Error("Discovery path input changed during read");
41029
- return createHash14("sha256").update(JSON.stringify({ version: 1, path, rows: before.rows, content })).digest("hex");
41083
+ return createHash15("sha256").update(JSON.stringify({ version: 1, path, rows: before.rows, content })).digest("hex");
41030
41084
  }
41031
41085
 
41032
41086
  // src/lib/plugin-discovery.ts
@@ -41038,7 +41092,7 @@ import { homedir as homedir2 } from "os";
41038
41092
  import { isAbsolute as isAbsolute15, join as join22, resolve as resolve13 } from "path";
41039
41093
 
41040
41094
  // src/lib/plugin-projection.ts
41041
- import { createHash as createHash15 } from "crypto";
41095
+ import { createHash as createHash16 } from "crypto";
41042
41096
  import { posix as posix2 } from "path";
41043
41097
  var PLUGIN_PROJECTION_MANIFEST = "plugin-projection.json";
41044
41098
  var PLUGIN_PROJECTION_LIMITS = Object.freeze({ files: 1024, bytes: 64 * 1024 * 1024, fileBytes: 16 * 1024 * 1024, metadataBytes: 512 * 1024, registrations: 64, history: 128 });
@@ -41049,7 +41103,7 @@ function pluginNeed(value, message) {
41049
41103
  if (!value)
41050
41104
  pluginRefusal(message);
41051
41105
  }
41052
- var pluginHash = (bytes) => createHash15("sha256").update(bytes).digest("hex");
41106
+ var pluginHash = (bytes) => createHash16("sha256").update(bytes).digest("hex");
41053
41107
  function pluginObject(value) {
41054
41108
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
41055
41109
  }
@@ -41237,7 +41291,7 @@ function buildPluginProjection(entries) {
41237
41291
  }
41238
41292
 
41239
41293
  // src/lib/plugin-projection-store.ts
41240
- import { createHash as createHash16, randomUUID as randomUUID3 } from "crypto";
41294
+ import { createHash as createHash17, randomUUID as randomUUID3 } from "crypto";
41241
41295
  import { constants as constants10, closeSync as closeSync13, fchmodSync, fstatSync as fstatSync13, fsyncSync as fsyncSync3, linkSync as linkSync2, lstatSync as lstatSync15, mkdirSync as mkdirSync5, openSync as openSync13, opendirSync as opendirSync3, readSync as readSync8, renameSync as renameSync3, rmdirSync as rmdirSync2, rmSync, unlinkSync as unlinkSync4, writeSync as writeSync2 } from "fs";
41242
41296
  import { dirname as dirname12, isAbsolute as isAbsolute13, join as join19, parse as parse5, resolve as resolve12 } from "path";
41243
41297
  var READ_FLAGS = constants10.O_RDONLY | constants10.O_NOFOLLOW | constants10.O_NONBLOCK;
@@ -41579,7 +41633,7 @@ function pluginExecutableDigest(path) {
41579
41633
  const opened = fstatSync13(fd, { bigint: true });
41580
41634
  same3(before, opened);
41581
41635
  fileShape(opened, maximum, "executable");
41582
- const hash2 = createHash16("sha256"), buffer = new Uint8Array(64 * 1024);
41636
+ const hash2 = createHash17("sha256"), buffer = new Uint8Array(64 * 1024);
41583
41637
  let remaining = Number(opened.size);
41584
41638
  while (remaining > 0) {
41585
41639
  const count = readSync8(fd, buffer, 0, Math.min(buffer.byteLength, remaining), null);
@@ -42574,7 +42628,7 @@ function captureManagedPluginRegistry(path, managedPlugins) {
42574
42628
  }
42575
42629
 
42576
42630
  // src/lib/claude-marketplace-registry.ts
42577
- import { createHash as createHash17 } from "crypto";
42631
+ import { createHash as createHash18 } from "crypto";
42578
42632
  import { closeSync as closeSync15, constants as constants12, fstatSync as fstatSync15, lstatSync as lstatSync18, openSync as openSync15, readSync as readSync10 } from "fs";
42579
42633
  import { basename as basename7, dirname as dirname14, isAbsolute as isAbsolute17, resolve as resolve15 } from "path";
42580
42634
  var CLAUDE_MARKETPLACE_REGISTRY_LIMITS = Object.freeze({ bytes: 1024 * 1024, rows: 1024, depth: 32, nodes: 65536, stringCharacters: 16384, pathCharacters: 4096 });
@@ -42596,13 +42650,13 @@ function parents2(path) {
42596
42650
  return result;
42597
42651
  }
42598
42652
  }
42599
- function readRegistry2(path, budget) {
42653
+ function readRegistry2(path, budget2) {
42600
42654
  absolutePath3(path);
42601
42655
  need5(basename7(path) === "known_marketplaces.json", "requires known_marketplaces.json");
42602
- need5(Number.isSafeInteger(budget.remaining) && budget.remaining >= 0, "has an invalid byte budget");
42656
+ need5(Number.isSafeInteger(budget2.remaining) && budget2.remaining >= 0, "has an invalid byte budget");
42603
42657
  const ancestors2 = parents2(path), initial = lstatSync18(path, { bigint: true });
42604
42658
  need5(initial.isFile() && !initial.isSymbolicLink() && initial.size <= BigInt(CLAUDE_MARKETPLACE_REGISTRY_LIMITS.bytes), "is not a bounded regular file");
42605
- need5(initial.size <= BigInt(budget.remaining), "exceeds its aggregate byte limit");
42659
+ need5(initial.size <= BigInt(budget2.remaining), "exceeds its aggregate byte limit");
42606
42660
  const fd = openSync15(path, constants12.O_RDONLY | constants12.O_NOFOLLOW | constants12.O_NONBLOCK);
42607
42661
  try {
42608
42662
  const opened = fstatSync15(fd, { bigint: true });
@@ -42621,7 +42675,7 @@ function readRegistry2(path, budget) {
42621
42675
  const now = lstatSync18(ancestor, { bigint: true });
42622
42676
  need5(now.isDirectory() && before.dev === now.dev && before.ino === now.ino && before.mode === now.mode, "parent changed during read");
42623
42677
  }
42624
- budget.remaining -= length;
42678
+ budget2.remaining -= length;
42625
42679
  try {
42626
42680
  return new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes.subarray(0, length));
42627
42681
  } catch {
@@ -42739,27 +42793,27 @@ function normalizeRow(row, version = 1) {
42739
42793
  need5(Number.isFinite(millis) && new Date(millis).toISOString() === updated, "contains an invalid recognized update timestamp");
42740
42794
  row.entries = row.entries.map(([key, value]) => [key, key === "lastUpdated" ? { kind: "validated-update-time" } : value]);
42741
42795
  }
42742
- function captureClaudeMarketplaceRegistry(path, budget = { remaining: 256 * 1024 * 1024 }) {
42743
- const value = parse6(readRegistry2(path, budget));
42796
+ function captureClaudeMarketplaceRegistry(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
42797
+ const value = parse6(readRegistry2(path, budget2));
42744
42798
  for (const [, row] of value.entries)
42745
42799
  normalizeRow(row);
42746
- const sha2562 = createHash17("sha256").update("hasna.skills.claude-marketplace-registry.v1\x00").update(JSON.stringify(value)).digest("hex");
42800
+ const sha2562 = createHash18("sha256").update("hasna.skills.claude-marketplace-registry.v1\x00").update(JSON.stringify(value)).digest("hex");
42747
42801
  return { path, hashMode: "claude-marketplace-registry", sha256: sha2562 };
42748
42802
  }
42749
- function captureClaudeMarketplaceRegistryV2(path, budget = { remaining: 256 * 1024 * 1024 }) {
42750
- const value = parse6(readRegistry2(path, budget));
42803
+ function captureClaudeMarketplaceRegistryV2(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
42804
+ const value = parse6(readRegistry2(path, budget2));
42751
42805
  for (const [, row] of value.entries)
42752
42806
  normalizeRow(row, 2);
42753
- const sha2562 = createHash17("sha256").update("hasna.skills.claude-marketplace-registry.v2\x00").update(JSON.stringify(value)).digest("hex");
42807
+ const sha2562 = createHash18("sha256").update("hasna.skills.claude-marketplace-registry.v2\x00").update(JSON.stringify(value)).digest("hex");
42754
42808
  return { path, hashMode: "claude-marketplace-registry-v2", sha256: sha2562 };
42755
42809
  }
42756
42810
 
42757
42811
  // src/lib/codex-hook-discovery-recovery.ts
42758
- import { createHash as createHash19 } from "crypto";
42812
+ import { createHash as createHash20 } from "crypto";
42759
42813
 
42760
42814
  // src/lib/codex-hook-trust-files.ts
42761
42815
  import { closeSync as closeSync16, constants as constants13, fstatSync as fstatSync16, fsyncSync as fsyncSync4, lstatSync as lstatSync19, openSync as openSync16, readSync as readSync11, writeFileSync as writeFileSync4 } from "fs";
42762
- import { createHash as createHash18 } from "crypto";
42816
+ import { createHash as createHash19 } from "crypto";
42763
42817
  import { dirname as dirname15 } from "path";
42764
42818
  function need6(value, code) {
42765
42819
  if (!value)
@@ -42795,7 +42849,7 @@ function snapshot(file, privateFile = false, options = {}) {
42795
42849
  }
42796
42850
  need6(length === Number(before.size) && sameStat(before, fstatSync16(fd, { bigint: true })) && sameStat(before, lstatSync19(file, { bigint: true })), "INPUT_CHANGED");
42797
42851
  const content = bytes.subarray(0, length), text2 = new TextDecoder("utf-8", { fatal: true }).decode(content);
42798
- return { file, privateFile, readOnlyPackage, text: text2, bytes: content, stat: before, sha256: createHash18("sha256").update(content).digest("hex") };
42852
+ return { file, privateFile, readOnlyPackage, text: text2, bytes: content, stat: before, sha256: createHash19("sha256").update(content).digest("hex") };
42799
42853
  } finally {
42800
42854
  closeSync16(fd);
42801
42855
  }
@@ -42811,7 +42865,7 @@ var matchedEvents = { ...events, PreToolUse: ["preToolUse", "pre_tool_use"] };
42811
42865
  var proofs = new WeakMap;
42812
42866
 
42813
42867
  // src/lib/codex-hook-discovery-recovery.ts
42814
- var sha3 = (text2) => createHash19("sha256").update(text2).digest("hex");
42868
+ var sha3 = (text2) => createHash20("sha256").update(text2).digest("hex");
42815
42869
  var fields = [...CODEX_DISCOVERY_PROJECTION_FIELDS];
42816
42870
  var proofs2 = new WeakMap;
42817
42871
  function assertCodexHookDiscoveryRecovery(binding, witness) {
@@ -42863,31 +42917,44 @@ function sumiConfigPath(home) {
42863
42917
  return join24(sumiConfigDirectory(home), "sumi.json");
42864
42918
  }
42865
42919
  function renderSumiPlugin(command, profile) {
42920
+ return renderSumiPluginVersion(command, profile, false);
42921
+ }
42922
+ function isManagedSumiPlugin(text2, command, profile) {
42923
+ return text2 === renderSumiPlugin(command, profile) || text2 === renderSumiPluginVersion(command, profile, true);
42924
+ }
42925
+ function renderSumiPluginVersion(command, profile, legacy) {
42926
+ const failure = (message) => legacy ? `new Error(${JSON.stringify(message)})` : "refusal()";
42866
42927
  return `// Managed by @hasna/skills. Regenerate with skills hook install --agent sumi.
42867
42928
  import { spawn } from "node:child_process";
42868
42929
  const command = ${JSON.stringify(command)};
42869
42930
  const profile = ${JSON.stringify(profile)};
42870
- function context(input) {
42931
+ ${legacy ? "" : `function refusal() {
42932
+ const error = new Error("Skills verification blocked this request. Review the Sumi Skills hook configuration, then retry.");
42933
+ error.name = "SkillsHookRefusal";
42934
+ error.skillsHookRefusal = { version: 1, code: "SKILLS_HOOK_REFUSED" };
42935
+ return error;
42936
+ }
42937
+ `}function context(input) {
42871
42938
  return new Promise((resolve, reject) => {
42872
42939
  const child = spawn(command, ["hook", "user-prompt", "--agent", "sumi", "--selection-profile", profile], { cwd: input.cwd, stdio: ["pipe", "pipe", "pipe"] });
42873
42940
  const chunks = []; let bytes = 0, failure;
42874
- const timer = setTimeout(() => { failure = new Error("Skills prompt hook timed out"); child.kill("SIGKILL"); }, 15000);
42875
- child.stdout.on("data", chunk => { bytes += chunk.length; if (bytes > 1048576) { failure = new Error("Skills prompt hook output exceeded its limit"); child.kill("SIGKILL"); } else chunks.push(chunk); });
42941
+ const timer = setTimeout(() => { failure = ${failure("Skills prompt hook timed out")}; child.kill("SIGKILL"); }, 15000);
42942
+ child.stdout.on("data", chunk => { bytes += chunk.length; if (bytes > 1048576) { failure = ${failure("Skills prompt hook output exceeded its limit")}; child.kill("SIGKILL"); } else chunks.push(chunk); });
42876
42943
  child.stderr.on("data", () => {});
42877
42944
  child.stdin.on("error", () => {});
42878
- child.on("error", error => { clearTimeout(timer); reject(error); });
42945
+ child.on("error", error => { clearTimeout(timer); reject(${legacy ? "error" : "refusal()"}); });
42879
42946
  child.on("close", code => {
42880
42947
  clearTimeout(timer);
42881
- if (failure || code !== 0) return reject(failure ?? new Error("Skills prompt hook failed"));
42948
+ if (failure || code !== 0) return reject(failure ?? ${failure("Skills prompt hook failed")});
42882
42949
  try {
42883
42950
  const result = JSON.parse(Buffer.concat(chunks).toString("utf8"));
42884
- if (!result || typeof result !== "object" || Array.isArray(result)) throw new Error("Invalid Skills hook response");
42885
- if (result.decision === "block" || result.continue === false) throw new Error("Skills prompt hook refused");
42886
- if (Object.keys(result).length && (!result.hookSpecificOutput || result.hookSpecificOutput.hookEventName !== input.hook_event_name)) throw new Error("Invalid Skills hook response");
42951
+ if (!result || typeof result !== "object" || Array.isArray(result)) throw ${failure("Invalid Skills hook response")};
42952
+ if (result.decision === "block" || result.continue === false) throw ${failure("Skills prompt hook refused")};
42953
+ if (Object.keys(result).length && (!result.hookSpecificOutput || result.hookSpecificOutput.hookEventName !== input.hook_event_name)) throw ${failure("Invalid Skills hook response")};
42887
42954
  const text = result.hookSpecificOutput?.additionalContext ?? "";
42888
- if (typeof text !== "string") throw new Error("Invalid Skills prompt context");
42955
+ if (typeof text !== "string") throw ${failure("Invalid Skills prompt context")};
42889
42956
  resolve(text);
42890
- } catch (error) { reject(error); }
42957
+ } catch (error) { reject(${legacy ? "error" : "refusal()"}); }
42891
42958
  });
42892
42959
  child.stdin.end(JSON.stringify(input));
42893
42960
  });
@@ -42895,13 +42962,14 @@ function context(input) {
42895
42962
  export default {
42896
42963
  id: "local.hasna-skills-cli",
42897
42964
  async setup(ctx) {
42898
- if (!ctx?.session?.hook || !ctx?.session?.get || !ctx?.skill?.transform || !ctx?.tool?.hook) throw new Error("Unsupported Sumi native Skills contract");
42965
+ if (!ctx?.session?.hook || !ctx?.session?.get || !ctx?.skill?.transform || !ctx?.tool?.hook) throw ${failure("Unsupported Sumi native Skills contract")};
42899
42966
  const registrations = [];
42900
42967
  const sessions = new Set();
42901
42968
  async function input(sessionID, prompt, first) {
42902
42969
  // The Promise adapter unwraps single-data endpoint responses.
42903
- const session = await ctx.session.get({ sessionID });
42904
- if (!session || session.id !== sessionID || typeof session.location?.directory !== "string" || (session.parentID !== undefined && typeof session.parentID !== "string") || session.parentID === sessionID) throw new Error("Invalid Sumi session custody");
42970
+ ${legacy ? "const session = await ctx.session.get({ sessionID });" : `let session;
42971
+ try { session = await ctx.session.get({ sessionID }); } catch { throw refusal(); }`}
42972
+ if (!session || session.id !== sessionID || typeof session.location?.directory !== "string" || (session.parentID !== undefined && typeof session.parentID !== "string") || session.parentID === sessionID) throw ${failure("Invalid Sumi session custody")};
42905
42973
  return { hook_event_name: first ? session.parentID ? "SubagentStart" : "SessionStart" : "UserPromptSubmit", cwd: session.location.directory, session_id: sessionID, parent_session_id: session.parentID ?? null, prompt, restore: true };
42906
42974
  }
42907
42975
  registrations.push(await ctx.skill.transform(editor => {
@@ -42910,11 +42978,11 @@ export default {
42910
42978
  // Native config transforms may add skills after this transform. Guard
42911
42979
  // both direct tool calls and prompt attachments at the consumption edge.
42912
42980
  registrations.push(await ctx.tool.hook("execute.before", event => {
42913
- if (event.tool === "skill" && event.input?.id !== "skills-cli") throw new Error("Native Sumi skill payload refused; use Skills CLI");
42981
+ if (event.tool === "skill" && event.input?.id !== "skills-cli") throw ${failure("Native Sumi skill payload refused; use Skills CLI")};
42914
42982
  }));
42915
42983
  registrations.push(await ctx.session.hook("prompt", async event => {
42916
- if (typeof event.prompt?.text !== "string") throw new Error("Invalid Sumi prompt");
42917
- if (event.prompt.skills !== undefined && (!Array.isArray(event.prompt.skills) || event.prompt.skills.some(skill => skill?.id !== "skills-cli"))) throw new Error("Native Sumi skill attachment refused; use Skills CLI");
42984
+ if (typeof event.prompt?.text !== "string") throw ${failure("Invalid Sumi prompt")};
42985
+ if (event.prompt.skills !== undefined && (!Array.isArray(event.prompt.skills) || event.prompt.skills.some(skill => skill?.id !== "skills-cli"))) throw ${failure("Native Sumi skill attachment refused; use Skills CLI")};
42918
42986
  await context(await input(event.sessionID, event.prompt.text, !sessions.has(event.sessionID)));
42919
42987
  sessions.add(event.sessionID);
42920
42988
  }));
@@ -42938,7 +43006,7 @@ var SUMI_SKILL_PERMISSIONS = [
42938
43006
  ];
42939
43007
 
42940
43008
  // src/lib/agent-discovery.ts
42941
- var digest2 = (text2) => createHash20("sha256").update(text2).digest("hex");
43009
+ var digest2 = (text2) => createHash21("sha256").update(text2).digest("hex");
42942
43010
  function parseConfig(text2, path, toml = false) {
42943
43011
  try {
42944
43012
  const value = toml ? Bun.TOML.parse(text2) : JSON.parse(text2);
@@ -42976,33 +43044,45 @@ function projectNativeDiscoveryFields(text2, format, fields2, path) {
42976
43044
  throw new Error("Expected native discovery configuration object");
42977
43045
  return digest2(JSON.stringify(Object.fromEntries(fields2.map((field2) => [field2, object6[field2] ?? null]))));
42978
43046
  }
42979
- function isSupersededCodexProjection(agent, configPath, source) {
43047
+ function isSupersededSettingsProjection(agent, configPath, source) {
43048
+ if (agent === "sumi")
43049
+ return source.path === configPath && source.format === "json" && isDeepStrictEqual6(source.fields, [...SUMI_DISCOVERY_PROJECTION_FIELDS]);
42980
43050
  return agent === "codex" && source.path === configPath && source.format === "toml" && isDeepStrictEqual6(source.fields, [...CODEX_DISCOVERY_PROJECTION_FIELDS]);
42981
43051
  }
42982
- function supersedesCodexProjection(sources, configPath) {
42983
- return sources.some((source) => source.path === configPath && (source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")));
43052
+ function supersedesSettingsProjection(agent, sources, configPath) {
43053
+ if (agent === "sumi")
43054
+ return sources.some((source) => source.path === configPath && source.hashMode === "sumi-settings-v1");
43055
+ return agent === "codex" && sources.some((source) => source.path === configPath && (source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")));
42984
43056
  }
42985
- function projected(source, changes, budget = discoveryByteBudget()) {
43057
+ function projected(source, changes, budget2 = discoveryByteBudget()) {
43058
+ if (source.hashMode === "sumi-settings-v1") {
43059
+ if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
43060
+ throw new Error("Sumi settings witnesses require exact typed metadata");
43061
+ const current = captureSumiSettings(source.path, budget2).sha256;
43062
+ if (current !== source.sha256)
43063
+ throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
43064
+ return changes?.has(source.path) ? hashSumiSettingsReplacement(changes.get(source.path), budget2) : current;
43065
+ }
42986
43066
  if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")) {
42987
43067
  if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
42988
43068
  throw new Error("Codex settings witnesses require exact typed metadata");
42989
- const current = (source.hashMode === "codex-settings-v4" ? captureCodexSettingsV4 : source.hashMode === "codex-settings-v3" ? captureCodexSettingsV3 : source.hashMode === "codex-settings-v2" ? captureCodexSettingsV2 : captureCodexSettings)(source.path, budget).sha256;
43069
+ const current = (source.hashMode === "codex-settings-v4" ? captureCodexSettingsV4 : source.hashMode === "codex-settings-v3" ? captureCodexSettingsV3 : source.hashMode === "codex-settings-v2" ? captureCodexSettingsV2 : captureCodexSettings)(source.path, budget2).sha256;
42990
43070
  if (current !== source.sha256)
42991
43071
  throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
42992
- return changes?.has(source.path) ? (source.hashMode === "codex-settings-v4" ? hashCodexSettingsReplacementV4 : source.hashMode === "codex-settings-v3" ? hashCodexSettingsReplacementV3 : source.hashMode === "codex-settings-v2" ? hashCodexSettingsReplacementV2 : hashCodexSettingsReplacement)(changes.get(source.path), budget) : current;
43072
+ return changes?.has(source.path) ? (source.hashMode === "codex-settings-v4" ? hashCodexSettingsReplacementV4 : source.hashMode === "codex-settings-v3" ? hashCodexSettingsReplacementV3 : source.hashMode === "codex-settings-v2" ? hashCodexSettingsReplacementV2 : hashCodexSettingsReplacement)(changes.get(source.path), budget2) : current;
42993
43073
  }
42994
43074
  if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") {
42995
43075
  if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
42996
43076
  throw new Error("Claude settings witnesses require exact typed metadata");
42997
- const current = (source.hashMode === "claude-settings-v3" ? captureClaudeSettingsV3 : source.hashMode === "claude-settings-v2" ? captureClaudeSettingsV2 : captureClaudeSettings)(source.path, budget).sha256;
43077
+ const current = (source.hashMode === "claude-settings-v3" ? captureClaudeSettingsV3 : source.hashMode === "claude-settings-v2" ? captureClaudeSettingsV2 : captureClaudeSettings)(source.path, budget2).sha256;
42998
43078
  if (current !== source.sha256)
42999
43079
  throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
43000
- return changes?.has(source.path) ? (source.hashMode === "claude-settings-v3" ? hashClaudeSettingsReplacementV3 : source.hashMode === "claude-settings-v2" ? hashClaudeSettingsReplacementV2 : hashClaudeSettingsReplacement)(changes.get(source.path), budget) : current;
43080
+ return changes?.has(source.path) ? (source.hashMode === "claude-settings-v3" ? hashClaudeSettingsReplacementV3 : source.hashMode === "claude-settings-v2" ? hashClaudeSettingsReplacementV2 : hashClaudeSettingsReplacement)(changes.get(source.path), budget2) : current;
43001
43081
  }
43002
43082
  if (source.hashMode === "claude-marketplace-registry" || source.hashMode === "claude-marketplace-registry-v2") {
43003
43083
  if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256) || changes?.has(source.path))
43004
43084
  throw new Error("Claude marketplace witnesses require an exact reviewed registry without synthetic changes");
43005
- const sha2562 = (source.hashMode === "claude-marketplace-registry-v2" ? captureClaudeMarketplaceRegistryV2 : captureClaudeMarketplaceRegistry)(source.path, budget).sha256;
43085
+ const sha2562 = (source.hashMode === "claude-marketplace-registry-v2" ? captureClaudeMarketplaceRegistryV2 : captureClaudeMarketplaceRegistry)(source.path, budget2).sha256;
43006
43086
  if (sha2562 !== source.sha256)
43007
43087
  throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
43008
43088
  return sha2562;
@@ -43020,8 +43100,8 @@ function projected(source, changes, budget = discoveryByteBudget()) {
43020
43100
  if (source.format !== undefined || source.fields !== undefined)
43021
43101
  throw new Error("Raw discovery witnesses cannot project configuration fields");
43022
43102
  if (source.hashMode === "path-bytes")
43023
- return hashDiscoveryPathFile(source.path, budget, changes);
43024
- return hashRawDiscoveryFile(source.path, budget, changes);
43103
+ return hashDiscoveryPathFile(source.path, budget2, changes);
43104
+ return hashRawDiscoveryFile(source.path, budget2, changes);
43025
43105
  }
43026
43106
  const text2 = read2(source.path, changes);
43027
43107
  if (text2 === null)
@@ -43169,7 +43249,7 @@ function verifyAgentDiscovery(binding, codexRecovery) {
43169
43249
  verifyDiscoveryDirectories(projected2, installationRoots);
43170
43250
  }
43171
43251
  const absentRoots = [...absentCodexSkillRoots(binding), ...absentRetiredClaudeRoots(binding), ...retiredRoots.filter((root2) => !lstatSync21(root2, { throwIfNoEntry: false }))];
43172
- const budget = discoveryByteBudget();
43252
+ const budget2 = discoveryByteBudget();
43173
43253
  for (const source of binding.sources) {
43174
43254
  assertMarketplaceBinding(binding, source);
43175
43255
  if (source.hashMode === "claude-plugin-registry" && binding.agent !== "claude")
@@ -43186,7 +43266,7 @@ function verifyAgentDiscovery(binding, codexRecovery) {
43186
43266
  safe4(source.path);
43187
43267
  continue;
43188
43268
  }
43189
- const current = projected(source, undefined, budget);
43269
+ const current = projected(source, undefined, budget2);
43190
43270
  if (current !== source.sha256 && !verifiesCodexHookDiscoverySource(binding, source, current, codexRecovery))
43191
43271
  throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
43192
43272
  }
@@ -43220,6 +43300,8 @@ function codexInstallationRoots(binding) {
43220
43300
  });
43221
43301
  }
43222
43302
  function assertMarketplaceBinding(binding, source) {
43303
+ if (source.hashMode === "sumi-settings-v1" && (binding.agent !== "sumi" || binding.method !== "reviewed" || basename8(source.path) !== "sumi.json"))
43304
+ throw new Error("Sumi settings witnesses require explicit reviewed Sumi configuration");
43223
43305
  if ((source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")) && (binding.agent !== "codex" || binding.method !== "reviewed" || basename8(source.path) !== "config.toml"))
43224
43306
  throw new Error("Codex settings witnesses require explicit reviewed Codex configuration");
43225
43307
  if ((source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") && (binding.agent !== "claude" || binding.method !== "reviewed" || basename8(source.path) !== "settings.json"))
@@ -43228,13 +43310,13 @@ function assertMarketplaceBinding(binding, source) {
43228
43310
  throw new Error("Claude marketplace witnesses require explicit reviewed Claude discovery");
43229
43311
  }
43230
43312
  function rebindAgentDiscovery(binding, changes) {
43231
- const budget = discoveryByteBudget();
43313
+ const budget2 = discoveryByteBudget();
43232
43314
  const installationRoots = codexInstallationRoots(binding), absentRoots = [...absentCodexSkillRoots(binding), ...absentRetiredClaudeRoots(binding), ...retiredCodexRoots(binding).filter((root2) => !lstatSync21(root2, { throwIfNoEntry: false }))];
43233
43315
  const rebound = { ...binding, sources: binding.sources.map((source) => {
43234
43316
  assertMarketplaceBinding(binding, source);
43235
43317
  if (!changes.has(source.path) && (installationRoots.some((root2) => source.path.startsWith(root2 + sep5)) || absentRoots.some((root2) => source.path.startsWith(root2 + sep5)) && source.format === undefined && source.fields === undefined && source.managedPlugins === undefined && [undefined, "bytes"].includes(source.hashMode)))
43236
43318
  return source;
43237
- const sha2562 = projected(source, changes, budget);
43319
+ const sha2562 = projected(source, changes, budget2);
43238
43320
  if (!changes.has(source.path) && sha2562 !== source.sha256)
43239
43321
  throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
43240
43322
  return { ...source, sha256: sha2562 };
@@ -43249,14 +43331,14 @@ function rebindAgentDiscovery(binding, changes) {
43249
43331
  function captureDiscoveryByteSources(paths) {
43250
43332
  if (!Array.isArray(paths) || paths.length > AGENT_POLICY_LIMITS.discoverySources || new Set(paths).size !== paths.length)
43251
43333
  throw new Error("Invalid raw discovery source collection");
43252
- const budget = discoveryByteBudget();
43253
- return paths.map((path) => ({ path, hashMode: "bytes", sha256: hashRawDiscoveryFile(path, budget) }));
43334
+ const budget2 = discoveryByteBudget();
43335
+ return paths.map((path) => ({ path, hashMode: "bytes", sha256: hashRawDiscoveryFile(path, budget2) }));
43254
43336
  }
43255
43337
  function captureDiscoveryPathSources(paths) {
43256
43338
  if (!Array.isArray(paths) || paths.length > AGENT_POLICY_LIMITS.discoverySources || new Set(paths).size !== paths.length)
43257
43339
  throw new Error("Invalid path discovery source collection");
43258
- const budget = discoveryByteBudget();
43259
- return paths.map((path) => ({ path, hashMode: "path-bytes", sha256: hashDiscoveryPathFile(path, budget) }));
43340
+ const budget2 = discoveryByteBudget();
43341
+ return paths.map((path) => ({ path, hashMode: "path-bytes", sha256: hashDiscoveryPathFile(path, budget2) }));
43260
43342
  }
43261
43343
  function assertProjectDiscovery(agent, directories, home, canonical6 = resolve17, reviewed) {
43262
43344
  const homeConfigPath = canonical6(agentDiscoveryConfigPath(home, agent));
@@ -43324,7 +43406,7 @@ function resolveAgentDiscovery(options) {
43324
43406
  if (agent === "hermes")
43325
43407
  assertHermesEnvironment(home);
43326
43408
  const configPath = agentDiscoveryConfigPath(home, agent);
43327
- 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"] : agent === "sumi" ? ["skills", "plugin", "plugins", "permissions"] : ["version"]);
43409
+ 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"] : agent === "sumi" ? [...SUMI_DISCOVERY_PROJECTION_FIELDS] : ["version"]);
43328
43410
  const config = configText === null ? {} : agent === "hermes" ? parseHermesConfig(configText) : parseConfig(configText, configPath, agent === "codex");
43329
43411
  const unresolved = (detail) => {
43330
43412
  throw new Error(`Native discovery is unresolved (${agent}: ${detail}); provide a reviewed --discovery-inputs file`);
@@ -43421,9 +43503,9 @@ function resolveAgentDiscovery(options) {
43421
43503
  verifyAgentDiscovery(retained);
43422
43504
  if (!retained.sources.some((source) => source.path === canonical6(configPath) && source.format === undefined && source.fields === undefined))
43423
43505
  unresolved("retained review is missing the full agent configuration source");
43424
- 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.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")))) && source.path !== canonical6(configPath)))
43506
+ if (retained.sources.some((source) => (source.hashMode === "sumi-settings-v1" || source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")))) && source.path !== canonical6(configPath)))
43425
43507
  unresolved("retained settings witness names another configuration source");
43426
- const covered = supersedesCodexProjection(retained.sources, canonical6(configPath)) ? sources.filter((source) => !isSupersededCodexProjection(agent, canonical6(configPath), source)) : sources;
43508
+ const covered = supersedesSettingsProjection(agent, retained.sources, canonical6(configPath)) ? sources.filter((source) => !isSupersededSettingsProjection(agent, canonical6(configPath), source)) : sources;
43427
43509
  if (covered.some((source) => !retained.sources.some((saved) => isDeepStrictEqual6(saved, source))) || [...roots].some((root2) => !retained.roots.includes(root2)) || agent === "gemini" && JSON.stringify(retained.builtinNames) !== JSON.stringify(builtinNames))
43428
43510
  unresolved("retained review is missing current runtime discovery coverage");
43429
43511
  return retained;
@@ -43438,11 +43520,11 @@ function resolveAgentDiscovery(options) {
43438
43520
  if (review.sources.some((source) => source.format !== undefined || source.fields !== undefined))
43439
43521
  throw new Error("Explicit discovery reviews require full source-file hashes");
43440
43522
  verifyAgentDiscovery(supplied);
43441
- 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.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")))) && source.path !== canonical6(configPath)))
43442
- throw new Error("Semantic settings witnesses must name the configured Claude configuration source");
43523
+ if (review.sources.some((source) => (source.hashMode === "sumi-settings-v1" || source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")))) && source.path !== canonical6(configPath)))
43524
+ throw new Error("Semantic settings witnesses must name the configured agent configuration source");
43443
43525
  if (!review.sources.some((source) => source.path === canonical6(configPath)))
43444
43526
  throw new Error("Discovery review must include the agent configuration source");
43445
- const reviewedSources = supersedesCodexProjection(review.sources, canonical6(configPath)) ? sources.filter((source) => !isSupersededCodexProjection(agent, canonical6(configPath), source)) : sources;
43527
+ const reviewedSources = supersedesSettingsProjection(agent, review.sources, canonical6(configPath)) ? sources.filter((source) => !isSupersededSettingsProjection(agent, canonical6(configPath), source)) : sources;
43446
43528
  return { ...supplied, roots: [...new Set([...roots, ...supplied.roots])].sort(), sources: [...reviewedSources, ...review.sources], ...agent === "gemini" ? { builtinNames } : {} };
43447
43529
  }
43448
43530
  function plugin(root2) {
@@ -43894,7 +43976,7 @@ function disableCodexBundledSkills(text2) {
43894
43976
  }
43895
43977
 
43896
43978
  // src/lib/agent-integration.ts
43897
- var sha4 = (data) => createHash21("sha256").update(data).digest("hex");
43979
+ var sha4 = (data) => createHash22("sha256").update(data).digest("hex");
43898
43980
  var ROOTS = NATIVE_SKILL_ROOTS;
43899
43981
  function hasTrustedDarwinAcl(fd, allowDenyOnly = false) {
43900
43982
  try {
@@ -44088,7 +44170,7 @@ function readNativeBytes(path, maximum = 64 * 1024 * 1024) {
44088
44170
  }
44089
44171
  }
44090
44172
  function treeHash(root2) {
44091
- const hash2 = createHash21("sha256");
44173
+ const hash2 = createHash22("sha256");
44092
44174
  let bytes = 0, files = 0;
44093
44175
  function visit2(path) {
44094
44176
  const stat2 = lstatSync22(path);
@@ -44582,7 +44664,7 @@ function planAgentIntegration(options) {
44582
44664
  const pluginPath = join26(sumiConfigDirectory(home), "plugins", "skills-cli.js"), pluginBefore = readOptional(pluginPath);
44583
44665
  const pluginAfter = renderSumiPlugin(command, profileId2);
44584
44666
  const priorCommand = policy.bridge?.commands?.sumi, priorProfile = policy.bridge?.profiles?.sumi ?? policy.profileId;
44585
- if (pluginBefore !== null && pluginBefore !== pluginAfter && !(typeof priorCommand === "string" && typeof priorProfile === "string" && pluginBefore === renderSumiPlugin(priorCommand, priorProfile)))
44667
+ if (pluginBefore !== null && pluginBefore !== pluginAfter && !(typeof priorCommand === "string" && typeof priorProfile === "string" && isManagedSumiPlugin(pluginBefore, priorCommand, priorProfile)))
44586
44668
  throw new Error("Refusing to overwrite a modified Sumi Skills plugin; preserve and review it first");
44587
44669
  if (pluginBefore !== pluginAfter)
44588
44670
  changes.push({ path: pluginPath, before: pluginBefore, after: pluginAfter });
@@ -44936,7 +45018,7 @@ function planAgentSettingsWitnessUpgrade(options) {
44936
45018
  const binding = policy.bridge?.discovery?.[options.agent];
44937
45019
  if (!binding || binding.agent !== options.agent || binding.method !== "reviewed")
44938
45020
  throw new Error("Settings witness upgrade requires an existing reviewed native binding");
44939
- const configPath = canonicalAgentPath(join26(home, options.agent === "claude" ? ".claude/settings.json" : ".codex/config.toml"), aliases);
45021
+ const configPath = canonicalAgentPath(options.agent === "sumi" ? sumiConfigPath(home) : join26(home, options.agent === "claude" ? ".claude/settings.json" : ".codex/config.toml"), aliases);
44940
45022
  const settings = readOptional(configPath);
44941
45023
  if (settings === null || sha4(settings) !== options.expectedSettingsSha256)
44942
45024
  throw new Error("Native settings preimage changed");
@@ -44962,7 +45044,19 @@ function planAgentSettingsWitnessUpgrade(options) {
44962
45044
  replaced.push(source);
44963
45045
  }
44964
45046
  }
44965
- const next = options.agent === "claude" ? upgradeClaudeSettingsWitness(previous, options.reviewedPreimage) : options.targetCodexVersion === 4 ? upgradeCodexSettingsWitnessV4(previous, options.reviewedPreimage) : options.targetCodexVersion === 3 ? upgradeCodexSettingsWitnessV3(previous, options.reviewedPreimage) : upgradeCodexSettingsWitness(previous, options.reviewedPreimage);
45047
+ if (options.agent === "sumi") {
45048
+ const preimage = readSumiSettingsPreimage(options.reviewedPreimage);
45049
+ for (const source of binding.sources) {
45050
+ if (source === previous || source.path !== configPath)
45051
+ continue;
45052
+ if (source.hashMode !== undefined || source.format !== "json" || !isDeepStrictEqual8(source.fields, [...SUMI_DISCOVERY_PROJECTION_FIELDS]) || typeof source.sha256 !== "string")
45053
+ throw new Error("Sumi settings witness upgrade found an unrecognized configuration witness");
45054
+ if (projectNativeDiscoveryFields(preimage, "json", source.fields, configPath) !== source.sha256)
45055
+ throw new Error("Reviewed preimage does not explain the Sumi discovery projection witness");
45056
+ replaced.push(source);
45057
+ }
45058
+ }
45059
+ const next = options.agent === "sumi" ? upgradeSumiSettingsWitness(previous, options.reviewedPreimage) : options.agent === "claude" ? upgradeClaudeSettingsWitness(previous, options.reviewedPreimage) : options.targetCodexVersion === 4 ? upgradeCodexSettingsWitnessV4(previous, options.reviewedPreimage) : options.targetCodexVersion === 3 ? upgradeCodexSettingsWitnessV3(previous, options.reviewedPreimage) : upgradeCodexSettingsWitness(previous, options.reviewedPreimage);
44966
45060
  const rebound = [];
44967
45061
  for (const source of binding.sources) {
44968
45062
  if (!replaced.includes(source)) {
@@ -45323,7 +45417,7 @@ function assertManagedAgentBridgeWithDiscovery(agent, options = {}, provenDiscov
45323
45417
  throw new Error("NATIVE_SKILL_DRIFT: Hermes supervisor binding changed; run skills hook install");
45324
45418
  assertHermesProtection(home, config, command, profile, supervisor);
45325
45419
  } else if (agent === "sumi") {
45326
- if (JSON.stringify(config.permissions?.filter((rule) => rule.action === "skill")) !== JSON.stringify(SUMI_SKILL_PERMISSIONS) || readOptional(join26(sumiConfigDirectory(home), "plugins", "skills-cli.js")) !== renderSumiPlugin(command, profile))
45420
+ if (JSON.stringify(config.permissions?.filter((rule) => rule.action === "skill")) !== JSON.stringify(SUMI_SKILL_PERMISSIONS) || !isManagedSumiPlugin(readOptional(join26(sumiConfigDirectory(home), "plugins", "skills-cli.js")), command, profile))
45327
45421
  throw new Error("NATIVE_SKILL_DRIFT: Sumi bridge protection changed; run skills hook install");
45328
45422
  } else if (agent === "opencode") {
45329
45423
  if (JSON.stringify(config.permission?.skill) !== JSON.stringify({ "*": "deny", [CLI_BRIDGE_NAME]: "allow" }) || readOptional(join26(home, ".config", "opencode", "plugins", "skills-cli.js")) !== renderOpenCodePlugin(command, profile))
@@ -45457,7 +45551,7 @@ import { basename as basename11, dirname as dirname20, isAbsolute as isAbsolute2
45457
45551
  var SKILLS = [];
45458
45552
 
45459
45553
  // src/lib/skill-hash.ts
45460
- import { createHash as createHash22 } from "crypto";
45554
+ import { createHash as createHash23 } from "crypto";
45461
45555
  import { existsSync as existsSync8, readdirSync as readdirSync9, readFileSync as readFileSync17, statSync as statSync8 } from "fs";
45462
45556
  import { join as join27, sep as sep7 } from "path";
45463
45557
  var CONTENT_HASH_ALGORITHM = "sha256";
@@ -45581,13 +45675,13 @@ function* bundleHashParts(files) {
45581
45675
  yield new TextEncoder().encode("\x00");
45582
45676
  }
45583
45677
  function hashBundleFiles(files) {
45584
- const hash2 = createHash22(CONTENT_HASH_ALGORITHM);
45678
+ const hash2 = createHash23(CONTENT_HASH_ALGORITHM);
45585
45679
  for (const part of bundleHashParts(files))
45586
45680
  hash2.update(part);
45587
45681
  return hash2.digest("hex");
45588
45682
  }
45589
45683
  async function hashBundleFilesCooperatively(files, check) {
45590
- const hash2 = createHash22(CONTENT_HASH_ALGORITHM);
45684
+ const hash2 = createHash23(CONTENT_HASH_ALGORITHM);
45591
45685
  let bytesSinceYield = 0;
45592
45686
  for (const part of bundleHashParts(files)) {
45593
45687
  for (let offset = 0;offset < part.byteLength; offset += 64 * 1024) {
@@ -48836,7 +48930,7 @@ async function executeSelectedLocal(selected, options = {}) {
48836
48930
  selection: selection2,
48837
48931
  target: "local",
48838
48932
  runtime: runtimeName,
48839
- inputDigest: `sha256:${createHash23("sha256").update(input).digest("hex")}`,
48933
+ inputDigest: `sha256:${createHash24("sha256").update(input).digest("hex")}`,
48840
48934
  runDirectory,
48841
48935
  ...executionGrant ? { executionGrant } : {},
48842
48936
  ...bindings ? { secretBinding: { schema: bindings.schema, selection: bindings.selection, consumer: bindings.consumer, secretsAuthority: bindings.secretsAuthority, bindings: bindings.bindings } } : {},
@@ -58126,7 +58220,7 @@ var import_node_http_handler2 = __toESM(require_dist_cjs6(), 1);
58126
58220
 
58127
58221
  // node_modules/@aws-sdk/checksums/dist-cjs/submodules/sha/index.js
58128
58222
  var { toUint8Array: toUint8Array2, concatBytes } = require_serde();
58129
- var { createHmac: createHmac2, createHash: createHash25 } = __require("crypto");
58223
+ var { createHmac: createHmac2, createHash: createHash26 } = __require("crypto");
58130
58224
  var { Sha256: Sha2562, Sha256Js, Sha256Node } = require_checksum();
58131
58225
  var BLOCK2 = 64;
58132
58226
  var DIGEST_LENGTH = 20;
@@ -58295,7 +58389,7 @@ class Sha1Js {
58295
58389
  }
58296
58390
  var hasNativeCrypto = (() => {
58297
58391
  try {
58298
- createHash25("sha1");
58392
+ createHash26("sha1");
58299
58393
  return true;
58300
58394
  } catch {
58301
58395
  return false;
@@ -58335,7 +58429,7 @@ function buildNativeClass() {
58335
58429
  this.finished = false;
58336
58430
  }
58337
58431
  createHash() {
58338
- return this.secret ? createHmac2("sha1", toBuffer(this.secret)) : createHash25("sha1");
58432
+ return this.secret ? createHmac2("sha1", toBuffer(this.secret)) : createHash26("sha1");
58339
58433
  }
58340
58434
  };
58341
58435
  }
@@ -59203,9 +59297,9 @@ import { mkdirSync as mkdirSync12, readFileSync as readFileSync25, readdirSync a
59203
59297
  import { dirname as dirname25, join as join40 } from "path";
59204
59298
 
59205
59299
  // src/server/auth.ts
59206
- import { createHash as createHash26 } from "crypto";
59300
+ import { createHash as createHash27 } from "crypto";
59207
59301
  function hashApiKey(token) {
59208
- return createHash26("sha256").update(token).digest("hex");
59302
+ return createHash27("sha256").update(token).digest("hex");
59209
59303
  }
59210
59304
  function bearerToken(request2) {
59211
59305
  const header = request2.headers.get("authorization") || "";
@@ -59527,7 +59621,7 @@ function validOperatorScopeEnrollmentInput(input) {
59527
59621
  }
59528
59622
 
59529
59623
  // src/lib/revision.ts
59530
- import { createHash as createHash27 } from "crypto";
59624
+ import { createHash as createHash28 } from "crypto";
59531
59625
  var REVISION_ID_PATTERN = /^[0-9a-f]{64}$/;
59532
59626
  function revisionIdOf(content) {
59533
59627
  const canonicalContent = {
@@ -59549,7 +59643,7 @@ function revisionIdOf(content) {
59549
59643
  canonicalContent.replacementSlug = content.replacementSlug ?? null;
59550
59644
  }
59551
59645
  const canonical6 = JSON.stringify(canonicalContent);
59552
- return createHash27("sha256").update(canonical6).digest("hex");
59646
+ return createHash28("sha256").update(canonical6).digest("hex");
59553
59647
  }
59554
59648
  function revisionIdOfRecord(record4) {
59555
59649
  return revisionIdOf(record4);
@@ -60633,7 +60727,7 @@ function nextMonthPrefix(monthPrefix) {
60633
60727
  }
60634
60728
 
60635
60729
  // src/server/skills-api.ts
60636
- import { createHash as createHash28 } from "crypto";
60730
+ import { createHash as createHash29 } from "crypto";
60637
60731
  var SLUG_PATTERN = /^[a-z0-9][a-z0-9._-]*$/;
60638
60732
  var SHA256_HEX2 = /^[0-9a-f]{64}$/;
60639
60733
  var MAX_SLUG_LENGTH = 128;
@@ -60823,7 +60917,7 @@ async function parsePublishRequest(request2, config) {
60823
60917
  if (bundleBytes.byteLength === 0) {
60824
60918
  throw new SkillRequestError(400, "BUNDLE_EMPTY", "the uploaded bundle is empty");
60825
60919
  }
60826
- const sha2562 = createHash28("sha256").update(bundleBytes).digest("hex");
60920
+ const sha2562 = createHash29("sha256").update(bundleBytes).digest("hex");
60827
60921
  const claimed = optionalString(manifest.bundleSha256);
60828
60922
  if (claimed)
60829
60923
  assertSha2562(claimed);
@@ -60938,7 +61032,7 @@ async function readPublishedBundle(store, artifactStorage, principal, slug) {
60938
61032
  if (!bytes) {
60939
61033
  throw new SkillRequestError(503, "BUNDLE_BACKEND_UNAVAILABLE", "bundle storage backend unavailable");
60940
61034
  }
60941
- const actual = createHash28("sha256").update(bytes).digest("hex");
61035
+ const actual = createHash29("sha256").update(bytes).digest("hex");
60942
61036
  if (actual !== record4.bundleSha256) {
60943
61037
  throw new SkillRequestError(500, "BUNDLE_DIGEST_DRIFT", `stored bundle for '${slug}' hashes to ${actual} but was published as ${record4.bundleSha256}`);
60944
61038
  }
@@ -61086,7 +61180,7 @@ async function readSkillVersionBundle(store, artifactStorage, principal, slug, v
61086
61180
  const bytes = await artifactStorage.readBundle(bundle2);
61087
61181
  if (!bytes)
61088
61182
  throw new SkillRequestError(503, "BUNDLE_BACKEND_UNAVAILABLE", "bundle storage backend unavailable");
61089
- const actual = createHash28("sha256").update(bytes).digest("hex");
61183
+ const actual = createHash29("sha256").update(bytes).digest("hex");
61090
61184
  if (actual !== found.bundleSha256) {
61091
61185
  throw new SkillRequestError(500, "BUNDLE_DIGEST_DRIFT", `stored bundle for '${slug}@${version2}' hashes to ${actual} but was published as ${found.bundleSha256}`);
61092
61186
  }
@@ -61789,7 +61883,7 @@ class RuntimeExecutionStore {
61789
61883
  }
61790
61884
 
61791
61885
  // src/sdk/execution/admission.ts
61792
- import { createHash as createHash30 } from "crypto";
61886
+ import { createHash as createHash31 } from "crypto";
61793
61887
 
61794
61888
  // src/sdk/execution/image-profile.ts
61795
61889
  class ImageProfileResolutionError extends Error {
@@ -62401,11 +62495,11 @@ function ownedAdmission(admission) {
62401
62495
  };
62402
62496
  }
62403
62497
  function digestInput(input) {
62404
- return createHash30("sha256").update(canonicalJson2(input)).digest("hex");
62498
+ return createHash31("sha256").update(canonicalJson2(input)).digest("hex");
62405
62499
  }
62406
62500
 
62407
62501
  // src/sdk/execution/dispatchers/ecs.ts
62408
- import { createHash as createHash31 } from "crypto";
62502
+ import { createHash as createHash32 } from "crypto";
62409
62503
 
62410
62504
  // src/sdk/execution/state-machine.ts
62411
62505
  var LEGAL_TRANSITIONS = {
@@ -65805,13 +65899,13 @@ function observedTask(states, taskArn) {
65805
65899
  return state2.lastStatus === "STOPPED" || LIVE_TASK_STATUSES.has(state2.lastStatus) ? state2 : undefined;
65806
65900
  }
65807
65901
  function clientTokenFor(runId3, attemptId) {
65808
- return createHash31("sha256").update(`${runId3}\x00${attemptId}`).digest("hex").slice(0, CLIENT_TOKEN_BYTES * 2);
65902
+ return createHash32("sha256").update(`${runId3}\x00${attemptId}`).digest("hex").slice(0, CLIENT_TOKEN_BYTES * 2);
65809
65903
  }
65810
65904
  function startedByFor(runId3, attemptNumber) {
65811
65905
  return `skills-exec/${runId3}/a${attemptNumber}`;
65812
65906
  }
65813
65907
  function requestDigestFor(admission, attemptId) {
65814
- return createHash31("sha256").update(canonicalJson2({ admission, attemptId })).digest("hex");
65908
+ return createHash32("sha256").update(canonicalJson2({ admission, attemptId })).digest("hex");
65815
65909
  }
65816
65910
 
65817
65911
  class EcsDispatcher {
@@ -66107,10 +66201,10 @@ function validText(value) {
66107
66201
  }
66108
66202
 
66109
66203
  // src/server/runtime-policy.ts
66110
- import { createHash as createHash33, createHmac as createHmac3, timingSafeEqual as timingSafeEqual2 } from "crypto";
66204
+ import { createHash as createHash34, createHmac as createHmac3, timingSafeEqual as timingSafeEqual2 } from "crypto";
66111
66205
 
66112
66206
  // src/server/runtime-pure-contract.ts
66113
- import { createHash as createHash32 } from "crypto";
66207
+ import { createHash as createHash33 } from "crypto";
66114
66208
  var PURE_DESCRIPTOR = Object.freeze({
66115
66209
  id: "regex-test.v1",
66116
66210
  runtime: "bun",
@@ -66134,7 +66228,7 @@ var PURE_LIMITS = Object.freeze({
66134
66228
  maxArtifactsBytes: 0,
66135
66229
  maxConcurrency: 1
66136
66230
  });
66137
- var hash2 = (bytes) => createHash32("sha256").update(bytes).digest("hex");
66231
+ var hash2 = (bytes) => createHash33("sha256").update(bytes).digest("hex");
66138
66232
  var object7 = (v2) => {
66139
66233
  if (!v2 || typeof v2 !== "object" || Array.isArray(v2))
66140
66234
  throw Error("Pure contract requires an object");
@@ -66363,7 +66457,7 @@ function verifyRuntimeToken(token, key, admission, attempt, now = Date.now()) {
66363
66457
  const actual = Buffer.from(token);
66364
66458
  return actual.length === expected.length && timingSafeEqual2(actual, expected);
66365
66459
  }
66366
- var hashBytes = (bytes) => createHash33("sha256").update(bytes).digest("hex");
66460
+ var hashBytes = (bytes) => createHash34("sha256").update(bytes).digest("hex");
66367
66461
 
66368
66462
  // src/server/runtime-api.ts
66369
66463
  async function createRuntimeService(options) {
@@ -72735,7 +72829,7 @@ var localRunExecutor = {
72735
72829
  // src/sdk/storage.ts
72736
72830
  var artifactStorageSeam = ArtifactStorage;
72737
72831
  // src/sdk/outputs.ts
72738
- import { createHash as createHash34 } from "crypto";
72832
+ import { createHash as createHash35 } from "crypto";
72739
72833
  class DatabaseOnlyObjectStore {
72740
72834
  usesS3 = false;
72741
72835
  async materialize(run, artifact, body4) {
@@ -72782,7 +72876,7 @@ function createGovernedArtifactWriter(options) {
72782
72876
  const stamped = {
72783
72877
  ...meta,
72784
72878
  byteSize: outputBytes,
72785
- sha256: createHash34("sha256").update(persistedBytes).digest("hex"),
72879
+ sha256: createHash35("sha256").update(persistedBytes).digest("hex"),
72786
72880
  visibility: options.visibility ?? config.defaultVisibility,
72787
72881
  ...config.artifactTtlSeconds !== undefined ? { expiresAt: expiresAtFor(createdAt, config.artifactTtlSeconds) } : {}
72788
72882
  };
@@ -91549,7 +91643,7 @@ function date4(params) {
91549
91643
  return _coercedDate(ZodDate2, params);
91550
91644
  }
91551
91645
  // src/lib/canonical-json.ts
91552
- import { createHash as createHash35 } from "crypto";
91646
+ import { createHash as createHash36 } from "crypto";
91553
91647
  function canonicalJson3(value, maximumBytes = 2 * 1024 * 1024) {
91554
91648
  return canonicalJsonAtDepth(value, maximumBytes, 64);
91555
91649
  }
@@ -91593,7 +91687,7 @@ function canonicalJsonAtDepth(value, maximumBytes, maximumDepth) {
91593
91687
  return visit3(value, 0);
91594
91688
  }
91595
91689
  function canonicalJsonSha256(value, maximumBytes) {
91596
- return createHash35("sha256").update(canonicalJson3(value, maximumBytes)).digest("hex");
91690
+ return createHash36("sha256").update(canonicalJson3(value, maximumBytes)).digest("hex");
91597
91691
  }
91598
91692
 
91599
91693
  // src/lib/remote-recurring-contract.ts
@@ -91780,7 +91874,7 @@ function recurringRequest(action, input2) {
91780
91874
  }
91781
91875
  return { path: path2, read: read3, method: read3 ? "GET" : "POST", body: read3 ? undefined : JSON.stringify(action === "preview" ? input2 : action === "activate" ? row.approval : { contractVersion: 1 }) };
91782
91876
  }
91783
- var budget = exports_external2.object({ reservedCredits: integer2, settledCredits: integer2, admittedOccurrences: integer2 });
91877
+ var budget2 = exports_external2.object({ reservedCredits: integer2, settledCredits: integer2, admittedOccurrences: integer2 });
91784
91878
  var period = exports_external2.object({ startsAt: instant2, endsAt: instant2 });
91785
91879
  var preview = exports_external2.object({
91786
91880
  contractVersion: exports_external2.literal(1),
@@ -91802,8 +91896,8 @@ var consent = exports_external2.object({
91802
91896
  state: exports_external2.enum(["active", "revoked", "expired"]),
91803
91897
  activatedAt: instant2,
91804
91898
  revokedAt: instant2.nullable(),
91805
- total: budget,
91806
- currentPeriod: budget.extend(period.shape).nullable(),
91899
+ total: budget2,
91900
+ currentPeriod: budget2.extend(period.shape).nullable(),
91807
91901
  nextDueAt: instant2.nullable()
91808
91902
  });
91809
91903
  var refusal3 = exports_external2.enum([
@@ -93707,7 +93801,7 @@ async function requestInvitationEmail(origin, action, input2) {
93707
93801
  }
93708
93802
 
93709
93803
  // src/lib/remote-private-publications.ts
93710
- import { createHash as createHash36 } from "crypto";
93804
+ import { createHash as createHash37 } from "crypto";
93711
93805
  var PRIVATE_PUBLICATION_MAX_BYTES = 16 * 1024 * 1024;
93712
93806
  var failures2 = {
93713
93807
  INVALID_REQUEST: [400, "The publication request is invalid."],
@@ -93754,7 +93848,7 @@ var hash4 = (v2) => typeof v2 === "string" && /^[a-f0-9]{64}$/.test(v2);
93754
93848
  var record10 = (v2) => !!v2 && typeof v2 === "object" && !Array.isArray(v2);
93755
93849
  var exact = (v2, keys3) => record10(v2) && Object.keys(v2).sort().join(",") === keys3.sort().join(",");
93756
93850
  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));
93757
- var publicationSha256 = (bytes) => createHash36("sha256").update(bytes).digest("hex");
93851
+ var publicationSha256 = (bytes) => createHash37("sha256").update(bytes).digest("hex");
93758
93852
  function checkedPublicationDeclaration(value) {
93759
93853
  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)
93760
93854
  return bad();
@@ -93774,7 +93868,7 @@ function checkedPublicationView(value, skillId, intentId, declaration) {
93774
93868
  return invalid7();
93775
93869
  return Object.freeze({ ...value });
93776
93870
  }
93777
- async function boundedJson(url2, init, token, mutation, budget2 = 15000, signal) {
93871
+ async function boundedJson(url2, init, token, mutation, budget3 = 15000, signal) {
93778
93872
  const controller = new AbortController;
93779
93873
  let reader;
93780
93874
  let response;
@@ -93829,7 +93923,7 @@ async function boundedJson(url2, init, token, mutation, budget2 = 15000, signal)
93829
93923
  controller.abort();
93830
93924
  reject(timeout);
93831
93925
  };
93832
- timer = setTimeout(abort, Math.max(1, Math.min(15000, budget2)));
93926
+ timer = setTimeout(abort, Math.max(1, Math.min(15000, budget3)));
93833
93927
  signal?.addEventListener("abort", abort, { once: true });
93834
93928
  })]);
93835
93929
  } catch (error61) {