@hasna/skills 0.10.48 → 0.10.49

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/index.js CHANGED
@@ -6988,7 +6988,7 @@ var require_public_api = __commonJS((exports) => {
6988
6988
  });
6989
6989
 
6990
6990
  // src/lib/registry.ts
6991
- import { existsSync as existsSync15, readFileSync as readFileSync20, readdirSync as readdirSync12 } from "fs";
6991
+ import { existsSync as existsSync15, readFileSync as readFileSync21, readdirSync as readdirSync12 } from "fs";
6992
6992
  import { join as join35 } from "path";
6993
6993
 
6994
6994
  // src/lib/config.ts
@@ -7256,13 +7256,13 @@ import {
7256
7256
  mkdirSync as mkdirSync10,
7257
7257
  mkdtempSync as mkdtempSync2,
7258
7258
  readdirSync as readdirSync11,
7259
- realpathSync as realpathSync12,
7259
+ realpathSync as realpathSync13,
7260
7260
  renameSync as renameSync6,
7261
7261
  rmSync as rmSync4,
7262
7262
  statSync as statSync11,
7263
7263
  writeFileSync as writeFileSync9
7264
7264
  } from "fs";
7265
- import { basename as basename12, dirname as dirname21, isAbsolute as isAbsolute19, join as join34, normalize as normalize4, relative as relative7, resolve as resolve20, sep as sep10 } from "path";
7265
+ import { basename as basename12, dirname as dirname21, isAbsolute as isAbsolute20, join as join34, normalize as normalize4, relative as relative7, resolve as resolve20, sep as sep10 } from "path";
7266
7266
 
7267
7267
  // src/lib/registry-data/index.ts
7268
7268
  var SKILLS = [];
@@ -8920,7 +8920,7 @@ var NATIVE_SKILL_ROOTS = [
8920
8920
  ];
8921
8921
 
8922
8922
  // src/lib/authoring-path.ts
8923
- import { lstatSync as lstatSync25, realpathSync as realpathSync11 } from "fs";
8923
+ import { lstatSync as lstatSync26, realpathSync as realpathSync12 } from "fs";
8924
8924
  import { homedir as homedir6 } from "os";
8925
8925
  import { basename as basename11, dirname as dirname20, join as join33, resolve as resolve19, sep as sep9 } from "path";
8926
8926
 
@@ -9538,9 +9538,9 @@ function assertAgentPolicyCollections(policy) {
9538
9538
  }
9539
9539
 
9540
9540
  // src/lib/agent-discovery.ts
9541
- import { createHash as createHash23 } from "crypto";
9542
- import { lstatSync as lstatSync24, readFileSync as readFileSync19, readdirSync as readdirSync10, realpathSync as realpathSync10 } from "fs";
9543
- import { basename as basename10, dirname as dirname19, isAbsolute as isAbsolute18, join as join32, resolve as resolve18, sep as sep8 } from "path";
9541
+ import { createHash as createHash24 } from "crypto";
9542
+ import { lstatSync as lstatSync25, readFileSync as readFileSync20, readdirSync as readdirSync10, realpathSync as realpathSync11 } from "fs";
9543
+ import { basename as basename10, dirname as dirname19, isAbsolute as isAbsolute19, join as join32, resolve as resolve18, sep as sep8 } from "path";
9544
9544
  import { isDeepStrictEqual as isDeepStrictEqual7 } from "util";
9545
9545
 
9546
9546
  // node_modules/yaml/dist/index.js
@@ -10230,12 +10230,12 @@ function projectReviewedClaudePluginManifest(text2, reviewedSha256) {
10230
10230
  }
10231
10231
 
10232
10232
  // src/lib/plugin-discovery.ts
10233
- import { closeSync as closeSync12, constants as constants12, fstatSync as fstatSync12, lstatSync as lstatSync22, openSync as openSync12, opendirSync as opendirSync5, readSync as readSync10 } from "fs";
10234
- import { basename as basename8, dirname as dirname17, isAbsolute as isAbsolute16, join as join31, resolve as resolve16 } from "path";
10233
+ import { closeSync as closeSync13, constants as constants13, fstatSync as fstatSync13, lstatSync as lstatSync23, openSync as openSync13, opendirSync as opendirSync5, readSync as readSync10 } from "fs";
10234
+ import { basename as basename8, dirname as dirname17, isAbsolute as isAbsolute17, join as join31, resolve as resolve16 } from "path";
10235
10235
 
10236
10236
  // src/lib/plugin-admission.ts
10237
10237
  import { homedir as homedir5 } from "os";
10238
- import { isAbsolute as isAbsolute15, join as join30, resolve as resolve15 } from "path";
10238
+ import { isAbsolute as isAbsolute16, join as join30, resolve as resolve15 } from "path";
10239
10239
 
10240
10240
  // src/lib/selection-cache.ts
10241
10241
  import { createHash as createHash9, randomUUID } from "crypto";
@@ -11572,7 +11572,7 @@ function replaceSkillSession(expected, replacement, plan, options = {}, beforeCo
11572
11572
  // package.json
11573
11573
  var package_default = {
11574
11574
  name: "@hasna/skills",
11575
- version: "0.10.48",
11575
+ version: "0.10.49",
11576
11576
  description: "Skills library for AI coding agents",
11577
11577
  type: "module",
11578
11578
  bin: {
@@ -13401,7 +13401,7 @@ async function prepareSkillDependencies(skillPath, env, timeoutMs = DEFAULT_PREP
13401
13401
  }
13402
13402
 
13403
13403
  // src/lib/skillinfo.ts
13404
- import { existsSync as existsSync13, readFileSync as readFileSync18 } from "fs";
13404
+ import { existsSync as existsSync13, readFileSync as readFileSync19 } from "fs";
13405
13405
  import { join as join28 } from "path";
13406
13406
 
13407
13407
  // src/lib/codex-corpus-write.ts
@@ -13566,7 +13566,7 @@ function withCodexCorpusWrite(roots, run, options = {}) {
13566
13566
  }
13567
13567
 
13568
13568
  // src/lib/installer.ts
13569
- import { existsSync as existsSync12, readFileSync as readFileSync17, rmSync as rmSync2 } from "fs";
13569
+ import { existsSync as existsSync12, readFileSync as readFileSync18, rmSync as rmSync2 } from "fs";
13570
13570
  import { join as join27 } from "path";
13571
13571
  import { homedir as homedir4 } from "os";
13572
13572
 
@@ -13574,10 +13574,10 @@ import { homedir as homedir4 } from "os";
13574
13574
  import {
13575
13575
  cpSync as cpSync2,
13576
13576
  existsSync as existsSync10,
13577
- lstatSync as lstatSync20,
13577
+ lstatSync as lstatSync21,
13578
13578
  mkdirSync as mkdirSync7,
13579
13579
  mkdtempSync,
13580
- readFileSync as readFileSync15,
13580
+ readFileSync as readFileSync16,
13581
13581
  readdirSync as readdirSync9,
13582
13582
  renameSync as renameSync4,
13583
13583
  rmSync,
@@ -15501,10 +15501,10 @@ function upgradeCodexSettingsWitnessV4(previous, reviewedSettingsPath) {
15501
15501
  }
15502
15502
 
15503
15503
  // src/lib/agent-integration.ts
15504
- import { createHash as createHash18, randomUUID as randomUUID3 } from "crypto";
15504
+ import { createHash as createHash19, randomUUID as randomUUID3 } from "crypto";
15505
15505
  import { isDeepStrictEqual as isDeepStrictEqual6 } from "util";
15506
- import { existsSync as existsSync9, lstatSync as lstatSync19, statSync as statSync9, mkdirSync as mkdirSync6, readFileSync as readFileSync14, readdirSync as readdirSync8, opendirSync as opendirSync3, readlinkSync as readlinkSync5, realpathSync as realpathSync9, renameSync as renameSync3, rmdirSync as rmdirSync2, writeFileSync as writeFileSync6, unlinkSync as unlinkSync4, chmodSync, openSync as openSync10, closeSync as closeSync10, fsyncSync as fsyncSync4, fstatSync as fstatSync10, readSync as readSync8, constants as constants10, linkSync as linkSync2 } from "fs";
15507
- import { dirname as dirname14, join as join23, resolve as resolve13, relative as relative6, isAbsolute as isAbsolute13, sep as sep7 } from "path";
15506
+ import { existsSync as existsSync9, lstatSync as lstatSync20, statSync as statSync9, mkdirSync as mkdirSync6, readFileSync as readFileSync15, readdirSync as readdirSync8, opendirSync as opendirSync3, readlinkSync as readlinkSync6, realpathSync as realpathSync10, renameSync as renameSync3, rmdirSync as rmdirSync2, writeFileSync as writeFileSync6, unlinkSync as unlinkSync4, chmodSync, openSync as openSync11, closeSync as closeSync11, fsyncSync as fsyncSync5, fstatSync as fstatSync11, readSync as readSync8, constants as constants11, linkSync as linkSync2 } from "fs";
15507
+ import { dirname as dirname14, join as join23, resolve as resolve13, relative as relative6, isAbsolute as isAbsolute14, sep as sep7 } from "path";
15508
15508
  import { homedir as homedir2 } from "os";
15509
15509
 
15510
15510
  // src/lib/managed-policy.ts
@@ -16068,8 +16068,144 @@ function unchanged2(before) {
16068
16068
  need5(sameStat(before.stat, after.stat) && after.sha256 === before.sha256, "INPUT_CHANGED");
16069
16069
  }
16070
16070
 
16071
+ // src/cli/commands/runtime-launcher.ts
16072
+ import { createHash as createHash18 } from "crypto";
16073
+ import { closeSync as closeSync10, constants as constants10, fchmodSync, fstatSync as fstatSync10, fsyncSync as fsyncSync4, lstatSync as lstatSync19, openSync as openSync10, readFileSync as readFileSync14, readlinkSync as readlinkSync5, realpathSync as realpathSync9, symlinkSync, writeSync as writeSync2 } from "fs";
16074
+ import { isAbsolute as isAbsolute13 } from "path";
16075
+ var PINNED_LAUNCHER_SCHEMA = "hasna-skills-pinned-launcher-v1";
16076
+ var LAUNCH_CWD_VARIABLE = "HASNA_SKILLS_LAUNCH_CWD";
16077
+ var PINNED_LAUNCHER_BUN_FLAGS = ["--config=/dev/null", "--no-env-file", "--no-macros", "--no-install"];
16078
+ var PINNED_LAUNCHER_ENV_NAMES = [
16079
+ "HOME",
16080
+ "PATH",
16081
+ "TMPDIR",
16082
+ "TERM",
16083
+ "TERM_PROGRAM",
16084
+ "TERM_PROGRAM_VERSION",
16085
+ "COLORTERM",
16086
+ "LANG",
16087
+ "USER",
16088
+ "LOGNAME",
16089
+ "SHELL",
16090
+ "TZ",
16091
+ "NO_COLOR",
16092
+ "FORCE_COLOR",
16093
+ "CI",
16094
+ "COLUMNS",
16095
+ "LINES",
16096
+ "EDITOR",
16097
+ "VISUAL",
16098
+ "PAGER",
16099
+ "SSH_AUTH_SOCK",
16100
+ "DATABASE_URL",
16101
+ "TERMINAL_CWD",
16102
+ "CODEX_HOME",
16103
+ "HERMES_HOME",
16104
+ "HERMES_ENABLE_PROJECT_PLUGINS",
16105
+ "HOST",
16106
+ "PORT",
16107
+ "NODE_ENV",
16108
+ "AGENT_ID",
16109
+ "ECS_CONTAINER_METADATA_URI_V4"
16110
+ ];
16111
+ var PINNED_LAUNCHER_ENV_PREFIXES = ["HASNA", "SKILLS", "SKILL", "MCP", "XDG", "LC", "AWS"];
16112
+ var ENV_PREFIX = new RegExp(`^(${PINNED_LAUNCHER_ENV_PREFIXES.join("|")})_`);
16113
+ var ENV_EXACT = new Set(PINNED_LAUNCHER_ENV_NAMES);
16114
+ function sha2562(bytes) {
16115
+ return createHash18("sha256").update(bytes).digest("hex");
16116
+ }
16117
+ function assertLauncherPath(value, code) {
16118
+ if (typeof value !== "string" || !isAbsolute13(value) || /['\x00-\x1f\x7f]/.test(value))
16119
+ throw new Error(code);
16120
+ }
16121
+ function renderPinnedLauncher(binding) {
16122
+ assertLauncherPath(binding.runtime, "LAUNCHER_RUNTIME_PATH_INVALID");
16123
+ assertLauncherPath(binding.cwd, "LAUNCHER_CWD_PATH_INVALID");
16124
+ assertLauncherPath(binding.entry, "LAUNCHER_ENTRY_PATH_INVALID");
16125
+ const names = PINNED_LAUNCHER_ENV_NAMES.join(" ");
16126
+ const prefixes = PINNED_LAUNCHER_ENV_PREFIXES.join("|");
16127
+ return [
16128
+ "#!/bin/sh -p",
16129
+ `# ${PINNED_LAUNCHER_SCHEMA}`,
16130
+ "# Written by `skills self-update`; rewrite it with `skills self-update`, do not edit by hand.",
16131
+ "# Runs the exact Skills entry below under one exact Bun from one trusted directory with",
16132
+ "# no working-directory configuration (no bunfig.toml, no .env, no macros, no auto-install)",
16133
+ "# and only the environment names allowed here. Everything else, BUN_* and NODE_OPTIONS",
16134
+ "# included, never reaches the runtime. The CLI returns to the caller's directory itself.",
16135
+ "# `-p` keeps the caller's exported functions and shell options out of this shell.",
16136
+ "set -eu",
16137
+ `${LAUNCH_CWD_VARIABLE}=$(pwd -P 2>/dev/null || :)`,
16138
+ `export ${LAUNCH_CWD_VARIABLE}`,
16139
+ `set -- '${binding.runtime}' ${PINNED_LAUNCHER_BUN_FLAGS.join(" ")} '--cwd=${binding.cwd}' '${binding.entry}' "$@"`,
16140
+ "hasna_skills_env=$(LC_ALL=C /usr/bin/awk 'BEGIN {",
16141
+ ` n = split("${names}", exact, " ")`,
16142
+ " for (i = 1; i <= n; i++) allow[exact[i]] = 1",
16143
+ " for (name in ENVIRON) {",
16144
+ " if (name !~ /^[A-Za-z_][A-Za-z0-9_]*$/) continue",
16145
+ ` if (name == "LC_ALL" || (!(name in allow) && name !~ /^(${prefixes})_/)) continue`,
16146
+ ' value = ENVIRON[name]; quoted = ""',
16147
+ ' while ((k = index(value, "\\047")) > 0) { quoted = quoted substr(value, 1, k - 1) "\\047\\\\\\047\\047"; value = substr(value, k + 1) }',
16148
+ ' printf "\\047%s=%s\\047 ", name, quoted value',
16149
+ " }",
16150
+ "}')",
16151
+ 'eval "set -- $hasna_skills_env \\"\\$@\\""',
16152
+ 'if [ "${LC_ALL+x}" = x ]; then set -- "LC_ALL=$LC_ALL" "$@"; fi',
16153
+ 'exec /usr/bin/env -i "$@"',
16154
+ ""
16155
+ ].join(`
16156
+ `);
16157
+ }
16158
+ var COMMAND_LINE = new RegExp(`^set -- '([^']+)' ${PINNED_LAUNCHER_BUN_FLAGS.join(" ")} '--cwd=([^']+)' '([^']+)' "\\$@"$`, "m");
16159
+ function parsePinnedLauncher(text2) {
16160
+ const match = COMMAND_LINE.exec(text2);
16161
+ if (!match)
16162
+ return null;
16163
+ const binding = { runtime: match[1], cwd: match[2], entry: match[3] };
16164
+ try {
16165
+ if (renderPinnedLauncher(binding) !== text2)
16166
+ return null;
16167
+ } catch {
16168
+ return null;
16169
+ }
16170
+ return binding;
16171
+ }
16172
+ var PINNED_LAUNCHER_MAX_BYTES = 16 * 1024;
16173
+ function resolveLauncherCommand(path) {
16174
+ const physical = realpathSync9(path);
16175
+ const stat = lstatSync19(physical);
16176
+ if (stat.isFile() && stat.size <= PINNED_LAUNCHER_MAX_BYTES) {
16177
+ const text2 = readFileSync14(physical, "utf8");
16178
+ const binding = parsePinnedLauncher(text2);
16179
+ if (binding) {
16180
+ let entry;
16181
+ try {
16182
+ entry = realpathSync9(binding.entry);
16183
+ } catch {
16184
+ throw new Error("LAUNCHER_ENTRY_UNREADABLE");
16185
+ }
16186
+ if (entry !== binding.entry)
16187
+ throw new Error("LAUNCHER_ENTRY_NOT_PHYSICAL");
16188
+ return { physical, entry, pinned: { ...binding, sha256: sha2562(text2) } };
16189
+ }
16190
+ }
16191
+ return { physical, entry: physical, pinned: null };
16192
+ }
16193
+ function assertPinnedLauncherRuntimeSafe(runtime) {
16194
+ assertLauncherPath(runtime, "LAUNCHER_RUNTIME_PATH_INVALID");
16195
+ let stat;
16196
+ try {
16197
+ stat = lstatSync19(runtime);
16198
+ } catch {
16199
+ throw new Error("LAUNCHER_RUNTIME_UNSAFE");
16200
+ }
16201
+ const uid = process.getuid?.() ?? -1;
16202
+ if (!stat.isFile() || stat.isSymbolicLink() || ![0, uid].includes(stat.uid) || (stat.mode & 18) !== 0 || (stat.mode & 64) === 0) {
16203
+ throw new Error("LAUNCHER_RUNTIME_UNSAFE");
16204
+ }
16205
+ }
16206
+
16071
16207
  // src/lib/agent-integration.ts
16072
- var sha3 = (data) => createHash18("sha256").update(data).digest("hex");
16208
+ var sha3 = (data) => createHash19("sha256").update(data).digest("hex");
16073
16209
  var ROOTS = NATIVE_SKILL_ROOTS;
16074
16210
  function hasTrustedDarwinAcl(fd, allowDenyOnly = false) {
16075
16211
  try {
@@ -16120,11 +16256,11 @@ function isSystemRootAlias(path) {
16120
16256
  const target = `/private${path}`, link = `private${path}`;
16121
16257
  const identity5 = (stat) => `${stat.dev}:${stat.ino}:${stat.ctimeNs}:${stat.uid}:${stat.mode}`;
16122
16258
  try {
16123
- const before = lstatSync19(path, { bigint: true });
16124
- if (!before.isSymbolicLink() || before.uid !== 0n || readlinkSync5(path) !== link)
16259
+ const before = lstatSync20(path, { bigint: true });
16260
+ if (!before.isSymbolicLink() || before.uid !== 0n || readlinkSync6(path) !== link)
16125
16261
  return false;
16126
16262
  const directories = ["/", "/private", target].map((directory) => {
16127
- const stat = lstatSync19(directory, { bigint: true });
16263
+ const stat = lstatSync20(directory, { bigint: true });
16128
16264
  if (!stat.isDirectory() || stat.uid !== 0n)
16129
16265
  throw new Error("Untrusted system alias directory");
16130
16266
  if (directory !== "/private/tmp") {
@@ -16132,23 +16268,23 @@ function isSystemRootAlias(path) {
16132
16268
  throw new Error("Writable system alias directory");
16133
16269
  } else if ((stat.mode & 0o1000n) === 0n)
16134
16270
  throw new Error("Unprotected system temporary directory");
16135
- const fd = openSync10(directory, constants10.O_RDONLY | constants10.O_DIRECTORY | constants10.O_NOFOLLOW);
16271
+ const fd = openSync11(directory, constants11.O_RDONLY | constants11.O_DIRECTORY | constants11.O_NOFOLLOW);
16136
16272
  try {
16137
- if (identity5(fstatSync10(fd, { bigint: true })) !== identity5(stat) || !hasTrustedDarwinAcl(fd) || identity5(fstatSync10(fd, { bigint: true })) !== identity5(stat))
16273
+ if (identity5(fstatSync11(fd, { bigint: true })) !== identity5(stat) || !hasTrustedDarwinAcl(fd) || identity5(fstatSync11(fd, { bigint: true })) !== identity5(stat))
16138
16274
  throw new Error("Unverified system alias directory ACL");
16139
16275
  } finally {
16140
- closeSync10(fd);
16276
+ closeSync11(fd);
16141
16277
  }
16142
16278
  return { directory, identity: identity5(stat) };
16143
16279
  });
16144
- return realpathSync9(path) === target && readlinkSync5(path) === link && identity5(lstatSync19(path, { bigint: true })) === identity5(before) && directories.every((item) => identity5(lstatSync19(item.directory, { bigint: true })) === item.identity);
16280
+ return realpathSync10(path) === target && readlinkSync6(path) === link && identity5(lstatSync20(path, { bigint: true })) === identity5(before) && directories.every((item) => identity5(lstatSync20(item.directory, { bigint: true })) === item.identity);
16145
16281
  } catch {
16146
16282
  return false;
16147
16283
  }
16148
16284
  }
16149
16285
  function canonicalSystemPath(path) {
16150
16286
  const absolute = resolve13(path), root = `/${absolute.split(sep7)[1]}`;
16151
- if (process.platform !== "darwin" || !["/var", "/tmp", "/etc"].includes(root) || !lstatSync19(root, { throwIfNoEntry: false })?.isSymbolicLink())
16287
+ if (process.platform !== "darwin" || !["/var", "/tmp", "/etc"].includes(root) || !lstatSync20(root, { throwIfNoEntry: false })?.isSymbolicLink())
16152
16288
  return absolute;
16153
16289
  if (!isSystemRootAlias(root))
16154
16290
  throw new Error(`Refusing symlink path: ${root}`);
@@ -16157,7 +16293,7 @@ function canonicalSystemPath(path) {
16157
16293
  function assertSafePath(path) {
16158
16294
  let cursor = resolve13(path);
16159
16295
  while (true) {
16160
- if (lstatSync19(cursor, { throwIfNoEntry: false })?.isSymbolicLink() && !isSystemRootAlias(cursor))
16296
+ if (lstatSync20(cursor, { throwIfNoEntry: false })?.isSymbolicLink() && !isSystemRootAlias(cursor))
16161
16297
  throw new Error(`Refusing symlink path: ${cursor}`);
16162
16298
  const parent = dirname14(cursor);
16163
16299
  if (parent === cursor)
@@ -16167,17 +16303,17 @@ function assertSafePath(path) {
16167
16303
  }
16168
16304
  function readRootAlias(home, agent) {
16169
16305
  assertSafePath(home);
16170
- const realHome = realpathSync9(home), alias = join23(realHome, `.${agent}`);
16171
- const stat = lstatSync19(alias, { throwIfNoEntry: false, bigint: true });
16306
+ const realHome = realpathSync10(home), alias = join23(realHome, `.${agent}`);
16307
+ const stat = lstatSync20(alias, { throwIfNoEntry: false, bigint: true });
16172
16308
  if (!stat?.isSymbolicLink())
16173
16309
  throw new Error(`Agent root alias changed after planning: ${alias}`);
16174
- const link = readlinkSync5(alias), targetPath = resolve13(dirname14(alias), link);
16310
+ const link = readlinkSync6(alias), targetPath = resolve13(dirname14(alias), link);
16175
16311
  assertSafePath(targetPath);
16176
- const targetStat = lstatSync19(targetPath, { throwIfNoEntry: false });
16312
+ const targetStat = lstatSync20(targetPath, { throwIfNoEntry: false });
16177
16313
  if (!targetStat?.isDirectory())
16178
16314
  throw new Error(`Agent root alias must target an existing directory: ${alias}`);
16179
- const target = realpathSync9(targetPath), inside = relative6(realHome, target);
16180
- if (!inside || inside === ".." || inside.startsWith(`..${sep7}`) || isAbsolute13(inside))
16315
+ const target = realpathSync10(targetPath), inside = relative6(realHome, target);
16316
+ if (!inside || inside === ".." || inside.startsWith(`..${sep7}`) || isAbsolute14(inside))
16181
16317
  throw new Error(`Agent root alias target must be inside the real home: ${alias}`);
16182
16318
  return { agent, home: realHome, alias, target, link, aliasIdentity: `${stat.dev}:${stat.ino}:${stat.ctimeNs}`, targetIdentity: `${targetStat.dev}:${targetStat.ino}` };
16183
16319
  }
@@ -16186,7 +16322,7 @@ function rootAliases(home, allowed = false) {
16186
16322
  return [];
16187
16323
  const result = [];
16188
16324
  for (const agent of ["claude", "codex"])
16189
- if (lstatSync19(join23(home, `.${agent}`), { throwIfNoEntry: false })?.isSymbolicLink())
16325
+ if (lstatSync20(join23(home, `.${agent}`), { throwIfNoEntry: false })?.isSymbolicLink())
16190
16326
  result.push(readRootAlias(home, agent));
16191
16327
  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))))
16192
16328
  throw new Error("Agent root alias targets must not overlap");
@@ -16203,17 +16339,17 @@ function disabledCodexSkillPaths(config, aliases) {
16203
16339
  const rows = skills.config;
16204
16340
  if (!Array.isArray(rows))
16205
16341
  return [];
16206
- 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" || !isAbsolute13(entry.path)) || entry.name !== undefined && (typeof entry.name !== "string" || !entry.name.trim())))
16342
+ 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" || !isAbsolute14(entry.path)) || entry.name !== undefined && (typeof entry.name !== "string" || !entry.name.trim())))
16207
16343
  return [];
16208
16344
  if (rows.some((entry) => entry.name !== undefined && entry.enabled !== false))
16209
16345
  return [];
16210
16346
  const settings = new Map;
16211
16347
  for (const entry of rows) {
16212
- if (typeof entry.path !== "string" || !isAbsolute13(entry.path))
16348
+ if (typeof entry.path !== "string" || !isAbsolute14(entry.path))
16213
16349
  continue;
16214
16350
  let document2;
16215
16351
  try {
16216
- document2 = realpathSync9(canonicalAgentPath(entry.path, aliases));
16352
+ document2 = realpathSync10(canonicalAgentPath(entry.path, aliases));
16217
16353
  } catch {
16218
16354
  continue;
16219
16355
  }
@@ -16234,16 +16370,16 @@ function recheckRootAliases(aliases) {
16234
16370
  }
16235
16371
  function nativeSourceDigest(path) {
16236
16372
  assertSafePath(path);
16237
- return lstatSync19(path, { throwIfNoEntry: false }) ? sha3(readNativeBytes(path, 1024 * 1024)) : null;
16373
+ return lstatSync20(path, { throwIfNoEntry: false }) ? sha3(readNativeBytes(path, 1024 * 1024)) : null;
16238
16374
  }
16239
16375
  function readNativeBytes(path, maximum = 64 * 1024 * 1024) {
16240
16376
  assertSafePath(path);
16241
- const before = lstatSync19(path);
16377
+ const before = lstatSync20(path);
16242
16378
  if (!before.isFile() || before.size > maximum)
16243
16379
  throw new Error("Unsupported or oversized native skill file");
16244
- const descriptor = openSync10(path, constants10.O_RDONLY | constants10.O_NOFOLLOW | constants10.O_NONBLOCK);
16380
+ const descriptor = openSync11(path, constants11.O_RDONLY | constants11.O_NOFOLLOW | constants11.O_NONBLOCK);
16245
16381
  try {
16246
- const opened = fstatSync10(descriptor);
16382
+ const opened = fstatSync11(descriptor);
16247
16383
  if (!opened.isFile() || opened.dev !== before.dev || opened.ino !== before.ino || opened.size !== before.size)
16248
16384
  throw new Error("Native skill file changed while reading");
16249
16385
  const bytes = Buffer.allocUnsafe(before.size + 1);
@@ -16254,19 +16390,19 @@ function readNativeBytes(path, maximum = 64 * 1024 * 1024) {
16254
16390
  break;
16255
16391
  length += count;
16256
16392
  }
16257
- const after = fstatSync10(descriptor), current = lstatSync19(path);
16393
+ const after = fstatSync11(descriptor), current = lstatSync20(path);
16258
16394
  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)
16259
16395
  throw new Error("Native skill file changed while reading");
16260
16396
  return bytes.subarray(0, length);
16261
16397
  } finally {
16262
- closeSync10(descriptor);
16398
+ closeSync11(descriptor);
16263
16399
  }
16264
16400
  }
16265
16401
  function treeHash(root) {
16266
- const hash2 = createHash18("sha256");
16402
+ const hash2 = createHash19("sha256");
16267
16403
  let bytes = 0, files = 0;
16268
16404
  function visit2(path) {
16269
- const stat = lstatSync19(path);
16405
+ const stat = lstatSync20(path);
16270
16406
  if (stat.isSymbolicLink())
16271
16407
  throw new Error(`Refusing symlink in skill: ${path}`);
16272
16408
  const rel = relative6(root, path);
@@ -16295,13 +16431,13 @@ function selectNativeMigrationTargets(inventory, manifest) {
16295
16431
  const identities = new Set;
16296
16432
  const selected = [];
16297
16433
  for (const target of manifest.targets) {
16298
- if (!isAbsolute13(target.projectRoot) || resolve13(target.projectRoot) !== target.projectRoot)
16434
+ if (!isAbsolute14(target.projectRoot) || resolve13(target.projectRoot) !== target.projectRoot)
16299
16435
  throw new Error(`Native migration target project root must be an existing absolute directory: ${target.projectRoot}`);
16300
16436
  const projectRoot = canonicalSystemPath(target.projectRoot), normalized = relative6(projectRoot, resolve13(projectRoot, target.path));
16301
- if (!existsSync9(projectRoot) || !lstatSync19(projectRoot).isDirectory())
16437
+ if (!existsSync9(projectRoot) || !lstatSync20(projectRoot).isDirectory())
16302
16438
  throw new Error(`Native migration target project root must be an existing absolute directory: ${target.projectRoot}`);
16303
16439
  assertSafePath(projectRoot);
16304
- if (isAbsolute13(target.path) || target.path.includes("\\") || target.path.includes("\x00") || !normalized || normalized === ".." || normalized.startsWith(`..${sep7}`) || normalized !== target.path || !/^[0-9a-f]{64}$/.test(target.treeSha256))
16440
+ if (isAbsolute14(target.path) || target.path.includes("\\") || target.path.includes("\x00") || !normalized || normalized === ".." || normalized.startsWith(`..${sep7}`) || normalized !== target.path || !/^[0-9a-f]{64}$/.test(target.treeSha256))
16305
16441
  throw new Error(`Invalid native migration target: ${target.path}`);
16306
16442
  const identity5 = `${target.agent}\x00${canonicalSystemPath(projectRoot)}\x00${normalized}`;
16307
16443
  if (identities.has(identity5))
@@ -16344,9 +16480,9 @@ function isCodexSkillDiscoveryInput(path) {
16344
16480
  }
16345
16481
  function inventoryNativeSkills(home = homedir2(), options = {}) {
16346
16482
  home = canonicalSystemPath(home);
16347
- if (options.reviewedCacheAlias !== undefined && (!options.includeVendor || !isAbsolute13(options.reviewedCacheAlias) || resolve13(options.reviewedCacheAlias) !== options.reviewedCacheAlias))
16483
+ if (options.reviewedCacheAlias !== undefined && (!options.includeVendor || !isAbsolute14(options.reviewedCacheAlias) || resolve13(options.reviewedCacheAlias) !== options.reviewedCacheAlias))
16348
16484
  throw new Error("A reviewed cache alias requires vendor inventory and an exact absolute path");
16349
- if (options.disabledVendorPaths?.some((path) => !isAbsolute13(path) || resolve13(path) !== path))
16485
+ if (options.disabledVendorPaths?.some((path) => !isAbsolute14(path) || resolve13(path) !== path))
16350
16486
  throw new Error("Disabled vendor paths must be exact absolute paths");
16351
16487
  const reviewedCacheAlias = options.reviewedCacheAlias === undefined ? undefined : canonicalSystemPath(options.reviewedCacheAlias);
16352
16488
  const disabledVendorPaths = new Set((options.disabledVendorPaths ?? []).map(canonicalSystemPath));
@@ -16365,7 +16501,7 @@ function inventoryNativeSkills(home = homedir2(), options = {}) {
16365
16501
  roots.push(["sumi", canonicalAgentPath(join23(project, directory, name), aliases)]);
16366
16502
  }
16367
16503
  const installationInputs = options.codexInstallationInputRoots ?? [];
16368
- if (installationInputs.some((input) => resolve13(input) !== input || realpathSync9(input) !== input || roots.some(([agent, path]) => agent === "codex" && (path === input || path.startsWith(input + sep7) || input.startsWith(path + sep7)))))
16504
+ if (installationInputs.some((input) => resolve13(input) !== input || realpathSync10(input) !== input || roots.some(([agent, path]) => agent === "codex" && (path === input || path.startsWith(input + sep7) || input.startsWith(path + sep7)))))
16369
16505
  throw new Error("Native installation input overlaps an unconditional skill-loading root");
16370
16506
  const entries = [], seen = new Set;
16371
16507
  const cacheScans = new Map, maxAliasProofEntries = 1e4;
@@ -16379,13 +16515,13 @@ function inventoryNativeSkills(home = homedir2(), options = {}) {
16379
16515
  }
16380
16516
  let reviewedCacheAliasFound = false;
16381
16517
  function verifiedSiblingCacheAlias(agent, path, parent) {
16382
- const link = readlinkSync5(path), lexicalTarget = resolve13(parent, link);
16383
- if (isAbsolute13(link) ? link !== lexicalTarget : dirname14(link) !== ".")
16518
+ const link = readlinkSync6(path), lexicalTarget = resolve13(parent, link);
16519
+ if (isAbsolute14(link) ? link !== lexicalTarget : dirname14(link) !== ".")
16384
16520
  return false;
16385
16521
  const target = canonicalSystemPath(lexicalTarget);
16386
16522
  if (dirname14(target) !== parent)
16387
16523
  return false;
16388
- if (!lstatSync19(target, { throwIfNoEntry: false })?.isDirectory())
16524
+ if (!lstatSync20(target, { throwIfNoEntry: false })?.isDirectory())
16389
16525
  return false;
16390
16526
  const scan = cacheScans.get(target);
16391
16527
  if (!scan?.complete || scan.entries > maxAliasProofEntries)
@@ -16410,7 +16546,7 @@ function inventoryNativeSkills(home = homedir2(), options = {}) {
16410
16546
  return scan;
16411
16547
  if (!existsSync9(path))
16412
16548
  return scan;
16413
- const stat = lstatSync19(path);
16549
+ const stat = lstatSync20(path);
16414
16550
  if (stat.isFile()) {
16415
16551
  if (agent === "sumi" && depth === 1 && path.endsWith(".md"))
16416
16552
  throw new Error("NATIVE_SKILL_DRIFT: flat Sumi skill documents require a dedicated migration adapter");
@@ -16427,7 +16563,7 @@ function inventoryNativeSkills(home = homedir2(), options = {}) {
16427
16563
  const marker = join23(path, ".hasna-skills.json");
16428
16564
  if (existsSync9(marker)) {
16429
16565
  try {
16430
- managed = JSON.parse(readFileSync14(marker, "utf8")).managedBy === "@hasna/skills";
16566
+ managed = JSON.parse(readFileSync15(marker, "utf8")).managedBy === "@hasna/skills";
16431
16567
  } catch {}
16432
16568
  }
16433
16569
  const bridge = (!vendor || agent === "sumi") && isOwnedCliBridge(path, bridgePaths);
@@ -16459,7 +16595,7 @@ function inventoryNativeSkills(home = homedir2(), options = {}) {
16459
16595
  if (isVendor && !options.includeVendor)
16460
16596
  continue;
16461
16597
  const child = join23(path, name);
16462
- if (isVendor && lstatSync19(child, { throwIfNoEntry: false })?.isSymbolicLink()) {
16598
+ if (isVendor && lstatSync20(child, { throwIfNoEntry: false })?.isSymbolicLink()) {
16463
16599
  const target = statSync9(child, { throwIfNoEntry: false });
16464
16600
  if (target?.isFile() || pluginCache && target?.isDirectory() && verifiedSiblingCacheAlias(agent, child, path)) {
16465
16601
  scan.entries++;
@@ -16502,7 +16638,7 @@ function inventoryNativeSkills(home = homedir2(), options = {}) {
16502
16638
  }
16503
16639
  function readOptional(path) {
16504
16640
  assertSafePath(path);
16505
- return existsSync9(path) ? readFileSync14(path, "utf8") : null;
16641
+ return existsSync9(path) ? readFileSync15(path, "utf8") : null;
16506
16642
  }
16507
16643
  function jsonObject(text2, path) {
16508
16644
  if (text2 === null)
@@ -16834,23 +16970,23 @@ function projectedHookAcl(path, observed) {
16834
16970
  if (process.platform !== "darwin")
16835
16971
  return;
16836
16972
  const identity5 = (stat) => `${stat.dev}:${stat.ino}:${stat.ctimeNs}:${stat.uid}:${stat.mode}:${stat.nlink}:${stat.size}:${stat.mtimeNs}`;
16837
- const fd = openSync10(path, constants10.O_RDONLY | constants10.O_NOFOLLOW | constants10.O_NONBLOCK | (observed.isDirectory() ? constants10.O_DIRECTORY : 0));
16973
+ const fd = openSync11(path, constants11.O_RDONLY | constants11.O_NOFOLLOW | constants11.O_NONBLOCK | (observed.isDirectory() ? constants11.O_DIRECTORY : 0));
16838
16974
  try {
16839
- if (identity5(fstatSync10(fd, { bigint: true })) !== identity5(observed) || !hasTrustedDarwinAcl(fd, true) || identity5(fstatSync10(fd, { bigint: true })) !== identity5(observed) || identity5(lstatSync19(path, { bigint: true })) !== identity5(observed))
16975
+ if (identity5(fstatSync11(fd, { bigint: true })) !== identity5(observed) || !hasTrustedDarwinAcl(fd, true) || identity5(fstatSync11(fd, { bigint: true })) !== identity5(observed) || identity5(lstatSync20(path, { bigint: true })) !== identity5(observed))
16840
16976
  hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
16841
16977
  } finally {
16842
- closeSync10(fd);
16978
+ closeSync11(fd);
16843
16979
  }
16844
16980
  }
16845
16981
  function projectedHookExecutable(command, expectedResolved) {
16846
16982
  try {
16847
- if (!isAbsolute13(command) || /[\0\r\n]/.test(command) || resolve13(command) !== command)
16983
+ if (!isAbsolute14(command) || /[\0\r\n]/.test(command) || resolve13(command) !== command)
16848
16984
  hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
16849
16985
  command = canonicalSystemPath(command);
16850
16986
  const parents2 = (file = command) => {
16851
16987
  const result = [];
16852
16988
  for (let path = dirname14(file);; path = dirname14(path)) {
16853
- const stat = lstatSync19(path, { bigint: true });
16989
+ const stat = lstatSync20(path, { bigint: true });
16854
16990
  if (!stat.isDirectory() || (stat.mode & 0o022n) !== 0n && !(stat.uid === 0n && (stat.mode & 0o1000n) !== 0n))
16855
16991
  hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
16856
16992
  projectedHookAcl(path, stat);
@@ -16860,13 +16996,22 @@ function projectedHookExecutable(command, expectedResolved) {
16860
16996
  }
16861
16997
  return result;
16862
16998
  };
16863
- const parentIdentity = parents2(), link = lstatSync19(command, { bigint: true });
16999
+ const parentIdentity = parents2(), link = lstatSync20(command, { bigint: true });
16864
17000
  if (link.uid !== BigInt(process.getuid()) || !link.isFile() && !link.isSymbolicLink())
16865
17001
  hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
16866
17002
  const linkIdentity = (stat) => `${stat.dev}:${stat.ino}:${stat.mode}:${stat.uid}:${stat.ctimeNs}`;
16867
- const resolved = realpathSync9(command);
17003
+ const target = resolveLauncherCommand(command), resolved = target.entry;
16868
17004
  if (expectedResolved !== undefined && resolved !== expectedResolved)
16869
17005
  hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
17006
+ let launcher, launcherParentIdentity;
17007
+ if (target.pinned) {
17008
+ launcherParentIdentity = parents2(target.physical);
17009
+ launcher = snapshot(target.physical, false);
17010
+ projectedHookAcl(launcher.file, launcher.stat);
17011
+ if (launcher.sha256 !== target.pinned.sha256 || (launcher.stat.mode & 0o100n) === 0n)
17012
+ hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
17013
+ assertPinnedLauncherRuntimeSafe(target.pinned.runtime);
17014
+ }
16870
17015
  const resolvedParentIdentity = parents2(resolved);
16871
17016
  const manifest = snapshot(join23(dirname14(dirname14(resolved)), "package.json"), false, { readOnlyPackage: true });
16872
17017
  projectedHookAcl(manifest.file, manifest.stat);
@@ -16879,8 +17024,15 @@ function projectedHookExecutable(command, expectedResolved) {
16879
17024
  hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
16880
17025
  const recheck = () => {
16881
17026
  try {
16882
- if (realpathSync9(command) !== resolved || linkIdentity(lstatSync19(command, { bigint: true })) !== linkIdentity(link) || !isDeepStrictEqual6(parents2(), parentIdentity) || !isDeepStrictEqual6(parents2(resolved), resolvedParentIdentity))
17027
+ const again = resolveLauncherCommand(command);
17028
+ if (again.entry !== resolved || again.physical !== target.physical || linkIdentity(lstatSync20(command, { bigint: true })) !== linkIdentity(link) || !isDeepStrictEqual6(parents2(), parentIdentity) || !isDeepStrictEqual6(parents2(resolved), resolvedParentIdentity))
16883
17029
  hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
17030
+ if (launcher) {
17031
+ if (!isDeepStrictEqual6(parents2(target.physical), launcherParentIdentity))
17032
+ hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
17033
+ projectedHookAcl(launcher.file, launcher.stat);
17034
+ unchanged2(launcher);
17035
+ }
16884
17036
  projectedHookAcl(cli.file, cli.stat);
16885
17037
  projectedHookAcl(manifest.file, manifest.stat);
16886
17038
  unchanged2(cli);
@@ -17002,7 +17154,7 @@ function claudeSettingsConsumers(home, path, discoveries, aliases) {
17002
17154
  const canonical6 = (value) => canonicalAgentPath(value, aliases);
17003
17155
  const containsSettings = (root) => {
17004
17156
  const distance = relative6(canonical6(root), path);
17005
- return distance === "" || distance !== ".." && !distance.startsWith(`..${sep7}`) && !isAbsolute13(distance);
17157
+ return distance === "" || distance !== ".." && !distance.startsWith(`..${sep7}`) && !isAbsolute14(distance);
17006
17158
  };
17007
17159
  return discoveries.filter((binding) => binding.agent === "claude" || binding.agent === "opencode" || canonical6(join23(home, AGENT_ADAPTERS[binding.agent].config)) === path || binding.sources.some((source) => canonical6(source.path) === path) || binding.roots.some(containsSettings) || binding.directories?.some((directory) => containsSettings(directory.path))).map((binding) => binding.agent);
17008
17160
  }
@@ -17035,7 +17187,7 @@ function planClaudeHookEventsUpdate(options) {
17035
17187
  recheckRootAliases(aliases);
17036
17188
  const path = canonicalAgentPath(join23(home, ".claude", "settings.json"), aliases);
17037
17189
  assertSafePath(path);
17038
- const before = lstatSync19(path, { throwIfNoEntry: false }) ? new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(readNativeBytes(path, 1024 * 1024)) : null;
17190
+ const before = lstatSync20(path, { throwIfNoEntry: false }) ? new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(readNativeBytes(path, 1024 * 1024)) : null;
17039
17191
  if ((before === null ? "absent" : sha3(before)) !== options.expectedSettingsSha256)
17040
17192
  throw new Error("Claude settings preimage changed");
17041
17193
  assertClaudeHookEventsReplacement(before, options.replacement, options.events);
@@ -17226,7 +17378,7 @@ function applyAgentIntegrationUnlocked(plan, options = {}, assertCurrent) {
17226
17378
  if (change.before !== null) {
17227
17379
  const backup = join23(backupRoot, `${index}-${sha3(change.path).slice(0, 12)}.backup`);
17228
17380
  writeFileSync6(backup, change.before, { mode: 384, flag: "wx" });
17229
- if (readFileSync14(backup, "utf8") !== change.before)
17381
+ if (readFileSync15(backup, "utf8") !== change.before)
17230
17382
  throw new Error("Native configuration preservation readback failed");
17231
17383
  backups.push(backup);
17232
17384
  }
@@ -17289,11 +17441,11 @@ function applyAgentIntegrationUnlocked(plan, options = {}, assertCurrent) {
17289
17441
  }
17290
17442
  function syncArchiveDirectory(path) {
17291
17443
  assertSafePath(path);
17292
- const descriptor = openSync10(path, constants10.O_RDONLY | constants10.O_DIRECTORY | constants10.O_NOFOLLOW | constants10.O_NONBLOCK);
17444
+ const descriptor = openSync11(path, constants11.O_RDONLY | constants11.O_DIRECTORY | constants11.O_NOFOLLOW | constants11.O_NONBLOCK);
17293
17445
  try {
17294
- fsyncSync4(descriptor);
17446
+ fsyncSync5(descriptor);
17295
17447
  } finally {
17296
- closeSync10(descriptor);
17448
+ closeSync11(descriptor);
17297
17449
  }
17298
17450
  }
17299
17451
  function writeArchiveJournal(path, value) {
@@ -17301,18 +17453,18 @@ function writeArchiveJournal(path, value) {
17301
17453
  const temporary = `${path}.skills-${randomUUID3()}`;
17302
17454
  let descriptor;
17303
17455
  try {
17304
- descriptor = openSync10(temporary, constants10.O_WRONLY | constants10.O_CREAT | constants10.O_EXCL | constants10.O_NOFOLLOW, 384);
17456
+ descriptor = openSync11(temporary, constants11.O_WRONLY | constants11.O_CREAT | constants11.O_EXCL | constants11.O_NOFOLLOW, 384);
17305
17457
  writeFileSync6(descriptor, `${JSON.stringify(value)}
17306
17458
  `);
17307
- fsyncSync4(descriptor);
17308
- closeSync10(descriptor);
17459
+ fsyncSync5(descriptor);
17460
+ closeSync11(descriptor);
17309
17461
  descriptor = undefined;
17310
17462
  renameSync3(temporary, path);
17311
17463
  syncArchiveDirectory(dirname14(path));
17312
17464
  } finally {
17313
17465
  if (descriptor !== undefined)
17314
- closeSync10(descriptor);
17315
- if (lstatSync19(temporary, { throwIfNoEntry: false }))
17466
+ closeSync11(descriptor);
17467
+ if (lstatSync20(temporary, { throwIfNoEntry: false }))
17316
17468
  unlinkSync4(temporary);
17317
17469
  }
17318
17470
  }
@@ -17358,7 +17510,7 @@ function archiveNativeSkillsUnlocked(inventory, options, assertCurrent) {
17358
17510
  const moved = [];
17359
17511
  const verifyArchive = (entry) => {
17360
17512
  assertSafePath(entry.archive);
17361
- const stat = lstatSync19(entry.archive);
17513
+ const stat = lstatSync20(entry.archive);
17362
17514
  if (entry.discoveryOnly ? !stat.isFile() : !stat.isDirectory())
17363
17515
  throw new Error("Archive type changed");
17364
17516
  if ((entry.discoveryOnly ? sha3(readNativeBytes(entry.archive)) : treeHash(entry.archive)) !== entry.hash)
@@ -17409,7 +17561,7 @@ function archiveNativeSkillsUnlocked(inventory, options, assertCurrent) {
17409
17561
  recheckRootAliases(aliases);
17410
17562
  assertSafePath(entry.source);
17411
17563
  assertSafePath(entry.archive);
17412
- if (lstatSync19(entry.source, { throwIfNoEntry: false })) {
17564
+ if (lstatSync20(entry.source, { throwIfNoEntry: false })) {
17413
17565
  entry.status = "recovery-required";
17414
17566
  entry.conflict = "source-occupied";
17415
17567
  continue;
@@ -17426,7 +17578,7 @@ function archiveNativeSkillsUnlocked(inventory, options, assertCurrent) {
17426
17578
  syncArchiveDirectory(dirname14(entry.source));
17427
17579
  unlinkSync4(entry.archive);
17428
17580
  } else {
17429
- if (lstatSync19(entry.source, { throwIfNoEntry: false })) {
17581
+ if (lstatSync20(entry.source, { throwIfNoEntry: false })) {
17430
17582
  entry.status = "recovery-required";
17431
17583
  entry.conflict = "source-occupied";
17432
17584
  continue;
@@ -17459,12 +17611,12 @@ function isInertCodexPluginCacheCopy(entry, cache, allowedHostPaths, read2) {
17459
17611
  return false;
17460
17612
  const document2 = join23(entry.path, "SKILL.md");
17461
17613
  const inside = relative6(cache, entry.path);
17462
- if (!inside || isAbsolute13(inside) || inside.split(sep7).some((segment) => segment === ".."))
17614
+ if (!inside || isAbsolute14(inside) || inside.split(sep7).some((segment) => segment === ".."))
17463
17615
  return false;
17464
17616
  assertSafePath(entry.path);
17465
- if (!lstatSync19(cache).isDirectory() || !lstatSync19(entry.path).isDirectory() || !lstatSync19(document2).isFile())
17617
+ if (!lstatSync20(cache).isDirectory() || !lstatSync20(entry.path).isDirectory() || !lstatSync20(document2).isFile())
17466
17618
  return false;
17467
- if (realpathSync9.native(cache) !== cache || realpathSync9.native(entry.path) !== entry.path || realpathSync9.native(document2) !== document2)
17619
+ if (realpathSync10.native(cache) !== cache || realpathSync10.native(entry.path) !== entry.path || realpathSync10.native(document2) !== document2)
17468
17620
  return false;
17469
17621
  if (!classifyCodexPluginCacheDocument(document2, cache, read2))
17470
17622
  return false;
@@ -17641,9 +17793,9 @@ function isSkillsOwnershipMarker(marker) {
17641
17793
  function hasSkillsOwnershipMarker(dir) {
17642
17794
  const path = join25(dir, SYNC_MARKER_FILE);
17643
17795
  try {
17644
- if (!lstatSync20(path).isFile())
17796
+ if (!lstatSync21(path).isFile())
17645
17797
  return false;
17646
- const marker = JSON.parse(readFileSync15(path, "utf8"));
17798
+ const marker = JSON.parse(readFileSync16(path, "utf8"));
17647
17799
  return isSkillsOwnershipMarker(marker);
17648
17800
  } catch {
17649
17801
  return false;
@@ -17860,7 +18012,7 @@ function writeManagedSkillDirUnlocked(dir, skillMd, options, assertCurrent) {
17860
18012
  if (dirExists && managed && hasSkillMd && !options.force && isPointerSkillMd(skillMd)) {
17861
18013
  let existingIsStub = false;
17862
18014
  try {
17863
- existingIsStub = isPointerSkillMd(readFileSync15(skillMdPath, "utf-8"));
18015
+ existingIsStub = isPointerSkillMd(readFileSync16(skillMdPath, "utf-8"));
17864
18016
  } catch {
17865
18017
  existingIsStub = false;
17866
18018
  }
@@ -17910,7 +18062,7 @@ function writeManagedSkillDirUnlocked(dir, skillMd, options, assertCurrent) {
17910
18062
  assertCurrent();
17911
18063
  renameDirectory(candidateDir, dir);
17912
18064
  assertCurrent();
17913
- if (readFileSync15(skillMdPath, "utf8") !== (skillMd.endsWith(`
18065
+ if (readFileSync16(skillMdPath, "utf8") !== (skillMd.endsWith(`
17914
18066
  `) ? skillMd : `${skillMd}
17915
18067
  `))
17916
18068
  throw new Error("Managed skill readback failed");
@@ -17954,7 +18106,7 @@ function sourceSkillMd(skillPath, name, description, kind, preferBundledDocs = f
17954
18106
  if (kind === undefined || kind === "instruction" || preferBundledDocs) {
17955
18107
  const skillMdPath = join25(skillPath, "SKILL.md");
17956
18108
  if (existsSync10(skillMdPath))
17957
- return readFileSync15(skillMdPath, "utf-8");
18109
+ return readFileSync16(skillMdPath, "utf-8");
17958
18110
  }
17959
18111
  return pointerSkillMd(name, description);
17960
18112
  }
@@ -17994,7 +18146,7 @@ function resolveSkillAlias(name) {
17994
18146
  }
17995
18147
 
17996
18148
  // src/lib/project-state.ts
17997
- import { existsSync as existsSync11, mkdirSync as mkdirSync8, readFileSync as readFileSync16, writeFileSync as writeFileSync8 } from "fs";
18149
+ import { existsSync as existsSync11, mkdirSync as mkdirSync8, readFileSync as readFileSync17, writeFileSync as writeFileSync8 } from "fs";
17998
18150
  import { join as join26 } from "path";
17999
18151
  var VALID_PIN_SOURCES = [
18000
18152
  "official",
@@ -18020,7 +18172,7 @@ function loadProjectConfig(targetDir = process.cwd()) {
18020
18172
  if (!existsSync11(path))
18021
18173
  return null;
18022
18174
  try {
18023
- return normalizeProjectConfig(JSON.parse(readFileSync16(path, "utf-8")));
18175
+ return normalizeProjectConfig(JSON.parse(readFileSync17(path, "utf-8")));
18024
18176
  } catch {
18025
18177
  return null;
18026
18178
  }
@@ -18207,7 +18359,7 @@ function createLocalSkillManifest(name, generateSkillMd) {
18207
18359
  let skillMd = "";
18208
18360
  const skillMdPath = join27(sourcePath, "SKILL.md");
18209
18361
  if (existsSync12(skillMdPath)) {
18210
- skillMd = readFileSync17(skillMdPath, "utf-8");
18362
+ skillMd = readFileSync18(skillMdPath, "utf-8");
18211
18363
  } else if (generateSkillMd) {
18212
18364
  skillMd = generateSkillMd(name) ?? "";
18213
18365
  } else {
@@ -18333,7 +18485,7 @@ function resolveAgentSkillMd(name, generateSkillMd) {
18333
18485
  const sourcePath = getSkillPath(name);
18334
18486
  const skillMdPath = join27(sourcePath, "SKILL.md");
18335
18487
  if (existsSync12(skillMdPath))
18336
- return readFileSync17(skillMdPath, "utf-8");
18488
+ return readFileSync18(skillMdPath, "utf-8");
18337
18489
  if (generateSkillMd)
18338
18490
  return generateSkillMd(name);
18339
18491
  return generateMinimalSkillMd(name);
@@ -18389,14 +18541,14 @@ function readBundledSkillVersion(name) {
18389
18541
  if (!existsSync12(pkgPath))
18390
18542
  return "unknown";
18391
18543
  try {
18392
- const pkg = JSON.parse(readFileSync17(pkgPath, "utf-8"));
18544
+ const pkg = JSON.parse(readFileSync18(pkgPath, "utf-8"));
18393
18545
  return pkg.version || "unknown";
18394
18546
  } catch {
18395
18547
  return "unknown";
18396
18548
  }
18397
18549
  }
18398
18550
  function readFileIfExists(path) {
18399
- return existsSync12(path) ? readFileSync17(path, "utf-8") : null;
18551
+ return existsSync12(path) ? readFileSync18(path, "utf-8") : null;
18400
18552
  }
18401
18553
  function loadProjectConfigCompat(targetDir) {
18402
18554
  return loadProjectConfig(targetDir);
@@ -18444,7 +18596,7 @@ function isInstructionSkillDir(skillPath, meta) {
18444
18596
  if (!existsSync13(skillMdPath))
18445
18597
  return false;
18446
18598
  try {
18447
- return parseSkillFrontmatter(readFileSync18(skillMdPath, "utf-8"))?.kind === "instruction";
18599
+ return parseSkillFrontmatter(readFileSync19(skillMdPath, "utf-8"))?.kind === "instruction";
18448
18600
  } catch {
18449
18601
  return false;
18450
18602
  }
@@ -18495,7 +18647,7 @@ function getSkillRequirements(name) {
18495
18647
  const meta = getSkill(name);
18496
18648
  let dependencies = {};
18497
18649
  try {
18498
- dependencies = JSON.parse(readFileSync18(join28(skillPath, "package.json"), "utf8")).dependencies || {};
18650
+ dependencies = JSON.parse(readFileSync19(join28(skillPath, "package.json"), "utf8")).dependencies || {};
18499
18651
  } catch {}
18500
18652
  return getSkillRequirementsFromContent(name, texts, dependencies, meta);
18501
18653
  }
@@ -18563,7 +18715,7 @@ async function runSkill(name, args, options = {}) {
18563
18715
  }
18564
18716
  let entryPoint2;
18565
18717
  try {
18566
- const pkg = JSON.parse(readFileSync18(pkgPath, "utf-8"));
18718
+ const pkg = JSON.parse(readFileSync19(pkgPath, "utf-8"));
18567
18719
  if (pkg.bin) {
18568
18720
  const binValues = Object.values(pkg.bin);
18569
18721
  entryPoint2 = binValues[0];
@@ -18666,7 +18818,7 @@ function generateSkillMd(name) {
18666
18818
  const pkgPath = join28(skillPath, "package.json");
18667
18819
  if (existsSync13(pkgPath)) {
18668
18820
  try {
18669
- const pkg = JSON.parse(readFileSync18(pkgPath, "utf-8"));
18821
+ const pkg = JSON.parse(readFileSync19(pkgPath, "utf-8"));
18670
18822
  if (pkg.bin) {
18671
18823
  const binKeys = Object.keys(pkg.bin);
18672
18824
  if (binKeys.length > 0)
@@ -18742,7 +18894,7 @@ function extractEnvVars(text2) {
18742
18894
  function readIfExists(path) {
18743
18895
  try {
18744
18896
  if (existsSync13(path)) {
18745
- return readFileSync18(path, "utf-8");
18897
+ return readFileSync19(path, "utf-8");
18746
18898
  }
18747
18899
  } catch {}
18748
18900
  return null;
@@ -18869,7 +19021,7 @@ function exactProfileSelection(spec, profile) {
18869
19021
  }
18870
19022
 
18871
19023
  // src/lib/plugin-projection.ts
18872
- import { createHash as createHash19 } from "crypto";
19024
+ import { createHash as createHash20 } from "crypto";
18873
19025
  import { posix } from "path";
18874
19026
  var PLUGIN_PROJECTION_MANIFEST = "plugin-projection.json";
18875
19027
  var PLUGIN_PROJECTION_LIMITS = Object.freeze({ files: 1024, bytes: 64 * 1024 * 1024, fileBytes: 16 * 1024 * 1024, metadataBytes: 512 * 1024, registrations: 64, history: 128 });
@@ -18880,7 +19032,7 @@ function pluginNeed(value, message) {
18880
19032
  if (!value)
18881
19033
  pluginRefusal(message);
18882
19034
  }
18883
- var pluginHash = (bytes) => createHash19("sha256").update(bytes).digest("hex");
19035
+ var pluginHash = (bytes) => createHash20("sha256").update(bytes).digest("hex");
18884
19036
  function pluginObject(value) {
18885
19037
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
18886
19038
  }
@@ -19068,16 +19220,16 @@ function buildPluginProjection(entries) {
19068
19220
  }
19069
19221
 
19070
19222
  // src/lib/plugin-projection-store.ts
19071
- import { createHash as createHash20, randomUUID as randomUUID4 } from "crypto";
19072
- import { constants as constants11, closeSync as closeSync11, fchmodSync, fstatSync as fstatSync11, fsyncSync as fsyncSync5, linkSync as linkSync3, lstatSync as lstatSync21, mkdirSync as mkdirSync9, openSync as openSync11, opendirSync as opendirSync4, readSync as readSync9, renameSync as renameSync5, rmdirSync as rmdirSync3, rmSync as rmSync3, unlinkSync as unlinkSync5, writeSync as writeSync2 } from "fs";
19073
- import { dirname as dirname16, isAbsolute as isAbsolute14, join as join29, parse as parse6, resolve as resolve14 } from "path";
19074
- var READ_FLAGS = constants11.O_RDONLY | constants11.O_NOFOLLOW | constants11.O_NONBLOCK;
19075
- var WRITE_FLAGS = constants11.O_WRONLY | constants11.O_CREAT | constants11.O_EXCL | constants11.O_NOFOLLOW | constants11.O_NONBLOCK;
19223
+ import { createHash as createHash21, randomUUID as randomUUID4 } from "crypto";
19224
+ import { constants as constants12, closeSync as closeSync12, fchmodSync as fchmodSync2, fstatSync as fstatSync12, fsyncSync as fsyncSync6, linkSync as linkSync3, lstatSync as lstatSync22, mkdirSync as mkdirSync9, openSync as openSync12, opendirSync as opendirSync4, readSync as readSync9, renameSync as renameSync5, rmdirSync as rmdirSync3, rmSync as rmSync3, unlinkSync as unlinkSync5, writeSync as writeSync3 } from "fs";
19225
+ import { dirname as dirname16, isAbsolute as isAbsolute15, join as join29, parse as parse6, resolve as resolve14 } from "path";
19226
+ var READ_FLAGS = constants12.O_RDONLY | constants12.O_NOFOLLOW | constants12.O_NONBLOCK;
19227
+ var WRITE_FLAGS = constants12.O_WRONLY | constants12.O_CREAT | constants12.O_EXCL | constants12.O_NOFOLLOW | constants12.O_NONBLOCK;
19076
19228
  var uid = () => typeof process.getuid === "function" ? BigInt(process.getuid()) : undefined;
19077
19229
  var missing = (error) => Boolean(error && typeof error === "object" && "code" in error && error.code === "ENOENT");
19078
19230
  function stat(path) {
19079
19231
  try {
19080
- return lstatSync21(path, { bigint: true });
19232
+ return lstatSync22(path, { bigint: true });
19081
19233
  } catch (error) {
19082
19234
  if (missing(error))
19083
19235
  return null;
@@ -19085,7 +19237,7 @@ function stat(path) {
19085
19237
  }
19086
19238
  }
19087
19239
  function canonical6(path) {
19088
- pluginNeed(typeof path === "string" && path.length <= 8192 && isAbsolute14(path) && resolve14(path) === path && !/[\x00-\x1f\x7f]/.test(path), "Plugin storage paths must be canonical absolute paths");
19240
+ pluginNeed(typeof path === "string" && path.length <= 8192 && isAbsolute15(path) && resolve14(path) === path && !/[\x00-\x1f\x7f]/.test(path), "Plugin storage paths must be canonical absolute paths");
19089
19241
  }
19090
19242
  function owner(stats, system = false) {
19091
19243
  const current = uid();
@@ -19153,8 +19305,8 @@ function readBytes(path, maximum, kind) {
19153
19305
  fileShape(before, maximum, kind);
19154
19306
  let fd;
19155
19307
  try {
19156
- fd = openSync11(path, READ_FLAGS);
19157
- const opened = fstatSync11(fd, { bigint: true });
19308
+ fd = openSync12(path, READ_FLAGS);
19309
+ const opened = fstatSync12(fd, { bigint: true });
19158
19310
  same3(before, opened);
19159
19311
  fileShape(opened, maximum, kind);
19160
19312
  const bytes = new Uint8Array(Number(opened.size));
@@ -19165,7 +19317,7 @@ function readBytes(path, maximum, kind) {
19165
19317
  offset += count;
19166
19318
  }
19167
19319
  pluginNeed(readSync9(fd, new Uint8Array(1), 0, 1, null) === 0, "Plugin file grew while being read");
19168
- same3(opened, fstatSync11(fd, { bigint: true }));
19320
+ same3(opened, fstatSync12(fd, { bigint: true }));
19169
19321
  same3(opened, stat(path));
19170
19322
  verifyAncestors(chain);
19171
19323
  return bytes;
@@ -19175,7 +19327,7 @@ function readBytes(path, maximum, kind) {
19175
19327
  return pluginRefusal("Cannot safely read plugin file");
19176
19328
  } finally {
19177
19329
  if (fd !== undefined)
19178
- closeSync11(fd);
19330
+ closeSync12(fd);
19179
19331
  }
19180
19332
  }
19181
19333
  function exactPaths(entries) {
@@ -19285,16 +19437,16 @@ function verifyPluginTree(root, witnesses) {
19285
19437
  function writeExclusive(path, bytes, mode) {
19286
19438
  let fd, created;
19287
19439
  try {
19288
- fd = openSync11(path, WRITE_FLAGS, mode);
19289
- fchmodSync(fd, mode);
19290
- created = fstatSync11(fd, { bigint: true });
19440
+ fd = openSync12(path, WRITE_FLAGS, mode);
19441
+ fchmodSync2(fd, mode);
19442
+ created = fstatSync12(fd, { bigint: true });
19291
19443
  let offset = 0;
19292
19444
  while (offset < bytes.byteLength) {
19293
- const count = writeSync2(fd, bytes, offset, bytes.byteLength - offset);
19445
+ const count = writeSync3(fd, bytes, offset, bytes.byteLength - offset);
19294
19446
  pluginNeed(count > 0, "Plugin file write did not progress");
19295
19447
  offset += count;
19296
19448
  }
19297
- fsyncSync5(fd);
19449
+ fsyncSync6(fd);
19298
19450
  } catch (error) {
19299
19451
  if (created) {
19300
19452
  same3(created, stat(path), true);
@@ -19303,7 +19455,7 @@ function writeExclusive(path, bytes, mode) {
19303
19455
  throw error;
19304
19456
  } finally {
19305
19457
  if (fd !== undefined)
19306
- closeSync11(fd);
19458
+ closeSync12(fd);
19307
19459
  }
19308
19460
  }
19309
19461
  function materializePluginTree(root, entries) {
@@ -19406,11 +19558,11 @@ function pluginExecutableDigest(path) {
19406
19558
  fileShape(before, maximum, "executable");
19407
19559
  let fd;
19408
19560
  try {
19409
- fd = openSync11(path, READ_FLAGS);
19410
- const opened = fstatSync11(fd, { bigint: true });
19561
+ fd = openSync12(path, READ_FLAGS);
19562
+ const opened = fstatSync12(fd, { bigint: true });
19411
19563
  same3(before, opened);
19412
19564
  fileShape(opened, maximum, "executable");
19413
- const hash2 = createHash20("sha256"), buffer = new Uint8Array(64 * 1024);
19565
+ const hash2 = createHash21("sha256"), buffer = new Uint8Array(64 * 1024);
19414
19566
  let remaining = Number(opened.size);
19415
19567
  while (remaining > 0) {
19416
19568
  const count = readSync9(fd, buffer, 0, Math.min(buffer.byteLength, remaining), null);
@@ -19419,7 +19571,7 @@ function pluginExecutableDigest(path) {
19419
19571
  remaining -= count;
19420
19572
  }
19421
19573
  pluginNeed(readSync9(fd, buffer, 0, 1, null) === 0, "Plugin executable grew during hashing");
19422
- same3(opened, fstatSync11(fd, { bigint: true }));
19574
+ same3(opened, fstatSync12(fd, { bigint: true }));
19423
19575
  same3(opened, stat(path));
19424
19576
  verifyAncestors(chain);
19425
19577
  return `sha256:${hash2.digest("hex")}`;
@@ -19429,7 +19581,7 @@ function pluginExecutableDigest(path) {
19429
19581
  return pluginRefusal("Cannot safely hash plugin executable");
19430
19582
  } finally {
19431
19583
  if (fd !== undefined)
19432
- closeSync11(fd);
19584
+ closeSync12(fd);
19433
19585
  }
19434
19586
  }
19435
19587
 
@@ -19468,7 +19620,7 @@ function validatePluginTarget(value) {
19468
19620
  for (const registration of value.registrations) {
19469
19621
  pluginKeys(registration, ["scope", "projectPath"]);
19470
19622
  pluginNeed(registration.scope === "user" || registration.scope === "project", "Unsupported plugin registration scope");
19471
- pluginNeed(registration.scope === "user" ? registration.projectPath === null : typeof registration.projectPath === "string" && isAbsolute15(registration.projectPath) && resolve15(registration.projectPath) === registration.projectPath, "Plugin scope requires its exact project path");
19623
+ pluginNeed(registration.scope === "user" ? registration.projectPath === null : typeof registration.projectPath === "string" && isAbsolute16(registration.projectPath) && resolve15(registration.projectPath) === registration.projectPath, "Plugin scope requires its exact project path");
19472
19624
  const key = JSON.stringify([registration.scope, registration.projectPath]);
19473
19625
  pluginNeed(!scopes.has(key), "Duplicate plugin registration scope");
19474
19626
  scopes.add(key);
@@ -19476,7 +19628,7 @@ function validatePluginTarget(value) {
19476
19628
  for (const key of ["native", "resolver"]) {
19477
19629
  pluginKeys(value[key], key === "native" ? ["version", "executable", "digest"] : ["executable", "digest"]);
19478
19630
  pluginText(value[key].executable);
19479
- pluginNeed(isAbsolute15(value[key].executable) && resolve15(value[key].executable) === value[key].executable, "Plugin executable must have a canonical absolute path");
19631
+ pluginNeed(isAbsolute16(value[key].executable) && resolve15(value[key].executable) === value[key].executable, "Plugin executable must have a canonical absolute path");
19480
19632
  pluginDigest(value[key].digest);
19481
19633
  }
19482
19634
  pluginNeed(["2.1.274", "2.1.276"].includes(value.native.version), "Plugin admission requires a certified Claude command-source runtime (2.1.274 or 2.1.276)");
@@ -19628,7 +19780,7 @@ function pluginResolverCommand(binding) {
19628
19780
  }
19629
19781
  function root(options) {
19630
19782
  const path = options.storeRoot ?? pluginAdmissionRoot();
19631
- pluginNeed(isAbsolute15(path) && resolve15(path) === path, "Invalid plugin admission store root");
19783
+ pluginNeed(isAbsolute16(path) && resolve15(path) === path, "Invalid plugin admission store root");
19632
19784
  return path;
19633
19785
  }
19634
19786
  function pluginBindingPath(storeRoot, id) {
@@ -19833,25 +19985,25 @@ function validateManagedPluginWitnesses(value) {
19833
19985
  pluginNeed(typeof item.bindingId === "string" && /^[a-f0-9]{64}$/.test(item.bindingId) && !seen.has(item.bindingId), "Invalid or duplicate managed plugin witness");
19834
19986
  seen.add(item.bindingId);
19835
19987
  pluginText(item.storeRoot);
19836
- pluginNeed(isAbsolute16(item.storeRoot) && resolve16(item.storeRoot) === item.storeRoot, "Invalid plugin receipt store path");
19988
+ pluginNeed(isAbsolute17(item.storeRoot) && resolve16(item.storeRoot) === item.storeRoot, "Invalid plugin receipt store path");
19837
19989
  }
19838
19990
  }
19839
19991
  function safe3(path) {
19840
19992
  pluginText(path);
19841
- pluginNeed(isAbsolute16(path) && resolve16(path) === path, "Invalid plugin registry path");
19993
+ pluginNeed(isAbsolute17(path) && resolve16(path) === path, "Invalid plugin registry path");
19842
19994
  for (let at = path;; at = dirname17(at)) {
19843
- pluginNeed(!lstatSync22(at, { throwIfNoEntry: false })?.isSymbolicLink(), "Plugin registry path traverses a symlink");
19995
+ pluginNeed(!lstatSync23(at, { throwIfNoEntry: false })?.isSymbolicLink(), "Plugin registry path traverses a symlink");
19844
19996
  if (at === dirname17(at))
19845
19997
  break;
19846
19998
  }
19847
19999
  }
19848
20000
  function readRegistry(path) {
19849
20001
  safe3(path);
19850
- const initial = lstatSync22(path);
20002
+ const initial = lstatSync23(path);
19851
20003
  pluginNeed(initial.isFile() && initial.size <= 1024 * 1024, "Plugin registry is not a bounded regular file");
19852
- const fd = openSync12(path, constants12.O_RDONLY | constants12.O_NOFOLLOW | constants12.O_NONBLOCK);
20004
+ const fd = openSync13(path, constants13.O_RDONLY | constants13.O_NOFOLLOW | constants13.O_NONBLOCK);
19853
20005
  try {
19854
- const opened = fstatSync12(fd);
20006
+ const opened = fstatSync13(fd);
19855
20007
  pluginNeed(opened.isFile() && opened.ino === initial.ino && opened.dev === initial.dev, "Plugin registry changed during open");
19856
20008
  const bytes = Buffer.alloc(1024 * 1024 + 1);
19857
20009
  let length = 0;
@@ -19861,7 +20013,7 @@ function readRegistry(path) {
19861
20013
  break;
19862
20014
  length += count;
19863
20015
  }
19864
- const after = fstatSync12(fd), current = lstatSync22(path);
20016
+ const after = fstatSync13(fd), current = lstatSync23(path);
19865
20017
  safe3(path);
19866
20018
  pluginNeed(length <= 1024 * 1024 && length === opened.size && after.size === opened.size && after.mtimeMs === opened.mtimeMs && after.ctimeMs === opened.ctimeMs && current.dev === opened.dev && current.ino === opened.ino && current.mtimeMs === opened.mtimeMs && current.ctimeMs === opened.ctimeMs, "Plugin registry changed during read");
19867
20019
  let value;
@@ -19873,7 +20025,7 @@ function readRegistry(path) {
19873
20025
  pluginNeed(pluginObject(value) && value.version === 2 && pluginObject(value.plugins), "Unsupported native plugin registry schema");
19874
20026
  return { value, rawDigest: pluginHash(bytes.subarray(0, length)) };
19875
20027
  } finally {
19876
- closeSync12(fd);
20028
+ closeSync13(fd);
19877
20029
  }
19878
20030
  }
19879
20031
  function nativeVersionMatches(version, receipt) {
@@ -19934,7 +20086,7 @@ function hashManagedPluginRegistry(path, managed) {
19934
20086
  return Object.fromEntries(Object.entries(row).filter(([key]) => !["version", "installPath", "sourceProducerPath", "previousProducerPaths", "lastUpdated"].includes(key)));
19935
20087
  });
19936
20088
  safe3(cacheRoot);
19937
- const before = lstatSync22(cacheRoot);
20089
+ const before = lstatSync23(cacheRoot);
19938
20090
  pluginNeed(before.isDirectory(), "Invalid managed plugin cache root");
19939
20091
  const directory = opendirSync5(cacheRoot), names = [];
19940
20092
  try {
@@ -19957,7 +20109,7 @@ function hashManagedPluginRegistry(path, managed) {
19957
20109
  }
19958
20110
  for (const row of rows)
19959
20111
  pluginNeed(names.includes(row.version), "Managed native plugin installation is missing");
19960
- const after = lstatSync22(cacheRoot);
20112
+ const after = lstatSync23(cacheRoot);
19961
20113
  safe3(cacheRoot);
19962
20114
  pluginNeed(before.dev === after.dev && before.ino === after.ino && before.mtimeMs === after.mtimeMs && before.ctimeMs === after.ctimeMs, "Managed cache version membership changed during verification");
19963
20115
  }
@@ -19969,22 +20121,22 @@ function captureManagedPluginRegistry(path, managedPlugins) {
19969
20121
  }
19970
20122
 
19971
20123
  // src/lib/claude-marketplace-registry.ts
19972
- import { createHash as createHash21 } from "crypto";
19973
- import { closeSync as closeSync13, constants as constants13, fstatSync as fstatSync13, lstatSync as lstatSync23, openSync as openSync13, readSync as readSync11 } from "fs";
19974
- import { basename as basename9, dirname as dirname18, isAbsolute as isAbsolute17, resolve as resolve17 } from "path";
20124
+ import { createHash as createHash22 } from "crypto";
20125
+ import { closeSync as closeSync14, constants as constants14, fstatSync as fstatSync14, lstatSync as lstatSync24, openSync as openSync14, readSync as readSync11 } from "fs";
20126
+ import { basename as basename9, dirname as dirname18, isAbsolute as isAbsolute18, resolve as resolve17 } from "path";
19975
20127
  var CLAUDE_MARKETPLACE_REGISTRY_LIMITS = Object.freeze({ bytes: 1024 * 1024, rows: 1024, depth: 32, nodes: 65536, stringCharacters: 16384, pathCharacters: 4096 });
19976
20128
  function need6(value, reason) {
19977
20129
  if (!value)
19978
20130
  throw new Error(`Claude marketplace registry ${reason}`);
19979
20131
  }
19980
20132
  function absolutePath3(value) {
19981
- need6(typeof value === "string" && value.length > 0 && value.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.pathCharacters && !/[\x00-\x1f\x7f]/.test(value) && isAbsolute17(value) && resolve17(value) === value, "requires a normalized absolute path");
20133
+ need6(typeof value === "string" && value.length > 0 && value.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.pathCharacters && !/[\x00-\x1f\x7f]/.test(value) && isAbsolute18(value) && resolve17(value) === value, "requires a normalized absolute path");
19982
20134
  }
19983
20135
  var sameFile2 = (a, b) => a.dev === b.dev && a.ino === b.ino && a.mode === b.mode && a.uid === b.uid && a.gid === b.gid && a.nlink === b.nlink && a.size === b.size && a.mtimeNs === b.mtimeNs && a.ctimeNs === b.ctimeNs;
19984
20136
  function parents2(path) {
19985
20137
  const result = [];
19986
20138
  for (let at = dirname18(path);; at = dirname18(at)) {
19987
- const stat2 = lstatSync23(at, { bigint: true });
20139
+ const stat2 = lstatSync24(at, { bigint: true });
19988
20140
  need6(stat2.isDirectory() && !stat2.isSymbolicLink(), "path traverses a symlink or non-directory");
19989
20141
  result.push([at, stat2]);
19990
20142
  if (at === dirname18(at))
@@ -19995,12 +20147,12 @@ function readRegistry2(path, budget2) {
19995
20147
  absolutePath3(path);
19996
20148
  need6(basename9(path) === "known_marketplaces.json", "requires known_marketplaces.json");
19997
20149
  need6(Number.isSafeInteger(budget2.remaining) && budget2.remaining >= 0, "has an invalid byte budget");
19998
- const ancestors2 = parents2(path), initial = lstatSync23(path, { bigint: true });
20150
+ const ancestors2 = parents2(path), initial = lstatSync24(path, { bigint: true });
19999
20151
  need6(initial.isFile() && !initial.isSymbolicLink() && initial.size <= BigInt(CLAUDE_MARKETPLACE_REGISTRY_LIMITS.bytes), "is not a bounded regular file");
20000
20152
  need6(initial.size <= BigInt(budget2.remaining), "exceeds its aggregate byte limit");
20001
- const fd = openSync13(path, constants13.O_RDONLY | constants13.O_NOFOLLOW | constants13.O_NONBLOCK);
20153
+ const fd = openSync14(path, constants14.O_RDONLY | constants14.O_NOFOLLOW | constants14.O_NONBLOCK);
20002
20154
  try {
20003
- const opened = fstatSync13(fd, { bigint: true });
20155
+ const opened = fstatSync14(fd, { bigint: true });
20004
20156
  need6(opened.isFile() && sameFile2(initial, opened), "changed during open");
20005
20157
  const bytes = Buffer.alloc(Number(opened.size) + 1);
20006
20158
  let length = 0;
@@ -20010,10 +20162,10 @@ function readRegistry2(path, budget2) {
20010
20162
  break;
20011
20163
  length += count;
20012
20164
  }
20013
- const after = fstatSync13(fd, { bigint: true }), current = lstatSync23(path, { bigint: true });
20165
+ const after = fstatSync14(fd, { bigint: true }), current = lstatSync24(path, { bigint: true });
20014
20166
  need6(current.isFile() && sameFile2(opened, after) && sameFile2(after, current) && BigInt(length) === opened.size, "changed during read");
20015
20167
  for (const [ancestor, before] of ancestors2) {
20016
- const now = lstatSync23(ancestor, { bigint: true });
20168
+ const now = lstatSync24(ancestor, { bigint: true });
20017
20169
  need6(now.isDirectory() && before.dev === now.dev && before.ino === now.ino && before.mode === now.mode, "parent changed during read");
20018
20170
  }
20019
20171
  budget2.remaining -= length;
@@ -20023,7 +20175,7 @@ function readRegistry2(path, budget2) {
20023
20175
  throw new Error("Claude marketplace registry is not strict UTF-8");
20024
20176
  }
20025
20177
  } finally {
20026
- closeSync13(fd);
20178
+ closeSync14(fd);
20027
20179
  }
20028
20180
  }
20029
20181
  function parse7(text2) {
@@ -20138,19 +20290,19 @@ function captureClaudeMarketplaceRegistry(path, budget2 = { remaining: 256 * 102
20138
20290
  const value = parse7(readRegistry2(path, budget2));
20139
20291
  for (const [, row] of value.entries)
20140
20292
  normalizeRow(row);
20141
- const sha2562 = createHash21("sha256").update("hasna.skills.claude-marketplace-registry.v1\x00").update(JSON.stringify(value)).digest("hex");
20142
- return { path, hashMode: "claude-marketplace-registry", sha256: sha2562 };
20293
+ const sha2563 = createHash22("sha256").update("hasna.skills.claude-marketplace-registry.v1\x00").update(JSON.stringify(value)).digest("hex");
20294
+ return { path, hashMode: "claude-marketplace-registry", sha256: sha2563 };
20143
20295
  }
20144
20296
  function captureClaudeMarketplaceRegistryV2(path, budget2 = { remaining: 256 * 1024 * 1024 }) {
20145
20297
  const value = parse7(readRegistry2(path, budget2));
20146
20298
  for (const [, row] of value.entries)
20147
20299
  normalizeRow(row, 2);
20148
- const sha2562 = createHash21("sha256").update("hasna.skills.claude-marketplace-registry.v2\x00").update(JSON.stringify(value)).digest("hex");
20149
- return { path, hashMode: "claude-marketplace-registry-v2", sha256: sha2562 };
20300
+ const sha2563 = createHash22("sha256").update("hasna.skills.claude-marketplace-registry.v2\x00").update(JSON.stringify(value)).digest("hex");
20301
+ return { path, hashMode: "claude-marketplace-registry-v2", sha256: sha2563 };
20150
20302
  }
20151
20303
 
20152
20304
  // src/lib/codex-hook-discovery-recovery.ts
20153
- import { createHash as createHash22 } from "crypto";
20305
+ import { createHash as createHash23 } from "crypto";
20154
20306
 
20155
20307
  // src/lib/codex-hook-additions-review.ts
20156
20308
  var events = { UserPromptSubmit: ["userPromptSubmit", "user_prompt_submit"], SessionStart: ["sessionStart", "session_start"], SubagentStart: ["subagentStart", "subagent_start"] };
@@ -20158,7 +20310,7 @@ var matchedEvents = { ...events, PreToolUse: ["preToolUse", "pre_tool_use"] };
20158
20310
  var proofs = new WeakMap;
20159
20311
 
20160
20312
  // src/lib/codex-hook-discovery-recovery.ts
20161
- var sha4 = (text2) => createHash22("sha256").update(text2).digest("hex");
20313
+ var sha4 = (text2) => createHash23("sha256").update(text2).digest("hex");
20162
20314
  var fields = [...CODEX_DISCOVERY_PROJECTION_FIELDS];
20163
20315
  var proofs2 = new WeakMap;
20164
20316
  function assertCodexHookDiscoveryRecovery(binding, witness) {
@@ -20177,7 +20329,7 @@ function verifiesCodexHookDiscoverySource(binding, source, currentDigest, witnes
20177
20329
  }
20178
20330
 
20179
20331
  // src/lib/agent-discovery.ts
20180
- var digest = (text2) => createHash23("sha256").update(text2).digest("hex");
20332
+ var digest = (text2) => createHash24("sha256").update(text2).digest("hex");
20181
20333
  function parseConfig(text2, path, toml = false) {
20182
20334
  try {
20183
20335
  const value = toml ? Bun.TOML.parse(text2) : JSON.parse(text2);
@@ -20189,10 +20341,10 @@ function parseConfig(text2, path, toml = false) {
20189
20341
  }
20190
20342
  }
20191
20343
  function safe4(path) {
20192
- if (!isAbsolute18(path) || path.includes("\x00"))
20344
+ if (!isAbsolute19(path) || path.includes("\x00"))
20193
20345
  throw new Error("Expected an absolute native discovery path");
20194
20346
  for (let cursor = path;; cursor = dirname19(cursor)) {
20195
- if (lstatSync24(cursor, { throwIfNoEntry: false })?.isSymbolicLink())
20347
+ if (lstatSync25(cursor, { throwIfNoEntry: false })?.isSymbolicLink())
20196
20348
  throw new Error(`Refusing symlink native discovery input: ${cursor}`);
20197
20349
  if (dirname19(cursor) === cursor)
20198
20350
  break;
@@ -20202,12 +20354,12 @@ function read2(path, changes) {
20202
20354
  safe4(path);
20203
20355
  if (changes?.has(path))
20204
20356
  return changes.get(path);
20205
- const stat2 = lstatSync24(path, { throwIfNoEntry: false });
20357
+ const stat2 = lstatSync25(path, { throwIfNoEntry: false });
20206
20358
  if (!stat2)
20207
20359
  return null;
20208
20360
  if (!stat2.isFile() || stat2.size > 16 * 1024 * 1024)
20209
20361
  throw new Error(`Unsupported or oversized native discovery input: ${path}`);
20210
- return readFileSync19(path, "utf8");
20362
+ return readFileSync20(path, "utf8");
20211
20363
  }
20212
20364
  function projectNativeDiscoveryFields(text2, format, fields2, path) {
20213
20365
  const object6 = format === "yaml" ? parseHermesConfig(text2) : parseConfig(text2, path, format === "toml");
@@ -20253,10 +20405,10 @@ function projected(source, changes, budget2 = discoveryByteBudget()) {
20253
20405
  if (source.hashMode === "claude-marketplace-registry" || source.hashMode === "claude-marketplace-registry-v2") {
20254
20406
  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))
20255
20407
  throw new Error("Claude marketplace witnesses require an exact reviewed registry without synthetic changes");
20256
- const sha2562 = (source.hashMode === "claude-marketplace-registry-v2" ? captureClaudeMarketplaceRegistryV2 : captureClaudeMarketplaceRegistry)(source.path, budget2).sha256;
20257
- if (sha2562 !== source.sha256)
20408
+ const sha2563 = (source.hashMode === "claude-marketplace-registry-v2" ? captureClaudeMarketplaceRegistryV2 : captureClaudeMarketplaceRegistry)(source.path, budget2).sha256;
20409
+ if (sha2563 !== source.sha256)
20258
20410
  throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
20259
- return sha2562;
20411
+ return sha2563;
20260
20412
  }
20261
20413
  if (source.hashMode === "claude-plugin-registry") {
20262
20414
  if (source.format !== undefined || source.fields !== undefined || !source.managedPlugins || changes?.has(source.path))
@@ -20293,7 +20445,7 @@ function absentCodexSkillRoots(binding) {
20293
20445
  return [];
20294
20446
  if (binding.agent !== "codex" || !Array.isArray(controls) || controls.length > 4096)
20295
20447
  throw new Error("Invalid disabled Codex discovery proof");
20296
- if (binding.method !== "reviewed" || controls.every((control) => lstatSync24(control.pluginParent, { throwIfNoEntry: false })))
20448
+ if (binding.method !== "reviewed" || controls.every((control) => lstatSync25(control.pluginParent, { throwIfNoEntry: false })))
20297
20449
  return [];
20298
20450
  const cache = dirname19(dirname19(controls[0].pluginParent)), config = join32(dirname19(dirname19(cache)), "config.toml");
20299
20451
  const source = binding.sources.find((source2) => source2.path === config && source2.sha256 !== null && source2.format === undefined && source2.fields === undefined);
@@ -20361,7 +20513,7 @@ function absentRetiredClaudeRoots(binding) {
20361
20513
  continue;
20362
20514
  const root2 = join32(cache, ...parts.slice(0, 3));
20363
20515
  safe4(root2);
20364
- if (lstatSync24(root2, { throwIfNoEntry: false }))
20516
+ if (lstatSync25(root2, { throwIfNoEntry: false }))
20365
20517
  continue;
20366
20518
  const claude = dirname19(dirname19(cache)), settings = join32(claude, "settings.json"), registry = join32(claude, "plugins/installed_plugins.json");
20367
20519
  const full = (path) => binding.sources.find((item) => item.path === path && item.sha256 !== null && item.format === undefined && item.fields === undefined);
@@ -20380,7 +20532,7 @@ function absentRetiredClaudeRoots(binding) {
20380
20532
  if (!Array.isArray(rows) || rows.length !== 1 || rows[0]?.scope !== "user" || typeof rows[0]?.installPath !== "string")
20381
20533
  continue;
20382
20534
  const active = rows[0].installPath;
20383
- if (rows[0].version !== basename10(active) || resolve18(active) !== active || dirname19(active) !== dirname19(root2) || active === root2 || !lstatSync24(active, { throwIfNoEntry: false })?.isDirectory() || realpathSync10(active) !== active)
20535
+ if (rows[0].version !== basename10(active) || resolve18(active) !== active || dirname19(active) !== dirname19(root2) || active === root2 || !lstatSync25(active, { throwIfNoEntry: false })?.isDirectory() || realpathSync11(active) !== active)
20384
20536
  continue;
20385
20537
  const activeManifest = full(join32(active, ".claude-plugin/plugin.json"));
20386
20538
  if (!activeManifest || projected(activeManifest) !== activeManifest.sha256)
@@ -20411,7 +20563,7 @@ function verifyAgentDiscovery(binding, codexRecovery) {
20411
20563
  const projection = binding.codexRetiredMaterializations.directories;
20412
20564
  if (projection.length !== ordinary.length || projection.some((item, index) => item.path !== ordinary[index]?.path))
20413
20565
  throw new Error("Missing retired Codex directory projection");
20414
- const omitted = [...retiredRoots, ...(binding.codexRetiredMaterializations.parents ?? []).filter((parent) => !lstatSync24(parent, { throwIfNoEntry: false }))];
20566
+ const omitted = [...retiredRoots, ...(binding.codexRetiredMaterializations.parents ?? []).filter((parent) => !lstatSync25(parent, { throwIfNoEntry: false }))];
20415
20567
  if (projection.every((item) => Array.isArray(item.entries)))
20416
20568
  verifyDiscoveryDirectoryProjection(projection, omitted);
20417
20569
  else {
@@ -20425,7 +20577,7 @@ function verifyAgentDiscovery(binding, codexRecovery) {
20425
20577
  verifyDiscoveryDirectories(ordinary);
20426
20578
  verifyDiscoveryDirectories(projected2, installationRoots);
20427
20579
  }
20428
- const absentRoots = [...absentCodexSkillRoots(binding), ...absentRetiredClaudeRoots(binding), ...retiredRoots.filter((root2) => !lstatSync24(root2, { throwIfNoEntry: false }))];
20580
+ const absentRoots = [...absentCodexSkillRoots(binding), ...absentRetiredClaudeRoots(binding), ...retiredRoots.filter((root2) => !lstatSync25(root2, { throwIfNoEntry: false }))];
20429
20581
  const budget2 = discoveryByteBudget();
20430
20582
  for (const source of binding.sources) {
20431
20583
  assertMarketplaceBinding(binding, source);
@@ -20451,7 +20603,7 @@ function verifyAgentDiscovery(binding, codexRecovery) {
20451
20603
  safe4(root2);
20452
20604
  for (const root2 of absentRoots) {
20453
20605
  safe4(root2);
20454
- if (lstatSync24(root2, { throwIfNoEntry: false }))
20606
+ if (lstatSync25(root2, { throwIfNoEntry: false }))
20455
20607
  throw new Error("Retired native materialization changed during discovery verification");
20456
20608
  }
20457
20609
  }
@@ -20490,19 +20642,19 @@ function assertMarketplaceBinding(binding, source) {
20490
20642
  }
20491
20643
  function rebindAgentDiscovery(binding, changes) {
20492
20644
  const budget2 = discoveryByteBudget();
20493
- const installationRoots = codexInstallationRoots(binding), absentRoots = [...absentCodexSkillRoots(binding), ...absentRetiredClaudeRoots(binding), ...retiredCodexRoots(binding).filter((root2) => !lstatSync24(root2, { throwIfNoEntry: false }))];
20645
+ const installationRoots = codexInstallationRoots(binding), absentRoots = [...absentCodexSkillRoots(binding), ...absentRetiredClaudeRoots(binding), ...retiredCodexRoots(binding).filter((root2) => !lstatSync25(root2, { throwIfNoEntry: false }))];
20494
20646
  const rebound = { ...binding, sources: binding.sources.map((source) => {
20495
20647
  assertMarketplaceBinding(binding, source);
20496
20648
  if (!changes.has(source.path) && (installationRoots.some((root2) => source.path.startsWith(root2 + sep8)) || absentRoots.some((root2) => source.path.startsWith(root2 + sep8)) && source.format === undefined && source.fields === undefined && source.managedPlugins === undefined && [undefined, "bytes"].includes(source.hashMode)))
20497
20649
  return source;
20498
- const sha2562 = projected(source, changes, budget2);
20499
- if (!changes.has(source.path) && sha2562 !== source.sha256)
20650
+ const sha2563 = projected(source, changes, budget2);
20651
+ if (!changes.has(source.path) && sha2563 !== source.sha256)
20500
20652
  throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
20501
- return { ...source, sha256: sha2562 };
20653
+ return { ...source, sha256: sha2563 };
20502
20654
  }) };
20503
20655
  for (const root2 of absentRoots) {
20504
20656
  safe4(root2);
20505
- if (lstatSync24(root2, { throwIfNoEntry: false }))
20657
+ if (lstatSync25(root2, { throwIfNoEntry: false }))
20506
20658
  throw new Error("Retired native materialization changed during discovery rebinding");
20507
20659
  }
20508
20660
  return rebound;
@@ -20557,13 +20709,13 @@ function assertProjectDiscovery(agent, directories, home, canonical7 = resolve18
20557
20709
  for (const name of ["plugin", "plugins"]) {
20558
20710
  const path = canonical7(join32(directory, ".sumi", name));
20559
20711
  safe4(path);
20560
- if (lstatSync24(path, { throwIfNoEntry: false })?.isDirectory() && readdirSync10(path).length)
20712
+ if (lstatSync25(path, { throwIfNoEntry: false })?.isDirectory() && readdirSync10(path).length)
20561
20713
  throw new Error(`NATIVE_SKILL_DRIFT: project Sumi plugins require a dedicated discovery review: ${path}`);
20562
20714
  }
20563
20715
  if (agent === "claude") {
20564
20716
  const commands = canonical7(join32(directory, ".claude/commands"));
20565
20717
  safe4(commands);
20566
- if (lstatSync24(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync10(commands).length)
20718
+ if (lstatSync25(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync10(commands).length)
20567
20719
  throw new Error("NATIVE_SKILL_DRIFT: legacy project command discovery requires a dedicated format adapter");
20568
20720
  }
20569
20721
  }
@@ -20603,7 +20755,7 @@ function resolveAgentDiscovery(options) {
20603
20755
  if (config.skills !== undefined && (!Array.isArray(config.skills) || config.skills.some((path) => typeof path !== "string")))
20604
20756
  unresolved("skills must be a string array");
20605
20757
  for (const value of config.skills ?? []) {
20606
- if (typeof value !== "string" || /[\0$]/.test(value) || !value || !(isAbsolute18(value) || value.startsWith("~/")))
20758
+ if (typeof value !== "string" || /[\0$]/.test(value) || !value || !(isAbsolute19(value) || value.startsWith("~/")))
20607
20759
  unresolved("remote or relative skill sources need a dedicated discovery adapter");
20608
20760
  roots.add(canonical7(value.startsWith("~/") ? join32(home, value.slice(2)) : value));
20609
20761
  }
@@ -20613,19 +20765,19 @@ function resolveAgentDiscovery(options) {
20613
20765
  const plugins = [join32(directory, "plugin"), join32(directory, "plugins")];
20614
20766
  for (const path of plugins) {
20615
20767
  safe4(path);
20616
- if (lstatSync24(path, { throwIfNoEntry: false })?.isDirectory())
20768
+ if (lstatSync25(path, { throwIfNoEntry: false })?.isDirectory())
20617
20769
  for (const name of readdirSync10(path).sort()) {
20618
20770
  if (name === "skills-cli.js" && path === plugins[1])
20619
20771
  continue;
20620
20772
  const target = join32(path, name);
20621
- if (!lstatSync24(target).isFile())
20773
+ if (!lstatSync25(target).isFile())
20622
20774
  unresolved("local plugin packages need a dedicated discovery adapter");
20623
20775
  witness(target);
20624
20776
  }
20625
20777
  }
20626
20778
  for (const root2 of roots) {
20627
20779
  safe4(root2);
20628
- if (lstatSync24(root2, { throwIfNoEntry: false })?.isDirectory() && readdirSync10(root2).some((name) => name.endsWith(".md")))
20780
+ if (lstatSync25(root2, { throwIfNoEntry: false })?.isDirectory() && readdirSync10(root2).some((name) => name.endsWith(".md")))
20629
20781
  unresolved("flat markdown skills require a dedicated native migration adapter");
20630
20782
  }
20631
20783
  }
@@ -20653,7 +20805,7 @@ function resolveAgentDiscovery(options) {
20653
20805
  const executable2 = Bun.which("gemini");
20654
20806
  if (executable2) {
20655
20807
  let packageRoot;
20656
- for (let directory = dirname19(realpathSync10(executable2)), depth = 0;depth < 8; directory = dirname19(directory), depth++) {
20808
+ for (let directory = dirname19(realpathSync11(executable2)), depth = 0;depth < 8; directory = dirname19(directory), depth++) {
20657
20809
  const path = join32(directory, "package.json"), raw = read2(path);
20658
20810
  if (raw !== null && parseConfig(raw, path).name === "@google/gemini-cli") {
20659
20811
  packageRoot = directory;
@@ -20667,7 +20819,7 @@ function resolveAgentDiscovery(options) {
20667
20819
  unresolved("installed Gemini package layout is not recognized");
20668
20820
  const builtinRoot = join32(packageRoot, "bundle/builtin");
20669
20821
  safe4(builtinRoot);
20670
- if (!lstatSync24(builtinRoot, { throwIfNoEntry: false })?.isDirectory())
20822
+ if (!lstatSync25(builtinRoot, { throwIfNoEntry: false })?.isDirectory())
20671
20823
  unresolved("installed Gemini builtin root is missing");
20672
20824
  for (const name of readdirSync10(builtinRoot).sort()) {
20673
20825
  const text2 = witness(join32(builtinRoot, name, "SKILL.md"));
@@ -20708,7 +20860,7 @@ function resolveAgentDiscovery(options) {
20708
20860
  if (agent !== "claude" || source.sha256 === null || source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || source.hashMode !== undefined && source.hashMode !== "bytes" || basename10(source.path) !== "plugin.json" || !source.path.endsWith(join32(sep8, ".claude-plugin", "plugin.json")))
20709
20861
  return source;
20710
20862
  const pluginRoot = dirname19(dirname19(source.path)), hooksPath = join32(pluginRoot, "hooks/hooks.json");
20711
- const hookStat = lstatSync24(hooksPath, { throwIfNoEntry: false });
20863
+ const hookStat = lstatSync25(hooksPath, { throwIfNoEntry: false });
20712
20864
  const text2 = read2(source.path);
20713
20865
  if (text2 === null)
20714
20866
  throw new Error("Reviewed Claude plugin manifest is missing");
@@ -20749,7 +20901,7 @@ function resolveAgentDiscovery(options) {
20749
20901
  unresolved("plugin hooks require a separate no-skill-injection review");
20750
20902
  const commands = join32(root2, "commands");
20751
20903
  safe4(commands);
20752
- if (agent === "claude" && (manifest.commands !== undefined || lstatSync24(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync10(commands).length))
20904
+ if (agent === "claude" && (manifest.commands !== undefined || lstatSync25(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync10(commands).length))
20753
20905
  unresolved("legacy command discovery requires retirement or a dedicated format adapter");
20754
20906
  const rootSkill = witness(join32(root2, "SKILL.md"));
20755
20907
  if (rootSkill !== null)
@@ -20771,7 +20923,7 @@ function resolveAgentDiscovery(options) {
20771
20923
  const installed = registrations === null ? {} : parseConfig(registrations, join32(home, ".claude/plugins/installed_plugins.json")).plugins;
20772
20924
  const commands = canonical7(join32(home, ".claude/commands"));
20773
20925
  safe4(commands);
20774
- if (lstatSync24(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync10(commands).length)
20926
+ if (lstatSync25(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync10(commands).length)
20775
20927
  unresolved("legacy home command discovery requires a dedicated format adapter");
20776
20928
  for (const [id, enabled] of Object.entries(config.enabledPlugins ?? {})) {
20777
20929
  if (enabled === false)
@@ -20791,7 +20943,7 @@ function resolveAgentDiscovery(options) {
20791
20943
  unresolved("unsupported plugin enablement");
20792
20944
  const split = id.lastIndexOf("@"), name = id.slice(0, split), marketplace = id.slice(split + 1);
20793
20945
  const market = config.marketplaces?.[marketplace] ?? (marketplace === "personal" ? { source_type: "local", source: home } : undefined);
20794
- if (split < 1 || market?.source_type !== "local" || typeof market.source !== "string" || !isAbsolute18(market.source))
20946
+ if (split < 1 || market?.source_type !== "local" || typeof market.source !== "string" || !isAbsolute19(market.source))
20795
20947
  unresolved("enabled plugin marketplace is not an explicit local source");
20796
20948
  const catalogText = witness(join32(market.source, ".agents/plugins/marketplace.json"));
20797
20949
  if (catalogText === null)
@@ -20807,13 +20959,13 @@ function resolveAgentDiscovery(options) {
20807
20959
  if ((config.plugin?.length ?? 0) > 0 || config.skills?.urls?.length)
20808
20960
  unresolved("external plugin or remote skill source");
20809
20961
  for (const path of config.skills?.paths ?? []) {
20810
- if (typeof path !== "string" || !isAbsolute18(path))
20962
+ if (typeof path !== "string" || !isAbsolute19(path))
20811
20963
  unresolved("relative or malformed added skill root");
20812
20964
  roots.add(path);
20813
20965
  }
20814
20966
  const localPlugins = join32(home, ".config/opencode/plugins");
20815
20967
  safe4(localPlugins);
20816
- if (lstatSync24(localPlugins, { throwIfNoEntry: false }) && readdirSync10(localPlugins).some((name) => name !== "skills-cli.js"))
20968
+ if (lstatSync25(localPlugins, { throwIfNoEntry: false }) && readdirSync10(localPlugins).some((name) => name !== "skills-cli.js"))
20817
20969
  unresolved("additional local plugin hooks require review");
20818
20970
  } else if (agent === "sumi") {
20819
20971
  if ((config.plugin?.length ?? 0) > 0 || (config.plugins?.length ?? 0) > 0 || sources.some((source) => source.path !== canonical7(configPath) && source.path !== canonical7(join32(sumiConfigDirectory(home), "sumi.jsonc")) && source.sha256 !== null))
@@ -20821,7 +20973,7 @@ function resolveAgentDiscovery(options) {
20821
20973
  } else if (agent === "hermes") {
20822
20974
  for (const directory of [join32(home, ".hermes/plugins"), join32(home, ".hermes/hermes-agent")]) {
20823
20975
  safe4(directory);
20824
- if (lstatSync24(directory, { throwIfNoEntry: false }))
20976
+ if (lstatSync25(directory, { throwIfNoEntry: false }))
20825
20977
  unresolved("installed runtime/plugin discovery requires reviewed source bindings");
20826
20978
  }
20827
20979
  if (Bun.which("hermes") || Object.keys(config.plugins ?? {}).length)
@@ -20831,11 +20983,11 @@ function resolveAgentDiscovery(options) {
20831
20983
  unresolved("custom extension or skill paths");
20832
20984
  const directory = join32(home, ".gemini/extensions");
20833
20985
  safe4(directory);
20834
- if (lstatSync24(directory, { throwIfNoEntry: false }))
20986
+ if (lstatSync25(directory, { throwIfNoEntry: false }))
20835
20987
  for (const name of readdirSync10(directory)) {
20836
20988
  const root2 = join32(directory, name);
20837
20989
  safe4(root2);
20838
- if (!lstatSync24(root2)?.isDirectory())
20990
+ if (!lstatSync25(root2)?.isDirectory())
20839
20991
  continue;
20840
20992
  const raw = witness(join32(root2, "gemini-extension.json"));
20841
20993
  if (raw === null)
@@ -20868,14 +21020,14 @@ function nativeRootMatch(path) {
20868
21020
  function physicalPath(path) {
20869
21021
  let cursor = resolve19(path);
20870
21022
  const suffix = [];
20871
- while (!lstatSync25(cursor, { throwIfNoEntry: false })) {
21023
+ while (!lstatSync26(cursor, { throwIfNoEntry: false })) {
20872
21024
  suffix.unshift(basename11(cursor));
20873
21025
  const parent = dirname20(cursor);
20874
21026
  if (parent === cursor)
20875
21027
  return resolve19(path);
20876
21028
  cursor = parent;
20877
21029
  }
20878
- return resolve19(realpathSync11(cursor), ...suffix);
21030
+ return resolve19(realpathSync12(cursor), ...suffix);
20879
21031
  }
20880
21032
  function contains(root2, path) {
20881
21033
  return path === root2 || path.startsWith(root2 + sep9);
@@ -20913,7 +21065,7 @@ function configuredRoots(home, explicitHome) {
20913
21065
  continue;
20914
21066
  }
20915
21067
  const nativeHome = join33(home, agent === "opencode" ? ".config/opencode" : `.${agent}`);
20916
- if (!lstatSync25(nativeHome, { throwIfNoEntry: false }))
21068
+ if (!lstatSync26(nativeHome, { throwIfNoEntry: false }))
20917
21069
  continue;
20918
21070
  roots.push(...resolveAgentDiscovery({ home, agent, canonical: physicalPath }).roots);
20919
21071
  }
@@ -21091,14 +21243,14 @@ function physicalImportPath(path) {
21091
21243
  suffix.unshift(basename12(ancestor));
21092
21244
  ancestor = dirname21(ancestor);
21093
21245
  }
21094
- return join34(realpathSync12(ancestor), ...suffix);
21246
+ return join34(realpathSync13(ancestor), ...suffix);
21095
21247
  }
21096
21248
  function assertDisjointImportPaths(source, destination) {
21097
- const sourcePath = realpathSync12(source);
21249
+ const sourcePath = realpathSync13(source);
21098
21250
  const destinationPath = physicalImportPath(destination);
21099
21251
  const contains2 = (parent, child) => {
21100
21252
  const path = relative7(parent, child);
21101
- return path === "" || !isAbsolute19(path) && path !== ".." && !path.startsWith(`..${sep10}`);
21253
+ return path === "" || !isAbsolute20(path) && path !== ".." && !path.startsWith(`..${sep10}`);
21102
21254
  };
21103
21255
  if (contains2(sourcePath, destinationPath) || contains2(destinationPath, sourcePath)) {
21104
21256
  throw new Error("Source and destination skill directories must not overlap");
@@ -21379,7 +21531,7 @@ function safeIsDirectory(path) {
21379
21531
  }
21380
21532
  }
21381
21533
  function isSafeRelativePath2(value) {
21382
- if (!value.trim() || isAbsolute19(value))
21534
+ if (!value.trim() || isAbsolute20(value))
21383
21535
  return false;
21384
21536
  const normalized = normalize4(value).replace(/\\/g, "/");
21385
21537
  return normalized !== ".." && !normalized.startsWith("../") && !normalized.includes("/../");
@@ -21594,7 +21746,7 @@ function discoverSkillsInDir(dir, source = "custom") {
21594
21746
  continue;
21595
21747
  let content;
21596
21748
  try {
21597
- content = readFileSync20(skillMdPath, "utf-8");
21749
+ content = readFileSync21(skillMdPath, "utf-8");
21598
21750
  } catch {
21599
21751
  continue;
21600
21752
  }
@@ -21631,7 +21783,7 @@ function findExtensionSkillPath(name) {
21631
21783
  continue;
21632
21784
  let content;
21633
21785
  try {
21634
- content = readFileSync20(skillMdPath, "utf-8");
21786
+ content = readFileSync21(skillMdPath, "utf-8");
21635
21787
  } catch {
21636
21788
  continue;
21637
21789
  }
@@ -21695,8 +21847,8 @@ function getAllTags(catalog) {
21695
21847
  return Array.from(tagSet).sort();
21696
21848
  }
21697
21849
  // src/lib/run-state.ts
21698
- import { createHash as createHash24, randomBytes } from "crypto";
21699
- import { existsSync as existsSync16, mkdirSync as mkdirSync11, readFileSync as readFileSync21, readdirSync as readdirSync13, statSync as statSync12, writeFileSync as writeFileSync10 } from "fs";
21850
+ import { createHash as createHash25, randomBytes } from "crypto";
21851
+ import { existsSync as existsSync16, mkdirSync as mkdirSync11, readFileSync as readFileSync23, readdirSync as readdirSync13, statSync as statSync12, writeFileSync as writeFileSync10 } from "fs";
21700
21852
  import { extname, join as join36, relative as relative8 } from "path";
21701
21853
  function createSkillRun(params, targetDir = process.cwd()) {
21702
21854
  const now = new Date;
@@ -21768,7 +21920,7 @@ function appendRunEvent(context, event, data = {}) {
21768
21920
  const line = JSON.stringify({ ts: new Date().toISOString(), event, ...data }) + `
21769
21921
  `;
21770
21922
  const path = join36(context.runDir, "events.ndjson");
21771
- const previous = existsSync16(path) ? readFileSync21(path, "utf-8") : "";
21923
+ const previous = existsSync16(path) ? readFileSync23(path, "utf-8") : "";
21772
21924
  writeFileSync10(path, previous + line);
21773
21925
  }
21774
21926
  function listSkillRuns(targetDir = process.cwd(), limit = 50) {
@@ -21818,11 +21970,11 @@ function collectRunArtifacts(context) {
21818
21970
  const artifacts = [];
21819
21971
  for (const path of walkFiles(context.exportDir)) {
21820
21972
  const stat2 = statSync12(path);
21821
- const bytes = readFileSync21(path);
21973
+ const bytes = readFileSync23(path);
21822
21974
  artifacts.push({
21823
21975
  path: toProjectRelative(context.targetDir, path),
21824
21976
  mime: mimeForPath(path),
21825
- sha256: createHash24("sha256").update(bytes).digest("hex"),
21977
+ sha256: createHash25("sha256").update(bytes).digest("hex"),
21826
21978
  sizeBytes: stat2.size
21827
21979
  });
21828
21980
  }
@@ -21833,7 +21985,7 @@ function readRunRecord(runDir) {
21833
21985
  if (!existsSync16(path))
21834
21986
  return null;
21835
21987
  try {
21836
- return JSON.parse(readFileSync21(path, "utf-8"));
21988
+ return JSON.parse(readFileSync23(path, "utf-8"));
21837
21989
  } catch {
21838
21990
  return null;
21839
21991
  }
@@ -41241,7 +41393,7 @@ function clone2(value) {
41241
41393
  return value === undefined ? undefined : JSON.parse(JSON.stringify(value));
41242
41394
  }
41243
41395
  // src/lib/canonical-json.ts
41244
- import { createHash as createHash25 } from "crypto";
41396
+ import { createHash as createHash26 } from "crypto";
41245
41397
  function canonicalJson2(value, maximumBytes = 2 * 1024 * 1024) {
41246
41398
  return canonicalJsonAtDepth(value, maximumBytes, 64);
41247
41399
  }
@@ -41285,7 +41437,7 @@ function canonicalJsonAtDepth(value, maximumBytes, maximumDepth) {
41285
41437
  return visit3(value, 0);
41286
41438
  }
41287
41439
  function canonicalJsonSha256(value, maximumBytes) {
41288
- return createHash25("sha256").update(canonicalJson2(value, maximumBytes)).digest("hex");
41440
+ return createHash26("sha256").update(canonicalJson2(value, maximumBytes)).digest("hex");
41289
41441
  }
41290
41442
 
41291
41443
  // src/lib/remote-recurring-contract.ts
@@ -43348,7 +43500,7 @@ async function createRemoteSkillsClient(env = process.env) {
43348
43500
  return connection ? new RemoteSkillsClient(connection.apiKey, connection.apiOrigin) : null;
43349
43501
  }
43350
43502
  // src/lib/scheduler.ts
43351
- import { existsSync as existsSync17, readFileSync as readFileSync23, writeFileSync as writeFileSync11, mkdirSync as mkdirSync12 } from "fs";
43503
+ import { existsSync as existsSync17, readFileSync as readFileSync25, writeFileSync as writeFileSync11, mkdirSync as mkdirSync12 } from "fs";
43352
43504
  import { join as join37 } from "path";
43353
43505
  function getSchedulesPath(targetDir = process.cwd()) {
43354
43506
  return join37(targetDir, ".skills", "schedules.json");
@@ -43357,7 +43509,7 @@ function loadSchedules(targetDir = process.cwd()) {
43357
43509
  const path = getSchedulesPath(targetDir);
43358
43510
  if (existsSync17(path)) {
43359
43511
  try {
43360
- return JSON.parse(readFileSync23(path, "utf-8"));
43512
+ return JSON.parse(readFileSync25(path, "utf-8"));
43361
43513
  } catch {}
43362
43514
  }
43363
43515
  return { version: 1, schedules: [] };
@@ -43552,7 +43704,7 @@ function recordScheduleRun(id, status, targetDir) {
43552
43704
  saveSchedules(data, targetDir);
43553
43705
  }
43554
43706
  // src/lib/revision.ts
43555
- import { createHash as createHash26 } from "crypto";
43707
+ import { createHash as createHash27 } from "crypto";
43556
43708
  var REVISION_ID_PATTERN = /^[0-9a-f]{64}$/;
43557
43709
  function revisionIdOf(content) {
43558
43710
  const canonicalContent = {
@@ -43574,13 +43726,13 @@ function revisionIdOf(content) {
43574
43726
  canonicalContent.replacementSlug = content.replacementSlug ?? null;
43575
43727
  }
43576
43728
  const canonical7 = JSON.stringify(canonicalContent);
43577
- return createHash26("sha256").update(canonical7).digest("hex");
43729
+ return createHash27("sha256").update(canonical7).digest("hex");
43578
43730
  }
43579
43731
  function revisionIdOfRecord(record8) {
43580
43732
  return revisionIdOf(record8);
43581
43733
  }
43582
43734
  // src/lib/pull.ts
43583
- import { existsSync as existsSync18, mkdirSync as mkdirSync13, mkdtempSync as mkdtempSync3, readFileSync as readFileSync25, renameSync as renameSync7, rmSync as rmSync5, writeFileSync as writeFileSync12 } from "fs";
43735
+ import { existsSync as existsSync18, mkdirSync as mkdirSync13, mkdtempSync as mkdtempSync3, readFileSync as readFileSync26, renameSync as renameSync7, rmSync as rmSync5, writeFileSync as writeFileSync12 } from "fs";
43584
43736
  import { dirname as dirname22, join as join38 } from "path";
43585
43737
 
43586
43738
  // src/lib/skill-bundles.ts
@@ -43780,7 +43932,7 @@ function reconcileTombstone(slug2, corpusOptions) {
43780
43932
  }
43781
43933
  function readPullMarker(dir) {
43782
43934
  try {
43783
- return JSON.parse(readFileSync25(join38(dir, PULL_MARKER_FILE), "utf-8"));
43935
+ return JSON.parse(readFileSync26(join38(dir, PULL_MARKER_FILE), "utf-8"));
43784
43936
  } catch {
43785
43937
  return null;
43786
43938
  }
@@ -44017,7 +44169,7 @@ function splitNameVersion(raw) {
44017
44169
  return version2 ? { name, version: version2 } : { name };
44018
44170
  }
44019
44171
  // src/lib/recurring-surface.ts
44020
- import { isAbsolute as isAbsolute20 } from "path";
44172
+ import { isAbsolute as isAbsolute21 } from "path";
44021
44173
 
44022
44174
  // src/lib/remote-invitation-recovery.ts
44023
44175
  class InvitationEmailInputError extends Error {
@@ -44115,7 +44267,7 @@ async function requestInvitationEmail(origin, action, input2) {
44115
44267
  }
44116
44268
 
44117
44269
  // src/lib/remote-private-publications.ts
44118
- import { createHash as createHash27 } from "crypto";
44270
+ import { createHash as createHash28 } from "crypto";
44119
44271
  var PRIVATE_PUBLICATION_MAX_BYTES = 16 * 1024 * 1024;
44120
44272
  var failures2 = {
44121
44273
  INVALID_REQUEST: [400, "The publication request is invalid."],
@@ -44162,7 +44314,7 @@ var hash3 = (v) => typeof v === "string" && /^[a-f0-9]{64}$/.test(v);
44162
44314
  var record9 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
44163
44315
  var exact = (v, keys) => record9(v) && Object.keys(v).sort().join(",") === keys.sort().join(",");
44164
44316
  var date5 = (v) => typeof v === "string" && /^\d{4}-\d\d-\d\dT[0-9:.]+(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(v) && Number.isFinite(Date.parse(v));
44165
- var publicationSha256 = (bytes) => createHash27("sha256").update(bytes).digest("hex");
44317
+ var publicationSha256 = (bytes) => createHash28("sha256").update(bytes).digest("hex");
44166
44318
  function checkedPublicationDeclaration(value) {
44167
44319
  if (!exact(value, ["idempotencyKey", "version", "expectedCurrentVersionId", "manifestText", "archiveSha256", "archiveByteSize"]) || !publicationUuid(value.idempotencyKey) || !(value.expectedCurrentVersionId === null || publicationUuid(value.expectedCurrentVersionId)) || typeof value.version !== "string" || !value.version || value.version.length > 128 || /[\p{Cc}\p{Cs}]/u.test(value.version) || typeof value.manifestText !== "string" || Buffer.byteLength(value.manifestText) > 16384 || !hash3(value.archiveSha256) || !Number.isSafeInteger(value.archiveByteSize) || Number(value.archiveByteSize) < 1 || Number(value.archiveByteSize) > PRIVATE_PUBLICATION_MAX_BYTES)
44168
44320
  return bad();
@@ -44676,7 +44828,7 @@ var stateSchema = exports_external.object({
44676
44828
  var uuid13 = exports_external.string().regex(/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/);
44677
44829
  var context = { userId: uuid13.optional(), membershipId: uuid13.optional() };
44678
44830
  var page2 = { limit: exports_external.number().int().min(1).max(100).optional(), cursor: exports_external.string().min(1).max(2048).optional() };
44679
- var directory = exports_external.string().max(4096).refine(isAbsolute20, "Use an absolute recovery directory");
44831
+ var directory = exports_external.string().max(4096).refine(isAbsolute21, "Use an absolute recovery directory");
44680
44832
  var email4 = exports_external.string().trim().toLowerCase().email().max(254);
44681
44833
  var code = exports_external.string().regex(/^\d{6}$/);
44682
44834
  var recurringSurfaceSchemas = {
@@ -46028,11 +46180,11 @@ function isApiMode(env = process.env) {
46028
46180
  }
46029
46181
  }
46030
46182
  // src/lib/native-storage.ts
46031
- import { createHash as createHash28, createHmac as createHmac2 } from "crypto";
46183
+ import { createHash as createHash29, createHmac as createHmac2 } from "crypto";
46032
46184
  import {
46033
46185
  existsSync as existsSync20,
46034
46186
  mkdirSync as mkdirSync16,
46035
- readFileSync as readFileSync26,
46187
+ readFileSync as readFileSync27,
46036
46188
  readdirSync as readdirSync14,
46037
46189
  statSync as statSync13,
46038
46190
  writeFileSync as writeFileSync14
@@ -46199,12 +46351,12 @@ function exportSkillsLocalSnapshot(targetDir = process.cwd(), options = {}) {
46199
46351
  const files = [];
46200
46352
  if (existsSync20(projectStateDir)) {
46201
46353
  for (const filePath of walkFiles2(projectStateDir)) {
46202
- const bytes = readFileSync26(filePath);
46354
+ const bytes = readFileSync27(filePath);
46203
46355
  const relativePath = toPosix(relative10(targetDir, filePath));
46204
46356
  files.push({
46205
46357
  path: relativePath,
46206
46358
  sizeBytes: bytes.byteLength,
46207
- sha256: createHash28("sha256").update(bytes).digest("hex"),
46359
+ sha256: createHash29("sha256").update(bytes).digest("hex"),
46208
46360
  ...options.includeFileContents ? { contentBase64: Buffer.from(bytes).toString("base64") } : {}
46209
46361
  });
46210
46362
  }
@@ -46229,7 +46381,7 @@ function importSkillsLocalSnapshot(snapshot2, targetDir = process.cwd(), options
46229
46381
  continue;
46230
46382
  }
46231
46383
  const bytes = Buffer.from(file2.contentBase64, "base64");
46232
- const hash4 = createHash28("sha256").update(bytes).digest("hex");
46384
+ const hash4 = createHash29("sha256").update(bytes).digest("hex");
46233
46385
  if (hash4 !== file2.sha256) {
46234
46386
  throw new Error(`Snapshot file checksum mismatch: ${file2.path}`);
46235
46387
  }
@@ -46561,7 +46713,7 @@ function toIsoString(value) {
46561
46713
  return Number.isNaN(date6.getTime()) ? value : date6.toISOString();
46562
46714
  }
46563
46715
  function sha256Hex2(value) {
46564
- return createHash28("sha256").update(value).digest("hex");
46716
+ return createHash29("sha256").update(value).digest("hex");
46565
46717
  }
46566
46718
  function normalizeHeaders(headers) {
46567
46719
  const result = {};
@@ -46613,15 +46765,15 @@ function toArrayBuffer(bytes) {
46613
46765
  return buffer;
46614
46766
  }
46615
46767
  // src/lib/station-snapshot.ts
46616
- import { createHash as createHash29 } from "crypto";
46768
+ import { createHash as createHash30 } from "crypto";
46617
46769
  import {
46618
46770
  copyFileSync,
46619
46771
  mkdirSync as mkdirSync17,
46620
- readFileSync as readFileSync27,
46772
+ readFileSync as readFileSync28,
46621
46773
  statSync as statSync15,
46622
46774
  writeFileSync as writeFileSync15
46623
46775
  } from "fs";
46624
- import { dirname as dirname26, isAbsolute as isAbsolute21, relative as relative11, resolve as resolve21, sep as sep13 } from "path";
46776
+ import { dirname as dirname26, isAbsolute as isAbsolute22, relative as relative11, resolve as resolve21, sep as sep13 } from "path";
46625
46777
 
46626
46778
  // src/lib/portable-snapshot-filter.ts
46627
46779
  import { readdirSync as readdirSync15, statSync as statSync14 } from "fs";
@@ -46788,7 +46940,7 @@ function validateStationId(stationId) {
46788
46940
  }
46789
46941
  }
46790
46942
  function sha256File(filePath) {
46791
- return createHash29("sha256").update(readFileSync27(filePath)).digest("hex");
46943
+ return createHash30("sha256").update(readFileSync28(filePath)).digest("hex");
46792
46944
  }
46793
46945
  function scanHome(definition, homesRoot) {
46794
46946
  const homePath = homePathFor(definition, homesRoot);
@@ -46887,7 +47039,7 @@ function writeStationSnapshot(options) {
46887
47039
  for (const plan of plans) {
46888
47040
  const destination = resolve21(repoRoot, plan.destination);
46889
47041
  const destinationRelative = relative11(repoRoot, destination);
46890
- if (destinationRelative.startsWith("..") || destinationRelative.startsWith(sep13) || isAbsolute21(destinationRelative)) {
47042
+ if (destinationRelative.startsWith("..") || destinationRelative.startsWith(sep13) || isAbsolute22(destinationRelative)) {
46891
47043
  throw new StationSnapshotError("DESTINATION_ESCAPE", `destination escapes repo root: ${plan.destination}`);
46892
47044
  }
46893
47045
  let existingDigest = null;
@@ -46939,12 +47091,12 @@ function writeStationSnapshot(options) {
46939
47091
  };
46940
47092
  }
46941
47093
  // src/lib/station-hydrate.ts
46942
- import { createHash as createHash30 } from "crypto";
47094
+ import { createHash as createHash31 } from "crypto";
46943
47095
  import {
46944
47096
  copyFileSync as copyFileSync2,
46945
47097
  mkdirSync as mkdirSync18,
46946
47098
  readdirSync as readdirSync16,
46947
- readFileSync as readFileSync28,
47099
+ readFileSync as readFileSync29,
46948
47100
  statSync as statSync16,
46949
47101
  writeFileSync as writeFileSync16
46950
47102
  } from "fs";
@@ -46963,7 +47115,7 @@ function readSnapshotManifest(repoRoot, stationId) {
46963
47115
  const manifestPath = join42(snapshotRoot, "sync-manifest.json");
46964
47116
  let manifest;
46965
47117
  try {
46966
- manifest = JSON.parse(readFileSync28(manifestPath, "utf8"));
47118
+ manifest = JSON.parse(readFileSync29(manifestPath, "utf8"));
46967
47119
  } catch (error61) {
46968
47120
  fail2("MANIFEST_UNREADABLE", `cannot read snapshot manifest: ${manifestPath}: ${error61.message}`);
46969
47121
  }
@@ -47099,7 +47251,7 @@ function planStationHydration(stationId, repoRoot) {
47099
47251
  for (const copy of copies) {
47100
47252
  let isStub = false;
47101
47253
  try {
47102
- isStub = isPointerSkillMd(readFileSync28(copy.fullPath, "utf8"));
47254
+ isStub = isPointerSkillMd(readFileSync29(copy.fullPath, "utf8"));
47103
47255
  } catch {
47104
47256
  isStub = false;
47105
47257
  }
@@ -47145,7 +47297,7 @@ function skillSha256(skill) {
47145
47297
  return sha256File(skill.files[0].winner.fullPath);
47146
47298
  }
47147
47299
  const joined = skill.files.map((file2) => sha256File(file2.winner.fullPath));
47148
- return createHash30("sha256").update(joined.sort().join(`
47300
+ return createHash31("sha256").update(joined.sort().join(`
47149
47301
  `)).digest("hex");
47150
47302
  }
47151
47303
  function writeStationHydration(options) {
@@ -47237,23 +47389,23 @@ function writeStationHydration(options) {
47237
47389
  };
47238
47390
  }
47239
47391
  // src/lib/private-publication-recovery.ts
47240
- import { constants as constants14, closeSync as closeSync14, fsyncSync as fsyncSync6, fstatSync as fstatSync14, lstatSync as lstatSync26, mkdirSync as mkdirSync19, openSync as openSync14, readSync as readSync12, realpathSync as realpathSync13, renameSync as renameSync8, unlinkSync as unlinkSync6, writeFileSync as writeFileSync17 } from "fs";
47241
- import { dirname as dirname28, isAbsolute as isAbsolute22, join as join43, resolve as resolve23 } from "path";
47392
+ import { constants as constants15, closeSync as closeSync15, fsyncSync as fsyncSync7, fstatSync as fstatSync15, lstatSync as lstatSync27, mkdirSync as mkdirSync19, openSync as openSync15, readSync as readSync12, realpathSync as realpathSync14, renameSync as renameSync8, unlinkSync as unlinkSync6, writeFileSync as writeFileSync17 } from "fs";
47393
+ import { dirname as dirname28, isAbsolute as isAbsolute23, join as join43, resolve as resolve23 } from "path";
47242
47394
  import { randomUUID as randomUUID5 } from "crypto";
47243
47395
  var fail3 = () => {
47244
47396
  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.");
47245
47397
  };
47246
47398
  function safeDirectory(directory2) {
47247
- if (!isAbsolute22(directory2) || directory2 !== resolve23(directory2) || realpathSync13(directory2) !== directory2)
47399
+ if (!isAbsolute23(directory2) || directory2 !== resolve23(directory2) || realpathSync14(directory2) !== directory2)
47248
47400
  return fail3();
47249
47401
  for (let path = directory2;; path = dirname28(path)) {
47250
- const stat2 = lstatSync26(path);
47402
+ const stat2 = lstatSync27(path);
47251
47403
  if (!stat2.isDirectory() || stat2.isSymbolicLink())
47252
47404
  return fail3();
47253
47405
  if (path === dirname28(path))
47254
47406
  break;
47255
47407
  }
47256
- const own2 = lstatSync26(directory2);
47408
+ const own2 = lstatSync27(directory2);
47257
47409
  if ((own2.mode & 63) !== 0 || process.getuid && own2.uid !== process.getuid())
47258
47410
  return fail3();
47259
47411
  return { dev: own2.dev, ino: own2.ino };
@@ -47265,9 +47417,9 @@ function unchangedDirectory(directory2, identity5) {
47265
47417
  }
47266
47418
  function readOwned(directory2, name, max) {
47267
47419
  const identity5 = safeDirectory(directory2), file2 = join43(directory2, name);
47268
- const fd = openSync14(file2, constants14.O_RDONLY | constants14.O_NOFOLLOW);
47420
+ const fd = openSync15(file2, constants15.O_RDONLY | constants15.O_NOFOLLOW);
47269
47421
  try {
47270
- const stat2 = fstatSync14(fd);
47422
+ const stat2 = fstatSync15(fd);
47271
47423
  if (!stat2.isFile() || stat2.nlink !== 1 || stat2.size > max || stat2.size < 1 || (stat2.mode & 63) !== 0 || process.getuid && stat2.uid !== process.getuid())
47272
47424
  return fail3();
47273
47425
  const buffer = Buffer.alloc(Math.min(max, stat2.size) + 1);
@@ -47278,22 +47430,22 @@ function readOwned(directory2, name, max) {
47278
47430
  break;
47279
47431
  length += count;
47280
47432
  }
47281
- const bytes = buffer.subarray(0, length), after = fstatSync14(fd);
47433
+ const bytes = buffer.subarray(0, length), after = fstatSync15(fd);
47282
47434
  unchangedDirectory(directory2, identity5);
47283
47435
  if (bytes.length !== stat2.size || stat2.size !== after.size || stat2.mtimeMs !== after.mtimeMs || stat2.ctimeMs !== after.ctimeMs)
47284
47436
  return fail3();
47285
47437
  return bytes;
47286
47438
  } finally {
47287
- closeSync14(fd);
47439
+ closeSync15(fd);
47288
47440
  }
47289
47441
  }
47290
47442
  function writeOwned(directory2, name, bytes) {
47291
- const fd = openSync14(join43(directory2, name), constants14.O_WRONLY | constants14.O_CREAT | constants14.O_EXCL | constants14.O_NOFOLLOW, 384);
47443
+ const fd = openSync15(join43(directory2, name), constants15.O_WRONLY | constants15.O_CREAT | constants15.O_EXCL | constants15.O_NOFOLLOW, 384);
47292
47444
  try {
47293
47445
  writeFileSync17(fd, bytes);
47294
- fsyncSync6(fd);
47446
+ fsyncSync7(fd);
47295
47447
  } finally {
47296
- closeSync14(fd);
47448
+ closeSync15(fd);
47297
47449
  }
47298
47450
  }
47299
47451
  function save(directory2, value) {
@@ -47302,11 +47454,11 @@ function save(directory2, value) {
47302
47454
  `);
47303
47455
  unchangedDirectory(directory2, identity5);
47304
47456
  renameSync8(join43(directory2, temporary), join43(directory2, "receipt.json"));
47305
- const fd = openSync14(directory2, constants14.O_RDONLY | constants14.O_NOFOLLOW);
47457
+ const fd = openSync15(directory2, constants15.O_RDONLY | constants15.O_NOFOLLOW);
47306
47458
  try {
47307
- fsyncSync6(fd);
47459
+ fsyncSync7(fd);
47308
47460
  } finally {
47309
- closeSync14(fd);
47461
+ closeSync15(fd);
47310
47462
  }
47311
47463
  }
47312
47464
  function bind(client2, receipt) {
@@ -47317,20 +47469,20 @@ async function locked(directory2, action) {
47317
47469
  const identity5 = safeDirectory(directory2), file2 = join43(directory2, "operation.lock");
47318
47470
  let fd;
47319
47471
  try {
47320
- fd = openSync14(file2, constants14.O_WRONLY | constants14.O_CREAT | constants14.O_EXCL | constants14.O_NOFOLLOW, 384);
47472
+ fd = openSync15(file2, constants15.O_WRONLY | constants15.O_CREAT | constants15.O_EXCL | constants15.O_NOFOLLOW, 384);
47321
47473
  } catch {
47322
47474
  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.");
47323
47475
  }
47324
- const lock = fstatSync14(fd);
47476
+ const lock = fstatSync15(fd);
47325
47477
  try {
47326
47478
  writeFileSync17(fd, JSON.stringify({ pid: process.pid }) + `
47327
47479
  `);
47328
- fsyncSync6(fd);
47480
+ fsyncSync7(fd);
47329
47481
  return await action();
47330
47482
  } finally {
47331
- closeSync14(fd);
47483
+ closeSync15(fd);
47332
47484
  unchangedDirectory(directory2, identity5);
47333
- const now = lstatSync26(file2);
47485
+ const now = lstatSync27(file2);
47334
47486
  if (now.dev !== lock.dev || now.ino !== lock.ino || !now.isFile() || now.isSymbolicLink())
47335
47487
  fail3();
47336
47488
  unlinkSync6(file2);
@@ -47382,15 +47534,15 @@ async function preparePrivatePublication(client2, sourceDirectory, recoveryDirec
47382
47534
  phase: "prepared",
47383
47535
  intent: null
47384
47536
  };
47385
- if (!isAbsolute22(recoveryDirectory) || resolve23(recoveryDirectory) !== recoveryDirectory || realpathSync13(dirname28(recoveryDirectory)) !== dirname28(recoveryDirectory))
47537
+ if (!isAbsolute23(recoveryDirectory) || resolve23(recoveryDirectory) !== recoveryDirectory || realpathSync14(dirname28(recoveryDirectory)) !== dirname28(recoveryDirectory))
47386
47538
  return fail3();
47387
47539
  mkdirSync19(recoveryDirectory, { mode: 448 });
47388
47540
  safeDirectory(recoveryDirectory);
47389
- const parent = openSync14(dirname28(recoveryDirectory), constants14.O_RDONLY | constants14.O_NOFOLLOW);
47541
+ const parent = openSync15(dirname28(recoveryDirectory), constants15.O_RDONLY | constants15.O_NOFOLLOW);
47390
47542
  try {
47391
- fsyncSync6(parent);
47543
+ fsyncSync7(parent);
47392
47544
  } finally {
47393
- closeSync14(parent);
47545
+ closeSync15(parent);
47394
47546
  }
47395
47547
  writeOwned(recoveryDirectory, "bundle.tgz", packed.bytes);
47396
47548
  save(recoveryDirectory, receipt);
@@ -47473,7 +47625,7 @@ async function inspectLocked(client2, directory2, cancel) {
47473
47625
  return privatePublicationResult(directory2, receipt);
47474
47626
  }
47475
47627
  // src/lib/skill-context.ts
47476
- import { createHash as createHash31 } from "crypto";
47628
+ import { createHash as createHash32 } from "crypto";
47477
47629
  import { resolve as resolve24 } from "path";
47478
47630
  function words(value) {
47479
47631
  return new Set(value.toLowerCase().match(/[a-z0-9]+/g) ?? []);
@@ -47566,7 +47718,7 @@ ${content}`;
47566
47718
  `);
47567
47719
  const receipt = {
47568
47720
  schemaVersion: 1,
47569
- id: createHash31("sha256").update(JSON.stringify({ profile: profile.profileRevision, sessionId, selections, omitted })).digest("hex"),
47721
+ id: createHash32("sha256").update(JSON.stringify({ profile: profile.profileRevision, sessionId, selections, omitted })).digest("hex"),
47570
47722
  profileId: profile.profileId,
47571
47723
  profileRevision: profile.profileRevision,
47572
47724
  authority: profile.authority,
@@ -47582,9 +47734,9 @@ ${content}`;
47582
47734
  return { context: context2, selections, omitted, receipt };
47583
47735
  }
47584
47736
  // src/lib/session-reconciliation.ts
47585
- import { createHash as createHash32 } from "crypto";
47737
+ import { createHash as createHash33 } from "crypto";
47586
47738
  var SESSION_RECONCILIATION_PLAN_TTL_MS = 5 * 60 * 1000;
47587
- var digest3 = (value) => createHash32("sha256").update(JSON.stringify(value)).digest("hex");
47739
+ var digest3 = (value) => createHash33("sha256").update(JSON.stringify(value)).digest("hex");
47588
47740
  function exactTimestamp(value) {
47589
47741
  const parsed = value === undefined ? Number.NaN : Date.parse(value);
47590
47742
  if (!Number.isFinite(parsed) || new Date(parsed).toISOString() !== value) {