@hasna/skills 0.10.48 → 0.10.50

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: sep11, join: join4 } = __require("path");
9007
- var { createHash: createHash26 } = __require("crypto");
9007
+ var { createHash: createHash27 } = __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 = createHash26("sha1");
9162
+ const hasher = createHash27("sha1");
9163
9163
  const cacheName = hasher.update(id2).digest("hex");
9164
9164
  return join4(getHomeDir(), ".aws", "sso", "cache", `${cacheName}.json`);
9165
9165
  };
@@ -9311,11 +9311,11 @@ var require_config = __commonJS((exports) => {
9311
9311
  };
9312
9312
  function getSelectorName(functionString) {
9313
9313
  try {
9314
- const constants15 = new Set(Array.from(functionString.match(/([A-Z_]){3,}/g) ?? []));
9315
- constants15.delete("CONFIG");
9316
- constants15.delete("CONFIG_PREFIX_SEPARATOR");
9317
- constants15.delete("ENV");
9318
- return [...constants15].join(", ");
9314
+ const constants16 = new Set(Array.from(functionString.match(/([A-Z_]){3,}/g) ?? []));
9315
+ constants16.delete("CONFIG");
9316
+ constants16.delete("CONFIG_PREFIX_SEPARATOR");
9317
+ constants16.delete("ENV");
9318
+ return [...constants16].join(", ");
9319
9319
  } catch (ignored) {
9320
9320
  return functionString;
9321
9321
  }
@@ -10511,10 +10511,10 @@ 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: createHash26, getRandomValues } = __require("crypto");
10514
+ var { createHmac: createHmac2, createHash: createHash27, getRandomValues } = __require("crypto");
10515
10515
  var { hasOwn: hasOwn2, HttpResponse } = require_transport();
10516
10516
  exports.hasOwn = hasOwn2;
10517
- var { ReadStream, lstatSync: lstatSync26, fstatSync: fstatSync4 } = __require("fs");
10517
+ var { ReadStream, lstatSync: lstatSync27, fstatSync: fstatSync4 } = __require("fs");
10518
10518
  var { toEndpointV1 } = require_endpoints();
10519
10519
  var { Readable, Writable, PassThrough } = __require("stream");
10520
10520
  var isArrayBuffer = (arg) => typeof ArrayBuffer === "function" && arg instanceof ArrayBuffer || Object.prototype.toString.call(arg) === "[object ArrayBuffer]";
@@ -11280,7 +11280,7 @@ var require_serde = __commonJS((exports) => {
11280
11280
  return body.end + 1 - body.start;
11281
11281
  } else if (body instanceof ReadStream) {
11282
11282
  if (body.path != null) {
11283
- return lstatSync26(body.path).size;
11283
+ return lstatSync27(body.path).size;
11284
11284
  } else if (typeof body.fd === "number") {
11285
11285
  return fstatSync4(body.fd).size;
11286
11286
  }
@@ -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)) : createHash26(this.algorithmIdentifier);
11419
+ this.hash = this.secret ? createHmac2(this.algorithmIdentifier, castSourceData(this.secret)) : createHash27(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: createHash26, createHmac: createHmac2 } = __require("crypto");
12158
+ var { createHash: createHash27, 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
- createHash26("md5");
12323
+ createHash27("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 = createHash26("md5");
12333
+ hash = createHash27("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 = createHash26("md5");
12342
+ this.hash = createHash27("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
- createHash26("sha256");
12632
+ createHash27("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)) : createHash26("sha256");
12672
+ return this.secret ? createHmac2("sha256", toBuffer(this.secret)) : createHash27("sha256");
12673
12673
  }
12674
12674
  };
12675
12675
  }
@@ -12730,9 +12730,9 @@ var require_checksum = __commonJS((exports) => {
12730
12730
  const hash2 = await subtle.digest("SHA-256", data);
12731
12731
  return new Uint8Array(hash2);
12732
12732
  }
12733
- const sha2562 = new Sha256Js(this.secret);
12734
- sha2562.update(data);
12735
- return sha2562.digest();
12733
+ const sha2563 = new Sha256Js(this.secret);
12734
+ sha2563.update(data);
12735
+ return sha2563.digest();
12736
12736
  }
12737
12737
  reset() {
12738
12738
  this.pending = [];
@@ -18071,9 +18071,9 @@ var require_dist_cjs3 = __commonJS((exports) => {
18071
18071
  sha256;
18072
18072
  uriEscapePath;
18073
18073
  applyChecksum;
18074
- constructor({ applyChecksum, credentials, region, service, sha256: sha2562, uriEscapePath = true }) {
18074
+ constructor({ applyChecksum, credentials, region, service, sha256: sha2563, uriEscapePath = true }) {
18075
18075
  this.service = service;
18076
- this.sha256 = sha2562;
18076
+ this.sha256 = sha2563;
18077
18077
  this.uriEscapePath = uriEscapePath;
18078
18078
  this.applyChecksum = typeof applyChecksum === "boolean" ? applyChecksum : true;
18079
18079
  this.regionProvider = normalizeProvider2(region);
@@ -18240,13 +18240,13 @@ ${toHex(hashedRequest)}`;
18240
18240
 
18241
18241
  class SignatureV4 extends SignatureV4Base {
18242
18242
  headerFormatter = new HeaderFormatter;
18243
- constructor({ applyChecksum, credentials, region, service, sha256: sha2562, uriEscapePath = true }) {
18243
+ constructor({ applyChecksum, credentials, region, service, sha256: sha2563, uriEscapePath = true }) {
18244
18244
  super({
18245
18245
  applyChecksum,
18246
18246
  credentials,
18247
18247
  region,
18248
18248
  service,
18249
- sha256: sha2562,
18249
+ sha256: sha2563,
18250
18250
  uriEscapePath
18251
18251
  });
18252
18252
  }
@@ -24474,7 +24474,7 @@ var require_httpAuthSchemes = __commonJS((exports) => {
24474
24474
  configurable: true
24475
24475
  });
24476
24476
  config.credentials = inputCredentials;
24477
- const { signingEscapePath = true, systemClockOffset = config.systemClockOffset || 0, sha256: sha2562 } = config;
24477
+ const { signingEscapePath = true, systemClockOffset = config.systemClockOffset || 0, sha256: sha2563 } = config;
24478
24478
  let signer;
24479
24479
  if (config.signer) {
24480
24480
  signer = normalizeProvider2(config.signer);
@@ -24494,7 +24494,7 @@ var require_httpAuthSchemes = __commonJS((exports) => {
24494
24494
  credentials: config.credentials,
24495
24495
  region: config.signingRegion,
24496
24496
  service: config.signingName,
24497
- sha256: sha2562,
24497
+ sha256: sha2563,
24498
24498
  uriEscapePath: signingEscapePath
24499
24499
  };
24500
24500
  const SignerCtor = config.signerConstructor || SignatureV4;
@@ -24517,7 +24517,7 @@ var require_httpAuthSchemes = __commonJS((exports) => {
24517
24517
  credentials: config.credentials,
24518
24518
  region: config.signingRegion,
24519
24519
  service: config.signingName,
24520
- sha256: sha2562,
24520
+ sha256: sha2563,
24521
24521
  uriEscapePath: signingEscapePath
24522
24522
  };
24523
24523
  const SignerCtor = config.signerConstructor || SignatureV4;
@@ -25679,7 +25679,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
25679
25679
  return this.connectOptions === undefined ? http2.connect(url) : http2.connect(url, this.connectOptions);
25680
25680
  }
25681
25681
  }
25682
- var { constants: constants15 } = http2;
25682
+ var { constants: constants16 } = http2;
25683
25683
 
25684
25684
  class NodeHttp2Handler {
25685
25685
  config;
@@ -25770,8 +25770,8 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
25770
25770
  }
25771
25771
  const clientHttp2Stream = session.request({
25772
25772
  ...request2.headers,
25773
- [constants15.HTTP2_HEADER_PATH]: path,
25774
- [constants15.HTTP2_HEADER_METHOD]: method
25773
+ [constants16.HTTP2_HEADER_PATH]: path,
25774
+ [constants16.HTTP2_HEADER_METHOD]: method
25775
25775
  });
25776
25776
  if (effectiveRequestTimeout) {
25777
25777
  clientHttp2Stream.setTimeout(effectiveRequestTimeout, () => {
@@ -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 createHash26, createPrivateKey, createPublicKey, sign } from "crypto";
29446
+ import { createHash as createHash27, 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 join38 } from "path";
@@ -29615,7 +29615,7 @@ var init_LoginCredentialsFetcher = __esm(() => {
29615
29615
  getTokenFilePath() {
29616
29616
  const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ?? join38(homedir7(), ".aws", "login", "cache");
29617
29617
  const loginSessionBytes = Buffer.from(this.loginSession, "utf8");
29618
- const loginSessionSha256 = createHash26("sha256").update(loginSessionBytes).digest("hex");
29618
+ const loginSessionSha256 = createHash27("sha256").update(loginSessionBytes).digest("hex");
29619
29619
  return join38(directory, `${loginSessionSha256}.json`);
29620
29620
  }
29621
29621
  derToRawSignature(derSignature) {
@@ -30946,7 +30946,7 @@ var fromWebToken = (init) => async (awsIdentityProperties) => {
30946
30946
  };
30947
30947
 
30948
30948
  // node_modules/@aws-sdk/credential-provider-web-identity/dist-es/fromTokenFile.js
30949
- import { readFileSync as readFileSync24 } from "fs";
30949
+ import { readFileSync as readFileSync25 } from "fs";
30950
30950
  var import_client19, import_config32, ENV_TOKEN_FILE = "AWS_WEB_IDENTITY_TOKEN_FILE", ENV_ROLE_ARN = "AWS_ROLE_ARN", ENV_ROLE_SESSION_NAME = "AWS_ROLE_SESSION_NAME", fromTokenFile = (init = {}) => async (awsIdentityProperties) => {
30951
30951
  init.logger?.debug("@aws-sdk/credential-provider-web-identity - fromTokenFile");
30952
30952
  const webIdentityTokenFile = init?.webIdentityTokenFile ?? process.env[ENV_TOKEN_FILE];
@@ -30959,7 +30959,7 @@ var import_client19, import_config32, ENV_TOKEN_FILE = "AWS_WEB_IDENTITY_TOKEN_F
30959
30959
  }
30960
30960
  const credentials = await fromWebToken({
30961
30961
  ...init,
30962
- webIdentityToken: import_config32.externalDataInterceptor?.getTokenRecord?.()[webIdentityTokenFile] ?? readFileSync24(webIdentityTokenFile, { encoding: "ascii" }),
30962
+ webIdentityToken: import_config32.externalDataInterceptor?.getTokenRecord?.()[webIdentityTokenFile] ?? readFileSync25(webIdentityTokenFile, { encoding: "ascii" }),
30963
30963
  roleArn,
30964
30964
  roleSessionName
30965
30965
  })(awsIdentityProperties);
@@ -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.48",
32376
+ version: "0.10.50",
32377
32377
  description: "Skills library for AI coding agents",
32378
32378
  type: "module",
32379
32379
  bin: {
@@ -37554,9 +37554,9 @@ async function reconcileSkillSession(input, options = {}) {
37554
37554
  return { applied: true, plan, planDigest, ...result };
37555
37555
  }
37556
37556
  // src/lib/selected-run.ts
37557
- import { createHash as createHash25 } from "crypto";
37557
+ import { createHash as createHash26 } from "crypto";
37558
37558
  import { spawn as spawn2 } from "child_process";
37559
- import { mkdirSync as mkdirSync11, mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync10, realpathSync as realpathSync14 } from "fs";
37559
+ import { mkdirSync as mkdirSync11, mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync10, realpathSync as realpathSync15 } from "fs";
37560
37560
  import { dirname as dirname22, join as join37, resolve as resolve21 } from "path";
37561
37561
  import { tmpdir, hostname as stationHostname2 } from "os";
37562
37562
 
@@ -37768,7 +37768,7 @@ async function prepareSkillDependencies(skillPath, env, timeoutMs = DEFAULT_PREP
37768
37768
  }
37769
37769
 
37770
37770
  // src/lib/skillinfo.ts
37771
- import { existsSync as existsSync15, readFileSync as readFileSync23 } from "fs";
37771
+ import { existsSync as existsSync15, readFileSync as readFileSync24 } from "fs";
37772
37772
  import { join as join36 } from "path";
37773
37773
 
37774
37774
  // src/lib/codex-corpus-write.ts
@@ -37933,7 +37933,7 @@ function withCodexCorpusWrite(roots, run, options = {}) {
37933
37933
  }
37934
37934
 
37935
37935
  // src/lib/installer.ts
37936
- import { existsSync as existsSync14, readFileSync as readFileSync22, rmSync as rmSync4 } from "fs";
37936
+ import { existsSync as existsSync14, readFileSync as readFileSync23, rmSync as rmSync4 } from "fs";
37937
37937
  import { join as join35 } from "path";
37938
37938
  import { homedir as homedir6 } from "os";
37939
37939
 
@@ -37941,10 +37941,10 @@ import { homedir as homedir6 } from "os";
37941
37941
  import {
37942
37942
  cpSync as cpSync2,
37943
37943
  existsSync as existsSync11,
37944
- lstatSync as lstatSync25,
37944
+ lstatSync as lstatSync26,
37945
37945
  mkdirSync as mkdirSync9,
37946
37946
  mkdtempSync as mkdtempSync2,
37947
- readFileSync as readFileSync19,
37947
+ readFileSync as readFileSync20,
37948
37948
  readdirSync as readdirSync11,
37949
37949
  renameSync as renameSync6,
37950
37950
  rmSync as rmSync3,
@@ -38140,6 +38140,8 @@ var BUILTIN_MODEL_SELECTIONS = new Set([
38140
38140
  "claude-opus-4-6[1m]",
38141
38141
  "claude-sonnet-4-6[1m]"
38142
38142
  ]);
38143
+ var CLAUDE_BUILTIN_THEMES = Object.freeze(["auto", "dark", "light", "dark-daltonized", "light-daltonized", "dark-ansi", "light-ansi"]);
38144
+ var BUILTIN_THEMES = new Set(CLAUDE_BUILTIN_THEMES);
38143
38145
  function canonical(value) {
38144
38146
  if (value.kind === "object")
38145
38147
  return { kind: "object", entries: value.entries.map(([key, child]) => [key, canonical(child)]).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0) };
@@ -38198,7 +38200,9 @@ function inferencePreference(key, child, version) {
38198
38200
  function settingsDigest(text, version = 1) {
38199
38201
  const value = parse2(text);
38200
38202
  value.entries = value.entries.filter(([key, child]) => {
38201
- if (version !== 1 && inferencePreference(key, child, version))
38203
+ if (version === 4 && key === "theme" && child.kind === "string" && BUILTIN_THEMES.has(child.value))
38204
+ return false;
38205
+ if (version !== 1 && inferencePreference(key, child, version === 4 ? 3 : version))
38202
38206
  return false;
38203
38207
  if (key === "model") {
38204
38208
  need(child.kind === "string", "contains an invalid model selection");
@@ -38256,6 +38260,26 @@ function upgradeClaudeSettingsWitness(previous, reviewedSettingsPath) {
38256
38260
  need(settingsDigest(before, 3) === sha2562, "non-preference settings changed; explicit discovery review required");
38257
38261
  return { path: previous.path, hashMode: "claude-settings-v3", sha256: sha2562 };
38258
38262
  }
38263
+ function captureClaudeSettingsV4(path, budget = { remaining: 256 * 1024 * 1024 }) {
38264
+ return { path, hashMode: "claude-settings-v4", sha256: settingsDigest(readNativeSettingsWitnessFile(path, budget), 4) };
38265
+ }
38266
+ function hashClaudeSettingsReplacementV4(text, budget) {
38267
+ need(typeof text === "string", "requires settings text");
38268
+ const bytes = Buffer.byteLength(text);
38269
+ need(bytes <= CLAUDE_SETTINGS_WITNESS_LIMITS.bytes && Number.isSafeInteger(budget.remaining) && budget.remaining >= bytes, "exceeds its byte limit");
38270
+ budget.remaining -= bytes;
38271
+ return settingsDigest(text, 4);
38272
+ }
38273
+ function upgradeClaudeSettingsWitnessV4(previous, reviewedSettingsPath) {
38274
+ need(previous && Object.keys(previous).every((key) => ["path", "hashMode", "sha256"].includes(key)) && (previous.hashMode === undefined || previous.hashMode === "bytes" || previous.hashMode === "claude-settings-v1" || previous.hashMode === "claude-settings-v2" || previous.hashMode === "claude-settings-v3") && typeof previous.sha256 === "string" && /^[a-f0-9]{64}$/.test(previous.sha256), "requires an exact prior settings witness");
38275
+ const budget = { remaining: 2 * CLAUDE_SETTINGS_WITNESS_LIMITS.bytes };
38276
+ const before = readNativeSettingsWitnessFile(reviewedSettingsPath, budget), current = readNativeSettingsWitnessFile(previous.path, budget);
38277
+ const beforeDigest = previous.hashMode === undefined || previous.hashMode === "bytes" ? createHash6("sha256").update(before).digest("hex") : settingsDigest(before, previous.hashMode === "claude-settings-v1" ? 1 : previous.hashMode === "claude-settings-v2" ? 2 : 3);
38278
+ need(beforeDigest === previous.sha256, "reviewed preimage does not match the prior witness");
38279
+ const sha2562 = settingsDigest(current, 4);
38280
+ need(settingsDigest(before, 4) === sha2562, "non-preference settings changed; explicit discovery review required");
38281
+ return { path: previous.path, hashMode: "claude-settings-v4", sha256: sha2562 };
38282
+ }
38259
38283
  function hashNativeJsonControls(text, excludedMetadata) {
38260
38284
  need(Buffer.byteLength(text) <= CLAUDE_SETTINGS_WITNESS_LIMITS.bytes, "exceeds its byte limit");
38261
38285
  const value = parse2(text);
@@ -40252,10 +40276,10 @@ var NATIVE_SKILL_ROOTS = [
40252
40276
  ];
40253
40277
 
40254
40278
  // src/lib/agent-integration.ts
40255
- import { createHash as createHash23, randomUUID as randomUUID4 } from "crypto";
40279
+ import { createHash as createHash24, randomUUID as randomUUID4 } from "crypto";
40256
40280
  import { isDeepStrictEqual as isDeepStrictEqual8 } from "util";
40257
- 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";
40258
- import { dirname as dirname17, join as join27, resolve as resolve18, relative as relative5, isAbsolute as isAbsolute19, sep as sep7 } from "path";
40281
+ import { existsSync as existsSync7, lstatSync as lstatSync23, statSync as statSync7, mkdirSync as mkdirSync6, readFileSync as readFileSync17, readdirSync as readdirSync8, opendirSync as opendirSync5, readlinkSync as readlinkSync6, realpathSync as realpathSync11, renameSync as renameSync4, rmdirSync as rmdirSync3, writeFileSync as writeFileSync5, unlinkSync as unlinkSync5, chmodSync, openSync as openSync18, closeSync as closeSync18, fsyncSync as fsyncSync6, fstatSync as fstatSync18, readSync as readSync12, constants as constants15, linkSync as linkSync3 } from "fs";
40282
+ import { dirname as dirname17, join as join27, resolve as resolve18, relative as relative5, isAbsolute as isAbsolute20, sep as sep7 } from "path";
40259
40283
  import { homedir as homedir3 } from "os";
40260
40284
 
40261
40285
  // src/lib/managed-policy.ts
@@ -40405,14 +40429,14 @@ function assertAgentPolicyCollections(policy) {
40405
40429
  text(source.path);
40406
40430
  requireBound(source.sha256 === null || typeof source.sha256 === "string" && /^[a-f0-9]{64}$/.test(source.sha256));
40407
40431
  if (source.hashMode !== undefined)
40408
- requireBound(["bytes", "path-bytes", "claude-plugin-manifest-v1", "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));
40432
+ requireBound(["bytes", "path-bytes", "claude-plugin-manifest-v1", "claude-plugin-registry", "claude-marketplace-registry", "claude-settings-v1", "claude-settings-v2", "claude-settings-v3", "claude-settings-v4", "claude-marketplace-registry-v2", "codex-settings-v1", "codex-settings-v2", "codex-settings-v3", "codex-settings-v4", "sumi-settings-v1"].includes(source.hashMode) && source.format === undefined && source.fields === undefined && (source.hashMode === "bytes" || source.sha256 !== null));
40409
40433
  if (source.hashMode === "claude-plugin-manifest-v1")
40410
40434
  requireBound(agent === "claude" && value.agent === "claude" && ["automatic", "reviewed"].includes(value.method) && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute8(source.path) && resolve7(source.path) === source.path && source.path.endsWith(join14(sep4, ".claude-plugin", "plugin.json")) && source.managedPlugins === undefined);
40411
40435
  if (source.hashMode === "sumi-settings-v1")
40412
40436
  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");
40413
40437
  if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4"))
40414
40438
  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");
40415
- if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3")
40439
+ if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "claude-settings-v4"))
40416
40440
  requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute8(source.path) && resolve7(source.path) === source.path && basename5(source.path) === "settings.json");
40417
40441
  if (source.hashMode === "claude-marketplace-registry" || source.hashMode === "claude-marketplace-registry-v2")
40418
40442
  requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute8(source.path) && resolve7(source.path) === source.path && basename5(source.path) === "known_marketplaces.json");
@@ -43246,13 +43270,13 @@ function projected(source, changes, budget2 = discoveryByteBudget()) {
43246
43270
  throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
43247
43271
  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;
43248
43272
  }
43249
- if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") {
43273
+ if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "claude-settings-v4")) {
43250
43274
  if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
43251
43275
  throw new Error("Claude settings witnesses require exact typed metadata");
43252
- const current = (source.hashMode === "claude-settings-v3" ? captureClaudeSettingsV3 : source.hashMode === "claude-settings-v2" ? captureClaudeSettingsV2 : captureClaudeSettings)(source.path, budget2).sha256;
43276
+ const current = (source.hashMode === "claude-settings-v4" ? captureClaudeSettingsV4 : source.hashMode === "claude-settings-v3" ? captureClaudeSettingsV3 : source.hashMode === "claude-settings-v2" ? captureClaudeSettingsV2 : captureClaudeSettings)(source.path, budget2).sha256;
43253
43277
  if (current !== source.sha256)
43254
43278
  throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
43255
- return changes?.has(source.path) ? (source.hashMode === "claude-settings-v3" ? hashClaudeSettingsReplacementV3 : source.hashMode === "claude-settings-v2" ? hashClaudeSettingsReplacementV2 : hashClaudeSettingsReplacement)(changes.get(source.path), budget2) : current;
43279
+ return changes?.has(source.path) ? (source.hashMode === "claude-settings-v4" ? hashClaudeSettingsReplacementV4 : source.hashMode === "claude-settings-v3" ? hashClaudeSettingsReplacementV3 : source.hashMode === "claude-settings-v2" ? hashClaudeSettingsReplacementV2 : hashClaudeSettingsReplacement)(changes.get(source.path), budget2) : current;
43256
43280
  }
43257
43281
  if (source.hashMode === "claude-marketplace-registry" || source.hashMode === "claude-marketplace-registry-v2") {
43258
43282
  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))
@@ -43487,7 +43511,7 @@ function assertMarketplaceBinding(binding, source) {
43487
43511
  throw new Error("Sumi settings witnesses require explicit reviewed Sumi configuration");
43488
43512
  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"))
43489
43513
  throw new Error("Codex settings witnesses require explicit reviewed Codex configuration");
43490
- 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"))
43514
+ if ((source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "claude-settings-v4")) && (binding.agent !== "claude" || binding.method !== "reviewed" || basename8(source.path) !== "settings.json"))
43491
43515
  throw new Error("Claude settings witnesses require explicit reviewed Claude configuration");
43492
43516
  if ((source.hashMode === "claude-marketplace-registry" || source.hashMode === "claude-marketplace-registry-v2") && (binding.agent !== "claude" || binding.method !== "reviewed"))
43493
43517
  throw new Error("Claude marketplace witnesses require explicit reviewed Claude discovery");
@@ -43689,7 +43713,7 @@ function resolveAgentDiscovery(options) {
43689
43713
  verifyAgentDiscovery(retained);
43690
43714
  if (!retained.sources.some((source) => source.path === canonical7(configPath) && source.format === undefined && source.fields === undefined))
43691
43715
  unresolved("retained review is missing the full agent configuration source");
43692
- 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 !== canonical7(configPath)))
43716
+ if (retained.sources.some((source) => (source.hashMode === "sumi-settings-v1" || source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "claude-settings-v4" || (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")))) && source.path !== canonical7(configPath)))
43693
43717
  unresolved("retained settings witness names another configuration source");
43694
43718
  const covered = supersedesSettingsProjection(agent, retained.sources, canonical7(configPath)) ? sources.filter((source) => !isSupersededSettingsProjection(agent, canonical7(configPath), source)) : sources;
43695
43719
  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))
@@ -43703,7 +43727,7 @@ function resolveAgentDiscovery(options) {
43703
43727
  if (review.sources.some((source) => source.format !== undefined || source.fields !== undefined))
43704
43728
  throw new Error("Explicit discovery reviews require full source-file hashes");
43705
43729
  verifyAgentDiscovery(supplied);
43706
- 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 !== canonical7(configPath)))
43730
+ if (review.sources.some((source) => (source.hashMode === "sumi-settings-v1" || source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "claude-settings-v4" || (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")))) && source.path !== canonical7(configPath)))
43707
43731
  throw new Error("Semantic settings witnesses must name the configured agent configuration source");
43708
43732
  if (!review.sources.some((source) => source.path === canonical7(configPath)))
43709
43733
  throw new Error("Discovery review must include the agent configuration source");
@@ -44188,8 +44212,144 @@ function disableCodexBundledSkills(text2) {
44188
44212
  return [...candidates][0];
44189
44213
  }
44190
44214
 
44215
+ // src/cli/commands/runtime-launcher.ts
44216
+ import { createHash as createHash23 } from "crypto";
44217
+ import { closeSync as closeSync17, constants as constants14, fchmodSync as fchmodSync2, fstatSync as fstatSync17, fsyncSync as fsyncSync5, lstatSync as lstatSync22, openSync as openSync17, readFileSync as readFileSync16, readlinkSync as readlinkSync5, realpathSync as realpathSync10, symlinkSync, writeSync as writeSync3 } from "fs";
44218
+ import { isAbsolute as isAbsolute19 } from "path";
44219
+ var PINNED_LAUNCHER_SCHEMA = "hasna-skills-pinned-launcher-v1";
44220
+ var LAUNCH_CWD_VARIABLE = "HASNA_SKILLS_LAUNCH_CWD";
44221
+ var PINNED_LAUNCHER_BUN_FLAGS = ["--config=/dev/null", "--no-env-file", "--no-macros", "--no-install"];
44222
+ var PINNED_LAUNCHER_ENV_NAMES = [
44223
+ "HOME",
44224
+ "PATH",
44225
+ "TMPDIR",
44226
+ "TERM",
44227
+ "TERM_PROGRAM",
44228
+ "TERM_PROGRAM_VERSION",
44229
+ "COLORTERM",
44230
+ "LANG",
44231
+ "USER",
44232
+ "LOGNAME",
44233
+ "SHELL",
44234
+ "TZ",
44235
+ "NO_COLOR",
44236
+ "FORCE_COLOR",
44237
+ "CI",
44238
+ "COLUMNS",
44239
+ "LINES",
44240
+ "EDITOR",
44241
+ "VISUAL",
44242
+ "PAGER",
44243
+ "SSH_AUTH_SOCK",
44244
+ "DATABASE_URL",
44245
+ "TERMINAL_CWD",
44246
+ "CODEX_HOME",
44247
+ "HERMES_HOME",
44248
+ "HERMES_ENABLE_PROJECT_PLUGINS",
44249
+ "HOST",
44250
+ "PORT",
44251
+ "NODE_ENV",
44252
+ "AGENT_ID",
44253
+ "ECS_CONTAINER_METADATA_URI_V4"
44254
+ ];
44255
+ var PINNED_LAUNCHER_ENV_PREFIXES = ["HASNA", "SKILLS", "SKILL", "MCP", "XDG", "LC", "AWS"];
44256
+ var ENV_PREFIX = new RegExp(`^(${PINNED_LAUNCHER_ENV_PREFIXES.join("|")})_`);
44257
+ var ENV_EXACT = new Set(PINNED_LAUNCHER_ENV_NAMES);
44258
+ function sha2562(bytes) {
44259
+ return createHash23("sha256").update(bytes).digest("hex");
44260
+ }
44261
+ function assertLauncherPath(value, code) {
44262
+ if (typeof value !== "string" || !isAbsolute19(value) || /['\x00-\x1f\x7f]/.test(value))
44263
+ throw new Error(code);
44264
+ }
44265
+ function renderPinnedLauncher(binding) {
44266
+ assertLauncherPath(binding.runtime, "LAUNCHER_RUNTIME_PATH_INVALID");
44267
+ assertLauncherPath(binding.cwd, "LAUNCHER_CWD_PATH_INVALID");
44268
+ assertLauncherPath(binding.entry, "LAUNCHER_ENTRY_PATH_INVALID");
44269
+ const names = PINNED_LAUNCHER_ENV_NAMES.join(" ");
44270
+ const prefixes = PINNED_LAUNCHER_ENV_PREFIXES.join("|");
44271
+ return [
44272
+ "#!/bin/sh -p",
44273
+ `# ${PINNED_LAUNCHER_SCHEMA}`,
44274
+ "# Written by `skills self-update`; rewrite it with `skills self-update`, do not edit by hand.",
44275
+ "# Runs the exact Skills entry below under one exact Bun from one trusted directory with",
44276
+ "# no working-directory configuration (no bunfig.toml, no .env, no macros, no auto-install)",
44277
+ "# and only the environment names allowed here. Everything else, BUN_* and NODE_OPTIONS",
44278
+ "# included, never reaches the runtime. The CLI returns to the caller's directory itself.",
44279
+ "# `-p` keeps the caller's exported functions and shell options out of this shell.",
44280
+ "set -eu",
44281
+ `${LAUNCH_CWD_VARIABLE}=$(pwd -P 2>/dev/null || :)`,
44282
+ `export ${LAUNCH_CWD_VARIABLE}`,
44283
+ `set -- '${binding.runtime}' ${PINNED_LAUNCHER_BUN_FLAGS.join(" ")} '--cwd=${binding.cwd}' '${binding.entry}' "$@"`,
44284
+ "hasna_skills_env=$(LC_ALL=C /usr/bin/awk 'BEGIN {",
44285
+ ` n = split("${names}", exact, " ")`,
44286
+ " for (i = 1; i <= n; i++) allow[exact[i]] = 1",
44287
+ " for (name in ENVIRON) {",
44288
+ " if (name !~ /^[A-Za-z_][A-Za-z0-9_]*$/) continue",
44289
+ ` if (name == "LC_ALL" || (!(name in allow) && name !~ /^(${prefixes})_/)) continue`,
44290
+ ' value = ENVIRON[name]; quoted = ""',
44291
+ ' while ((k = index(value, "\\047")) > 0) { quoted = quoted substr(value, 1, k - 1) "\\047\\\\\\047\\047"; value = substr(value, k + 1) }',
44292
+ ' printf "\\047%s=%s\\047 ", name, quoted value',
44293
+ " }",
44294
+ "}')",
44295
+ 'eval "set -- $hasna_skills_env \\"\\$@\\""',
44296
+ 'if [ "${LC_ALL+x}" = x ]; then set -- "LC_ALL=$LC_ALL" "$@"; fi',
44297
+ 'exec /usr/bin/env -i "$@"',
44298
+ ""
44299
+ ].join(`
44300
+ `);
44301
+ }
44302
+ var COMMAND_LINE = new RegExp(`^set -- '([^']+)' ${PINNED_LAUNCHER_BUN_FLAGS.join(" ")} '--cwd=([^']+)' '([^']+)' "\\$@"$`, "m");
44303
+ function parsePinnedLauncher(text2) {
44304
+ const match = COMMAND_LINE.exec(text2);
44305
+ if (!match)
44306
+ return null;
44307
+ const binding = { runtime: match[1], cwd: match[2], entry: match[3] };
44308
+ try {
44309
+ if (renderPinnedLauncher(binding) !== text2)
44310
+ return null;
44311
+ } catch {
44312
+ return null;
44313
+ }
44314
+ return binding;
44315
+ }
44316
+ var PINNED_LAUNCHER_MAX_BYTES = 16 * 1024;
44317
+ function resolveLauncherCommand(path) {
44318
+ const physical = realpathSync10(path);
44319
+ const stat2 = lstatSync22(physical);
44320
+ if (stat2.isFile() && stat2.size <= PINNED_LAUNCHER_MAX_BYTES) {
44321
+ const text2 = readFileSync16(physical, "utf8");
44322
+ const binding = parsePinnedLauncher(text2);
44323
+ if (binding) {
44324
+ let entry;
44325
+ try {
44326
+ entry = realpathSync10(binding.entry);
44327
+ } catch {
44328
+ throw new Error("LAUNCHER_ENTRY_UNREADABLE");
44329
+ }
44330
+ if (entry !== binding.entry)
44331
+ throw new Error("LAUNCHER_ENTRY_NOT_PHYSICAL");
44332
+ return { physical, entry, pinned: { ...binding, sha256: sha2562(text2) } };
44333
+ }
44334
+ }
44335
+ return { physical, entry: physical, pinned: null };
44336
+ }
44337
+ function assertPinnedLauncherRuntimeSafe(runtime) {
44338
+ assertLauncherPath(runtime, "LAUNCHER_RUNTIME_PATH_INVALID");
44339
+ let stat2;
44340
+ try {
44341
+ stat2 = lstatSync22(runtime);
44342
+ } catch {
44343
+ throw new Error("LAUNCHER_RUNTIME_UNSAFE");
44344
+ }
44345
+ const uid2 = process.getuid?.() ?? -1;
44346
+ if (!stat2.isFile() || stat2.isSymbolicLink() || ![0, uid2].includes(stat2.uid) || (stat2.mode & 18) !== 0 || (stat2.mode & 64) === 0) {
44347
+ throw new Error("LAUNCHER_RUNTIME_UNSAFE");
44348
+ }
44349
+ }
44350
+
44191
44351
  // src/lib/agent-integration.ts
44192
- var sha4 = (data) => createHash23("sha256").update(data).digest("hex");
44352
+ var sha4 = (data) => createHash24("sha256").update(data).digest("hex");
44193
44353
  var ROOTS = NATIVE_SKILL_ROOTS;
44194
44354
  function hasTrustedDarwinAcl(fd, allowDenyOnly = false) {
44195
44355
  try {
@@ -44240,11 +44400,11 @@ function isSystemRootAlias(path) {
44240
44400
  const target = `/private${path}`, link = `private${path}`;
44241
44401
  const identity5 = (stat2) => `${stat2.dev}:${stat2.ino}:${stat2.ctimeNs}:${stat2.uid}:${stat2.mode}`;
44242
44402
  try {
44243
- const before = lstatSync22(path, { bigint: true });
44244
- if (!before.isSymbolicLink() || before.uid !== 0n || readlinkSync5(path) !== link)
44403
+ const before = lstatSync23(path, { bigint: true });
44404
+ if (!before.isSymbolicLink() || before.uid !== 0n || readlinkSync6(path) !== link)
44245
44405
  return false;
44246
44406
  const directories = ["/", "/private", target].map((directory) => {
44247
- const stat2 = lstatSync22(directory, { bigint: true });
44407
+ const stat2 = lstatSync23(directory, { bigint: true });
44248
44408
  if (!stat2.isDirectory() || stat2.uid !== 0n)
44249
44409
  throw new Error("Untrusted system alias directory");
44250
44410
  if (directory !== "/private/tmp") {
@@ -44252,23 +44412,23 @@ function isSystemRootAlias(path) {
44252
44412
  throw new Error("Writable system alias directory");
44253
44413
  } else if ((stat2.mode & 0o1000n) === 0n)
44254
44414
  throw new Error("Unprotected system temporary directory");
44255
- const fd = openSync17(directory, constants14.O_RDONLY | constants14.O_DIRECTORY | constants14.O_NOFOLLOW);
44415
+ const fd = openSync18(directory, constants15.O_RDONLY | constants15.O_DIRECTORY | constants15.O_NOFOLLOW);
44256
44416
  try {
44257
- if (identity5(fstatSync17(fd, { bigint: true })) !== identity5(stat2) || !hasTrustedDarwinAcl(fd) || identity5(fstatSync17(fd, { bigint: true })) !== identity5(stat2))
44417
+ if (identity5(fstatSync18(fd, { bigint: true })) !== identity5(stat2) || !hasTrustedDarwinAcl(fd) || identity5(fstatSync18(fd, { bigint: true })) !== identity5(stat2))
44258
44418
  throw new Error("Unverified system alias directory ACL");
44259
44419
  } finally {
44260
- closeSync17(fd);
44420
+ closeSync18(fd);
44261
44421
  }
44262
44422
  return { directory, identity: identity5(stat2) };
44263
44423
  });
44264
- return realpathSync10(path) === target && readlinkSync5(path) === link && identity5(lstatSync22(path, { bigint: true })) === identity5(before) && directories.every((item) => identity5(lstatSync22(item.directory, { bigint: true })) === item.identity);
44424
+ return realpathSync11(path) === target && readlinkSync6(path) === link && identity5(lstatSync23(path, { bigint: true })) === identity5(before) && directories.every((item) => identity5(lstatSync23(item.directory, { bigint: true })) === item.identity);
44265
44425
  } catch {
44266
44426
  return false;
44267
44427
  }
44268
44428
  }
44269
44429
  function canonicalSystemPath(path) {
44270
44430
  const absolute = resolve18(path), root2 = `/${absolute.split(sep7)[1]}`;
44271
- if (process.platform !== "darwin" || !["/var", "/tmp", "/etc"].includes(root2) || !lstatSync22(root2, { throwIfNoEntry: false })?.isSymbolicLink())
44431
+ if (process.platform !== "darwin" || !["/var", "/tmp", "/etc"].includes(root2) || !lstatSync23(root2, { throwIfNoEntry: false })?.isSymbolicLink())
44272
44432
  return absolute;
44273
44433
  if (!isSystemRootAlias(root2))
44274
44434
  throw new Error(`Refusing symlink path: ${root2}`);
@@ -44277,7 +44437,7 @@ function canonicalSystemPath(path) {
44277
44437
  function assertSafePath(path) {
44278
44438
  let cursor = resolve18(path);
44279
44439
  while (true) {
44280
- if (lstatSync22(cursor, { throwIfNoEntry: false })?.isSymbolicLink() && !isSystemRootAlias(cursor))
44440
+ if (lstatSync23(cursor, { throwIfNoEntry: false })?.isSymbolicLink() && !isSystemRootAlias(cursor))
44281
44441
  throw new Error(`Refusing symlink path: ${cursor}`);
44282
44442
  const parent = dirname17(cursor);
44283
44443
  if (parent === cursor)
@@ -44287,17 +44447,17 @@ function assertSafePath(path) {
44287
44447
  }
44288
44448
  function readRootAlias(home, agent) {
44289
44449
  assertSafePath(home);
44290
- const realHome = realpathSync10(home), alias = join27(realHome, `.${agent}`);
44291
- const stat2 = lstatSync22(alias, { throwIfNoEntry: false, bigint: true });
44450
+ const realHome = realpathSync11(home), alias = join27(realHome, `.${agent}`);
44451
+ const stat2 = lstatSync23(alias, { throwIfNoEntry: false, bigint: true });
44292
44452
  if (!stat2?.isSymbolicLink())
44293
44453
  throw new Error(`Agent root alias changed after planning: ${alias}`);
44294
- const link = readlinkSync5(alias), targetPath = resolve18(dirname17(alias), link);
44454
+ const link = readlinkSync6(alias), targetPath = resolve18(dirname17(alias), link);
44295
44455
  assertSafePath(targetPath);
44296
- const targetStat = lstatSync22(targetPath, { throwIfNoEntry: false });
44456
+ const targetStat = lstatSync23(targetPath, { throwIfNoEntry: false });
44297
44457
  if (!targetStat?.isDirectory())
44298
44458
  throw new Error(`Agent root alias must target an existing directory: ${alias}`);
44299
- const target = realpathSync10(targetPath), inside = relative5(realHome, target);
44300
- if (!inside || inside === ".." || inside.startsWith(`..${sep7}`) || isAbsolute19(inside))
44459
+ const target = realpathSync11(targetPath), inside = relative5(realHome, target);
44460
+ if (!inside || inside === ".." || inside.startsWith(`..${sep7}`) || isAbsolute20(inside))
44301
44461
  throw new Error(`Agent root alias target must be inside the real home: ${alias}`);
44302
44462
  return { agent, home: realHome, alias, target, link, aliasIdentity: `${stat2.dev}:${stat2.ino}:${stat2.ctimeNs}`, targetIdentity: `${targetStat.dev}:${targetStat.ino}` };
44303
44463
  }
@@ -44306,7 +44466,7 @@ function rootAliases(home, allowed = false) {
44306
44466
  return [];
44307
44467
  const result = [];
44308
44468
  for (const agent of ["claude", "codex"])
44309
- if (lstatSync22(join27(home, `.${agent}`), { throwIfNoEntry: false })?.isSymbolicLink())
44469
+ if (lstatSync23(join27(home, `.${agent}`), { throwIfNoEntry: false })?.isSymbolicLink())
44310
44470
  result.push(readRootAlias(home, agent));
44311
44471
  if (result.some((item, index) => result.slice(index + 1).some((other) => item.target === other.target || item.target.startsWith(other.target + sep7) || other.target.startsWith(item.target + sep7))))
44312
44472
  throw new Error("Agent root alias targets must not overlap");
@@ -44323,17 +44483,17 @@ function disabledCodexSkillPaths(config, aliases) {
44323
44483
  const rows = skills.config;
44324
44484
  if (!Array.isArray(rows))
44325
44485
  return [];
44326
- if (rows.some((entry) => !entry || typeof entry !== "object" || Array.isArray(entry) || typeof entry.enabled !== "boolean" || entry.path !== undefined === (entry.name !== undefined) || entry.path !== undefined && (typeof entry.path !== "string" || !isAbsolute19(entry.path)) || entry.name !== undefined && (typeof entry.name !== "string" || !entry.name.trim())))
44486
+ if (rows.some((entry) => !entry || typeof entry !== "object" || Array.isArray(entry) || typeof entry.enabled !== "boolean" || entry.path !== undefined === (entry.name !== undefined) || entry.path !== undefined && (typeof entry.path !== "string" || !isAbsolute20(entry.path)) || entry.name !== undefined && (typeof entry.name !== "string" || !entry.name.trim())))
44327
44487
  return [];
44328
44488
  if (rows.some((entry) => entry.name !== undefined && entry.enabled !== false))
44329
44489
  return [];
44330
44490
  const settings = new Map;
44331
44491
  for (const entry of rows) {
44332
- if (typeof entry.path !== "string" || !isAbsolute19(entry.path))
44492
+ if (typeof entry.path !== "string" || !isAbsolute20(entry.path))
44333
44493
  continue;
44334
44494
  let document2;
44335
44495
  try {
44336
- document2 = realpathSync10(canonicalAgentPath(entry.path, aliases));
44496
+ document2 = realpathSync11(canonicalAgentPath(entry.path, aliases));
44337
44497
  } catch {
44338
44498
  continue;
44339
44499
  }
@@ -44354,16 +44514,16 @@ function recheckRootAliases(aliases) {
44354
44514
  }
44355
44515
  function nativeSourceDigest(path) {
44356
44516
  assertSafePath(path);
44357
- return lstatSync22(path, { throwIfNoEntry: false }) ? sha4(readNativeBytes(path, 1024 * 1024)) : null;
44517
+ return lstatSync23(path, { throwIfNoEntry: false }) ? sha4(readNativeBytes(path, 1024 * 1024)) : null;
44358
44518
  }
44359
44519
  function readNativeBytes(path, maximum = 64 * 1024 * 1024) {
44360
44520
  assertSafePath(path);
44361
- const before = lstatSync22(path);
44521
+ const before = lstatSync23(path);
44362
44522
  if (!before.isFile() || before.size > maximum)
44363
44523
  throw new Error("Unsupported or oversized native skill file");
44364
- const descriptor = openSync17(path, constants14.O_RDONLY | constants14.O_NOFOLLOW | constants14.O_NONBLOCK);
44524
+ const descriptor = openSync18(path, constants15.O_RDONLY | constants15.O_NOFOLLOW | constants15.O_NONBLOCK);
44365
44525
  try {
44366
- const opened = fstatSync17(descriptor);
44526
+ const opened = fstatSync18(descriptor);
44367
44527
  if (!opened.isFile() || opened.dev !== before.dev || opened.ino !== before.ino || opened.size !== before.size)
44368
44528
  throw new Error("Native skill file changed while reading");
44369
44529
  const bytes = Buffer.allocUnsafe(before.size + 1);
@@ -44374,19 +44534,19 @@ function readNativeBytes(path, maximum = 64 * 1024 * 1024) {
44374
44534
  break;
44375
44535
  length += count;
44376
44536
  }
44377
- const after = fstatSync17(descriptor), current = lstatSync22(path);
44537
+ const after = fstatSync18(descriptor), current = lstatSync23(path);
44378
44538
  if (current.dev !== opened.dev || current.ino !== opened.ino || current.size !== after.size || current.mtimeMs !== after.mtimeMs || current.ctimeMs !== after.ctimeMs || length !== before.size || after.size !== before.size || after.mtimeMs !== opened.mtimeMs || after.ctimeMs !== opened.ctimeMs)
44379
44539
  throw new Error("Native skill file changed while reading");
44380
44540
  return bytes.subarray(0, length);
44381
44541
  } finally {
44382
- closeSync17(descriptor);
44542
+ closeSync18(descriptor);
44383
44543
  }
44384
44544
  }
44385
44545
  function treeHash(root2) {
44386
- const hash2 = createHash23("sha256");
44546
+ const hash2 = createHash24("sha256");
44387
44547
  let bytes = 0, files = 0;
44388
44548
  function visit2(path) {
44389
- const stat2 = lstatSync22(path);
44549
+ const stat2 = lstatSync23(path);
44390
44550
  if (stat2.isSymbolicLink())
44391
44551
  throw new Error(`Refusing symlink in skill: ${path}`);
44392
44552
  const rel = relative5(root2, path);
@@ -44415,13 +44575,13 @@ function selectNativeMigrationTargets(inventory, manifest) {
44415
44575
  const identities = new Set;
44416
44576
  const selected = [];
44417
44577
  for (const target of manifest.targets) {
44418
- if (!isAbsolute19(target.projectRoot) || resolve18(target.projectRoot) !== target.projectRoot)
44578
+ if (!isAbsolute20(target.projectRoot) || resolve18(target.projectRoot) !== target.projectRoot)
44419
44579
  throw new Error(`Native migration target project root must be an existing absolute directory: ${target.projectRoot}`);
44420
44580
  const projectRoot = canonicalSystemPath(target.projectRoot), normalized = relative5(projectRoot, resolve18(projectRoot, target.path));
44421
- if (!existsSync7(projectRoot) || !lstatSync22(projectRoot).isDirectory())
44581
+ if (!existsSync7(projectRoot) || !lstatSync23(projectRoot).isDirectory())
44422
44582
  throw new Error(`Native migration target project root must be an existing absolute directory: ${target.projectRoot}`);
44423
44583
  assertSafePath(projectRoot);
44424
- if (isAbsolute19(target.path) || target.path.includes("\\") || target.path.includes("\x00") || !normalized || normalized === ".." || normalized.startsWith(`..${sep7}`) || normalized !== target.path || !/^[0-9a-f]{64}$/.test(target.treeSha256))
44584
+ if (isAbsolute20(target.path) || target.path.includes("\\") || target.path.includes("\x00") || !normalized || normalized === ".." || normalized.startsWith(`..${sep7}`) || normalized !== target.path || !/^[0-9a-f]{64}$/.test(target.treeSha256))
44425
44585
  throw new Error(`Invalid native migration target: ${target.path}`);
44426
44586
  const identity5 = `${target.agent}\x00${canonicalSystemPath(projectRoot)}\x00${normalized}`;
44427
44587
  if (identities.has(identity5))
@@ -44464,9 +44624,9 @@ function isCodexSkillDiscoveryInput(path) {
44464
44624
  }
44465
44625
  function inventoryNativeSkills(home = homedir3(), options = {}) {
44466
44626
  home = canonicalSystemPath(home);
44467
- if (options.reviewedCacheAlias !== undefined && (!options.includeVendor || !isAbsolute19(options.reviewedCacheAlias) || resolve18(options.reviewedCacheAlias) !== options.reviewedCacheAlias))
44627
+ if (options.reviewedCacheAlias !== undefined && (!options.includeVendor || !isAbsolute20(options.reviewedCacheAlias) || resolve18(options.reviewedCacheAlias) !== options.reviewedCacheAlias))
44468
44628
  throw new Error("A reviewed cache alias requires vendor inventory and an exact absolute path");
44469
- if (options.disabledVendorPaths?.some((path) => !isAbsolute19(path) || resolve18(path) !== path))
44629
+ if (options.disabledVendorPaths?.some((path) => !isAbsolute20(path) || resolve18(path) !== path))
44470
44630
  throw new Error("Disabled vendor paths must be exact absolute paths");
44471
44631
  const reviewedCacheAlias = options.reviewedCacheAlias === undefined ? undefined : canonicalSystemPath(options.reviewedCacheAlias);
44472
44632
  const disabledVendorPaths = new Set((options.disabledVendorPaths ?? []).map(canonicalSystemPath));
@@ -44485,7 +44645,7 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
44485
44645
  roots.push(["sumi", canonicalAgentPath(join27(project, directory, name), aliases)]);
44486
44646
  }
44487
44647
  const installationInputs = options.codexInstallationInputRoots ?? [];
44488
- if (installationInputs.some((input) => resolve18(input) !== input || realpathSync10(input) !== input || roots.some(([agent, path]) => agent === "codex" && (path === input || path.startsWith(input + sep7) || input.startsWith(path + sep7)))))
44648
+ if (installationInputs.some((input) => resolve18(input) !== input || realpathSync11(input) !== input || roots.some(([agent, path]) => agent === "codex" && (path === input || path.startsWith(input + sep7) || input.startsWith(path + sep7)))))
44489
44649
  throw new Error("Native installation input overlaps an unconditional skill-loading root");
44490
44650
  const entries = [], seen = new Set;
44491
44651
  const cacheScans = new Map, maxAliasProofEntries = 1e4;
@@ -44499,13 +44659,13 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
44499
44659
  }
44500
44660
  let reviewedCacheAliasFound = false;
44501
44661
  function verifiedSiblingCacheAlias(agent, path, parent) {
44502
- const link = readlinkSync5(path), lexicalTarget = resolve18(parent, link);
44503
- if (isAbsolute19(link) ? link !== lexicalTarget : dirname17(link) !== ".")
44662
+ const link = readlinkSync6(path), lexicalTarget = resolve18(parent, link);
44663
+ if (isAbsolute20(link) ? link !== lexicalTarget : dirname17(link) !== ".")
44504
44664
  return false;
44505
44665
  const target = canonicalSystemPath(lexicalTarget);
44506
44666
  if (dirname17(target) !== parent)
44507
44667
  return false;
44508
- if (!lstatSync22(target, { throwIfNoEntry: false })?.isDirectory())
44668
+ if (!lstatSync23(target, { throwIfNoEntry: false })?.isDirectory())
44509
44669
  return false;
44510
44670
  const scan = cacheScans.get(target);
44511
44671
  if (!scan?.complete || scan.entries > maxAliasProofEntries)
@@ -44530,7 +44690,7 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
44530
44690
  return scan;
44531
44691
  if (!existsSync7(path))
44532
44692
  return scan;
44533
- const stat2 = lstatSync22(path);
44693
+ const stat2 = lstatSync23(path);
44534
44694
  if (stat2.isFile()) {
44535
44695
  if (agent === "sumi" && depth === 1 && path.endsWith(".md"))
44536
44696
  throw new Error("NATIVE_SKILL_DRIFT: flat Sumi skill documents require a dedicated migration adapter");
@@ -44547,7 +44707,7 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
44547
44707
  const marker = join27(path, ".hasna-skills.json");
44548
44708
  if (existsSync7(marker)) {
44549
44709
  try {
44550
- managed = JSON.parse(readFileSync16(marker, "utf8")).managedBy === "@hasna/skills";
44710
+ managed = JSON.parse(readFileSync17(marker, "utf8")).managedBy === "@hasna/skills";
44551
44711
  } catch {}
44552
44712
  }
44553
44713
  const bridge = (!vendor || agent === "sumi") && isOwnedCliBridge(path, bridgePaths);
@@ -44579,7 +44739,7 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
44579
44739
  if (isVendor && !options.includeVendor)
44580
44740
  continue;
44581
44741
  const child = join27(path, name);
44582
- if (isVendor && lstatSync22(child, { throwIfNoEntry: false })?.isSymbolicLink()) {
44742
+ if (isVendor && lstatSync23(child, { throwIfNoEntry: false })?.isSymbolicLink()) {
44583
44743
  const target = statSync7(child, { throwIfNoEntry: false });
44584
44744
  if (target?.isFile() || pluginCache && target?.isDirectory() && verifiedSiblingCacheAlias(agent, child, path)) {
44585
44745
  scan.entries++;
@@ -44622,7 +44782,7 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
44622
44782
  }
44623
44783
  function readOptional(path) {
44624
44784
  assertSafePath(path);
44625
- return existsSync7(path) ? readFileSync16(path, "utf8") : null;
44785
+ return existsSync7(path) ? readFileSync17(path, "utf8") : null;
44626
44786
  }
44627
44787
  function jsonObject(text2, path) {
44628
44788
  if (text2 === null)
@@ -44954,23 +45114,23 @@ function projectedHookAcl(path, observed) {
44954
45114
  if (process.platform !== "darwin")
44955
45115
  return;
44956
45116
  const identity5 = (stat2) => `${stat2.dev}:${stat2.ino}:${stat2.ctimeNs}:${stat2.uid}:${stat2.mode}:${stat2.nlink}:${stat2.size}:${stat2.mtimeNs}`;
44957
- const fd = openSync17(path, constants14.O_RDONLY | constants14.O_NOFOLLOW | constants14.O_NONBLOCK | (observed.isDirectory() ? constants14.O_DIRECTORY : 0));
45117
+ const fd = openSync18(path, constants15.O_RDONLY | constants15.O_NOFOLLOW | constants15.O_NONBLOCK | (observed.isDirectory() ? constants15.O_DIRECTORY : 0));
44958
45118
  try {
44959
- if (identity5(fstatSync17(fd, { bigint: true })) !== identity5(observed) || !hasTrustedDarwinAcl(fd, true) || identity5(fstatSync17(fd, { bigint: true })) !== identity5(observed) || identity5(lstatSync22(path, { bigint: true })) !== identity5(observed))
45119
+ if (identity5(fstatSync18(fd, { bigint: true })) !== identity5(observed) || !hasTrustedDarwinAcl(fd, true) || identity5(fstatSync18(fd, { bigint: true })) !== identity5(observed) || identity5(lstatSync23(path, { bigint: true })) !== identity5(observed))
44960
45120
  hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
44961
45121
  } finally {
44962
- closeSync17(fd);
45122
+ closeSync18(fd);
44963
45123
  }
44964
45124
  }
44965
45125
  function projectedHookExecutable(command, expectedResolved) {
44966
45126
  try {
44967
- if (!isAbsolute19(command) || /[\0\r\n]/.test(command) || resolve18(command) !== command)
45127
+ if (!isAbsolute20(command) || /[\0\r\n]/.test(command) || resolve18(command) !== command)
44968
45128
  hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
44969
45129
  command = canonicalSystemPath(command);
44970
45130
  const parents3 = (file = command) => {
44971
45131
  const result = [];
44972
45132
  for (let path = dirname17(file);; path = dirname17(path)) {
44973
- const stat2 = lstatSync22(path, { bigint: true });
45133
+ const stat2 = lstatSync23(path, { bigint: true });
44974
45134
  if (!stat2.isDirectory() || (stat2.mode & 0o022n) !== 0n && !(stat2.uid === 0n && (stat2.mode & 0o1000n) !== 0n))
44975
45135
  hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
44976
45136
  projectedHookAcl(path, stat2);
@@ -44980,13 +45140,22 @@ function projectedHookExecutable(command, expectedResolved) {
44980
45140
  }
44981
45141
  return result;
44982
45142
  };
44983
- const parentIdentity = parents3(), link = lstatSync22(command, { bigint: true });
45143
+ const parentIdentity = parents3(), link = lstatSync23(command, { bigint: true });
44984
45144
  if (link.uid !== BigInt(process.getuid()) || !link.isFile() && !link.isSymbolicLink())
44985
45145
  hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
44986
45146
  const linkIdentity = (stat2) => `${stat2.dev}:${stat2.ino}:${stat2.mode}:${stat2.uid}:${stat2.ctimeNs}`;
44987
- const resolved = realpathSync10(command);
45147
+ const target = resolveLauncherCommand(command), resolved = target.entry;
44988
45148
  if (expectedResolved !== undefined && resolved !== expectedResolved)
44989
45149
  hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
45150
+ let launcher, launcherParentIdentity;
45151
+ if (target.pinned) {
45152
+ launcherParentIdentity = parents3(target.physical);
45153
+ launcher = snapshot(target.physical, false);
45154
+ projectedHookAcl(launcher.file, launcher.stat);
45155
+ if (launcher.sha256 !== target.pinned.sha256 || (launcher.stat.mode & 0o100n) === 0n)
45156
+ hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
45157
+ assertPinnedLauncherRuntimeSafe(target.pinned.runtime);
45158
+ }
44990
45159
  const resolvedParentIdentity = parents3(resolved);
44991
45160
  const manifest = snapshot(join27(dirname17(dirname17(resolved)), "package.json"), false, { readOnlyPackage: true });
44992
45161
  projectedHookAcl(manifest.file, manifest.stat);
@@ -44999,8 +45168,15 @@ function projectedHookExecutable(command, expectedResolved) {
44999
45168
  hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
45000
45169
  const recheck = () => {
45001
45170
  try {
45002
- if (realpathSync10(command) !== resolved || linkIdentity(lstatSync22(command, { bigint: true })) !== linkIdentity(link) || !isDeepStrictEqual8(parents3(), parentIdentity) || !isDeepStrictEqual8(parents3(resolved), resolvedParentIdentity))
45171
+ const again = resolveLauncherCommand(command);
45172
+ if (again.entry !== resolved || again.physical !== target.physical || linkIdentity(lstatSync23(command, { bigint: true })) !== linkIdentity(link) || !isDeepStrictEqual8(parents3(), parentIdentity) || !isDeepStrictEqual8(parents3(resolved), resolvedParentIdentity))
45003
45173
  hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
45174
+ if (launcher) {
45175
+ if (!isDeepStrictEqual8(parents3(target.physical), launcherParentIdentity))
45176
+ hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
45177
+ projectedHookAcl(launcher.file, launcher.stat);
45178
+ unchanged2(launcher);
45179
+ }
45004
45180
  projectedHookAcl(cli.file, cli.stat);
45005
45181
  projectedHookAcl(manifest.file, manifest.stat);
45006
45182
  unchanged2(cli);
@@ -45122,7 +45298,7 @@ function claudeSettingsConsumers(home, path, discoveries, aliases) {
45122
45298
  const canonical7 = (value) => canonicalAgentPath(value, aliases);
45123
45299
  const containsSettings = (root2) => {
45124
45300
  const distance = relative5(canonical7(root2), path);
45125
- return distance === "" || distance !== ".." && !distance.startsWith(`..${sep7}`) && !isAbsolute19(distance);
45301
+ return distance === "" || distance !== ".." && !distance.startsWith(`..${sep7}`) && !isAbsolute20(distance);
45126
45302
  };
45127
45303
  return discoveries.filter((binding) => binding.agent === "claude" || binding.agent === "opencode" || canonical7(join27(home, AGENT_ADAPTERS[binding.agent].config)) === path || binding.sources.some((source) => canonical7(source.path) === path) || binding.roots.some(containsSettings) || binding.directories?.some((directory) => containsSettings(directory.path))).map((binding) => binding.agent);
45128
45304
  }
@@ -45155,7 +45331,7 @@ function planClaudeHookEventsUpdate(options) {
45155
45331
  recheckRootAliases(aliases);
45156
45332
  const path = canonicalAgentPath(join27(home, ".claude", "settings.json"), aliases);
45157
45333
  assertSafePath(path);
45158
- const before = lstatSync22(path, { throwIfNoEntry: false }) ? new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(readNativeBytes(path, 1024 * 1024)) : null;
45334
+ const before = lstatSync23(path, { throwIfNoEntry: false }) ? new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(readNativeBytes(path, 1024 * 1024)) : null;
45159
45335
  if ((before === null ? "absent" : sha4(before)) !== options.expectedSettingsSha256)
45160
45336
  throw new Error("Claude settings preimage changed");
45161
45337
  assertClaudeHookEventsReplacement(before, options.replacement, options.events);
@@ -45222,6 +45398,8 @@ function atomicWrite2(path, content) {
45222
45398
  function planAgentSettingsWitnessUpgrade(options) {
45223
45399
  if (options.targetCodexVersion !== undefined && (options.agent !== "codex" || ![2, 3, 4].includes(options.targetCodexVersion)))
45224
45400
  throw new Error("Invalid Codex witness target version");
45401
+ if (options.targetClaudeVersion !== undefined && (options.agent !== "claude" || ![3, 4].includes(options.targetClaudeVersion)))
45402
+ throw new Error("Invalid Claude witness target version");
45225
45403
  const home = resolve18(options.home ?? homedir3()), dataDir2 = options.dataDir ?? getDataDirReadOnly();
45226
45404
  const snapshot2 = readManagedSkillPolicySnapshot(dataDir2);
45227
45405
  if (!snapshot2 || sha4(snapshot2.text) !== options.expectedPolicySha256)
@@ -45269,7 +45447,7 @@ function planAgentSettingsWitnessUpgrade(options) {
45269
45447
  replaced.push(source);
45270
45448
  }
45271
45449
  }
45272
- 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);
45450
+ const next = options.agent === "sumi" ? upgradeSumiSettingsWitness(previous, options.reviewedPreimage) : options.agent === "claude" ? options.targetClaudeVersion === 4 ? upgradeClaudeSettingsWitnessV4(previous, options.reviewedPreimage) : upgradeClaudeSettingsWitness(previous, options.reviewedPreimage) : options.targetCodexVersion === 4 ? upgradeCodexSettingsWitnessV4(previous, options.reviewedPreimage) : options.targetCodexVersion === 3 ? upgradeCodexSettingsWitnessV3(previous, options.reviewedPreimage) : upgradeCodexSettingsWitness(previous, options.reviewedPreimage);
45273
45451
  const rebound = [];
45274
45452
  for (const source of binding.sources) {
45275
45453
  if (!replaced.includes(source)) {
@@ -45315,7 +45493,7 @@ function applyAgentIntegrationUnlocked(plan, options = {}, assertCurrent) {
45315
45493
  const upgrade = plan.settingsWitnessUpgrade;
45316
45494
  if (!plan.managedAgentChecks || !plan.observedPolicy?.before)
45317
45495
  throw new Error("Invalid settings witness upgrade plan");
45318
- const verified = planAgentSettingsWitnessUpgrade({ agent: upgrade.agent, ...upgrade.agent === "codex" ? { targetCodexVersion: upgrade.toHashMode === "codex-settings-v4" ? 4 : upgrade.toHashMode === "codex-settings-v3" ? 3 : 2 } : {}, reviewedPreimage: upgrade.reviewedPreimage, home: plan.managedAgentChecks.home, dataDir: plan.dataDir, expectedPolicySha256: sha4(plan.observedPolicy.before), expectedSettingsSha256: upgrade.currentSettingsSha256 });
45496
+ const verified = planAgentSettingsWitnessUpgrade({ agent: upgrade.agent, ...upgrade.agent === "codex" ? { targetCodexVersion: upgrade.toHashMode === "codex-settings-v4" ? 4 : upgrade.toHashMode === "codex-settings-v3" ? 3 : 2 } : {}, ...upgrade.agent === "claude" && upgrade.toHashMode === "claude-settings-v4" ? { targetClaudeVersion: 4 } : {}, reviewedPreimage: upgrade.reviewedPreimage, home: plan.managedAgentChecks.home, dataDir: plan.dataDir, expectedPolicySha256: sha4(plan.observedPolicy.before), expectedSettingsSha256: upgrade.currentSettingsSha256 });
45319
45497
  if (JSON.stringify(verified.changes) !== JSON.stringify(plan.changes) || JSON.stringify(verified.settingsWitnessUpgrade) !== JSON.stringify(upgrade))
45320
45498
  throw new Error("Settings witness upgrade plan changed");
45321
45499
  provenDiscovery = verified.discoveryBefore[0];
@@ -45346,7 +45524,7 @@ function applyAgentIntegrationUnlocked(plan, options = {}, assertCurrent) {
45346
45524
  if (change.before !== null) {
45347
45525
  const backup = join27(backupRoot, `${index}-${sha4(change.path).slice(0, 12)}.backup`);
45348
45526
  writeFileSync5(backup, change.before, { mode: 384, flag: "wx" });
45349
- if (readFileSync16(backup, "utf8") !== change.before)
45527
+ if (readFileSync17(backup, "utf8") !== change.before)
45350
45528
  throw new Error("Native configuration preservation readback failed");
45351
45529
  backups.push(backup);
45352
45530
  }
@@ -45409,11 +45587,11 @@ function applyAgentIntegrationUnlocked(plan, options = {}, assertCurrent) {
45409
45587
  }
45410
45588
  function syncArchiveDirectory(path) {
45411
45589
  assertSafePath(path);
45412
- const descriptor = openSync17(path, constants14.O_RDONLY | constants14.O_DIRECTORY | constants14.O_NOFOLLOW | constants14.O_NONBLOCK);
45590
+ const descriptor = openSync18(path, constants15.O_RDONLY | constants15.O_DIRECTORY | constants15.O_NOFOLLOW | constants15.O_NONBLOCK);
45413
45591
  try {
45414
- fsyncSync5(descriptor);
45592
+ fsyncSync6(descriptor);
45415
45593
  } finally {
45416
- closeSync17(descriptor);
45594
+ closeSync18(descriptor);
45417
45595
  }
45418
45596
  }
45419
45597
  function writeArchiveJournal(path, value) {
@@ -45421,18 +45599,18 @@ function writeArchiveJournal(path, value) {
45421
45599
  const temporary = `${path}.skills-${randomUUID4()}`;
45422
45600
  let descriptor;
45423
45601
  try {
45424
- descriptor = openSync17(temporary, constants14.O_WRONLY | constants14.O_CREAT | constants14.O_EXCL | constants14.O_NOFOLLOW, 384);
45602
+ descriptor = openSync18(temporary, constants15.O_WRONLY | constants15.O_CREAT | constants15.O_EXCL | constants15.O_NOFOLLOW, 384);
45425
45603
  writeFileSync5(descriptor, `${JSON.stringify(value)}
45426
45604
  `);
45427
- fsyncSync5(descriptor);
45428
- closeSync17(descriptor);
45605
+ fsyncSync6(descriptor);
45606
+ closeSync18(descriptor);
45429
45607
  descriptor = undefined;
45430
45608
  renameSync4(temporary, path);
45431
45609
  syncArchiveDirectory(dirname17(path));
45432
45610
  } finally {
45433
45611
  if (descriptor !== undefined)
45434
- closeSync17(descriptor);
45435
- if (lstatSync22(temporary, { throwIfNoEntry: false }))
45612
+ closeSync18(descriptor);
45613
+ if (lstatSync23(temporary, { throwIfNoEntry: false }))
45436
45614
  unlinkSync5(temporary);
45437
45615
  }
45438
45616
  }
@@ -45478,7 +45656,7 @@ function archiveNativeSkillsUnlocked(inventory, options, assertCurrent) {
45478
45656
  const moved = [];
45479
45657
  const verifyArchive = (entry) => {
45480
45658
  assertSafePath(entry.archive);
45481
- const stat2 = lstatSync22(entry.archive);
45659
+ const stat2 = lstatSync23(entry.archive);
45482
45660
  if (entry.discoveryOnly ? !stat2.isFile() : !stat2.isDirectory())
45483
45661
  throw new Error("Archive type changed");
45484
45662
  if ((entry.discoveryOnly ? sha4(readNativeBytes(entry.archive)) : treeHash(entry.archive)) !== entry.hash)
@@ -45529,7 +45707,7 @@ function archiveNativeSkillsUnlocked(inventory, options, assertCurrent) {
45529
45707
  recheckRootAliases(aliases);
45530
45708
  assertSafePath(entry.source);
45531
45709
  assertSafePath(entry.archive);
45532
- if (lstatSync22(entry.source, { throwIfNoEntry: false })) {
45710
+ if (lstatSync23(entry.source, { throwIfNoEntry: false })) {
45533
45711
  entry.status = "recovery-required";
45534
45712
  entry.conflict = "source-occupied";
45535
45713
  continue;
@@ -45546,7 +45724,7 @@ function archiveNativeSkillsUnlocked(inventory, options, assertCurrent) {
45546
45724
  syncArchiveDirectory(dirname17(entry.source));
45547
45725
  unlinkSync5(entry.archive);
45548
45726
  } else {
45549
- if (lstatSync22(entry.source, { throwIfNoEntry: false })) {
45727
+ if (lstatSync23(entry.source, { throwIfNoEntry: false })) {
45550
45728
  entry.status = "recovery-required";
45551
45729
  entry.conflict = "source-occupied";
45552
45730
  continue;
@@ -45579,12 +45757,12 @@ function isInertCodexPluginCacheCopy(entry, cache, allowedHostPaths, read3) {
45579
45757
  return false;
45580
45758
  const document2 = join27(entry.path, "SKILL.md");
45581
45759
  const inside = relative5(cache, entry.path);
45582
- if (!inside || isAbsolute19(inside) || inside.split(sep7).some((segment) => segment === ".."))
45760
+ if (!inside || isAbsolute20(inside) || inside.split(sep7).some((segment) => segment === ".."))
45583
45761
  return false;
45584
45762
  assertSafePath(entry.path);
45585
- if (!lstatSync22(cache).isDirectory() || !lstatSync22(entry.path).isDirectory() || !lstatSync22(document2).isFile())
45763
+ if (!lstatSync23(cache).isDirectory() || !lstatSync23(entry.path).isDirectory() || !lstatSync23(document2).isFile())
45586
45764
  return false;
45587
- if (realpathSync10.native(cache) !== cache || realpathSync10.native(entry.path) !== entry.path || realpathSync10.native(document2) !== document2)
45765
+ if (realpathSync11.native(cache) !== cache || realpathSync11.native(entry.path) !== entry.path || realpathSync11.native(document2) !== document2)
45588
45766
  return false;
45589
45767
  if (!classifyCodexPluginCacheDocument(document2, cache, read3))
45590
45768
  return false;
@@ -45752,20 +45930,20 @@ import {
45752
45930
  mkdirSync as mkdirSync8,
45753
45931
  mkdtempSync,
45754
45932
  readdirSync as readdirSync10,
45755
- realpathSync as realpathSync13,
45933
+ realpathSync as realpathSync14,
45756
45934
  renameSync as renameSync5,
45757
45935
  rmSync as rmSync2,
45758
45936
  statSync as statSync10,
45759
45937
  writeFileSync as writeFileSync7
45760
45938
  } from "fs";
45761
- import { basename as basename11, dirname as dirname20, isAbsolute as isAbsolute20, join as join31, normalize as normalize4, relative as relative7, resolve as resolve20, sep as sep10 } from "path";
45939
+ import { basename as basename11, dirname as dirname20, isAbsolute as isAbsolute21, join as join31, normalize as normalize4, relative as relative7, resolve as resolve20, sep as sep10 } from "path";
45762
45940
 
45763
45941
  // src/lib/registry-data/index.ts
45764
45942
  var SKILLS = [];
45765
45943
 
45766
45944
  // src/lib/skill-hash.ts
45767
- import { createHash as createHash24 } from "crypto";
45768
- import { existsSync as existsSync8, readdirSync as readdirSync9, readFileSync as readFileSync17, statSync as statSync8 } from "fs";
45945
+ import { createHash as createHash25 } from "crypto";
45946
+ import { existsSync as existsSync8, readdirSync as readdirSync9, readFileSync as readFileSync18, statSync as statSync8 } from "fs";
45769
45947
  import { join as join28, sep as sep8 } from "path";
45770
45948
  var CONTENT_HASH_ALGORITHM = "sha256";
45771
45949
  var HASH_EXCLUDE_DIRS = new Set([".git", "node_modules", "dist", "build", ".turbo"]);
@@ -45862,7 +46040,7 @@ function collectDirectory(files, dir, rel) {
45862
46040
  }
45863
46041
  }
45864
46042
  function collectFile(files, absolute, rel) {
45865
- const buffer = readFileSync17(absolute);
46043
+ const buffer = readFileSync18(absolute);
45866
46044
  files.push(normalizeBundleFile(rel.split(sep8).join("/"), buffer));
45867
46045
  }
45868
46046
  function normalizeBundleFile(rel, buffer) {
@@ -45888,13 +46066,13 @@ function* bundleHashParts(files) {
45888
46066
  yield new TextEncoder().encode("\x00");
45889
46067
  }
45890
46068
  function hashBundleFiles(files) {
45891
- const hash2 = createHash24(CONTENT_HASH_ALGORITHM);
46069
+ const hash2 = createHash25(CONTENT_HASH_ALGORITHM);
45892
46070
  for (const part of bundleHashParts(files))
45893
46071
  hash2.update(part);
45894
46072
  return hash2.digest("hex");
45895
46073
  }
45896
46074
  async function hashBundleFilesCooperatively(files, check) {
45897
- const hash2 = createHash24(CONTENT_HASH_ALGORITHM);
46075
+ const hash2 = createHash25(CONTENT_HASH_ALGORITHM);
45898
46076
  let bytesSinceYield = 0;
45899
46077
  for (const part of bundleHashParts(files)) {
45900
46078
  for (let offset = 0;offset < part.byteLength; offset += 64 * 1024) {
@@ -46277,10 +46455,10 @@ function validateRuntimeContract(manifest, issues, strict) {
46277
46455
  import {
46278
46456
  cpSync,
46279
46457
  existsSync as existsSync9,
46280
- lstatSync as lstatSync23,
46458
+ lstatSync as lstatSync24,
46281
46459
  mkdirSync as mkdirSync7,
46282
- readFileSync as readFileSync18,
46283
- realpathSync as realpathSync11,
46460
+ readFileSync as readFileSync19,
46461
+ realpathSync as realpathSync12,
46284
46462
  writeFileSync as writeFileSync6
46285
46463
  } from "fs";
46286
46464
  import { basename as basename9, dirname as dirname18, join as join29, relative as relative6 } from "path";
@@ -46344,7 +46522,7 @@ function readManifest(skillPath, fallbackName, normalizeName) {
46344
46522
  const skillMdPath = join29(skillPath, "SKILL.md");
46345
46523
  const pkgPath = join29(skillPath, "package.json");
46346
46524
  const jsonManifest = existsSync9(skillJsonPath) ? readJsonObject(skillJsonPath) : undefined;
46347
- const frontmatter = existsSync9(skillMdPath) ? parseSkillFrontmatter(readFileSync18(skillMdPath, "utf-8")) ?? undefined : undefined;
46525
+ const frontmatter = existsSync9(skillMdPath) ? parseSkillFrontmatter(readFileSync19(skillMdPath, "utf-8")) ?? undefined : undefined;
46348
46526
  const pkg = existsSync9(pkgPath) ? readJsonObject(pkgPath) : undefined;
46349
46527
  const name = normalizeName(stringField(jsonManifest, "name") ?? frontmatter?.name ?? stringValue(pkg?.name) ?? fallbackName);
46350
46528
  const description = stringField(jsonManifest, "description") ?? frontmatter?.description ?? stringValue(pkg?.description) ?? `${name} skill`;
@@ -46378,7 +46556,7 @@ function readDeclaredSkillVersion(skillPath) {
46378
46556
  const skillMdPath = join29(skillPath, "SKILL.md");
46379
46557
  const pkgPath = join29(skillPath, "package.json");
46380
46558
  const jsonManifest = existsSync9(skillJsonPath) ? readJsonObject(skillJsonPath) : undefined;
46381
- const frontmatter = existsSync9(skillMdPath) ? parseSkillFrontmatter(readFileSync18(skillMdPath, "utf-8")) ?? undefined : undefined;
46559
+ const frontmatter = existsSync9(skillMdPath) ? parseSkillFrontmatter(readFileSync19(skillMdPath, "utf-8")) ?? undefined : undefined;
46382
46560
  const pkg = existsSync9(pkgPath) ? readJsonObject(pkgPath) : undefined;
46383
46561
  return stringField(jsonManifest, "version") ?? frontmatter?.version ?? stringValue(pkg?.version);
46384
46562
  }
@@ -46499,7 +46677,7 @@ function readExistingSkillJson(skillPath) {
46499
46677
  if (!existsSync9(path))
46500
46678
  return {};
46501
46679
  try {
46502
- const parsed = JSON.parse(readFileSync18(path, "utf-8"));
46680
+ const parsed = JSON.parse(readFileSync19(path, "utf-8"));
46503
46681
  return isRecord3(parsed) ? parsed : {};
46504
46682
  } catch {
46505
46683
  return {};
@@ -46536,7 +46714,7 @@ function ensurePortableSkillFiles(skillPath, manifest) {
46536
46714
  if (!existsSync9(join29(skillPath, "SKILL.md")))
46537
46715
  writeFileSync6(join29(skillPath, "SKILL.md"), renderSkillMd(next));
46538
46716
  else
46539
- writeFileSync6(join29(skillPath, "SKILL.md"), ensureSkillMdFrontmatter(readFileSync18(join29(skillPath, "SKILL.md"), "utf-8"), next));
46717
+ writeFileSync6(join29(skillPath, "SKILL.md"), ensureSkillMdFrontmatter(readFileSync19(join29(skillPath, "SKILL.md"), "utf-8"), next));
46540
46718
  if (!existsSync9(join29(skillPath, "AGENTS.md")))
46541
46719
  writeFileSync6(join29(skillPath, "AGENTS.md"), renderAgentsMd(next));
46542
46720
  ensurePackageJson(skillPath, next);
@@ -46597,7 +46775,7 @@ function ensureInstructionSkillFiles(skillPath, manifest) {
46597
46775
  writeFileSync6(join29(skillPath, "SKILL.md"), renderSkillMd(next));
46598
46776
  } else {
46599
46777
  const path = join29(skillPath, "SKILL.md");
46600
- const content = readFileSync18(path, "utf8");
46778
+ const content = readFileSync19(path, "utf8");
46601
46779
  const declaredName = parseSkillFrontmatter(content)?.name;
46602
46780
  if (declaredName && declaredName !== next.name) {
46603
46781
  writeFileSync6(path, renameInstructionFrontmatter(content, next.name));
@@ -46635,7 +46813,7 @@ function renameInstructionFrontmatter(content, name) {
46635
46813
  return renamed + content.slice(frontmatter[0].length);
46636
46814
  }
46637
46815
  function copySkillDirectory(source, destination) {
46638
- const resolvedSource = lstatSync23(source).isSymbolicLink() ? realpathSync11(source) : source;
46816
+ const resolvedSource = lstatSync24(source).isSymbolicLink() ? realpathSync12(source) : source;
46639
46817
  mkdirSync7(destination, { recursive: true });
46640
46818
  cpSync(resolvedSource, destination, {
46641
46819
  recursive: true,
@@ -46648,7 +46826,7 @@ function copySkillDirectory(source, destination) {
46648
46826
  if (isExcludedCopyEntry(segments[i], i === 0))
46649
46827
  return false;
46650
46828
  }
46651
- if (lstatSync23(src).isSymbolicLink())
46829
+ if (lstatSync24(src).isSymbolicLink())
46652
46830
  return false;
46653
46831
  return true;
46654
46832
  }
@@ -46889,7 +47067,7 @@ function inferRuntimeFromCommands(commands) {
46889
47067
  return { ...defaultRuntimeContract(entrypoint), runtime: "python3" };
46890
47068
  }
46891
47069
  function readJsonObject(path) {
46892
- const parsed = JSON.parse(readFileSync18(path, "utf-8"));
47070
+ const parsed = JSON.parse(readFileSync19(path, "utf-8"));
46893
47071
  if (!isRecord3(parsed))
46894
47072
  throw new Error(`${basename9(path)} must contain a JSON object`);
46895
47073
  return parsed;
@@ -46927,7 +47105,7 @@ function escapeJsString(value) {
46927
47105
  }
46928
47106
 
46929
47107
  // src/lib/authoring-path.ts
46930
- import { lstatSync as lstatSync24, realpathSync as realpathSync12 } from "fs";
47108
+ import { lstatSync as lstatSync25, realpathSync as realpathSync13 } from "fs";
46931
47109
  import { homedir as homedir4 } from "os";
46932
47110
  import { basename as basename10, dirname as dirname19, join as join30, resolve as resolve19, sep as sep9 } from "path";
46933
47111
  var NATIVE_DISCOVERY_ROOTS = NATIVE_SKILL_ROOTS.map(([, path]) => path.split("/"));
@@ -46948,14 +47126,14 @@ function nativeRootMatch(path) {
46948
47126
  function physicalPath(path) {
46949
47127
  let cursor = resolve19(path);
46950
47128
  const suffix = [];
46951
- while (!lstatSync24(cursor, { throwIfNoEntry: false })) {
47129
+ while (!lstatSync25(cursor, { throwIfNoEntry: false })) {
46952
47130
  suffix.unshift(basename10(cursor));
46953
47131
  const parent = dirname19(cursor);
46954
47132
  if (parent === cursor)
46955
47133
  return resolve19(path);
46956
47134
  cursor = parent;
46957
47135
  }
46958
- return resolve19(realpathSync12(cursor), ...suffix);
47136
+ return resolve19(realpathSync13(cursor), ...suffix);
46959
47137
  }
46960
47138
  function contains(root2, path) {
46961
47139
  return path === root2 || path.startsWith(root2 + sep9);
@@ -46993,7 +47171,7 @@ function configuredRoots(home, explicitHome) {
46993
47171
  continue;
46994
47172
  }
46995
47173
  const nativeHome = join30(home, agent === "opencode" ? ".config/opencode" : `.${agent}`);
46996
- if (!lstatSync24(nativeHome, { throwIfNoEntry: false }))
47174
+ if (!lstatSync25(nativeHome, { throwIfNoEntry: false }))
46997
47175
  continue;
46998
47176
  roots.push(...resolveAgentDiscovery({ home, agent, canonical: physicalPath }).roots);
46999
47177
  }
@@ -47171,14 +47349,14 @@ function physicalImportPath(path) {
47171
47349
  suffix.unshift(basename11(ancestor));
47172
47350
  ancestor = dirname20(ancestor);
47173
47351
  }
47174
- return join31(realpathSync13(ancestor), ...suffix);
47352
+ return join31(realpathSync14(ancestor), ...suffix);
47175
47353
  }
47176
47354
  function assertDisjointImportPaths(source, destination) {
47177
- const sourcePath = realpathSync13(source);
47355
+ const sourcePath = realpathSync14(source);
47178
47356
  const destinationPath = physicalImportPath(destination);
47179
47357
  const contains2 = (parent, child) => {
47180
47358
  const path = relative7(parent, child);
47181
- return path === "" || !isAbsolute20(path) && path !== ".." && !path.startsWith(`..${sep10}`);
47359
+ return path === "" || !isAbsolute21(path) && path !== ".." && !path.startsWith(`..${sep10}`);
47182
47360
  };
47183
47361
  if (contains2(sourcePath, destinationPath) || contains2(destinationPath, sourcePath)) {
47184
47362
  throw new Error("Source and destination skill directories must not overlap");
@@ -47459,7 +47637,7 @@ function safeIsDirectory(path) {
47459
47637
  }
47460
47638
  }
47461
47639
  function isSafeRelativePath2(value) {
47462
- if (!value.trim() || isAbsolute20(value))
47640
+ if (!value.trim() || isAbsolute21(value))
47463
47641
  return false;
47464
47642
  const normalized = normalize4(value).replace(/\\/g, "/");
47465
47643
  return normalized !== ".." && !normalized.startsWith("../") && !normalized.includes("/../");
@@ -47486,9 +47664,9 @@ function isSkillsOwnershipMarker(marker) {
47486
47664
  function hasSkillsOwnershipMarker(dir) {
47487
47665
  const path = join32(dir, SYNC_MARKER_FILE);
47488
47666
  try {
47489
- if (!lstatSync25(path).isFile())
47667
+ if (!lstatSync26(path).isFile())
47490
47668
  return false;
47491
- const marker = JSON.parse(readFileSync19(path, "utf8"));
47669
+ const marker = JSON.parse(readFileSync20(path, "utf8"));
47492
47670
  return isSkillsOwnershipMarker(marker);
47493
47671
  } catch {
47494
47672
  return false;
@@ -47705,7 +47883,7 @@ function writeManagedSkillDirUnlocked(dir, skillMd, options, assertCurrent) {
47705
47883
  if (dirExists && managed && hasSkillMd && !options.force && isPointerSkillMd(skillMd)) {
47706
47884
  let existingIsStub = false;
47707
47885
  try {
47708
- existingIsStub = isPointerSkillMd(readFileSync19(skillMdPath, "utf-8"));
47886
+ existingIsStub = isPointerSkillMd(readFileSync20(skillMdPath, "utf-8"));
47709
47887
  } catch {
47710
47888
  existingIsStub = false;
47711
47889
  }
@@ -47755,7 +47933,7 @@ function writeManagedSkillDirUnlocked(dir, skillMd, options, assertCurrent) {
47755
47933
  assertCurrent();
47756
47934
  renameDirectory(candidateDir, dir);
47757
47935
  assertCurrent();
47758
- if (readFileSync19(skillMdPath, "utf8") !== (skillMd.endsWith(`
47936
+ if (readFileSync20(skillMdPath, "utf8") !== (skillMd.endsWith(`
47759
47937
  `) ? skillMd : `${skillMd}
47760
47938
  `))
47761
47939
  throw new Error("Managed skill readback failed");
@@ -47799,7 +47977,7 @@ function sourceSkillMd(skillPath, name, description, kind, preferBundledDocs = f
47799
47977
  if (kind === undefined || kind === "instruction" || preferBundledDocs) {
47800
47978
  const skillMdPath = join32(skillPath, "SKILL.md");
47801
47979
  if (existsSync11(skillMdPath))
47802
- return readFileSync19(skillMdPath, "utf-8");
47980
+ return readFileSync20(skillMdPath, "utf-8");
47803
47981
  }
47804
47982
  return pointerSkillMd(name, description);
47805
47983
  }
@@ -47829,7 +48007,7 @@ function normalizeSkillName(name) {
47829
48007
  }
47830
48008
 
47831
48009
  // src/lib/registry.ts
47832
- import { existsSync as existsSync12, readFileSync as readFileSync20, readdirSync as readdirSync12 } from "fs";
48010
+ import { existsSync as existsSync12, readFileSync as readFileSync21, readdirSync as readdirSync12 } from "fs";
47833
48011
  import { join as join33 } from "path";
47834
48012
 
47835
48013
  // src/lib/registry-merge.ts
@@ -48045,7 +48223,7 @@ function discoverSkillsInDir(dir, source = "custom") {
48045
48223
  continue;
48046
48224
  let content;
48047
48225
  try {
48048
- content = readFileSync20(skillMdPath, "utf-8");
48226
+ content = readFileSync21(skillMdPath, "utf-8");
48049
48227
  } catch {
48050
48228
  continue;
48051
48229
  }
@@ -48082,7 +48260,7 @@ function findExtensionSkillPath(name) {
48082
48260
  continue;
48083
48261
  let content;
48084
48262
  try {
48085
- content = readFileSync20(skillMdPath, "utf-8");
48263
+ content = readFileSync21(skillMdPath, "utf-8");
48086
48264
  } catch {
48087
48265
  continue;
48088
48266
  }
@@ -48147,7 +48325,7 @@ function getAllTags(catalog) {
48147
48325
  }
48148
48326
 
48149
48327
  // src/lib/project-state.ts
48150
- import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync21, writeFileSync as writeFileSync9 } from "fs";
48328
+ import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync22, writeFileSync as writeFileSync9 } from "fs";
48151
48329
  import { join as join34 } from "path";
48152
48330
  var VALID_PIN_SOURCES = [
48153
48331
  "official",
@@ -48173,7 +48351,7 @@ function loadProjectConfig(targetDir = process.cwd()) {
48173
48351
  if (!existsSync13(path))
48174
48352
  return null;
48175
48353
  try {
48176
- return normalizeProjectConfig(JSON.parse(readFileSync21(path, "utf-8")));
48354
+ return normalizeProjectConfig(JSON.parse(readFileSync22(path, "utf-8")));
48177
48355
  } catch {
48178
48356
  return null;
48179
48357
  }
@@ -48360,7 +48538,7 @@ function createLocalSkillManifest(name, generateSkillMd) {
48360
48538
  let skillMd = "";
48361
48539
  const skillMdPath = join35(sourcePath, "SKILL.md");
48362
48540
  if (existsSync14(skillMdPath)) {
48363
- skillMd = readFileSync22(skillMdPath, "utf-8");
48541
+ skillMd = readFileSync23(skillMdPath, "utf-8");
48364
48542
  } else if (generateSkillMd) {
48365
48543
  skillMd = generateSkillMd(name) ?? "";
48366
48544
  } else {
@@ -48486,7 +48664,7 @@ function resolveAgentSkillMd(name, generateSkillMd) {
48486
48664
  const sourcePath = getSkillPath(name);
48487
48665
  const skillMdPath = join35(sourcePath, "SKILL.md");
48488
48666
  if (existsSync14(skillMdPath))
48489
- return readFileSync22(skillMdPath, "utf-8");
48667
+ return readFileSync23(skillMdPath, "utf-8");
48490
48668
  if (generateSkillMd)
48491
48669
  return generateSkillMd(name);
48492
48670
  return generateMinimalSkillMd(name);
@@ -48542,14 +48720,14 @@ function readBundledSkillVersion(name) {
48542
48720
  if (!existsSync14(pkgPath))
48543
48721
  return "unknown";
48544
48722
  try {
48545
- const pkg = JSON.parse(readFileSync22(pkgPath, "utf-8"));
48723
+ const pkg = JSON.parse(readFileSync23(pkgPath, "utf-8"));
48546
48724
  return pkg.version || "unknown";
48547
48725
  } catch {
48548
48726
  return "unknown";
48549
48727
  }
48550
48728
  }
48551
48729
  function readFileIfExists(path) {
48552
- return existsSync14(path) ? readFileSync22(path, "utf-8") : null;
48730
+ return existsSync14(path) ? readFileSync23(path, "utf-8") : null;
48553
48731
  }
48554
48732
  function loadProjectConfigCompat(targetDir) {
48555
48733
  return loadProjectConfig(targetDir);
@@ -48597,7 +48775,7 @@ function isInstructionSkillDir(skillPath, meta) {
48597
48775
  if (!existsSync15(skillMdPath))
48598
48776
  return false;
48599
48777
  try {
48600
- return parseSkillFrontmatter(readFileSync23(skillMdPath, "utf-8"))?.kind === "instruction";
48778
+ return parseSkillFrontmatter(readFileSync24(skillMdPath, "utf-8"))?.kind === "instruction";
48601
48779
  } catch {
48602
48780
  return false;
48603
48781
  }
@@ -48648,7 +48826,7 @@ function getSkillRequirements(name) {
48648
48826
  const meta = getSkill(name);
48649
48827
  let dependencies = {};
48650
48828
  try {
48651
- dependencies = JSON.parse(readFileSync23(join36(skillPath, "package.json"), "utf8")).dependencies || {};
48829
+ dependencies = JSON.parse(readFileSync24(join36(skillPath, "package.json"), "utf8")).dependencies || {};
48652
48830
  } catch {}
48653
48831
  return getSkillRequirementsFromContent(name, texts, dependencies, meta);
48654
48832
  }
@@ -48716,7 +48894,7 @@ async function runSkill(name, args, options = {}) {
48716
48894
  }
48717
48895
  let entryPoint2;
48718
48896
  try {
48719
- const pkg = JSON.parse(readFileSync23(pkgPath, "utf-8"));
48897
+ const pkg = JSON.parse(readFileSync24(pkgPath, "utf-8"));
48720
48898
  if (pkg.bin) {
48721
48899
  const binValues = Object.values(pkg.bin);
48722
48900
  entryPoint2 = binValues[0];
@@ -48819,7 +48997,7 @@ function generateSkillMd(name) {
48819
48997
  const pkgPath = join36(skillPath, "package.json");
48820
48998
  if (existsSync15(pkgPath)) {
48821
48999
  try {
48822
- const pkg = JSON.parse(readFileSync23(pkgPath, "utf-8"));
49000
+ const pkg = JSON.parse(readFileSync24(pkgPath, "utf-8"));
48823
49001
  if (pkg.bin) {
48824
49002
  const binKeys = Object.keys(pkg.bin);
48825
49003
  if (binKeys.length > 0)
@@ -48895,7 +49073,7 @@ function extractEnvVars(text2) {
48895
49073
  function readIfExists(path) {
48896
49074
  try {
48897
49075
  if (existsSync15(path)) {
48898
- return readFileSync23(path, "utf-8");
49076
+ return readFileSync24(path, "utf-8");
48899
49077
  }
48900
49078
  } catch {}
48901
49079
  return null;
@@ -49126,7 +49304,7 @@ async function executeSelectedLocal(selected, options = {}) {
49126
49304
  const { authority: authority2, workspaceId, profileRevision, slug, version, bundleDigest } = selection2;
49127
49305
  const request2 = {
49128
49306
  selection: { authority: authority2, workspaceId, profileId, profileRevision, slug, version, bundleDigest },
49129
- consumer: { stationId: process.env.HASNA_STATION || stationHostname2(), workspaceDirectory: realpathSync14(options.cwd ?? process.cwd()) }
49307
+ consumer: { stationId: process.env.HASNA_STATION || stationHostname2(), workspaceDirectory: realpathSync15(options.cwd ?? process.cwd()) }
49130
49308
  };
49131
49309
  const grant = await (options.resolveExecutionGrant ?? resolveExecutionGrant)(request2);
49132
49310
  if (!grant || !grantIdentifier(grant.policyRevision) || !grantIdentifier(grant.grantId))
@@ -49143,7 +49321,7 @@ async function executeSelectedLocal(selected, options = {}) {
49143
49321
  selection: selection2,
49144
49322
  target: "local",
49145
49323
  runtime: runtimeName,
49146
- inputDigest: `sha256:${createHash25("sha256").update(input).digest("hex")}`,
49324
+ inputDigest: `sha256:${createHash26("sha256").update(input).digest("hex")}`,
49147
49325
  runDirectory,
49148
49326
  ...executionGrant ? { executionGrant } : {},
49149
49327
  ...bindings ? { secretBinding: { schema: bindings.schema, selection: bindings.selection, consumer: bindings.consumer, secretsAuthority: bindings.secretsAuthority, bindings: bindings.bindings } } : {},
@@ -58433,7 +58611,7 @@ var import_node_http_handler2 = __toESM(require_dist_cjs6(), 1);
58433
58611
 
58434
58612
  // node_modules/@aws-sdk/checksums/dist-cjs/submodules/sha/index.js
58435
58613
  var { toUint8Array: toUint8Array2, concatBytes } = require_serde();
58436
- var { createHmac: createHmac2, createHash: createHash27 } = __require("crypto");
58614
+ var { createHmac: createHmac2, createHash: createHash28 } = __require("crypto");
58437
58615
  var { Sha256: Sha2562, Sha256Js, Sha256Node } = require_checksum();
58438
58616
  var BLOCK2 = 64;
58439
58617
  var DIGEST_LENGTH = 20;
@@ -58602,7 +58780,7 @@ class Sha1Js {
58602
58780
  }
58603
58781
  var hasNativeCrypto = (() => {
58604
58782
  try {
58605
- createHash27("sha1");
58783
+ createHash28("sha1");
58606
58784
  return true;
58607
58785
  } catch {
58608
58786
  return false;
@@ -58642,7 +58820,7 @@ function buildNativeClass() {
58642
58820
  this.finished = false;
58643
58821
  }
58644
58822
  createHash() {
58645
- return this.secret ? createHmac2("sha1", toBuffer(this.secret)) : createHash27("sha1");
58823
+ return this.secret ? createHmac2("sha1", toBuffer(this.secret)) : createHash28("sha1");
58646
58824
  }
58647
58825
  };
58648
58826
  }
@@ -58917,11 +59095,11 @@ class ArtifactStorage {
58917
59095
  }));
58918
59096
  return await bodyToText(response.Body);
58919
59097
  }
58920
- async putBundle(orgId, sha2562, bytes, contentType = "application/gzip") {
58921
- assertSha256(sha2562);
59098
+ async putBundle(orgId, sha2563, bytes, contentType = "application/gzip") {
59099
+ assertSha256(sha2563);
58922
59100
  if (!this.bucket)
58923
59101
  return { storageKind: "db", bytes };
58924
- const key = this.bundleKeyFor(orgId, sha2562);
59102
+ const key = this.bundleKeyFor(orgId, sha2563);
58925
59103
  await this.s3.send(new PutObjectCommand({
58926
59104
  Bucket: this.bucket,
58927
59105
  Key: key,
@@ -58941,11 +59119,11 @@ class ArtifactStorage {
58941
59119
  }));
58942
59120
  return await bodyToBytes(response.Body);
58943
59121
  }
58944
- async deleteBundle(orgId, sha2562) {
59122
+ async deleteBundle(orgId, sha2563) {
58945
59123
  if (!this.bucket || !this.s3)
58946
59124
  return;
58947
- assertSha256(sha2562);
58948
- await this.s3.send(new DeleteObjectCommand({ Bucket: this.bucket, Key: this.bundleKeyFor(orgId, sha2562) }));
59125
+ assertSha256(sha2563);
59126
+ await this.s3.send(new DeleteObjectCommand({ Bucket: this.bucket, Key: this.bundleKeyFor(orgId, sha2563) }));
58949
59127
  }
58950
59128
  async deleteObject(artifact) {
58951
59129
  if (!this.bucket || !this.s3)
@@ -58992,8 +59170,8 @@ class ArtifactStorage {
58992
59170
  versionKeyFor(orgId, slug, version2, file) {
58993
59171
  return `${this.prefix}/skills/${encodeURIComponent(orgId)}/${encodeURIComponent(slug)}/${encodeURIComponent(version2)}/${file}`;
58994
59172
  }
58995
- bundleKeyFor(orgId, sha2562) {
58996
- return `${this.prefix}/bundles/${encodeURIComponent(orgId)}/${sha2562}.tar.gz`;
59173
+ bundleKeyFor(orgId, sha2563) {
59174
+ return `${this.prefix}/bundles/${encodeURIComponent(orgId)}/${sha2563}.tar.gz`;
58997
59175
  }
58998
59176
  }
58999
59177
  function assertSha256(value) {
@@ -59214,7 +59392,7 @@ import { mkdirSync as mkdirSync13 } from "fs";
59214
59392
  import { dirname as dirname26 } from "path";
59215
59393
 
59216
59394
  // src/server/database-url.ts
59217
- import { isAbsolute as isAbsolute21, join as join39 } from "path";
59395
+ import { isAbsolute as isAbsolute22, join as join39 } from "path";
59218
59396
  import { fileURLToPath as fileURLToPath3 } from "url";
59219
59397
  var DEFAULT_SQLITE_FILENAME2 = "server.db";
59220
59398
  var SQLITE_MEMORY_PATH = ":memory:";
@@ -59250,7 +59428,7 @@ function resolveDatabaseTarget(raw) {
59250
59428
  throw new Error(`unsupported database scheme "${scheme}:". Supported: postgres://, postgresql://, sqlite:, file:, ` + `an absolute or relative path to a .db/.sqlite file, ":memory:", or "memory:" (non-durable, tests only). ` + `Leave the setting empty to use the default SQLite database at ${defaultSqlitePath()}.`);
59251
59429
  }
59252
59430
  if (looksLikeSqlitePath(value)) {
59253
- const path = isAbsolute21(value) ? value : join39(process.cwd(), value);
59431
+ const path = isAbsolute22(value) ? value : join39(process.cwd(), value);
59254
59432
  return { kind: "sqlite", path, durable: true, label: `sqlite (${path})` };
59255
59433
  }
59256
59434
  throw new Error(`could not resolve a database backend from "${value}". Use postgres://\u2026, sqlite:\u2026, an absolute or ` + `relative path ending in ${SQLITE_EXTENSIONS.join("/")}, ":memory:", or leave it empty for the ` + `default SQLite database at ${defaultSqlitePath()}.`);
@@ -59274,7 +59452,7 @@ function sqlitePathFromUrl(value, scheme) {
59274
59452
  }
59275
59453
  return rest.slice(2).replace(/^\/\/+/, "/");
59276
59454
  }
59277
- return isAbsolute21(rest) ? rest : join39(process.cwd(), rest);
59455
+ return isAbsolute22(rest) ? rest : join39(process.cwd(), rest);
59278
59456
  }
59279
59457
  function looksLikeSqlitePath(value) {
59280
59458
  if (value.includes("/"))
@@ -59506,13 +59684,13 @@ class PostgresSkillSelectionStore {
59506
59684
 
59507
59685
  // src/server/sqlite-store.ts
59508
59686
  import { randomUUID as randomUUID8 } from "crypto";
59509
- import { mkdirSync as mkdirSync12, readFileSync as readFileSync25, readdirSync as readdirSync13 } from "fs";
59687
+ import { mkdirSync as mkdirSync12, readFileSync as readFileSync26, readdirSync as readdirSync13 } from "fs";
59510
59688
  import { dirname as dirname25, join as join41 } from "path";
59511
59689
 
59512
59690
  // src/server/auth.ts
59513
- import { createHash as createHash28 } from "crypto";
59691
+ import { createHash as createHash29 } from "crypto";
59514
59692
  function hashApiKey(token) {
59515
- return createHash28("sha256").update(token).digest("hex");
59693
+ return createHash29("sha256").update(token).digest("hex");
59516
59694
  }
59517
59695
  function bearerToken(request2) {
59518
59696
  const header = request2.headers.get("authorization") || "";
@@ -59836,7 +60014,7 @@ function validOperatorScopeEnrollmentInput(input) {
59836
60014
  }
59837
60015
 
59838
60016
  // src/lib/revision.ts
59839
- import { createHash as createHash29 } from "crypto";
60017
+ import { createHash as createHash30 } from "crypto";
59840
60018
  var REVISION_ID_PATTERN = /^[0-9a-f]{64}$/;
59841
60019
  function revisionIdOf(content) {
59842
60020
  const canonicalContent = {
@@ -59858,7 +60036,7 @@ function revisionIdOf(content) {
59858
60036
  canonicalContent.replacementSlug = content.replacementSlug ?? null;
59859
60037
  }
59860
60038
  const canonical7 = JSON.stringify(canonicalContent);
59861
- return createHash29("sha256").update(canonical7).digest("hex");
60039
+ return createHash30("sha256").update(canonical7).digest("hex");
59862
60040
  }
59863
60041
  function revisionIdOfRecord(record4) {
59864
60042
  return revisionIdOf(record4);
@@ -60467,8 +60645,8 @@ class SqliteSkillsStore {
60467
60645
  return purged;
60468
60646
  })();
60469
60647
  }
60470
- async getSkillBundle(principal, sha2562) {
60471
- const row = this.get("SELECT * FROM skills_bundles WHERE org_id = ? AND sha256 = ? LIMIT 1", [principal.orgId, sha2562]);
60648
+ async getSkillBundle(principal, sha2563) {
60649
+ const row = this.get("SELECT * FROM skills_bundles WHERE org_id = ? AND sha256 = ? LIMIT 1", [principal.orgId, sha2563]);
60472
60650
  return row ? rowToSkillBundle(row) : null;
60473
60651
  }
60474
60652
  async listSkillVersions(principal, slug) {
@@ -60532,11 +60710,11 @@ class SqliteSkillsStore {
60532
60710
  async listPublishedSlugs(principal) {
60533
60711
  return this.all("SELECT slug FROM skills_registry WHERE org_id = ? AND tombstoned_at IS NULL ORDER BY slug ASC", [principal.orgId]).map((row) => String(row.slug));
60534
60712
  }
60535
- collectOrphanBundle(orgId, sha2562) {
60536
- const referenced = this.get("SELECT 1 AS present FROM skills_registry WHERE org_id = ? AND bundle_sha256 = ? LIMIT 1", [orgId, sha2562]) ?? this.get("SELECT 1 AS present FROM skills_versions WHERE org_id = ? AND bundle_sha256 = ? LIMIT 1", [orgId, sha2562]);
60713
+ collectOrphanBundle(orgId, sha2563) {
60714
+ const referenced = this.get("SELECT 1 AS present FROM skills_registry WHERE org_id = ? AND bundle_sha256 = ? LIMIT 1", [orgId, sha2563]) ?? this.get("SELECT 1 AS present FROM skills_versions WHERE org_id = ? AND bundle_sha256 = ? LIMIT 1", [orgId, sha2563]);
60537
60715
  if (referenced)
60538
60716
  return;
60539
- this.db.run("DELETE FROM skills_bundles WHERE org_id = ? AND sha256 = ?", [orgId, sha2562]);
60717
+ this.db.run("DELETE FROM skills_bundles WHERE org_id = ? AND sha256 = ?", [orgId, sha2563]);
60540
60718
  }
60541
60719
  get(sql, params) {
60542
60720
  return this.db.query(sql).get(...params) ?? null;
@@ -60562,7 +60740,7 @@ function applySqliteMigrations(db, migrationsDir = resolveMigrationsDir("sqlite"
60562
60740
  const appliedNow = [];
60563
60741
  for (const file of files) {
60564
60742
  const version2 = file.replace(/\.sql$/, "");
60565
- const text2 = readFileSync25(join41(migrationsDir, file), "utf8");
60743
+ const text2 = readFileSync26(join41(migrationsDir, file), "utf8");
60566
60744
  const apply = db.transaction(() => {
60567
60745
  const already = db.query("SELECT 1 AS present FROM schema_migrations WHERE version = ? LIMIT 1").get(version2);
60568
60746
  if (already)
@@ -60942,7 +61120,7 @@ function nextMonthPrefix(monthPrefix) {
60942
61120
  }
60943
61121
 
60944
61122
  // src/server/skills-api.ts
60945
- import { createHash as createHash30 } from "crypto";
61123
+ import { createHash as createHash31 } from "crypto";
60946
61124
  var SLUG_PATTERN = /^[a-z0-9][a-z0-9._-]*$/;
60947
61125
  var SHA256_HEX2 = /^[0-9a-f]{64}$/;
60948
61126
  var MAX_SLUG_LENGTH = 128;
@@ -61132,19 +61310,19 @@ async function parsePublishRequest(request2, config) {
61132
61310
  if (bundleBytes.byteLength === 0) {
61133
61311
  throw new SkillRequestError(400, "BUNDLE_EMPTY", "the uploaded bundle is empty");
61134
61312
  }
61135
- const sha2562 = createHash30("sha256").update(bundleBytes).digest("hex");
61313
+ const sha2563 = createHash31("sha256").update(bundleBytes).digest("hex");
61136
61314
  const claimed = optionalString(manifest.bundleSha256);
61137
61315
  if (claimed)
61138
61316
  assertSha2562(claimed);
61139
- if (claimed && claimed !== sha2562) {
61140
- throw new SkillRequestError(400, "BUNDLE_DIGEST_MISMATCH", `bundle digest ${sha2562} does not match the declared ${claimed}`);
61317
+ if (claimed && claimed !== sha2563) {
61318
+ throw new SkillRequestError(400, "BUNDLE_DIGEST_MISMATCH", `bundle digest ${sha2563} does not match the declared ${claimed}`);
61141
61319
  }
61142
61320
  const input = buildPublishInput(manifest);
61143
61321
  return {
61144
61322
  input: {
61145
61323
  ...input,
61146
61324
  bundle: {
61147
- sha256: sha2562,
61325
+ sha256: sha2563,
61148
61326
  byteSize: bundleBytes.byteLength,
61149
61327
  contentType: optionalString(manifest.bundleContentType) ?? "application/gzip",
61150
61328
  storageKind: "db"
@@ -61229,10 +61407,10 @@ async function storePublishedSkill(store, artifactStorage, principal, parsed, ex
61229
61407
  async function deletePublishedSkill(store, artifactStorage, principal, slug, tombstoneWindowMs) {
61230
61408
  return store.deleteSkill(principal, slug, tombstoneWindowMs);
61231
61409
  }
61232
- async function discardCollectedObject(store, artifactStorage, principal, sha2562) {
61233
- if (await store.getSkillBundle(principal, sha2562))
61410
+ async function discardCollectedObject(store, artifactStorage, principal, sha2563) {
61411
+ if (await store.getSkillBundle(principal, sha2563))
61234
61412
  return;
61235
- await artifactStorage.deleteBundle(principal.orgId, sha2562);
61413
+ await artifactStorage.deleteBundle(principal.orgId, sha2563);
61236
61414
  }
61237
61415
  async function readPublishedBundle(store, artifactStorage, principal, slug) {
61238
61416
  const record4 = await store.getSkill(principal, slug);
@@ -61247,7 +61425,7 @@ async function readPublishedBundle(store, artifactStorage, principal, slug) {
61247
61425
  if (!bytes) {
61248
61426
  throw new SkillRequestError(503, "BUNDLE_BACKEND_UNAVAILABLE", "bundle storage backend unavailable");
61249
61427
  }
61250
- const actual = createHash30("sha256").update(bytes).digest("hex");
61428
+ const actual = createHash31("sha256").update(bytes).digest("hex");
61251
61429
  if (actual !== record4.bundleSha256) {
61252
61430
  throw new SkillRequestError(500, "BUNDLE_DIGEST_DRIFT", `stored bundle for '${slug}' hashes to ${actual} but was published as ${record4.bundleSha256}`);
61253
61431
  }
@@ -61395,7 +61573,7 @@ async function readSkillVersionBundle(store, artifactStorage, principal, slug, v
61395
61573
  const bytes = await artifactStorage.readBundle(bundle2);
61396
61574
  if (!bytes)
61397
61575
  throw new SkillRequestError(503, "BUNDLE_BACKEND_UNAVAILABLE", "bundle storage backend unavailable");
61398
- const actual = createHash30("sha256").update(bytes).digest("hex");
61576
+ const actual = createHash31("sha256").update(bytes).digest("hex");
61399
61577
  if (actual !== found.bundleSha256) {
61400
61578
  throw new SkillRequestError(500, "BUNDLE_DIGEST_DRIFT", `stored bundle for '${slug}@${version2}' hashes to ${actual} but was published as ${found.bundleSha256}`);
61401
61579
  }
@@ -62111,7 +62289,7 @@ class RuntimeExecutionStore {
62111
62289
  }
62112
62290
 
62113
62291
  // src/sdk/execution/admission.ts
62114
- import { createHash as createHash32 } from "crypto";
62292
+ import { createHash as createHash33 } from "crypto";
62115
62293
 
62116
62294
  // src/sdk/execution/image-profile.ts
62117
62295
  class ImageProfileResolutionError extends Error {
@@ -62723,11 +62901,11 @@ function ownedAdmission(admission) {
62723
62901
  };
62724
62902
  }
62725
62903
  function digestInput(input) {
62726
- return createHash32("sha256").update(canonicalJson2(input)).digest("hex");
62904
+ return createHash33("sha256").update(canonicalJson2(input)).digest("hex");
62727
62905
  }
62728
62906
 
62729
62907
  // src/sdk/execution/dispatchers/ecs.ts
62730
- import { createHash as createHash33 } from "crypto";
62908
+ import { createHash as createHash34 } from "crypto";
62731
62909
 
62732
62910
  // src/sdk/execution/state-machine.ts
62733
62911
  var LEGAL_TRANSITIONS = {
@@ -66127,13 +66305,13 @@ function observedTask(states, taskArn) {
66127
66305
  return state2.lastStatus === "STOPPED" || LIVE_TASK_STATUSES.has(state2.lastStatus) ? state2 : undefined;
66128
66306
  }
66129
66307
  function clientTokenFor(runId3, attemptId) {
66130
- return createHash33("sha256").update(`${runId3}\x00${attemptId}`).digest("hex").slice(0, CLIENT_TOKEN_BYTES * 2);
66308
+ return createHash34("sha256").update(`${runId3}\x00${attemptId}`).digest("hex").slice(0, CLIENT_TOKEN_BYTES * 2);
66131
66309
  }
66132
66310
  function startedByFor(runId3, attemptNumber) {
66133
66311
  return `skills-exec/${runId3}/a${attemptNumber}`;
66134
66312
  }
66135
66313
  function requestDigestFor(admission, attemptId) {
66136
- return createHash33("sha256").update(canonicalJson2({ admission, attemptId })).digest("hex");
66314
+ return createHash34("sha256").update(canonicalJson2({ admission, attemptId })).digest("hex");
66137
66315
  }
66138
66316
 
66139
66317
  class EcsDispatcher {
@@ -66429,10 +66607,10 @@ function validText(value) {
66429
66607
  }
66430
66608
 
66431
66609
  // src/server/runtime-policy.ts
66432
- import { createHash as createHash35, createHmac as createHmac3, timingSafeEqual as timingSafeEqual2 } from "crypto";
66610
+ import { createHash as createHash36, createHmac as createHmac3, timingSafeEqual as timingSafeEqual2 } from "crypto";
66433
66611
 
66434
66612
  // src/server/runtime-pure-contract.ts
66435
- import { createHash as createHash34 } from "crypto";
66613
+ import { createHash as createHash35 } from "crypto";
66436
66614
  var PURE_DESCRIPTOR = Object.freeze({
66437
66615
  id: "regex-test.v1",
66438
66616
  runtime: "bun",
@@ -66456,7 +66634,7 @@ var PURE_LIMITS = Object.freeze({
66456
66634
  maxArtifactsBytes: 0,
66457
66635
  maxConcurrency: 1
66458
66636
  });
66459
- var hash2 = (bytes) => createHash34("sha256").update(bytes).digest("hex");
66637
+ var hash2 = (bytes) => createHash35("sha256").update(bytes).digest("hex");
66460
66638
  var object7 = (v2) => {
66461
66639
  if (!v2 || typeof v2 !== "object" || Array.isArray(v2))
66462
66640
  throw Error("Pure contract requires an object");
@@ -66685,7 +66863,7 @@ function verifyRuntimeToken(token, key, admission, attempt, now = Date.now()) {
66685
66863
  const actual = Buffer.from(token);
66686
66864
  return actual.length === expected.length && timingSafeEqual2(actual, expected);
66687
66865
  }
66688
- var hashBytes = (bytes) => createHash35("sha256").update(bytes).digest("hex");
66866
+ var hashBytes = (bytes) => createHash36("sha256").update(bytes).digest("hex");
66689
66867
 
66690
66868
  // src/server/runtime-api.ts
66691
66869
  async function createRuntimeService(options) {
@@ -66786,8 +66964,8 @@ function publicJob(job) {
66786
66964
  artifacts: (job.result?.artifacts ?? []).map(({ base64, ...meta }) => meta)
66787
66965
  };
66788
66966
  }
66789
- function findReview(service, tenant, slug, version2, sha2562) {
66790
- return service.config.reviewedBundles.find((b4) => b4.slug === slug && b4.version === version2 && b4.sha256 === sha2562 && (!b4.executionContract || b4.tenantId === tenant && b4.imageDigest === service.config.imageDigest));
66967
+ function findReview(service, tenant, slug, version2, sha2563) {
66968
+ return service.config.reviewedBundles.find((b4) => b4.slug === slug && b4.version === version2 && b4.sha256 === sha2563 && (!b4.executionContract || b4.tenantId === tenant && b4.imageDigest === service.config.imageDigest));
66791
66969
  }
66792
66970
  function sameContract(admission, contract, image) {
66793
66971
  return digestInput(admission.executionContract ?? null) === digestInput(contract ?? null) && (!contract || admission.runtimeImageDigest === image);
@@ -67641,8 +67819,8 @@ class MemorySkillsStore {
67641
67819
  }
67642
67820
  return purged;
67643
67821
  }
67644
- async getSkillBundle(principal, sha2562) {
67645
- const bundle2 = this.bundles.get(skillKey(principal.orgId, sha2562));
67822
+ async getSkillBundle(principal, sha2563) {
67823
+ const bundle2 = this.bundles.get(skillKey(principal.orgId, sha2563));
67646
67824
  return bundle2 && bundle2.orgId === principal.orgId ? bundle2 : null;
67647
67825
  }
67648
67826
  async pinSkill(principal, slug, metadata = {}) {
@@ -67685,10 +67863,10 @@ class MemorySkillsStore {
67685
67863
  async listPublishedSlugs(principal) {
67686
67864
  return Array.from(this.skills.values()).filter((skill) => skill.orgId === principal.orgId && !skill.tombstonedAt).map((skill) => skill.slug).sort();
67687
67865
  }
67688
- collectOrphanBundle(orgId, sha2562) {
67689
- const referenced = Array.from(this.skills.values()).some((skill) => skill.orgId === orgId && skill.bundleSha256 === sha2562) || Array.from(this.versions.values()).some((v2) => v2.orgId === orgId && v2.bundleSha256 === sha2562);
67866
+ collectOrphanBundle(orgId, sha2563) {
67867
+ const referenced = Array.from(this.skills.values()).some((skill) => skill.orgId === orgId && skill.bundleSha256 === sha2563) || Array.from(this.versions.values()).some((v2) => v2.orgId === orgId && v2.bundleSha256 === sha2563);
67690
67868
  if (!referenced)
67691
- this.bundles.delete(skillKey(orgId, sha2562));
67869
+ this.bundles.delete(skillKey(orgId, sha2563));
67692
67870
  }
67693
67871
  patchRun(runId3, patch) {
67694
67872
  const run = this.runs.get(runId3);
@@ -68349,8 +68527,8 @@ class PostgresSkillsStore {
68349
68527
  return purged;
68350
68528
  });
68351
68529
  }
68352
- async getSkillBundle(principal, sha2562) {
68353
- const rows = await this.sql`SELECT * FROM skills_bundles WHERE org_id = ${principal.orgId} AND sha256 = ${sha2562} LIMIT 1`;
68530
+ async getSkillBundle(principal, sha2563) {
68531
+ const rows = await this.sql`SELECT * FROM skills_bundles WHERE org_id = ${principal.orgId} AND sha256 = ${sha2563} LIMIT 1`;
68354
68532
  return rows[0] ? rowToSkillBundle(rows[0]) : null;
68355
68533
  }
68356
68534
  async listSkillVersions(principal, slug) {
@@ -68444,12 +68622,12 @@ class PostgresSkillsStore {
68444
68622
  `;
68445
68623
  return rows.map((row) => String(row.slug));
68446
68624
  }
68447
- async collectOrphanBundle(orgId, sha2562) {
68625
+ async collectOrphanBundle(orgId, sha2563) {
68448
68626
  await this.sql`
68449
68627
  DELETE FROM skills_bundles
68450
- WHERE org_id = ${orgId} AND sha256 = ${sha2562}
68451
- AND NOT EXISTS (SELECT 1 FROM skills_registry WHERE org_id = ${orgId} AND bundle_sha256 = ${sha2562})
68452
- AND NOT EXISTS (SELECT 1 FROM skills_versions WHERE org_id = ${orgId} AND bundle_sha256 = ${sha2562})
68628
+ WHERE org_id = ${orgId} AND sha256 = ${sha2563}
68629
+ AND NOT EXISTS (SELECT 1 FROM skills_registry WHERE org_id = ${orgId} AND bundle_sha256 = ${sha2563})
68630
+ AND NOT EXISTS (SELECT 1 FROM skills_versions WHERE org_id = ${orgId} AND bundle_sha256 = ${sha2563})
68453
68631
  `;
68454
68632
  }
68455
68633
  }
@@ -73061,7 +73239,7 @@ var localRunExecutor = {
73061
73239
  // src/sdk/storage.ts
73062
73240
  var artifactStorageSeam = ArtifactStorage;
73063
73241
  // src/sdk/outputs.ts
73064
- import { createHash as createHash36 } from "crypto";
73242
+ import { createHash as createHash37 } from "crypto";
73065
73243
  class DatabaseOnlyObjectStore {
73066
73244
  usesS3 = false;
73067
73245
  async materialize(run, artifact, body4) {
@@ -73108,7 +73286,7 @@ function createGovernedArtifactWriter(options) {
73108
73286
  const stamped = {
73109
73287
  ...meta,
73110
73288
  byteSize: outputBytes,
73111
- sha256: createHash36("sha256").update(persistedBytes).digest("hex"),
73289
+ sha256: createHash37("sha256").update(persistedBytes).digest("hex"),
73112
73290
  visibility: options.visibility ?? config.defaultVisibility,
73113
73291
  ...config.artifactTtlSeconds !== undefined ? { expiresAt: expiresAtFor(createdAt, config.artifactTtlSeconds) } : {}
73114
73292
  };
@@ -91875,7 +92053,7 @@ function date4(params) {
91875
92053
  return _coercedDate(ZodDate2, params);
91876
92054
  }
91877
92055
  // src/lib/canonical-json.ts
91878
- import { createHash as createHash37 } from "crypto";
92056
+ import { createHash as createHash38 } from "crypto";
91879
92057
  function canonicalJson3(value, maximumBytes = 2 * 1024 * 1024) {
91880
92058
  return canonicalJsonAtDepth(value, maximumBytes, 64);
91881
92059
  }
@@ -91919,7 +92097,7 @@ function canonicalJsonAtDepth(value, maximumBytes, maximumDepth) {
91919
92097
  return visit3(value, 0);
91920
92098
  }
91921
92099
  function canonicalJsonSha256(value, maximumBytes) {
91922
- return createHash37("sha256").update(canonicalJson3(value, maximumBytes)).digest("hex");
92100
+ return createHash38("sha256").update(canonicalJson3(value, maximumBytes)).digest("hex");
91923
92101
  }
91924
92102
 
91925
92103
  // src/lib/remote-recurring-contract.ts
@@ -94033,7 +94211,7 @@ async function requestInvitationEmail(origin, action, input2) {
94033
94211
  }
94034
94212
 
94035
94213
  // src/lib/remote-private-publications.ts
94036
- import { createHash as createHash38 } from "crypto";
94214
+ import { createHash as createHash39 } from "crypto";
94037
94215
  var PRIVATE_PUBLICATION_MAX_BYTES = 16 * 1024 * 1024;
94038
94216
  var failures2 = {
94039
94217
  INVALID_REQUEST: [400, "The publication request is invalid."],
@@ -94080,7 +94258,7 @@ var hash4 = (v2) => typeof v2 === "string" && /^[a-f0-9]{64}$/.test(v2);
94080
94258
  var record10 = (v2) => !!v2 && typeof v2 === "object" && !Array.isArray(v2);
94081
94259
  var exact = (v2, keys3) => record10(v2) && Object.keys(v2).sort().join(",") === keys3.sort().join(",");
94082
94260
  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));
94083
- var publicationSha256 = (bytes) => createHash38("sha256").update(bytes).digest("hex");
94261
+ var publicationSha256 = (bytes) => createHash39("sha256").update(bytes).digest("hex");
94084
94262
  function checkedPublicationDeclaration(value) {
94085
94263
  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)
94086
94264
  return bad();
@@ -94562,23 +94740,23 @@ class RemoteSkillsAuthClient {
94562
94740
  }
94563
94741
  }
94564
94742
  // src/lib/private-publication-recovery.ts
94565
- import { constants as constants15, closeSync as closeSync18, fsyncSync as fsyncSync6, fstatSync as fstatSync18, lstatSync as lstatSync26, mkdirSync as mkdirSync15, openSync as openSync18, readSync as readSync13, realpathSync as realpathSync15, renameSync as renameSync7, unlinkSync as unlinkSync6, writeFileSync as writeFileSync11 } from "fs";
94566
- import { dirname as dirname28, isAbsolute as isAbsolute22, join as join43, resolve as resolve23 } from "path";
94743
+ import { constants as constants16, closeSync as closeSync19, fsyncSync as fsyncSync7, fstatSync as fstatSync19, lstatSync as lstatSync27, mkdirSync as mkdirSync15, openSync as openSync19, readSync as readSync13, realpathSync as realpathSync16, renameSync as renameSync7, unlinkSync as unlinkSync6, writeFileSync as writeFileSync11 } from "fs";
94744
+ import { dirname as dirname28, isAbsolute as isAbsolute23, join as join43, resolve as resolve23 } from "path";
94567
94745
  import { randomUUID as randomUUID12 } from "crypto";
94568
94746
  var fail2 = () => {
94569
94747
  throw new PrivatePublicationError("PUBLICATION_RECOVERY_INVALID", "The recovery directory is invalid or changed. Preserve it and inspect the existing intent; do not start a replacement automatically.");
94570
94748
  };
94571
94749
  function safeDirectory(directory) {
94572
- if (!isAbsolute22(directory) || directory !== resolve23(directory) || realpathSync15(directory) !== directory)
94750
+ if (!isAbsolute23(directory) || directory !== resolve23(directory) || realpathSync16(directory) !== directory)
94573
94751
  return fail2();
94574
94752
  for (let path2 = directory;; path2 = dirname28(path2)) {
94575
- const stat2 = lstatSync26(path2);
94753
+ const stat2 = lstatSync27(path2);
94576
94754
  if (!stat2.isDirectory() || stat2.isSymbolicLink())
94577
94755
  return fail2();
94578
94756
  if (path2 === dirname28(path2))
94579
94757
  break;
94580
94758
  }
94581
- const own2 = lstatSync26(directory);
94759
+ const own2 = lstatSync27(directory);
94582
94760
  if ((own2.mode & 63) !== 0 || process.getuid && own2.uid !== process.getuid())
94583
94761
  return fail2();
94584
94762
  return { dev: own2.dev, ino: own2.ino };
@@ -94590,9 +94768,9 @@ function unchangedDirectory(directory, identity5) {
94590
94768
  }
94591
94769
  function readOwned(directory, name, max) {
94592
94770
  const identity5 = safeDirectory(directory), file2 = join43(directory, name);
94593
- const fd = openSync18(file2, constants15.O_RDONLY | constants15.O_NOFOLLOW);
94771
+ const fd = openSync19(file2, constants16.O_RDONLY | constants16.O_NOFOLLOW);
94594
94772
  try {
94595
- const stat2 = fstatSync18(fd);
94773
+ const stat2 = fstatSync19(fd);
94596
94774
  if (!stat2.isFile() || stat2.nlink !== 1 || stat2.size > max || stat2.size < 1 || (stat2.mode & 63) !== 0 || process.getuid && stat2.uid !== process.getuid())
94597
94775
  return fail2();
94598
94776
  const buffer = Buffer.alloc(Math.min(max, stat2.size) + 1);
@@ -94603,22 +94781,22 @@ function readOwned(directory, name, max) {
94603
94781
  break;
94604
94782
  length += count;
94605
94783
  }
94606
- const bytes = buffer.subarray(0, length), after = fstatSync18(fd);
94784
+ const bytes = buffer.subarray(0, length), after = fstatSync19(fd);
94607
94785
  unchangedDirectory(directory, identity5);
94608
94786
  if (bytes.length !== stat2.size || stat2.size !== after.size || stat2.mtimeMs !== after.mtimeMs || stat2.ctimeMs !== after.ctimeMs)
94609
94787
  return fail2();
94610
94788
  return bytes;
94611
94789
  } finally {
94612
- closeSync18(fd);
94790
+ closeSync19(fd);
94613
94791
  }
94614
94792
  }
94615
94793
  function writeOwned(directory, name, bytes) {
94616
- const fd = openSync18(join43(directory, name), constants15.O_WRONLY | constants15.O_CREAT | constants15.O_EXCL | constants15.O_NOFOLLOW, 384);
94794
+ const fd = openSync19(join43(directory, name), constants16.O_WRONLY | constants16.O_CREAT | constants16.O_EXCL | constants16.O_NOFOLLOW, 384);
94617
94795
  try {
94618
94796
  writeFileSync11(fd, bytes);
94619
- fsyncSync6(fd);
94797
+ fsyncSync7(fd);
94620
94798
  } finally {
94621
- closeSync18(fd);
94799
+ closeSync19(fd);
94622
94800
  }
94623
94801
  }
94624
94802
  function save(directory, value) {
@@ -94627,11 +94805,11 @@ function save(directory, value) {
94627
94805
  `);
94628
94806
  unchangedDirectory(directory, identity5);
94629
94807
  renameSync7(join43(directory, temporary), join43(directory, "receipt.json"));
94630
- const fd = openSync18(directory, constants15.O_RDONLY | constants15.O_NOFOLLOW);
94808
+ const fd = openSync19(directory, constants16.O_RDONLY | constants16.O_NOFOLLOW);
94631
94809
  try {
94632
- fsyncSync6(fd);
94810
+ fsyncSync7(fd);
94633
94811
  } finally {
94634
- closeSync18(fd);
94812
+ closeSync19(fd);
94635
94813
  }
94636
94814
  }
94637
94815
  function bind(client2, receipt) {
@@ -94642,20 +94820,20 @@ async function locked(directory, action) {
94642
94820
  const identity5 = safeDirectory(directory), file2 = join43(directory, "operation.lock");
94643
94821
  let fd;
94644
94822
  try {
94645
- fd = openSync18(file2, constants15.O_WRONLY | constants15.O_CREAT | constants15.O_EXCL | constants15.O_NOFOLLOW, 384);
94823
+ fd = openSync19(file2, constants16.O_WRONLY | constants16.O_CREAT | constants16.O_EXCL | constants16.O_NOFOLLOW, 384);
94646
94824
  } catch {
94647
94825
  throw new PrivatePublicationError("PUBLICATION_RECOVERY_BUSY", "Another operation holds this recovery directory. If it crashed, confirm that process has stopped before explicitly removing operation.lock and resuming.");
94648
94826
  }
94649
- const lock = fstatSync18(fd);
94827
+ const lock = fstatSync19(fd);
94650
94828
  try {
94651
94829
  writeFileSync11(fd, JSON.stringify({ pid: process.pid }) + `
94652
94830
  `);
94653
- fsyncSync6(fd);
94831
+ fsyncSync7(fd);
94654
94832
  return await action();
94655
94833
  } finally {
94656
- closeSync18(fd);
94834
+ closeSync19(fd);
94657
94835
  unchangedDirectory(directory, identity5);
94658
- const now2 = lstatSync26(file2);
94836
+ const now2 = lstatSync27(file2);
94659
94837
  if (now2.dev !== lock.dev || now2.ino !== lock.ino || !now2.isFile() || now2.isSymbolicLink())
94660
94838
  fail2();
94661
94839
  unlinkSync6(file2);
@@ -94707,15 +94885,15 @@ async function preparePrivatePublication(client2, sourceDirectory, recoveryDirec
94707
94885
  phase: "prepared",
94708
94886
  intent: null
94709
94887
  };
94710
- if (!isAbsolute22(recoveryDirectory) || resolve23(recoveryDirectory) !== recoveryDirectory || realpathSync15(dirname28(recoveryDirectory)) !== dirname28(recoveryDirectory))
94888
+ if (!isAbsolute23(recoveryDirectory) || resolve23(recoveryDirectory) !== recoveryDirectory || realpathSync16(dirname28(recoveryDirectory)) !== dirname28(recoveryDirectory))
94711
94889
  return fail2();
94712
94890
  mkdirSync15(recoveryDirectory, { mode: 448 });
94713
94891
  safeDirectory(recoveryDirectory);
94714
- const parent = openSync18(dirname28(recoveryDirectory), constants15.O_RDONLY | constants15.O_NOFOLLOW);
94892
+ const parent = openSync19(dirname28(recoveryDirectory), constants16.O_RDONLY | constants16.O_NOFOLLOW);
94715
94893
  try {
94716
- fsyncSync6(parent);
94894
+ fsyncSync7(parent);
94717
94895
  } finally {
94718
- closeSync18(parent);
94896
+ closeSync19(parent);
94719
94897
  }
94720
94898
  writeOwned(recoveryDirectory, "bundle.tgz", packed.bytes);
94721
94899
  save(recoveryDirectory, receipt);