@hasna/skills 0.10.24 → 0.10.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/mcp.js CHANGED
@@ -20019,7 +20019,7 @@ var package_default;
20019
20019
  var init_package = __esm(() => {
20020
20020
  package_default = {
20021
20021
  name: "@hasna/skills",
20022
- version: "0.10.24",
20022
+ version: "0.10.26",
20023
20023
  description: "Skills library for AI coding agents",
20024
20024
  type: "module",
20025
20025
  bin: {
@@ -38266,6 +38266,18 @@ function assertAgentPolicyCollections(policy) {
38266
38266
  if (control.appSha256 !== undefined)
38267
38267
  requireBound(typeof control.appSha256 === "string" && /^[a-f0-9]{64}$/.test(control.appSha256));
38268
38268
  }
38269
+ if (bridge.codexInactivePlugins !== undefined) {
38270
+ const controls = array3(bridge.codexInactivePlugins, 4096), ids = new Set;
38271
+ requireBound(controls.length === 0 || object4(bridge.codexPluginSkillReview) && bridge.codexPluginSkillReview.version === "codex-cli 0.160.0" && typeof bridge.codexPluginSkillReview.catalogSha256 === "string" && /^[a-f0-9]{64}$/.test(bridge.codexPluginSkillReview.catalogSha256));
38272
+ for (const control of controls) {
38273
+ requireBound(object4(control) && Object.keys(control).every((key) => ["pluginId", "namespace", "pluginParent", "sourceType", "sourceSha256"].includes(key)));
38274
+ text(control.pluginId, 1024);
38275
+ text(control.namespace, 64);
38276
+ text(control.pluginParent);
38277
+ requireBound(!ids.has(control.pluginId) && isAbsolute3(control.pluginParent) && resolve2(control.pluginParent) === control.pluginParent && ["local", "git", "npm"].includes(control.sourceType) && typeof control.sourceSha256 === "string" && /^[a-f0-9]{64}$/.test(control.sourceSha256));
38278
+ ids.add(control.pluginId);
38279
+ }
38280
+ }
38269
38281
  if (bridge.disabledBuiltins !== undefined)
38270
38282
  for (const builtin of array3(bridge.disabledBuiltins, AGENT_POLICY_LIMITS.builtinNames)) {
38271
38283
  requireBound(object4(builtin));
@@ -38278,6 +38290,25 @@ function assertAgentPolicyCollections(policy) {
38278
38290
  text(agent, 128);
38279
38291
  requireBound(object4(value));
38280
38292
  text(value.agent, 128);
38293
+ if (value.codexInstallationInputs !== undefined) {
38294
+ const proof = record3(value.codexInstallationInputs, 4), inputs = array3(proof.plugins, 4096), ids = new Set;
38295
+ requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && proof.version === "codex-cli 0.160.0" && typeof proof.catalogSha256 === "string" && /^[a-f0-9]{64}$/.test(proof.catalogSha256) && inputs.length > 0 && object4(bridge.codexPluginSkillReview) && bridge.codexPluginSkillReview.version === proof.version && bridge.codexPluginSkillReview.catalogSha256 === proof.catalogSha256);
38296
+ for (const input2 of inputs) {
38297
+ requireBound(object4(input2) && Object.keys(input2).every((key) => ["pluginId", "namespace", "pluginParent", "sourceRoot", "sourceSha256"].includes(key)));
38298
+ text(input2.pluginId, 1024);
38299
+ text(input2.namespace, 64);
38300
+ text(input2.pluginParent);
38301
+ text(input2.sourceRoot);
38302
+ requireBound(!ids.has(input2.pluginId) && [input2.pluginParent, input2.sourceRoot].every((path) => isAbsolute3(path) && resolve2(path) === path) && typeof input2.sourceSha256 === "string" && /^[a-f0-9]{64}$/.test(input2.sourceSha256));
38303
+ ids.add(input2.pluginId);
38304
+ }
38305
+ if (proof.directories !== undefined)
38306
+ for (const directory of array3(proof.directories, AGENT_POLICY_LIMITS.discoveryDirectories)) {
38307
+ requireBound(object4(directory));
38308
+ text(directory.path);
38309
+ requireBound(directory.sha256 === null || typeof directory.sha256 === "string" && /^[a-f0-9]{64}$/.test(directory.sha256));
38310
+ }
38311
+ }
38281
38312
  for (const root of array3(value.roots, AGENT_POLICY_LIMITS.discoveryRoots))
38282
38313
  text(root);
38283
38314
  for (const source of array3(value.sources, AGENT_POLICY_LIMITS.discoverySources)) {
@@ -45378,7 +45409,7 @@ function safe(path) {
45378
45409
  function same(before, after) {
45379
45410
  return Boolean(after && after.isDirectory() && before.dev === after.dev && before.ino === after.ino && before.mtimeMs === after.mtimeMs && before.ctimeMs === after.ctimeMs);
45380
45411
  }
45381
- function capture(path, budget) {
45412
+ function capture(path, budget, excludedRoots) {
45382
45413
  safe(path);
45383
45414
  const root = lstatSync5(path, { throwIfNoEntry: false });
45384
45415
  if (!root)
@@ -45407,7 +45438,7 @@ function capture(path, budget) {
45407
45438
  budget.bytes += Buffer.byteLength(row);
45408
45439
  need(budget.bytes <= AGENT_POLICY_LIMITS.discoveryDirectoryBytes, "Native discovery directory metadata limit exceeded");
45409
45440
  hash2.update(row);
45410
- if (stat.isDirectory())
45441
+ if (stat.isDirectory() && !excludedRoots.includes(child))
45411
45442
  walk(child, childRelative, stat, depth + 1);
45412
45443
  }
45413
45444
  need(same(before, lstatSync5(current, { throwIfNoEntry: false })), "Native discovery directory changed while reading");
@@ -45416,16 +45447,18 @@ function capture(path, budget) {
45416
45447
  safe(path);
45417
45448
  return { path, sha256: hash2.digest("hex") };
45418
45449
  }
45419
- function captureDiscoveryDirectories(paths) {
45450
+ function captureDiscoveryDirectories(paths, excludedRoots = []) {
45420
45451
  need(Array.isArray(paths) && paths.length <= AGENT_POLICY_LIMITS.discoveryDirectories && new Set(paths).size === paths.length, "Invalid native discovery directory collection");
45421
45452
  const budget = { entries: 0, bytes: 0 };
45422
- return paths.map((path) => capture(path, budget));
45453
+ for (const root of excludedRoots)
45454
+ safe(root);
45455
+ return paths.map((path) => capture(path, budget, excludedRoots));
45423
45456
  }
45424
- function verifyDiscoveryDirectories(directories) {
45457
+ function verifyDiscoveryDirectories(directories, excludedRoots = []) {
45425
45458
  need(Array.isArray(directories) && directories.length <= AGENT_POLICY_LIMITS.discoveryDirectories, "Invalid native discovery directory collection");
45426
45459
  for (const directory of directories)
45427
45460
  need(directory && typeof directory === "object" && (directory.sha256 === null || typeof directory.sha256 === "string" && /^[a-f0-9]{64}$/.test(directory.sha256)), "Invalid native discovery directory digest");
45428
- const current = captureDiscoveryDirectories(directories.map((directory) => directory.path));
45461
+ const current = captureDiscoveryDirectories(directories.map((directory) => directory.path), excludedRoots);
45429
45462
  for (let i = 0;i < directories.length; i++)
45430
45463
  need(current[i].sha256 === directories[i].sha256, `Native discovery directory membership changed; run skills hook install with a fresh discovery review: ${directories[i].path}`);
45431
45464
  }
@@ -47413,6 +47446,17 @@ function hashClaudeSettingsReplacementV3(text2, budget) {
47413
47446
  budget.remaining -= bytes;
47414
47447
  return settingsDigest(text2, 3);
47415
47448
  }
47449
+ function hashNativeJsonControls(text2, excludedMetadata) {
47450
+ need2(Buffer.byteLength(text2) <= CLAUDE_SETTINGS_WITNESS_LIMITS.bytes, "exceeds its byte limit");
47451
+ const value = parse8(text2);
47452
+ value.entries = value.entries.filter(([key, child]) => {
47453
+ if (key !== excludedMetadata)
47454
+ return true;
47455
+ need2(child.kind === "string" && child.value.length <= 128, "has invalid version metadata");
47456
+ return false;
47457
+ });
47458
+ return createHash8("sha256").update("hasna.skills.native-json-controls.v1\x00").update(JSON.stringify(canonical2(value))).digest("hex");
47459
+ }
47416
47460
  var CLAUDE_SETTINGS_WITNESS_LIMITS, sameFile = (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, BOOLEAN_PREFERENCES, ENUM_PREFERENCES, BUILTIN_MODEL_SELECTIONS, PERSISTED_EFFORT_LEVELS;
47417
47461
  var init_claude_settings_witness = __esm(() => {
47418
47462
  CLAUDE_SETTINGS_WITNESS_LIMITS = Object.freeze({ bytes: 1024 * 1024, rows: 1024, depth: 32, nodes: 65536, stringCharacters: 16384, pathCharacters: 4096 });
@@ -47499,12 +47543,47 @@ var init_codex_hook_rpc = __esm(() => {
47499
47543
  });
47500
47544
 
47501
47545
  // src/lib/codex-native-skill-catalog.ts
47546
+ function codexPluginSourceIsConfigControlled(plugin) {
47547
+ const remoteRealms = ["openai-curated-remote", "created-by-me-remote", "workspace-directory", "workspace-shared-with-me", "workspace-shared-with-me-private", "workspace-shared-with-me-unlisted"];
47548
+ return Boolean(plugin.sourceType && ["local", "git", "npm"].includes(plugin.sourceType) && plugin.sourceSha256 && /^[a-f0-9]{64}$/.test(plugin.sourceSha256) && !plugin.remotePluginId && !remoteRealms.includes(plugin.id.slice(plugin.id.lastIndexOf("@") + 1)));
47549
+ }
47502
47550
  var init_codex_native_skill_catalog = __esm(() => {
47503
47551
  init_codex_hook_rpc();
47504
47552
  init_codex_native_compatibility();
47553
+ init_claude_settings_witness();
47505
47554
  });
47506
47555
 
47507
47556
  // src/lib/codex-plugin-skill-controls.ts
47557
+ import { basename as basename5, dirname as dirname10, join as join16, relative as relative4, resolve as resolve9, sep as sep4 } from "path";
47558
+ import { lstatSync as lstatSync11, readdirSync as readdirSync6, readlinkSync as readlinkSync3, realpathSync as realpathSync3 } from "fs";
47559
+ function refuse() {
47560
+ throw new Error("CODEX_NATIVE_SKILL_IDENTITY_UNSUPPORTED: review native plugin names and hook controls");
47561
+ }
47562
+ function sourceInputUnchanged(input2, cache, read) {
47563
+ try {
47564
+ const parts = relative4(cache, input2.pluginParent).split(sep4);
47565
+ if (parts.length !== 2 || parts.some((part) => !identifier2(part)) || parts[1] !== input2.namespace || input2.pluginId !== `${parts[1]}@${parts[0]}` || !codexPluginSourceIsConfigControlled({ id: input2.pluginId, sourceType: "local", sourceSha256: input2.sourceSha256 }) || input2.sourceSha256 !== hashNativeJsonControls(JSON.stringify({ type: "local", path: input2.sourceRoot })) || resolve9(input2.sourceRoot) !== input2.sourceRoot || !lstatSync11(input2.sourceRoot).isDirectory() || realpathSync3(input2.sourceRoot) !== input2.sourceRoot || input2.sourceRoot === cache || input2.sourceRoot.startsWith(cache + sep4) || cache.startsWith(input2.sourceRoot + sep4))
47566
+ return false;
47567
+ const path = join16(input2.sourceRoot, ".codex-plugin/plugin.json"), stat = lstatSync11(path);
47568
+ if (!stat.isFile() || stat.size > 1024 * 1024 || realpathSync3(path) !== path)
47569
+ return false;
47570
+ const text2 = read(path);
47571
+ hashNativeJsonControls(text2);
47572
+ const manifest = JSON.parse(text2);
47573
+ return Boolean(manifest && typeof manifest === "object" && !Array.isArray(manifest) && manifest.name === input2.namespace);
47574
+ } catch {
47575
+ return false;
47576
+ }
47577
+ }
47578
+ function reviewedCodexPluginSourceRoots(cache, inputs, read) {
47579
+ if (!Array.isArray(inputs) || inputs.length > 4096 || new Set(inputs.map((input2) => input2.pluginId)).size !== inputs.length || new Set(inputs.map((input2) => input2.sourceRoot)).size !== inputs.length || inputs.some((input2) => !sourceInputUnchanged(input2, cache, read)))
47580
+ refuse();
47581
+ const roots = inputs.map((input2) => input2.sourceRoot);
47582
+ if (roots.some((root) => roots.some((other) => root !== other && root.startsWith(other + sep4))))
47583
+ refuse();
47584
+ return roots;
47585
+ }
47586
+ var identifier2 = (v) => typeof v === "string" && /^[A-Za-z0-9_-]{1,64}$/.test(v);
47508
47587
  var init_codex_plugin_skill_controls = __esm(() => {
47509
47588
  init_claude_settings_witness();
47510
47589
  init_codex_native_compatibility();
@@ -47759,8 +47838,8 @@ var init_codex_settings_witness = __esm(() => {
47759
47838
  });
47760
47839
 
47761
47840
  // src/lib/managed-policy.ts
47762
- import { closeSync as closeSync9, constants as constants6, fstatSync as fstatSync9, lstatSync as lstatSync11, openSync as openSync9, readSync as readSync5 } from "fs";
47763
- import { join as join16 } from "path";
47841
+ import { closeSync as closeSync9, constants as constants6, fstatSync as fstatSync9, lstatSync as lstatSync12, openSync as openSync9, readSync as readSync5 } from "fs";
47842
+ import { join as join17 } from "path";
47764
47843
  function refusal(reason = "is unreadable") {
47765
47844
  return new SkillSelectionError("INVALID_AGENT_POLICY", `The Skills agent loading policy ${reason}; refusing legacy fallback.`);
47766
47845
  }
@@ -47785,10 +47864,10 @@ function parseManagedSkillPolicy(text2) {
47785
47864
  return value;
47786
47865
  }
47787
47866
  function readManagedSkillPolicySnapshot(dataDir2 = getDataDirReadOnly()) {
47788
- const path = join16(dataDir2, "agent-policy.json");
47867
+ const path = join17(dataDir2, "agent-policy.json");
47789
47868
  let descriptor, observed = false;
47790
47869
  try {
47791
- const stat = lstatSync11(path);
47870
+ const stat = lstatSync12(path);
47792
47871
  observed = true;
47793
47872
  if (!stat.isFile() || stat.isSymbolicLink())
47794
47873
  throw refusal();
@@ -47814,7 +47893,7 @@ function readManagedSkillPolicySnapshot(dataDir2 = getDataDirReadOnly()) {
47814
47893
  return { text: text2, value: parseManagedSkillPolicy(text2) };
47815
47894
  } catch (error61) {
47816
47895
  if (error61.code === "ENOENT" && !observed) {
47817
- if (lstatSync11(path, { throwIfNoEntry: false }) === undefined)
47896
+ if (lstatSync12(path, { throwIfNoEntry: false }) === undefined)
47818
47897
  return null;
47819
47898
  }
47820
47899
  if (error61 instanceof SkillSelectionError)
@@ -47916,12 +47995,12 @@ var init_skill_aliases = __esm(() => {
47916
47995
 
47917
47996
  // src/lib/project-state.ts
47918
47997
  import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync12, writeFileSync as writeFileSync4 } from "fs";
47919
- import { join as join17 } from "path";
47998
+ import { join as join18 } from "path";
47920
47999
  function getProjectStateDir(targetDir = process.cwd()) {
47921
- return join17(targetDir, SKILLS_PROJECT_DIR);
48000
+ return join18(targetDir, SKILLS_PROJECT_DIR);
47922
48001
  }
47923
48002
  function getProjectConfigPath(targetDir = process.cwd()) {
47924
- return join17(getProjectStateDir(targetDir), PROJECT_CONFIG_FILE);
48003
+ return join18(getProjectStateDir(targetDir), PROJECT_CONFIG_FILE);
47925
48004
  }
47926
48005
  function loadProjectConfig(targetDir = process.cwd()) {
47927
48006
  const path = getProjectConfigPath(targetDir);
@@ -48037,7 +48116,7 @@ var init_project_state = __esm(() => {
48037
48116
 
48038
48117
  // src/lib/installer.ts
48039
48118
  import { existsSync as existsSync9, readFileSync as readFileSync13, rmSync } from "fs";
48040
- import { join as join18 } from "path";
48119
+ import { join as join19 } from "path";
48041
48120
  import { homedir as homedir2 } from "os";
48042
48121
  function getSkillPath(name) {
48043
48122
  const skillName = normalizeSkillName(getCanonicalSkillName(name));
@@ -48047,7 +48126,7 @@ function getSkillPath(name) {
48047
48126
  const extensionPath = findExtensionSkillPath(skillName);
48048
48127
  if (extensionPath)
48049
48128
  return extensionPath;
48050
- return join18(getPortableSkillsRoot(), skillName);
48129
+ return join19(getPortableSkillsRoot(), skillName);
48051
48130
  }
48052
48131
  function getCanonicalSkillName(name) {
48053
48132
  return getSkill(name)?.name ?? resolveSkillAlias(normalizeSkillSlug(name));
@@ -48101,11 +48180,11 @@ function getAgentSkillsDir(agent, scope = "global", projectDir) {
48101
48180
  const base = projectDir || process.cwd();
48102
48181
  switch (agent) {
48103
48182
  case "pi":
48104
- return scope === "project" ? join18(base, ".pi", "skills") : join18(homedir2(), ".pi", "agent", "skills");
48183
+ return scope === "project" ? join19(base, ".pi", "skills") : join19(homedir2(), ".pi", "agent", "skills");
48105
48184
  case "opencode":
48106
- return scope === "project" ? join18(base, ".opencode", "skills") : join18(homedir2(), ".config", "opencode", "skills");
48185
+ return scope === "project" ? join19(base, ".opencode", "skills") : join19(homedir2(), ".config", "opencode", "skills");
48107
48186
  default:
48108
- return scope === "project" ? join18(base, `.${agent}`, "skills") : join18(homedir2(), `.${agent}`, "skills");
48187
+ return scope === "project" ? join19(base, `.${agent}`, "skills") : join19(homedir2(), `.${agent}`, "skills");
48109
48188
  }
48110
48189
  }
48111
48190
  function warnMissingDependencies(name, targetDir) {
@@ -48120,7 +48199,7 @@ function warnMissingDependencies(name, targetDir) {
48120
48199
  }
48121
48200
  }
48122
48201
  function readBundledSkillVersion(name) {
48123
- const pkgPath = join18(getSkillPath(name), "package.json");
48202
+ const pkgPath = join19(getSkillPath(name), "package.json");
48124
48203
  if (!existsSync9(pkgPath))
48125
48204
  return "unknown";
48126
48205
  try {
@@ -48189,11 +48268,11 @@ var init_skill_doc_file = __esm(() => {
48189
48268
 
48190
48269
  // src/lib/skillinfo.ts
48191
48270
  import { existsSync as existsSync10, readFileSync as readFileSync14 } from "fs";
48192
- import { join as join19 } from "path";
48271
+ import { join as join20 } from "path";
48193
48272
  function isInstructionSkillDir(skillPath, meta3) {
48194
48273
  if (meta3?.kind === "instruction")
48195
48274
  return true;
48196
- const skillMdPath = join19(skillPath, "SKILL.md");
48275
+ const skillMdPath = join20(skillPath, "SKILL.md");
48197
48276
  if (!existsSync10(skillMdPath))
48198
48277
  return false;
48199
48278
  try {
@@ -48207,9 +48286,9 @@ function getSkillDocs(name) {
48207
48286
  if (!existsSync10(skillPath))
48208
48287
  return null;
48209
48288
  return {
48210
- skillMd: readIfExists(join19(skillPath, "SKILL.md")),
48211
- readme: readIfExists(join19(skillPath, "README.md")),
48212
- claudeMd: readIfExists(join19(skillPath, "CLAUDE.md"))
48289
+ skillMd: readIfExists(join20(skillPath, "SKILL.md")),
48290
+ readme: readIfExists(join20(skillPath, "README.md")),
48291
+ claudeMd: readIfExists(join20(skillPath, "CLAUDE.md"))
48213
48292
  };
48214
48293
  }
48215
48294
  function getSkillBestDoc(name, file2) {
@@ -48225,14 +48304,14 @@ function getSkillRequirements(name) {
48225
48304
  return null;
48226
48305
  const texts = [];
48227
48306
  for (const file2 of ["SKILL.md", "README.md", "CLAUDE.md", ".env.example", ".env.local.example"]) {
48228
- const content = readIfExists(join19(skillPath, file2));
48307
+ const content = readIfExists(join20(skillPath, file2));
48229
48308
  if (content)
48230
48309
  texts.push(content);
48231
48310
  }
48232
48311
  const meta3 = getSkill(name);
48233
48312
  let dependencies = {};
48234
48313
  try {
48235
- dependencies = JSON.parse(readFileSync14(join19(skillPath, "package.json"), "utf8")).dependencies || {};
48314
+ dependencies = JSON.parse(readFileSync14(join20(skillPath, "package.json"), "utf8")).dependencies || {};
48236
48315
  } catch {}
48237
48316
  return getSkillRequirementsFromContent(name, texts, dependencies, meta3);
48238
48317
  }
@@ -48294,7 +48373,7 @@ async function runSkill(name, args, options = {}) {
48294
48373
  error: `Skill '${name}' is an instruction skill (kind: instruction) and is not runnable. Instruction skills are consumed by coding agents via SKILL.md, not executed with 'skills run'.`
48295
48374
  };
48296
48375
  }
48297
- const pkgPath = join19(skillPath, "package.json");
48376
+ const pkgPath = join20(skillPath, "package.json");
48298
48377
  if (!existsSync10(pkgPath)) {
48299
48378
  return { exitCode: 1, error: `No package.json in skill '${name}'` };
48300
48379
  }
@@ -48314,12 +48393,12 @@ async function runSkill(name, args, options = {}) {
48314
48393
  } catch {
48315
48394
  return { exitCode: 1, error: `Failed to parse package.json for skill '${name}'` };
48316
48395
  }
48317
- const entryPath = join19(skillPath, entryPoint2);
48396
+ const entryPath = join20(skillPath, entryPoint2);
48318
48397
  if (!existsSync10(entryPath)) {
48319
48398
  return { exitCode: 1, error: `Entry point '${entryPoint2}' not found in skill '${name}'` };
48320
48399
  }
48321
48400
  const env = { ...process.env, ...options.env };
48322
- if (!existsSync10(join19(skillPath, "node_modules")) || hasDependencyPreparationMarker(skillPath)) {
48401
+ if (!existsSync10(join20(skillPath, "node_modules")) || hasDependencyPreparationMarker(skillPath)) {
48323
48402
  const failure = await prepareSkillDependencies(skillPath, env, options.preparationTimeoutMs);
48324
48403
  if (failure)
48325
48404
  return failure;
@@ -48345,7 +48424,7 @@ async function runSkill(name, args, options = {}) {
48345
48424
  function detectProjectSkills(cwd = process.cwd()) {
48346
48425
  let pkg;
48347
48426
  try {
48348
- pkg = JSON.parse(readFileSync14(join19(cwd, "package.json"), "utf8"));
48427
+ pkg = JSON.parse(readFileSync14(join20(cwd, "package.json"), "utf8"));
48349
48428
  } catch {
48350
48429
  return { detected: [], recommended: [] };
48351
48430
  }
@@ -48633,11 +48712,11 @@ var init_plugin_projection = __esm(() => {
48633
48712
  });
48634
48713
 
48635
48714
  // src/lib/plugin-projection-store.ts
48636
- import { constants as constants7, closeSync as closeSync10, fchmodSync, fstatSync as fstatSync10, fsyncSync as fsyncSync2, linkSync, lstatSync as lstatSync12, mkdirSync as mkdirSync6, openSync as openSync10, opendirSync as opendirSync2, readSync as readSync6, renameSync as renameSync2, rmdirSync as rmdirSync2, rmSync as rmSync2, unlinkSync as unlinkSync3, writeSync as writeSync2 } from "fs";
48637
- import { dirname as dirname10, isAbsolute as isAbsolute9, join as join20, parse as parse9, resolve as resolve9 } from "path";
48715
+ import { constants as constants7, closeSync as closeSync10, fchmodSync, fstatSync as fstatSync10, fsyncSync as fsyncSync2, linkSync, lstatSync as lstatSync13, mkdirSync as mkdirSync6, openSync as openSync10, opendirSync as opendirSync2, readSync as readSync6, renameSync as renameSync2, rmdirSync as rmdirSync2, rmSync as rmSync2, unlinkSync as unlinkSync3, writeSync as writeSync2 } from "fs";
48716
+ import { dirname as dirname11, isAbsolute as isAbsolute9, join as join21, parse as parse9, resolve as resolve10 } from "path";
48638
48717
  function stat(path) {
48639
48718
  try {
48640
- return lstatSync12(path, { bigint: true });
48719
+ return lstatSync13(path, { bigint: true });
48641
48720
  } catch (error61) {
48642
48721
  if (missing(error61))
48643
48722
  return null;
@@ -48645,7 +48724,7 @@ function stat(path) {
48645
48724
  }
48646
48725
  }
48647
48726
  function canonical5(path) {
48648
- pluginNeed(typeof path === "string" && path.length <= 8192 && isAbsolute9(path) && resolve9(path) === path && !/[\x00-\x1f\x7f]/.test(path), "Plugin storage paths must be canonical absolute paths");
48727
+ pluginNeed(typeof path === "string" && path.length <= 8192 && isAbsolute9(path) && resolve10(path) === path && !/[\x00-\x1f\x7f]/.test(path), "Plugin storage paths must be canonical absolute paths");
48649
48728
  }
48650
48729
  function owner(stats, system = false) {
48651
48730
  const current = uid();
@@ -48656,11 +48735,11 @@ function same3(left, right, identityOnly = false) {
48656
48735
  }
48657
48736
  function ancestors(path, create = false) {
48658
48737
  canonical5(path);
48659
- const result = [], parent = dirname10(path), filesystemRoot = parse9(parent).root;
48738
+ const result = [], parent = dirname11(path), filesystemRoot = parse9(parent).root;
48660
48739
  let current = filesystemRoot;
48661
48740
  for (const segment of ["", ...parent.slice(filesystemRoot.length).split("/").filter(Boolean)]) {
48662
48741
  if (segment)
48663
- current = join20(current, segment);
48742
+ current = join21(current, segment);
48664
48743
  let currentStat = stat(current);
48665
48744
  if (!currentStat && create) {
48666
48745
  try {
@@ -48758,7 +48837,7 @@ function directoryNames(path) {
48758
48837
  function snapshotPluginTree(root, options = {}) {
48759
48838
  const chain = ancestors(root), entries = [], files = [], directories = [];
48760
48839
  let bytes = 0, visited = 0;
48761
- const visit3 = (directory, relative4) => {
48840
+ const visit3 = (directory, relative5) => {
48762
48841
  const before = stat(directory);
48763
48842
  pluginNeed(before && before.isDirectory() && !before.isSymbolicLink(), "Plugin tree must contain real directories");
48764
48843
  const names = directoryNames(directory);
@@ -48766,18 +48845,18 @@ function snapshotPluginTree(root, options = {}) {
48766
48845
  directories.push({ path: directory, stat: before, names });
48767
48846
  for (const name of names) {
48768
48847
  pluginNeed(++visited <= PLUGIN_PROJECTION_LIMITS.files * 50, "Plugin tree membership exceeds its limit");
48769
- const path = relative4 ? `${relative4}/${name}` : name;
48848
+ const path = relative5 ? `${relative5}/${name}` : name;
48770
48849
  pluginNeed(new TextEncoder().encode(path).byteLength <= 100 && !/[\\:\x00-\x1f\x7f]/u.test(path), "Plugin entry path exceeds its limit or is unsafe");
48771
- const absolute = join20(directory, name), entryStat = stat(absolute);
48850
+ const absolute = join21(directory, name), entryStat = stat(absolute);
48772
48851
  pluginNeed(entryStat, "Plugin tree member disappeared");
48773
- if (relative4 === "" && name === ".orphaned_at" && (options.nativeRuntime === "claude-2.1.274" || options.nativeRuntime === "claude-2.1.276")) {
48852
+ if (relative5 === "" && name === ".orphaned_at" && (options.nativeRuntime === "claude-2.1.274" || options.nativeRuntime === "claude-2.1.276")) {
48774
48853
  const bytes2 = readBytes(absolute, 32, "native-pin");
48775
48854
  pluginNeed(/^[1-9][0-9]{12}$/.test(new TextDecoder().decode(bytes2)), "Malformed native orphan timestamp");
48776
48855
  same3(entryStat, stat(absolute));
48777
48856
  files.push({ path: absolute, stat: entryStat });
48778
48857
  continue;
48779
48858
  }
48780
- if (relative4 === "" && name === ".in_use" && (options.nativeRuntime === "claude-2.1.274" || options.nativeRuntime === "claude-2.1.276")) {
48859
+ if (relative5 === "" && name === ".in_use" && (options.nativeRuntime === "claude-2.1.274" || options.nativeRuntime === "claude-2.1.276")) {
48781
48860
  pluginNeed(entryStat.isDirectory() && !entryStat.isSymbolicLink(), "Native plugin pins require a real directory");
48782
48861
  owner(entryStat);
48783
48862
  const pins = directoryNames(absolute);
@@ -48785,7 +48864,7 @@ function snapshotPluginTree(root, options = {}) {
48785
48864
  directories.push({ path: absolute, stat: entryStat, names: pins });
48786
48865
  for (const pin of pins) {
48787
48866
  pluginNeed(/^[1-9][0-9]{0,9}$/.test(pin) && Number(pin) <= 2147483647, "Unrecognized native plugin pin name");
48788
- const pinPath = join20(absolute, pin), pinStat = stat(pinPath);
48867
+ const pinPath = join21(absolute, pin), pinStat = stat(pinPath);
48789
48868
  pluginNeed(pinStat, "Native plugin pin disappeared");
48790
48869
  const bytes2 = readBytes(pinPath, 4096, "native-pin");
48791
48870
  let value;
@@ -48882,7 +48961,7 @@ var init_selected_manifest = __esm(() => {
48882
48961
  });
48883
48962
 
48884
48963
  // src/lib/plugin-admission.ts
48885
- import { isAbsolute as isAbsolute10, join as join21, resolve as resolve10 } from "path";
48964
+ import { isAbsolute as isAbsolute10, join as join22, resolve as resolve11 } from "path";
48886
48965
  function validatePluginTarget(value) {
48887
48966
  pluginKeys(value, ["schemaVersion", "pluginId", "registrations", "native", "resolver"]);
48888
48967
  pluginNeed(value.schemaVersion === 1, "Invalid plugin admission target");
@@ -48892,7 +48971,7 @@ function validatePluginTarget(value) {
48892
48971
  for (const registration of value.registrations) {
48893
48972
  pluginKeys(registration, ["scope", "projectPath"]);
48894
48973
  pluginNeed(registration.scope === "user" || registration.scope === "project", "Unsupported plugin registration scope");
48895
- pluginNeed(registration.scope === "user" ? registration.projectPath === null : typeof registration.projectPath === "string" && isAbsolute10(registration.projectPath) && resolve10(registration.projectPath) === registration.projectPath, "Plugin scope requires its exact project path");
48974
+ pluginNeed(registration.scope === "user" ? registration.projectPath === null : typeof registration.projectPath === "string" && isAbsolute10(registration.projectPath) && resolve11(registration.projectPath) === registration.projectPath, "Plugin scope requires its exact project path");
48896
48975
  const key = JSON.stringify([registration.scope, registration.projectPath]);
48897
48976
  pluginNeed(!scopes.has(key), "Duplicate plugin registration scope");
48898
48977
  scopes.add(key);
@@ -48900,7 +48979,7 @@ function validatePluginTarget(value) {
48900
48979
  for (const key of ["native", "resolver"]) {
48901
48980
  pluginKeys(value[key], key === "native" ? ["version", "executable", "digest"] : ["executable", "digest"]);
48902
48981
  pluginText(value[key].executable);
48903
- pluginNeed(isAbsolute10(value[key].executable) && resolve10(value[key].executable) === value[key].executable, "Plugin executable must have a canonical absolute path");
48982
+ pluginNeed(isAbsolute10(value[key].executable) && resolve11(value[key].executable) === value[key].executable, "Plugin executable must have a canonical absolute path");
48904
48983
  pluginDigest(value[key].digest);
48905
48984
  }
48906
48985
  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)");
@@ -49043,12 +49122,12 @@ function pluginResolverCommand(binding) {
49043
49122
  }
49044
49123
  function pluginBindingPath(storeRoot, id) {
49045
49124
  pluginNeed(/^[a-f0-9]{64}$/.test(id), "Invalid plugin binding identifier");
49046
- return join21(storeRoot, "bindings", `${id}.json`);
49125
+ return join22(storeRoot, "bindings", `${id}.json`);
49047
49126
  }
49048
49127
  function pluginReceiptPath(storeRoot, id, digest) {
49049
49128
  pluginNeed(/^[a-f0-9]{64}$/.test(id), "Invalid plugin binding identifier");
49050
49129
  pluginDigest(digest);
49051
- return join21(storeRoot, "receipts", id, `${digest.slice(7)}.json`);
49130
+ return join22(storeRoot, "receipts", id, `${digest.slice(7)}.json`);
49052
49131
  }
49053
49132
  function readPluginBinding(storeRoot, id) {
49054
49133
  const value = readPluginJson(pluginBindingPath(storeRoot, id));
@@ -49068,7 +49147,7 @@ function readPluginAdmissionReceipt(storeRoot, id, digest) {
49068
49147
  pluginNeed(receipt.plan.bindingId === id && receipt.plan.planDigest === digest, "Plugin receipt identity differs from its filename");
49069
49148
  const binding = readPluginBinding(storeRoot, id);
49070
49149
  pluginNeed(canonicalJson(binding) === canonicalJson(receipt.plan.binding) && receipt.plan.sourceCommand === pluginResolverCommand(binding), "Plugin receipt binding changed");
49071
- pluginNeed(receipt.materializedPath === join21(storeRoot, "objects", id, digest.slice(7)), "Plugin receipt points outside its immutable materialization");
49150
+ pluginNeed(receipt.materializedPath === join22(storeRoot, "objects", id, digest.slice(7)), "Plugin receipt points outside its immutable materialization");
49072
49151
  pluginText(receipt.admittedAt, 64);
49073
49152
  pluginNeed(Number.isFinite(Date.parse(receipt.admittedAt)), "Invalid plugin admission time");
49074
49153
  return receipt;
@@ -49085,8 +49164,8 @@ var init_plugin_admission = __esm(() => {
49085
49164
  });
49086
49165
 
49087
49166
  // src/lib/plugin-discovery.ts
49088
- import { closeSync as closeSync11, constants as constants8, fstatSync as fstatSync11, lstatSync as lstatSync13, openSync as openSync11, opendirSync as opendirSync3, readSync as readSync7 } from "fs";
49089
- import { basename as basename5, dirname as dirname11, isAbsolute as isAbsolute11, join as join22, resolve as resolve11 } from "path";
49167
+ import { closeSync as closeSync11, constants as constants8, fstatSync as fstatSync11, lstatSync as lstatSync14, openSync as openSync11, opendirSync as opendirSync3, readSync as readSync7 } from "fs";
49168
+ import { basename as basename6, dirname as dirname12, isAbsolute as isAbsolute11, join as join23, resolve as resolve12 } from "path";
49090
49169
  function validateManagedPluginWitnesses(value) {
49091
49170
  pluginNeed(Array.isArray(value) && value.length > 0 && value.length <= PLUGIN_PROJECTION_LIMITS.registrations, "Invalid managed plugin witness collection");
49092
49171
  const seen = new Set;
@@ -49095,21 +49174,21 @@ function validateManagedPluginWitnesses(value) {
49095
49174
  pluginNeed(typeof item.bindingId === "string" && /^[a-f0-9]{64}$/.test(item.bindingId) && !seen.has(item.bindingId), "Invalid or duplicate managed plugin witness");
49096
49175
  seen.add(item.bindingId);
49097
49176
  pluginText(item.storeRoot);
49098
- pluginNeed(isAbsolute11(item.storeRoot) && resolve11(item.storeRoot) === item.storeRoot, "Invalid plugin receipt store path");
49177
+ pluginNeed(isAbsolute11(item.storeRoot) && resolve12(item.storeRoot) === item.storeRoot, "Invalid plugin receipt store path");
49099
49178
  }
49100
49179
  }
49101
49180
  function safe3(path) {
49102
49181
  pluginText(path);
49103
- pluginNeed(isAbsolute11(path) && resolve11(path) === path, "Invalid plugin registry path");
49104
- for (let at = path;; at = dirname11(at)) {
49105
- pluginNeed(!lstatSync13(at, { throwIfNoEntry: false })?.isSymbolicLink(), "Plugin registry path traverses a symlink");
49106
- if (at === dirname11(at))
49182
+ pluginNeed(isAbsolute11(path) && resolve12(path) === path, "Invalid plugin registry path");
49183
+ for (let at = path;; at = dirname12(at)) {
49184
+ pluginNeed(!lstatSync14(at, { throwIfNoEntry: false })?.isSymbolicLink(), "Plugin registry path traverses a symlink");
49185
+ if (at === dirname12(at))
49107
49186
  break;
49108
49187
  }
49109
49188
  }
49110
49189
  function readRegistry(path) {
49111
49190
  safe3(path);
49112
- const initial = lstatSync13(path);
49191
+ const initial = lstatSync14(path);
49113
49192
  pluginNeed(initial.isFile() && initial.size <= 1024 * 1024, "Plugin registry is not a bounded regular file");
49114
49193
  const fd = openSync11(path, constants8.O_RDONLY | constants8.O_NOFOLLOW | constants8.O_NONBLOCK);
49115
49194
  try {
@@ -49123,7 +49202,7 @@ function readRegistry(path) {
49123
49202
  break;
49124
49203
  length += count;
49125
49204
  }
49126
- const after = fstatSync11(fd), current = lstatSync13(path);
49205
+ const after = fstatSync11(fd), current = lstatSync14(path);
49127
49206
  safe3(path);
49128
49207
  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");
49129
49208
  let value;
@@ -49153,7 +49232,7 @@ function hashManagedPluginRegistry(path, managed) {
49153
49232
  seen.add(target.pluginId);
49154
49233
  const rows = plugins[target.pluginId];
49155
49234
  pluginNeed(Array.isArray(rows) && rows.length === target.registrations.length, "Managed plugin registration membership changed");
49156
- const [name, market] = target.pluginId.split("@"), cacheRoot = join22(dirname11(path), "cache", market, name);
49235
+ const [name, market] = target.pluginId.split("@"), cacheRoot = join23(dirname12(path), "cache", market, name);
49157
49236
  const scopes = new Set, approvals = new Map, currentFiles = new Map;
49158
49237
  plugins[target.pluginId] = rows.map((row) => {
49159
49238
  pluginNeed(pluginObject(row), "Invalid managed plugin registration");
@@ -49166,10 +49245,10 @@ function hashManagedPluginRegistry(path, managed) {
49166
49245
  pluginText(row.sourceProducerPath);
49167
49246
  pluginText(row.lastUpdated, 64);
49168
49247
  pluginNeed(Number.isFinite(Date.parse(row.lastUpdated)), "Invalid managed plugin update timestamp");
49169
- pluginNeed(/^(?:[A-Za-z0-9][A-Za-z0-9._+-]*-)?[a-f0-9]{12}$/.test(row.version) && row.installPath === join22(cacheRoot, row.version), "Managed plugin cache path or version is outside its registration");
49248
+ pluginNeed(/^(?:[A-Za-z0-9][A-Za-z0-9._+-]*-)?[a-f0-9]{12}$/.test(row.version) && row.installPath === join23(cacheRoot, row.version), "Managed plugin cache path or version is outside its registration");
49170
49249
  const approval = (producer) => {
49171
49250
  pluginText(producer);
49172
- const digest = `sha256:${basename5(producer)}`;
49251
+ const digest = `sha256:${basename6(producer)}`;
49173
49252
  const receipt2 = readPluginAdmissionReceipt(witness.storeRoot, witness.bindingId, digest);
49174
49253
  pluginNeed(receipt2.materializedPath === producer, "Managed producer path is not an approved immutable projection");
49175
49254
  if (!verified.has(producer)) {
@@ -49196,7 +49275,7 @@ function hashManagedPluginRegistry(path, managed) {
49196
49275
  return Object.fromEntries(Object.entries(row).filter(([key]) => !["version", "installPath", "sourceProducerPath", "previousProducerPaths", "lastUpdated"].includes(key)));
49197
49276
  });
49198
49277
  safe3(cacheRoot);
49199
- const before = lstatSync13(cacheRoot);
49278
+ const before = lstatSync14(cacheRoot);
49200
49279
  pluginNeed(before.isDirectory(), "Invalid managed plugin cache root");
49201
49280
  const directory = opendirSync3(cacheRoot), names = [];
49202
49281
  try {
@@ -49209,17 +49288,17 @@ function hashManagedPluginRegistry(path, managed) {
49209
49288
  directory.closeSync();
49210
49289
  }
49211
49290
  for (const version2 of names.sort()) {
49212
- const files = pluginFileWitnesses(snapshotPluginTree(join22(cacheRoot, version2), { nativeRuntime: `claude-${target.native.version}` }));
49291
+ const files = pluginFileWitnesses(snapshotPluginTree(join23(cacheRoot, version2), { nativeRuntime: `claude-${target.native.version}` }));
49213
49292
  verifiedBytes += files.reduce((total, file2) => total + file2.size, 0);
49214
49293
  pluginNeed(verifiedBytes <= 256 * 1024 * 1024, "Managed plugin verification exceeds its aggregate byte budget");
49215
49294
  const serialized = JSON.stringify(files);
49216
- const expected = currentFiles.get(join22(cacheRoot, version2));
49295
+ const expected = currentFiles.get(join23(cacheRoot, version2));
49217
49296
  pluginNeed(expected === undefined || serialized === expected, "Current native cache differs from its exact registered producer receipt");
49218
49297
  pluginNeed([...approvals.values()].some((receipt) => nativeVersionMatches(version2, receipt) && JSON.stringify(receipt.plan.files) === serialized), "A retained native plugin cache version differs from every approved projection");
49219
49298
  }
49220
49299
  for (const row of rows)
49221
49300
  pluginNeed(names.includes(row.version), "Managed native plugin installation is missing");
49222
- const after = lstatSync13(cacheRoot);
49301
+ const after = lstatSync14(cacheRoot);
49223
49302
  safe3(cacheRoot);
49224
49303
  pluginNeed(before.dev === after.dev && before.ino === after.ino && before.mtimeMs === after.mtimeMs && before.ctimeMs === after.ctimeMs, "Managed cache version membership changed during verification");
49225
49304
  }
@@ -49234,30 +49313,30 @@ var init_plugin_discovery = __esm(() => {
49234
49313
 
49235
49314
  // src/lib/claude-marketplace-registry.ts
49236
49315
  import { createHash as createHash13 } from "crypto";
49237
- import { closeSync as closeSync12, constants as constants9, fstatSync as fstatSync12, lstatSync as lstatSync14, openSync as openSync12, readSync as readSync8 } from "fs";
49238
- import { basename as basename6, dirname as dirname12, isAbsolute as isAbsolute12, resolve as resolve12 } from "path";
49316
+ import { closeSync as closeSync12, constants as constants9, fstatSync as fstatSync12, lstatSync as lstatSync15, openSync as openSync12, readSync as readSync8 } from "fs";
49317
+ import { basename as basename7, dirname as dirname13, isAbsolute as isAbsolute12, resolve as resolve13 } from "path";
49239
49318
  function need5(value, reason) {
49240
49319
  if (!value)
49241
49320
  throw new Error(`Claude marketplace registry ${reason}`);
49242
49321
  }
49243
49322
  function absolutePath2(value) {
49244
- need5(typeof value === "string" && value.length > 0 && value.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.pathCharacters && !/[\x00-\x1f\x7f]/.test(value) && isAbsolute12(value) && resolve12(value) === value, "requires a normalized absolute path");
49323
+ need5(typeof value === "string" && value.length > 0 && value.length <= CLAUDE_MARKETPLACE_REGISTRY_LIMITS.pathCharacters && !/[\x00-\x1f\x7f]/.test(value) && isAbsolute12(value) && resolve13(value) === value, "requires a normalized absolute path");
49245
49324
  }
49246
49325
  function parents2(path) {
49247
49326
  const result = [];
49248
- for (let at = dirname12(path);; at = dirname12(at)) {
49249
- const stat2 = lstatSync14(at, { bigint: true });
49327
+ for (let at = dirname13(path);; at = dirname13(at)) {
49328
+ const stat2 = lstatSync15(at, { bigint: true });
49250
49329
  need5(stat2.isDirectory() && !stat2.isSymbolicLink(), "path traverses a symlink or non-directory");
49251
49330
  result.push([at, stat2]);
49252
- if (at === dirname12(at))
49331
+ if (at === dirname13(at))
49253
49332
  return result;
49254
49333
  }
49255
49334
  }
49256
49335
  function readRegistry2(path, budget) {
49257
49336
  absolutePath2(path);
49258
- need5(basename6(path) === "known_marketplaces.json", "requires known_marketplaces.json");
49337
+ need5(basename7(path) === "known_marketplaces.json", "requires known_marketplaces.json");
49259
49338
  need5(Number.isSafeInteger(budget.remaining) && budget.remaining >= 0, "has an invalid byte budget");
49260
- const ancestors2 = parents2(path), initial = lstatSync14(path, { bigint: true });
49339
+ const ancestors2 = parents2(path), initial = lstatSync15(path, { bigint: true });
49261
49340
  need5(initial.isFile() && !initial.isSymbolicLink() && initial.size <= BigInt(CLAUDE_MARKETPLACE_REGISTRY_LIMITS.bytes), "is not a bounded regular file");
49262
49341
  need5(initial.size <= BigInt(budget.remaining), "exceeds its aggregate byte limit");
49263
49342
  const fd = openSync12(path, constants9.O_RDONLY | constants9.O_NOFOLLOW | constants9.O_NONBLOCK);
@@ -49272,10 +49351,10 @@ function readRegistry2(path, budget) {
49272
49351
  break;
49273
49352
  length += count;
49274
49353
  }
49275
- const after = fstatSync12(fd, { bigint: true }), current = lstatSync14(path, { bigint: true });
49354
+ const after = fstatSync12(fd, { bigint: true }), current = lstatSync15(path, { bigint: true });
49276
49355
  need5(current.isFile() && sameFile2(opened, after) && sameFile2(after, current) && BigInt(length) === opened.size, "changed during read");
49277
49356
  for (const [ancestor, before] of ancestors2) {
49278
- const now = lstatSync14(ancestor, { bigint: true });
49357
+ const now = lstatSync15(ancestor, { bigint: true });
49279
49358
  need5(now.isDirectory() && before.dev === now.dev && before.ino === now.ino && before.mode === now.mode, "parent changed during read");
49280
49359
  }
49281
49360
  budget.remaining -= length;
@@ -49415,26 +49494,26 @@ var init_claude_marketplace_registry = __esm(() => {
49415
49494
  });
49416
49495
 
49417
49496
  // src/lib/codex-hook-trust-files.ts
49418
- import { closeSync as closeSync13, constants as constants10, fstatSync as fstatSync13, fsyncSync as fsyncSync3, lstatSync as lstatSync15, openSync as openSync13, readSync as readSync9, writeFileSync as writeFileSync5 } from "fs";
49497
+ import { closeSync as closeSync13, constants as constants10, fstatSync as fstatSync13, fsyncSync as fsyncSync3, lstatSync as lstatSync16, openSync as openSync13, readSync as readSync9, writeFileSync as writeFileSync5 } from "fs";
49419
49498
  import { createHash as createHash14 } from "crypto";
49420
- import { dirname as dirname13 } from "path";
49499
+ import { dirname as dirname14 } from "path";
49421
49500
  function need6(value, code) {
49422
49501
  if (!value)
49423
49502
  throw new Error(`CODEX_HOOK_TRUST_${code}`);
49424
49503
  }
49425
49504
  function safeParents(file2) {
49426
- for (let p = dirname13(file2);; p = dirname13(p)) {
49427
- const s = lstatSync15(p);
49505
+ for (let p = dirname14(file2);; p = dirname14(p)) {
49506
+ const s = lstatSync16(p);
49428
49507
  need6(s.isDirectory() && !s.isSymbolicLink(), "UNSAFE_PARENT");
49429
49508
  need6((s.mode & 18) === 0 || s.uid === 0 && (s.mode & 512) !== 0, "UNSAFE_PARENT");
49430
- if (dirname13(p) === p)
49509
+ if (dirname14(p) === p)
49431
49510
  break;
49432
49511
  }
49433
49512
  }
49434
49513
  function snapshot(file2, privateFile = false, options = {}) {
49435
49514
  const readOnlyPackage = options.readOnlyPackage === true && !privateFile;
49436
49515
  safeParents(file2);
49437
- const initial = lstatSync15(file2, { bigint: true });
49516
+ const initial = lstatSync16(file2, { bigint: true });
49438
49517
  need6(initial.isFile() && initial.uid === BigInt(process.getuid()) && (initial.nlink === 1n || readOnlyPackage && initial.nlink > 1n) && (initial.mode & 0o022n) === 0n && (!privateFile || (initial.mode & 0o777n) === 0o600n), "UNSAFE_FILE");
49439
49518
  need6(initial.size <= 8n * 1024n * 1024n, "FILE_BOUND");
49440
49519
  const fd = openSync13(file2, constants10.O_RDONLY | constants10.O_NOFOLLOW | constants10.O_NONBLOCK);
@@ -49449,7 +49528,7 @@ function snapshot(file2, privateFile = false, options = {}) {
49449
49528
  break;
49450
49529
  length += n2;
49451
49530
  }
49452
- need6(length === Number(before.size) && sameStat(before, fstatSync13(fd, { bigint: true })) && sameStat(before, lstatSync15(file2, { bigint: true })), "INPUT_CHANGED");
49531
+ need6(length === Number(before.size) && sameStat(before, fstatSync13(fd, { bigint: true })) && sameStat(before, lstatSync16(file2, { bigint: true })), "INPUT_CHANGED");
49453
49532
  const content = bytes.subarray(0, length), text2 = new TextDecoder("utf-8", { fatal: true }).decode(content);
49454
49533
  return { file: file2, privateFile, readOnlyPackage, text: text2, bytes: content, stat: before, sha256: createHash14("sha256").update(content).digest("hex") };
49455
49534
  } finally {
@@ -49504,8 +49583,8 @@ var init_codex_hook_discovery_recovery = __esm(() => {
49504
49583
 
49505
49584
  // src/lib/agent-discovery.ts
49506
49585
  import { createHash as createHash16 } from "crypto";
49507
- import { lstatSync as lstatSync16, readFileSync as readFileSync15, readdirSync as readdirSync6, realpathSync as realpathSync3 } from "fs";
49508
- import { basename as basename7, dirname as dirname14, isAbsolute as isAbsolute13, join as join23, resolve as resolve13, sep as sep4 } from "path";
49586
+ import { lstatSync as lstatSync17, readFileSync as readFileSync15, readdirSync as readdirSync7, realpathSync as realpathSync4 } from "fs";
49587
+ import { basename as basename8, dirname as dirname15, isAbsolute as isAbsolute13, join as join24, resolve as resolve14, sep as sep5 } from "path";
49509
49588
  import { isDeepStrictEqual as isDeepStrictEqual2 } from "util";
49510
49589
  function parseConfig(text2, path, toml = false) {
49511
49590
  try {
@@ -49520,10 +49599,10 @@ function parseConfig(text2, path, toml = false) {
49520
49599
  function safe4(path) {
49521
49600
  if (!isAbsolute13(path) || path.includes("\x00"))
49522
49601
  throw new Error("Expected an absolute native discovery path");
49523
- for (let cursor = path;; cursor = dirname14(cursor)) {
49524
- if (lstatSync16(cursor, { throwIfNoEntry: false })?.isSymbolicLink())
49602
+ for (let cursor = path;; cursor = dirname15(cursor)) {
49603
+ if (lstatSync17(cursor, { throwIfNoEntry: false })?.isSymbolicLink())
49525
49604
  throw new Error(`Refusing symlink native discovery input: ${cursor}`);
49526
- if (dirname14(cursor) === cursor)
49605
+ if (dirname15(cursor) === cursor)
49527
49606
  break;
49528
49607
  }
49529
49608
  }
@@ -49531,7 +49610,7 @@ function read(path, changes) {
49531
49610
  safe4(path);
49532
49611
  if (changes?.has(path))
49533
49612
  return changes.get(path);
49534
- const stat2 = lstatSync16(path, { throwIfNoEntry: false });
49613
+ const stat2 = lstatSync17(path, { throwIfNoEntry: false });
49535
49614
  if (!stat2)
49536
49615
  return null;
49537
49616
  if (!stat2.isFile() || stat2.size > 16 * 1024 * 1024)
@@ -49605,8 +49684,16 @@ function verifyAgentDiscovery(binding, codexRecovery) {
49605
49684
  throw new Error("Invalid native discovery binding");
49606
49685
  if (binding.agent === "hermes" && !binding.directories?.length)
49607
49686
  throw new Error("Hermes discovery requires directory membership coverage; run skills hook install with a fresh discovery review");
49608
- if (binding.directories !== undefined)
49609
- verifyDiscoveryDirectories(binding.directories);
49687
+ const installationRoots = codexInstallationRoots(binding);
49688
+ const installationInput = (path) => installationRoots.some((root) => path === root || path.startsWith(root + sep5));
49689
+ if (binding.directories !== undefined) {
49690
+ const projected2 = binding.codexInstallationInputs?.directories ?? [];
49691
+ const ancestors2 = binding.directories.filter((directory) => installationRoots.some((root) => root.startsWith(directory.path + sep5)));
49692
+ if (projected2.length !== ancestors2.length || projected2.some((directory) => !ancestors2.some((original) => original.path === directory.path)))
49693
+ throw new Error("Missing installation input directory projection");
49694
+ verifyDiscoveryDirectories(binding.directories.filter((directory) => !installationInput(directory.path) && !ancestors2.includes(directory)));
49695
+ verifyDiscoveryDirectories(projected2, installationRoots);
49696
+ }
49610
49697
  const budget = discoveryByteBudget();
49611
49698
  for (const source of binding.sources) {
49612
49699
  assertMarketplaceBinding(binding, source);
@@ -49616,6 +49703,10 @@ function verifyAgentDiscovery(binding, codexRecovery) {
49616
49703
  throw new Error("Invalid native discovery projection");
49617
49704
  if (source.sha256 !== null && !/^[a-f0-9]{64}$/.test(source.sha256))
49618
49705
  throw new Error("Invalid native discovery digest");
49706
+ if (installationInput(source.path)) {
49707
+ safe4(source.path);
49708
+ continue;
49709
+ }
49619
49710
  const current = projected(source, undefined, budget);
49620
49711
  if (current !== source.sha256 && !verifiesCodexHookDiscoverySource(binding, source, current, codexRecovery))
49621
49712
  throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
@@ -49623,19 +49714,40 @@ function verifyAgentDiscovery(binding, codexRecovery) {
49623
49714
  for (const root of binding.roots)
49624
49715
  safe4(root);
49625
49716
  }
49717
+ function codexInstallationRoots(binding) {
49718
+ const proof = binding.codexInstallationInputs;
49719
+ if (proof === undefined)
49720
+ return [];
49721
+ if (binding.agent !== "codex" || binding.method !== "reviewed" || proof.version !== "codex-cli 0.160.0" || !/^[a-f0-9]{64}$/.test(proof.catalogSha256) || !Array.isArray(proof.plugins) || !proof.plugins.length)
49722
+ throw new Error("Invalid native installation input proof");
49723
+ const cache = dirname15(dirname15(proof.plugins[0].pluginParent));
49724
+ const config2 = join24(dirname15(dirname15(cache)), "config.toml"), home = dirname15(dirname15(dirname15(cache)));
49725
+ const configSource = binding.sources.find((source) => source.path === config2 && source.sha256 !== null && (!source.format || source.format === "toml" && source.fields?.includes("plugins")));
49726
+ const nativeRoots = NATIVE_SKILL_ROOTS.filter(([agent]) => agent === "codex").map(([, path]) => join24(home, path));
49727
+ if (!configSource || proof.plugins.some((input2) => nativeRoots.some((root) => root === input2.sourceRoot || root.startsWith(input2.sourceRoot + sep5) || input2.sourceRoot.startsWith(root + sep5)) || binding.sources.some((source) => basename8(source.path) === "config.toml" && (source.path === input2.sourceRoot || source.path.startsWith(input2.sourceRoot + sep5)))))
49728
+ throw new Error("Native installation input overlaps configuration or loading roots");
49729
+ if (proof.plugins.some((input2) => dirname15(dirname15(input2.pluginParent)) !== cache || !binding.sources.some((source) => source.path === join24(input2.sourceRoot, ".codex-plugin/plugin.json") && source.sha256 !== null && source.format === undefined && source.fields === undefined)))
49730
+ throw new Error("Missing native installation input source witness");
49731
+ return reviewedCodexPluginSourceRoots(cache, proof.plugins, (path) => {
49732
+ const text2 = read(path);
49733
+ if (text2 === null)
49734
+ throw new Error("Missing native installation input");
49735
+ return text2;
49736
+ });
49737
+ }
49626
49738
  function assertMarketplaceBinding(binding, source) {
49627
- if ((source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2") && (binding.agent !== "codex" || binding.method !== "reviewed" || basename7(source.path) !== "config.toml"))
49739
+ if ((source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2") && (binding.agent !== "codex" || binding.method !== "reviewed" || basename8(source.path) !== "config.toml"))
49628
49740
  throw new Error("Codex settings witnesses require explicit reviewed Codex configuration");
49629
- if ((source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") && (binding.agent !== "claude" || binding.method !== "reviewed" || basename7(source.path) !== "settings.json"))
49741
+ if ((source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") && (binding.agent !== "claude" || binding.method !== "reviewed" || basename8(source.path) !== "settings.json"))
49630
49742
  throw new Error("Claude settings witnesses require explicit reviewed Claude configuration");
49631
49743
  if ((source.hashMode === "claude-marketplace-registry" || source.hashMode === "claude-marketplace-registry-v2") && (binding.agent !== "claude" || binding.method !== "reviewed"))
49632
49744
  throw new Error("Claude marketplace witnesses require explicit reviewed Claude discovery");
49633
49745
  }
49634
49746
  function agentDiscoveryConfigPath(home, agent) {
49635
- return join23(home, agent === "hermes" ? ".hermes/config.yaml" : agent === "opencode" ? ".config/opencode/opencode.json" : `.${agent}/${agent === "codex" ? "config.toml" : agent === "cursor" ? "hooks.json" : "settings.json"}`);
49747
+ return join24(home, agent === "hermes" ? ".hermes/config.yaml" : agent === "opencode" ? ".config/opencode/opencode.json" : `.${agent}/${agent === "codex" ? "config.toml" : agent === "cursor" ? "hooks.json" : "settings.json"}`);
49636
49748
  }
49637
49749
  function resolveAgentDiscovery(options) {
49638
- const canonical6 = options.canonical ?? resolve13, home = resolve13(options.home), agent = options.agent;
49750
+ const canonical6 = options.canonical ?? resolve14, home = resolve14(options.home), agent = options.agent;
49639
49751
  const sources = [], roots = new Set, builtinNames = [];
49640
49752
  const witness = (path, format, fields2) => {
49641
49753
  const source = { path: canonical6(path), sha256: null, ...format ? { format, fields: fields2 } : {} };
@@ -49652,7 +49764,7 @@ function resolveAgentDiscovery(options) {
49652
49764
  throw new Error(`Native discovery is unresolved (${agent}: ${detail}); provide a reviewed --discovery-inputs file`);
49653
49765
  };
49654
49766
  if (agent === "hermes") {
49655
- const profile = witness(join23(home, ".hermes/active_profile"));
49767
+ const profile = witness(join24(home, ".hermes/active_profile"));
49656
49768
  if (profile?.trim() && profile.trim() !== "default")
49657
49769
  unresolved("a non-default profile is active");
49658
49770
  const declared = config2.skills?.external_dirs ?? [], paths = typeof declared === "string" ? [declared] : declared;
@@ -49666,7 +49778,7 @@ function resolveAgentDiscovery(options) {
49666
49778
  continue;
49667
49779
  if (normalized.startsWith("~") && normalized !== "~" && !normalized.startsWith("~/"))
49668
49780
  unresolved("user-specific tilde expansion requires a separate discovery adapter");
49669
- const path = normalized === "~" ? home : normalized.startsWith("~/") ? join23(home, normalized.slice(2)) : resolve13(home, ".hermes", normalized);
49781
+ const path = normalized === "~" ? home : normalized.startsWith("~/") ? join24(home, normalized.slice(2)) : resolve14(home, ".hermes", normalized);
49670
49782
  safe4(path);
49671
49783
  roots.add(path);
49672
49784
  }
@@ -49675,24 +49787,24 @@ function resolveAgentDiscovery(options) {
49675
49787
  const executable = Bun.which("gemini");
49676
49788
  if (executable) {
49677
49789
  let packageRoot;
49678
- for (let directory = dirname14(realpathSync3(executable)), depth = 0;depth < 8; directory = dirname14(directory), depth++) {
49679
- const path = join23(directory, "package.json"), raw = read(path);
49790
+ for (let directory = dirname15(realpathSync4(executable)), depth = 0;depth < 8; directory = dirname15(directory), depth++) {
49791
+ const path = join24(directory, "package.json"), raw = read(path);
49680
49792
  if (raw !== null && parseConfig(raw, path).name === "@google/gemini-cli") {
49681
49793
  packageRoot = directory;
49682
49794
  witness(path);
49683
49795
  break;
49684
49796
  }
49685
- if (dirname14(directory) === directory)
49797
+ if (dirname15(directory) === directory)
49686
49798
  break;
49687
49799
  }
49688
49800
  if (!packageRoot)
49689
49801
  unresolved("installed Gemini package layout is not recognized");
49690
- const builtinRoot = join23(packageRoot, "bundle/builtin");
49802
+ const builtinRoot = join24(packageRoot, "bundle/builtin");
49691
49803
  safe4(builtinRoot);
49692
- if (!lstatSync16(builtinRoot, { throwIfNoEntry: false })?.isDirectory())
49804
+ if (!lstatSync17(builtinRoot, { throwIfNoEntry: false })?.isDirectory())
49693
49805
  unresolved("installed Gemini builtin root is missing");
49694
- for (const name of readdirSync6(builtinRoot).sort()) {
49695
- const text2 = witness(join23(builtinRoot, name, "SKILL.md"));
49806
+ for (const name of readdirSync7(builtinRoot).sort()) {
49807
+ const text2 = witness(join24(builtinRoot, name, "SKILL.md"));
49696
49808
  const match = text2?.match(/^---\r?\n[\s\S]*?^name:\s*([a-z0-9][a-z0-9-]*)\s*$/m);
49697
49809
  if (!match?.[1] || builtinNames.includes(match[1]))
49698
49810
  unresolved("installed Gemini builtin name is missing or ambiguous");
@@ -49734,39 +49846,39 @@ function resolveAgentDiscovery(options) {
49734
49846
  function plugin(root) {
49735
49847
  root = canonical6(root);
49736
49848
  safe4(root);
49737
- const manifestPath = join23(root, agent === "claude" ? ".claude-plugin/plugin.json" : ".codex-plugin/plugin.json");
49849
+ const manifestPath = join24(root, agent === "claude" ? ".claude-plugin/plugin.json" : ".codex-plugin/plugin.json");
49738
49850
  const raw = witness(manifestPath);
49739
49851
  if (raw === null)
49740
49852
  unresolved("plugin manifest missing");
49741
49853
  const manifest = parseConfig(raw, manifestPath);
49742
- const hooks = witness(join23(root, "hooks/hooks.json"));
49854
+ const hooks = witness(join24(root, "hooks/hooks.json"));
49743
49855
  if (manifest.hooks !== undefined || hooks !== null)
49744
49856
  unresolved("plugin hooks require a separate no-skill-injection review");
49745
- const commands = join23(root, "commands");
49857
+ const commands = join24(root, "commands");
49746
49858
  safe4(commands);
49747
- if (agent === "claude" && (manifest.commands !== undefined || lstatSync16(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync6(commands).length))
49859
+ if (agent === "claude" && (manifest.commands !== undefined || lstatSync17(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync7(commands).length))
49748
49860
  unresolved("legacy command discovery requires retirement or a dedicated format adapter");
49749
- const rootSkill = witness(join23(root, "SKILL.md"));
49861
+ const rootSkill = witness(join24(root, "SKILL.md"));
49750
49862
  if (rootSkill !== null)
49751
49863
  roots.add(root);
49752
49864
  const declared = manifest.skills === undefined ? ["./skills"] : typeof manifest.skills === "string" ? [manifest.skills] : manifest.skills;
49753
49865
  if (!Array.isArray(declared) || declared.some((path) => typeof path !== "string"))
49754
49866
  unresolved("unsupported plugin skill paths");
49755
49867
  if (agent === "claude")
49756
- roots.add(join23(root, "skills"));
49868
+ roots.add(join24(root, "skills"));
49757
49869
  for (const value of declared) {
49758
- const path = resolve13(root, value);
49759
- if (path !== root && !path.startsWith(root + sep4))
49870
+ const path = resolve14(root, value);
49871
+ if (path !== root && !path.startsWith(root + sep5))
49760
49872
  unresolved("plugin skill path escapes its root");
49761
- roots.add(path.endsWith(`${sep4}SKILL.md`) ? dirname14(path) : path);
49873
+ roots.add(path.endsWith(`${sep5}SKILL.md`) ? dirname15(path) : path);
49762
49874
  }
49763
49875
  }
49764
49876
  if (agent === "claude") {
49765
- const registrations = witness(join23(home, ".claude/plugins/installed_plugins.json"));
49766
- const installed = registrations === null ? {} : parseConfig(registrations, join23(home, ".claude/plugins/installed_plugins.json")).plugins;
49767
- const commands = canonical6(join23(home, ".claude/commands"));
49877
+ const registrations = witness(join24(home, ".claude/plugins/installed_plugins.json"));
49878
+ const installed = registrations === null ? {} : parseConfig(registrations, join24(home, ".claude/plugins/installed_plugins.json")).plugins;
49879
+ const commands = canonical6(join24(home, ".claude/commands"));
49768
49880
  safe4(commands);
49769
- if (lstatSync16(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync6(commands).length)
49881
+ if (lstatSync17(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync7(commands).length)
49770
49882
  unresolved("legacy home command discovery requires a dedicated format adapter");
49771
49883
  for (const [id, enabled] of Object.entries(config2.enabledPlugins ?? {})) {
49772
49884
  if (enabled === false)
@@ -49788,16 +49900,16 @@ function resolveAgentDiscovery(options) {
49788
49900
  const market = config2.marketplaces?.[marketplace] ?? (marketplace === "personal" ? { source_type: "local", source: home } : undefined);
49789
49901
  if (split < 1 || market?.source_type !== "local" || typeof market.source !== "string" || !isAbsolute13(market.source))
49790
49902
  unresolved("enabled plugin marketplace is not an explicit local source");
49791
- const catalogText = witness(join23(market.source, ".agents/plugins/marketplace.json"));
49903
+ const catalogText = witness(join24(market.source, ".agents/plugins/marketplace.json"));
49792
49904
  if (catalogText === null)
49793
49905
  unresolved("marketplace catalog missing");
49794
- const catalog = parseConfig(catalogText, join23(market.source, ".agents/plugins/marketplace.json")), matches = Array.isArray(catalog.plugins) ? catalog.plugins.filter((item) => item.name === name) : [];
49906
+ const catalog = parseConfig(catalogText, join24(market.source, ".agents/plugins/marketplace.json")), matches = Array.isArray(catalog.plugins) ? catalog.plugins.filter((item) => item.name === name) : [];
49795
49907
  if (matches.length !== 1 || matches[0]?.source?.source !== "local" || typeof matches[0]?.source?.path !== "string")
49796
49908
  unresolved("plugin catalog source is missing or ambiguous");
49797
- plugin(resolve13(market.source, matches[0].source.path));
49909
+ plugin(resolve14(market.source, matches[0].source.path));
49798
49910
  }
49799
49911
  } else if (agent === "opencode") {
49800
- if (witness(join23(home, ".config/opencode/opencode.jsonc")) !== null || witness(join23(home, ".config/opencode/config.json")) !== null)
49912
+ if (witness(join24(home, ".config/opencode/opencode.jsonc")) !== null || witness(join24(home, ".config/opencode/config.json")) !== null)
49801
49913
  unresolved("additional config layers require review");
49802
49914
  if ((config2.plugin?.length ?? 0) > 0 || config2.skills?.urls?.length)
49803
49915
  unresolved("external plugin or remote skill source");
@@ -49806,14 +49918,14 @@ function resolveAgentDiscovery(options) {
49806
49918
  unresolved("relative or malformed added skill root");
49807
49919
  roots.add(path);
49808
49920
  }
49809
- const localPlugins = join23(home, ".config/opencode/plugins");
49921
+ const localPlugins = join24(home, ".config/opencode/plugins");
49810
49922
  safe4(localPlugins);
49811
- if (lstatSync16(localPlugins, { throwIfNoEntry: false }) && readdirSync6(localPlugins).some((name) => name !== "skills-cli.js"))
49923
+ if (lstatSync17(localPlugins, { throwIfNoEntry: false }) && readdirSync7(localPlugins).some((name) => name !== "skills-cli.js"))
49812
49924
  unresolved("additional local plugin hooks require review");
49813
49925
  } else if (agent === "hermes") {
49814
- for (const directory of [join23(home, ".hermes/plugins"), join23(home, ".hermes/hermes-agent")]) {
49926
+ for (const directory of [join24(home, ".hermes/plugins"), join24(home, ".hermes/hermes-agent")]) {
49815
49927
  safe4(directory);
49816
- if (lstatSync16(directory, { throwIfNoEntry: false }))
49928
+ if (lstatSync17(directory, { throwIfNoEntry: false }))
49817
49929
  unresolved("installed runtime/plugin discovery requires reviewed source bindings");
49818
49930
  }
49819
49931
  if (Bun.which("hermes") || Object.keys(config2.plugins ?? {}).length)
@@ -49821,24 +49933,24 @@ function resolveAgentDiscovery(options) {
49821
49933
  } else if (agent === "gemini") {
49822
49934
  if (Object.keys(config2.extensions ?? {}).length || config2.skills?.paths?.length)
49823
49935
  unresolved("custom extension or skill paths");
49824
- const directory = join23(home, ".gemini/extensions");
49936
+ const directory = join24(home, ".gemini/extensions");
49825
49937
  safe4(directory);
49826
- if (lstatSync16(directory, { throwIfNoEntry: false }))
49827
- for (const name of readdirSync6(directory)) {
49828
- const root = join23(directory, name);
49938
+ if (lstatSync17(directory, { throwIfNoEntry: false }))
49939
+ for (const name of readdirSync7(directory)) {
49940
+ const root = join24(directory, name);
49829
49941
  safe4(root);
49830
- if (!lstatSync16(root)?.isDirectory())
49942
+ if (!lstatSync17(root)?.isDirectory())
49831
49943
  continue;
49832
- const raw = witness(join23(root, "gemini-extension.json"));
49944
+ const raw = witness(join24(root, "gemini-extension.json"));
49833
49945
  if (raw === null)
49834
49946
  unresolved("extension registration missing");
49835
- const manifest = parseConfig(raw, join23(root, "gemini-extension.json"));
49836
- if (manifest.hooks !== undefined || witness(join23(root, "hooks/hooks.json")) !== null || witness(join23(root, ".gemini-extension-install.json")) !== null)
49947
+ const manifest = parseConfig(raw, join24(root, "gemini-extension.json"));
49948
+ if (manifest.hooks !== undefined || witness(join24(root, "hooks/hooks.json")) !== null || witness(join24(root, ".gemini-extension-install.json")) !== null)
49837
49949
  unresolved("extension hooks or linked registration require review");
49838
- roots.add(join23(root, "skills"));
49950
+ roots.add(join24(root, "skills"));
49839
49951
  }
49840
49952
  }
49841
- return { agent, roots: [...roots].sort(), sources, method: "automatic", ...agent === "gemini" ? { builtinNames } : {}, ...agent === "hermes" ? { directories: captureDiscoveryDirectories([join23(home, ".hermes/plugins"), join23(home, ".hermes/hermes-agent")].map((path) => canonical6(path))) } : {} };
49953
+ return { agent, roots: [...roots].sort(), sources, method: "automatic", ...agent === "gemini" ? { builtinNames } : {}, ...agent === "hermes" ? { directories: captureDiscoveryDirectories([join24(home, ".hermes/plugins"), join24(home, ".hermes/hermes-agent")].map((path) => canonical6(path))) } : {} };
49842
49954
  }
49843
49955
  var digest = (text2) => createHash16("sha256").update(text2).digest("hex");
49844
49956
  var init_agent_discovery = __esm(() => {
@@ -49853,15 +49965,17 @@ var init_agent_discovery = __esm(() => {
49853
49965
  init_claude_settings_witness();
49854
49966
  init_codex_hook_discovery_recovery();
49855
49967
  init_codex_settings_witness();
49968
+ init_codex_plugin_skill_controls();
49969
+ init_native_discovery_roots();
49856
49970
  init_agent_discovery_directories();
49857
49971
  });
49858
49972
 
49859
49973
  // src/lib/authoring-path.ts
49860
- import { lstatSync as lstatSync17, realpathSync as realpathSync4 } from "fs";
49974
+ import { lstatSync as lstatSync18, realpathSync as realpathSync5 } from "fs";
49861
49975
  import { homedir as homedir3 } from "os";
49862
- import { basename as basename8, dirname as dirname15, join as join24, resolve as resolve14, sep as sep5 } from "path";
49976
+ import { basename as basename9, dirname as dirname16, join as join25, resolve as resolve15, sep as sep6 } from "path";
49863
49977
  function pathParts(path) {
49864
- return resolve14(path).split(sep5).filter(Boolean);
49978
+ return resolve15(path).split(sep6).filter(Boolean);
49865
49979
  }
49866
49980
  function nativeRootMatch(path) {
49867
49981
  const parts = pathParts(path);
@@ -49875,24 +49989,24 @@ function nativeRootMatch(path) {
49875
49989
  return;
49876
49990
  }
49877
49991
  function physicalPath(path) {
49878
- let cursor = resolve14(path);
49992
+ let cursor = resolve15(path);
49879
49993
  const suffix = [];
49880
- while (!lstatSync17(cursor, { throwIfNoEntry: false })) {
49881
- suffix.unshift(basename8(cursor));
49882
- const parent = dirname15(cursor);
49994
+ while (!lstatSync18(cursor, { throwIfNoEntry: false })) {
49995
+ suffix.unshift(basename9(cursor));
49996
+ const parent = dirname16(cursor);
49883
49997
  if (parent === cursor)
49884
- return resolve14(path);
49998
+ return resolve15(path);
49885
49999
  cursor = parent;
49886
50000
  }
49887
- return resolve14(realpathSync4(cursor), ...suffix);
50001
+ return resolve15(realpathSync5(cursor), ...suffix);
49888
50002
  }
49889
50003
  function contains(root, path) {
49890
- return path === root || path.startsWith(root + sep5);
50004
+ return path === root || path.startsWith(root + sep6);
49891
50005
  }
49892
50006
  function configuredRoots(home, explicitHome) {
49893
- const homeData = join24(home, ".hasna", "skills");
50007
+ const homeData = join25(home, ".hasna", "skills");
49894
50008
  const homePolicy = readManagedSkillPolicySnapshot(homeData);
49895
- const configuredPolicy = !explicitHome && resolve14(getDataDirReadOnly()) !== resolve14(homeData) ? readManagedSkillPolicySnapshot(getDataDirReadOnly()) : null;
50009
+ const configuredPolicy = !explicitHome && resolve15(getDataDirReadOnly()) !== resolve15(homeData) ? readManagedSkillPolicySnapshot(getDataDirReadOnly()) : null;
49896
50010
  const policy = homePolicy ?? configuredPolicy;
49897
50011
  const bridge = policy?.value.bridge;
49898
50012
  if (bridge && (typeof bridge.home !== "string" || physicalPath(bridge.home) !== physicalPath(home))) {
@@ -49921,8 +50035,8 @@ function configuredRoots(home, explicitHome) {
49921
50035
  admitBinding(binding);
49922
50036
  continue;
49923
50037
  }
49924
- const nativeHome = join24(home, agent === "opencode" ? ".config/opencode" : `.${agent}`);
49925
- if (!lstatSync17(nativeHome, { throwIfNoEntry: false }))
50038
+ const nativeHome = join25(home, agent === "opencode" ? ".config/opencode" : `.${agent}`);
50039
+ if (!lstatSync18(nativeHome, { throwIfNoEntry: false }))
49926
50040
  continue;
49927
50041
  roots.push(...resolveAgentDiscovery({ home, agent, canonical: physicalPath }).roots);
49928
50042
  }
@@ -49931,22 +50045,22 @@ function configuredRoots(home, explicitHome) {
49931
50045
  function assertPortableAuthoringPath(path, options = {}) {
49932
50046
  if (typeof path !== "string" || !path || path.includes("\x00"))
49933
50047
  throw new Error("Invalid portable authoring path");
49934
- const lexical = resolve14(path);
50048
+ const lexical = resolve15(path);
49935
50049
  const physical = physicalPath(lexical);
49936
50050
  const candidates = [lexical, physical];
49937
50051
  let native = candidates.map(nativeRootMatch).find(Boolean);
49938
- const home = resolve14(options.homeDir ?? homedir3());
49939
- const defaults = NATIVE_DISCOVERY_ROOTS.map((parts) => join24(home, ...parts));
49940
- defaults.push(join24(home, ".codex/plugins/cache"), join24(home, ".claude/plugins/cache"), join24(home, ".claude/plugins/synced"), join24(home, ".gemini/extensions"));
50052
+ const home = resolve15(options.homeDir ?? homedir3());
50053
+ const defaults = NATIVE_DISCOVERY_ROOTS.map((parts) => join25(home, ...parts));
50054
+ defaults.push(join25(home, ".codex/plugins/cache"), join25(home, ".claude/plugins/cache"), join25(home, ".claude/plugins/synced"), join25(home, ".gemini/extensions"));
49941
50055
  for (const root of defaults) {
49942
- if (candidates.some((candidate) => contains(resolve14(root), candidate) || contains(physicalPath(root), candidate)))
50056
+ if (candidates.some((candidate) => contains(resolve15(root), candidate) || contains(physicalPath(root), candidate)))
49943
50057
  native ??= root;
49944
50058
  }
49945
50059
  if (native) {
49946
50060
  throw new Error(`Refusing portable Skills authoring below native discovery root '${native}': ${lexical}. Set HASNA_SKILLS_DIR to a private authoring corpus outside native roots.`);
49947
50061
  }
49948
50062
  for (const root of configuredRoots(home, options.homeDir !== undefined)) {
49949
- if (candidates.some((candidate) => contains(resolve14(root), candidate) || contains(physicalPath(root), candidate))) {
50063
+ if (candidates.some((candidate) => contains(resolve15(root), candidate) || contains(physicalPath(root), candidate))) {
49950
50064
  throw new Error(`Refusing portable Skills authoring below configured native discovery root: ${lexical}`);
49951
50065
  }
49952
50066
  }
@@ -49966,29 +50080,29 @@ import {
49966
50080
  existsSync as existsSync11,
49967
50081
  mkdirSync as mkdirSync7,
49968
50082
  mkdtempSync,
49969
- readdirSync as readdirSync7,
49970
- realpathSync as realpathSync5,
50083
+ readdirSync as readdirSync8,
50084
+ realpathSync as realpathSync6,
49971
50085
  renameSync as renameSync3,
49972
50086
  rmSync as rmSync3,
49973
50087
  statSync as statSync7,
49974
50088
  writeFileSync as writeFileSync6
49975
50089
  } from "fs";
49976
- import { basename as basename9, dirname as dirname16, isAbsolute as isAbsolute14, join as join25, normalize as normalize3, relative as relative4, resolve as resolve15, sep as sep6 } from "path";
50090
+ import { basename as basename10, dirname as dirname17, isAbsolute as isAbsolute14, join as join26, normalize as normalize3, relative as relative5, resolve as resolve16, sep as sep7 } from "path";
49977
50091
  function getPortableSkillsRoot(options = {}) {
49978
50092
  return resolvePortableSkillsRoot(options, true);
49979
50093
  }
49980
50094
  function resolvePortableSkillsRoot(options, migrate) {
49981
50095
  if (options.rootDir)
49982
50096
  return options.rootDir;
49983
- const appDir = options.homeDir ? join25(options.homeDir, ".hasna", "skills") : migrate ? getDataDir() : getDataDirReadOnly();
49984
- const cache = join25(appDir, SKILLS_CACHE_DIRNAME);
50097
+ const appDir = options.homeDir ? join26(options.homeDir, ".hasna", "skills") : migrate ? getDataDir() : getDataDirReadOnly();
50098
+ const cache = join26(appDir, SKILLS_CACHE_DIRNAME);
49985
50099
  if (isOwnerLayoutMigrated(appDir) && safeIsDirectory(cache))
49986
50100
  return cache;
49987
- const installed = join25(appDir, INSTALLED_SKILLS_DIRNAME);
50101
+ const installed = join26(appDir, INSTALLED_SKILLS_DIRNAME);
49988
50102
  return installed;
49989
50103
  }
49990
50104
  function getPortableSkillPath(name, options = {}) {
49991
- return join25(getPortableSkillsRoot(options), normalizePortableSkillName(name));
50105
+ return join26(getPortableSkillsRoot(options), normalizePortableSkillName(name));
49992
50106
  }
49993
50107
  function findPortableSkill(name, options = {}) {
49994
50108
  let normalized;
@@ -50011,10 +50125,10 @@ function listPortableSkills(options = {}) {
50011
50125
  if (!safeIsDirectory(root))
50012
50126
  return [];
50013
50127
  const skills = [];
50014
- for (const entry of readdirSync7(root).sort()) {
50128
+ for (const entry of readdirSync8(root).sort()) {
50015
50129
  if (entry.startsWith("."))
50016
50130
  continue;
50017
- const path = join25(root, entry);
50131
+ const path = join26(root, entry);
50018
50132
  if (!safeIsDirectory(path))
50019
50133
  continue;
50020
50134
  try {
@@ -50047,9 +50161,9 @@ function isOfficialSkillName(name) {
50047
50161
  function scaffoldPortableSkill(name, options = {}) {
50048
50162
  const skillName = normalizeNewPortableSkillName(name);
50049
50163
  const readOnlyRoot = resolvePortableSkillsRoot(options, false);
50050
- assertPortableAuthoringPath(join25(readOnlyRoot, skillName), options);
50164
+ assertPortableAuthoringPath(join26(readOnlyRoot, skillName), options);
50051
50165
  const root = getPortableSkillsRoot(options);
50052
- const skillPath = join25(root, skillName);
50166
+ const skillPath = join26(root, skillName);
50053
50167
  assertPortableAuthoringPath(skillPath, options);
50054
50168
  if (existsSync11(skillPath)) {
50055
50169
  if (!options.overwrite)
@@ -50068,20 +50182,20 @@ function scaffoldPortableSkill(name, options = {}) {
50068
50182
  return { name: skillName, path: skillPath, manifest, created: true };
50069
50183
  }
50070
50184
  function physicalImportPath(path) {
50071
- let ancestor = resolve15(path);
50185
+ let ancestor = resolve16(path);
50072
50186
  const suffix = [];
50073
50187
  while (!existsSync11(ancestor)) {
50074
- suffix.unshift(basename9(ancestor));
50075
- ancestor = dirname16(ancestor);
50188
+ suffix.unshift(basename10(ancestor));
50189
+ ancestor = dirname17(ancestor);
50076
50190
  }
50077
- return join25(realpathSync5(ancestor), ...suffix);
50191
+ return join26(realpathSync6(ancestor), ...suffix);
50078
50192
  }
50079
50193
  function assertDisjointImportPaths(source, destination) {
50080
- const sourcePath = realpathSync5(source);
50194
+ const sourcePath = realpathSync6(source);
50081
50195
  const destinationPath = physicalImportPath(destination);
50082
50196
  const contains2 = (parent, child) => {
50083
- const path = relative4(parent, child);
50084
- return path === "" || !isAbsolute14(path) && path !== ".." && !path.startsWith(`..${sep6}`);
50197
+ const path = relative5(parent, child);
50198
+ return path === "" || !isAbsolute14(path) && path !== ".." && !path.startsWith(`..${sep7}`);
50085
50199
  };
50086
50200
  if (contains2(sourcePath, destinationPath) || contains2(destinationPath, sourcePath)) {
50087
50201
  throw new Error("Source and destination skill directories must not overlap");
@@ -50096,15 +50210,15 @@ function portPortableSkill(sourcePath, options = {}) {
50096
50210
  const explicitName = options.name != null;
50097
50211
  const skillName = normalizeNewPortableSkillName(options.name ?? inferred.name);
50098
50212
  if (isOfficialSkillName(skillName) && !options.allowShadow) {
50099
- const sourceSlug = safeNormalizeName(basename9(absoluteSource));
50100
- const via = explicitName ? `Name '${skillName}' matches a bundled official skill.` : `Inferred name '${skillName}'${sourceSlug && sourceSlug !== skillName ? ` (from source folder '${basename9(absoluteSource)}')` : ""} matches a bundled official skill.`;
50213
+ const sourceSlug = safeNormalizeName(basename10(absoluteSource));
50214
+ const via = explicitName ? `Name '${skillName}' matches a bundled official skill.` : `Inferred name '${skillName}'${sourceSlug && sourceSlug !== skillName ? ` (from source folder '${basename10(absoluteSource)}')` : ""} matches a bundled official skill.`;
50101
50215
  throw new Error(`${via} Importing it would shadow the official '${skillName}'. ` + `Pass --name to choose a different name, or --allow-shadow to override deliberately.`);
50102
50216
  }
50103
- const readOnlyDestination = join25(resolvePortableSkillsRoot(options, false), skillName);
50217
+ const readOnlyDestination = join26(resolvePortableSkillsRoot(options, false), skillName);
50104
50218
  assertPortableAuthoringPath(readOnlyDestination, options);
50105
50219
  assertDisjointImportPaths(absoluteSource, readOnlyDestination);
50106
50220
  const root = getPortableSkillsRoot(options);
50107
- const destination = join25(root, skillName);
50221
+ const destination = join26(root, skillName);
50108
50222
  assertPortableAuthoringPath(destination, options);
50109
50223
  assertDisjointImportPaths(absoluteSource, destination);
50110
50224
  if (existsSync11(destination)) {
@@ -50112,7 +50226,7 @@ function portPortableSkill(sourcePath, options = {}) {
50112
50226
  throw new Error(`Skill '${skillName}' already exists at ${destination}`);
50113
50227
  rmSync3(destination, { recursive: true, force: true });
50114
50228
  }
50115
- mkdirSync7(dirname16(destination), { recursive: true });
50229
+ mkdirSync7(dirname17(destination), { recursive: true });
50116
50230
  copySkillDirectory(absoluteSource, destination);
50117
50231
  const base = {
50118
50232
  ...inferred,
@@ -50136,8 +50250,8 @@ function validatePortableSkillDirectory(name, skillPath) {
50136
50250
  const warnings = [...base.warnings];
50137
50251
  let manifest;
50138
50252
  if (existsSync11(skillPath)) {
50139
- const skillJsonPath = join25(skillPath, "skill.json");
50140
- const skillMdPath = join25(skillPath, "SKILL.md");
50253
+ const skillJsonPath = join26(skillPath, "skill.json");
50254
+ const skillMdPath = join26(skillPath, "SKILL.md");
50141
50255
  if (!existsSync11(skillJsonPath) && !existsSync11(skillMdPath)) {
50142
50256
  add3(issues, "portable.manifest_missing", "Missing portable manifest: expected SKILL.md frontmatter and/or skill.json");
50143
50257
  }
@@ -50157,7 +50271,7 @@ function validatePortableSkillDirectory(name, skillPath) {
50157
50271
  add3(issues, "portable.version_missing", "Portable manifest missing version");
50158
50272
  }
50159
50273
  const contractIssues = validatePortableManifestContract(manifest, {
50160
- strict: existsSync11(join25(skillPath, "skill.json")),
50274
+ strict: existsSync11(join26(skillPath, "skill.json")),
50161
50275
  skillPath
50162
50276
  });
50163
50277
  for (const issue2 of contractIssues)
@@ -50197,7 +50311,7 @@ function validatePortableSkillDirectory(name, skillPath) {
50197
50311
  add3(issues, "portable.command_entry_unsafe", `Command '${command.name}' entry '${command.entry}' must stay inside the skill directory`);
50198
50312
  continue;
50199
50313
  }
50200
- const entryPath = join25(skillPath, command.entry);
50314
+ const entryPath = join26(skillPath, command.entry);
50201
50315
  if (!existsSync11(entryPath))
50202
50316
  add3(issues, "portable.command_entry_missing", `Command '${command.name}' entry '${command.entry}' is missing`);
50203
50317
  else if (statSync7(entryPath).isDirectory())
@@ -50208,7 +50322,7 @@ function validatePortableSkillDirectory(name, skillPath) {
50208
50322
  } catch (error61) {
50209
50323
  add3(issues, "portable.manifest_invalid", error61.message);
50210
50324
  }
50211
- if (manifest?.kind !== "instruction" && !existsSync11(join25(skillPath, "AGENTS.md"))) {
50325
+ if (manifest?.kind !== "instruction" && !existsSync11(join26(skillPath, "AGENTS.md"))) {
50212
50326
  add3(issues, "portable.agents_missing", "Missing AGENTS.md with build-out instructions for coding agents");
50213
50327
  }
50214
50328
  }
@@ -50435,8 +50549,8 @@ var init_search = __esm(() => {
50435
50549
  });
50436
50550
 
50437
50551
  // src/lib/registry.ts
50438
- import { existsSync as existsSync12, readFileSync as readFileSync16, readdirSync as readdirSync8 } from "fs";
50439
- import { join as join26 } from "path";
50552
+ import { existsSync as existsSync12, readFileSync as readFileSync16, readdirSync as readdirSync9 } from "fs";
50553
+ import { join as join27 } from "path";
50440
50554
  function parseSkillMdFrontmatter(content) {
50441
50555
  const match = content.match(/^---\n([\s\S]*?)\n---/);
50442
50556
  if (!match)
@@ -50473,11 +50587,11 @@ function discoverSkillsInDir(dir, source = "custom") {
50473
50587
  return [];
50474
50588
  const result = [];
50475
50589
  try {
50476
- const entries = readdirSync8(dir, { withFileTypes: true });
50590
+ const entries = readdirSync9(dir, { withFileTypes: true });
50477
50591
  for (const entry of entries) {
50478
50592
  if (!entry.isDirectory())
50479
50593
  continue;
50480
- const skillMdPath = join26(dir, entry.name, "SKILL.md");
50594
+ const skillMdPath = join27(dir, entry.name, "SKILL.md");
50481
50595
  if (!existsSync12(skillMdPath))
50482
50596
  continue;
50483
50597
  let content;
@@ -50497,7 +50611,7 @@ function discoverSkillsInDir(dir, source = "custom") {
50497
50611
  category: fm.category || "Development Tools",
50498
50612
  tags: fm.tags || [],
50499
50613
  ...fm.kind ? { kind: fm.kind } : {},
50500
- ...isHostedMetadataSkillDir(join26(dir, entry.name)) ? { serverOwned: true } : {},
50614
+ ...isHostedMetadataSkillDir(join27(dir, entry.name)) ? { serverOwned: true } : {},
50501
50615
  source
50502
50616
  });
50503
50617
  }
@@ -50509,12 +50623,12 @@ function findExtensionSkillPath(name) {
50509
50623
  if (!config2.extensionsDir || !existsSync12(config2.extensionsDir))
50510
50624
  return null;
50511
50625
  try {
50512
- const entries = readdirSync8(config2.extensionsDir, { withFileTypes: true });
50626
+ const entries = readdirSync9(config2.extensionsDir, { withFileTypes: true });
50513
50627
  for (const entry of entries) {
50514
50628
  if (!entry.isDirectory())
50515
50629
  continue;
50516
- const skillDir = join26(config2.extensionsDir, entry.name);
50517
- const skillMdPath = join26(skillDir, "SKILL.md");
50630
+ const skillDir = join27(config2.extensionsDir, entry.name);
50631
+ const skillMdPath = join27(skillDir, "SKILL.md");
50518
50632
  if (!existsSync12(skillMdPath))
50519
50633
  continue;
50520
50634
  let content;
@@ -51712,13 +51826,13 @@ var init_remote_workspace_leave = __esm(() => {
51712
51826
 
51713
51827
  // src/lib/auth-store.ts
51714
51828
  import { chmodSync, existsSync as existsSync13, mkdirSync as mkdirSync8, readFileSync as readFileSync17, renameSync as renameSync4, statSync as statSync8, unlinkSync as unlinkSync4, writeFileSync as writeFileSync7 } from "fs";
51715
- import { basename as basename10, dirname as dirname17, join as join27 } from "path";
51829
+ import { basename as basename11, dirname as dirname18, join as join28 } from "path";
51716
51830
  function getAuthFilePath(env = process.env) {
51717
51831
  return skillsCredentialFilePath(env);
51718
51832
  }
51719
51833
  function getIdentityFilePath(env = process.env) {
51720
51834
  const file2 = skillsCredentialFilePath(env);
51721
- return join27(dirname17(file2), basename10(file2).replace(/^credentials/, "identity") + ".json");
51835
+ return join28(dirname18(file2), basename11(file2).replace(/^credentials/, "identity") + ".json");
51722
51836
  }
51723
51837
  function getApiUrl(action, env = process.env, options = {}) {
51724
51838
  return requireSkillsApiOrigin(action, env, options);
@@ -51946,10 +52060,10 @@ async function readQuoteUnavailableCode(response) {
51946
52060
  let timer;
51947
52061
  let deadlineExceeded = false;
51948
52062
  const expired = Symbol("quote body deadline");
51949
- const deadline = new Promise((resolve16) => {
52063
+ const deadline = new Promise((resolve17) => {
51950
52064
  timer = setTimeout(() => {
51951
52065
  deadlineExceeded = true;
51952
- resolve16(expired);
52066
+ resolve17(expired);
51953
52067
  reader.cancel().catch(() => {});
51954
52068
  }, 1500);
51955
52069
  });
@@ -53432,12 +53546,12 @@ class RemotePrivatePublicationsClient {
53432
53546
  previous = view;
53433
53547
  if (!["queued", "verifying"].includes(view.state) || Date.now() >= until)
53434
53548
  return view;
53435
- await new Promise((resolve16) => {
53549
+ await new Promise((resolve17) => {
53436
53550
  const timer = setTimeout(done, Math.min(1000, until - Date.now()));
53437
53551
  function done() {
53438
53552
  clearTimeout(timer);
53439
53553
  options.signal?.removeEventListener("abort", done);
53440
- resolve16();
53554
+ resolve17();
53441
53555
  }
53442
53556
  options.signal?.addEventListener("abort", done, { once: true });
53443
53557
  });
@@ -53725,10 +53839,10 @@ var init_remote_auth = __esm(() => {
53725
53839
  });
53726
53840
 
53727
53841
  // src/lib/workspace-profile.ts
53728
- import { constants as constants11, closeSync as closeSync14, fstatSync as fstatSync14, lstatSync as lstatSync18, mkdirSync as mkdirSync9, mkdtempSync as mkdtempSync2, openSync as openSync14, readFileSync as readFileSync18, renameSync as renameSync5, rmSync as rmSync4, writeFileSync as writeFileSync8 } from "fs";
53842
+ import { constants as constants11, closeSync as closeSync14, fstatSync as fstatSync14, lstatSync as lstatSync19, mkdirSync as mkdirSync9, mkdtempSync as mkdtempSync2, openSync as openSync14, readFileSync as readFileSync18, renameSync as renameSync5, rmSync as rmSync4, writeFileSync as writeFileSync8 } from "fs";
53729
53843
  function stat2(path) {
53730
53844
  try {
53731
- return lstatSync18(path);
53845
+ return lstatSync19(path);
53732
53846
  } catch (error61) {
53733
53847
  if (error61.code === "ENOENT")
53734
53848
  return null;
@@ -53957,8 +54071,8 @@ var init_recurring_customer = __esm(() => {
53957
54071
  });
53958
54072
 
53959
54073
  // src/lib/recurring-recovery.ts
53960
- import { constants as constants12, closeSync as closeSync15, fsyncSync as fsyncSync4, fstatSync as fstatSync15, lstatSync as lstatSync19, mkdirSync as mkdirSync10, openSync as openSync15, readSync as readSync10, realpathSync as realpathSync6, renameSync as renameSync6, unlinkSync as unlinkSync5, writeFileSync as writeFileSync9 } from "fs";
53961
- import { dirname as dirname18, isAbsolute as isAbsolute15, join as join28, resolve as resolve16 } from "path";
54074
+ import { constants as constants12, closeSync as closeSync15, fsyncSync as fsyncSync4, fstatSync as fstatSync15, lstatSync as lstatSync20, mkdirSync as mkdirSync10, openSync as openSync15, readSync as readSync10, realpathSync as realpathSync7, renameSync as renameSync6, unlinkSync as unlinkSync5, writeFileSync as writeFileSync9 } from "fs";
54075
+ import { dirname as dirname19, isAbsolute as isAbsolute15, join as join29, resolve as resolve17 } from "path";
53962
54076
  import { randomUUID as randomUUID2 } from "crypto";
53963
54077
 
53964
54078
  class RecoveryOwner {
@@ -53966,33 +54080,33 @@ class RecoveryOwner {
53966
54080
  parents = [];
53967
54081
  constructor(directory) {
53968
54082
  this.directory = directory;
53969
- if (!isAbsolute15(directory) || resolve16(directory) !== directory || realpathSync6(directory) !== directory)
54083
+ if (!isAbsolute15(directory) || resolve17(directory) !== directory || realpathSync7(directory) !== directory)
53970
54084
  invalid5();
53971
- for (let path = directory;; path = dirname18(path)) {
53972
- const stat3 = lstatSync19(path);
54085
+ for (let path = directory;; path = dirname19(path)) {
54086
+ const stat3 = lstatSync20(path);
53973
54087
  if (!stat3.isDirectory() || stat3.isSymbolicLink())
53974
54088
  invalid5();
53975
54089
  this.parents.push({ path, dev: stat3.dev, ino: stat3.ino });
53976
- if (path === dirname18(path))
54090
+ if (path === dirname19(path))
53977
54091
  break;
53978
54092
  }
53979
54093
  this.assert();
53980
54094
  }
53981
54095
  assert() {
53982
- if (realpathSync6(this.directory) !== this.directory)
54096
+ if (realpathSync7(this.directory) !== this.directory)
53983
54097
  invalid5();
53984
54098
  for (const prior of this.parents) {
53985
- const now = lstatSync19(prior.path);
54099
+ const now = lstatSync20(prior.path);
53986
54100
  if (!now.isDirectory() || now.isSymbolicLink() || now.dev !== prior.dev || now.ino !== prior.ino)
53987
54101
  invalid5();
53988
54102
  }
53989
- const own2 = lstatSync19(this.directory);
54103
+ const own2 = lstatSync20(this.directory);
53990
54104
  if ((own2.mode & 511) !== 448 || (own2.mode & 3584) !== 0 || process.getuid && own2.uid !== process.getuid())
53991
54105
  invalid5();
53992
54106
  }
53993
54107
  read(name) {
53994
54108
  this.assert();
53995
- const fd = openSync15(join28(this.directory, name), constants12.O_RDONLY | constants12.O_NOFOLLOW | constants12.O_NONBLOCK);
54109
+ const fd = openSync15(join29(this.directory, name), constants12.O_RDONLY | constants12.O_NOFOLLOW | constants12.O_NONBLOCK);
53996
54110
  try {
53997
54111
  const before = fstatSync15(fd);
53998
54112
  if (!before.isFile() || before.nlink !== 1 || (before.mode & 4095) !== 384 || before.size < 1 || before.size > 8192 || process.getuid && before.uid !== process.getuid())
@@ -54005,7 +54119,7 @@ class RecoveryOwner {
54005
54119
  break;
54006
54120
  size += n2;
54007
54121
  }
54008
- const after = fstatSync15(fd), path = lstatSync19(join28(this.directory, name));
54122
+ const after = fstatSync15(fd), path = lstatSync20(join29(this.directory, name));
54009
54123
  if (size !== before.size || after.size !== before.size || before.mtimeMs !== after.mtimeMs || before.ctimeMs !== after.ctimeMs || path.dev !== before.dev || path.ino !== before.ino || !path.isFile() || path.isSymbolicLink())
54010
54124
  invalid5();
54011
54125
  this.assert();
@@ -54018,7 +54132,7 @@ class RecoveryOwner {
54018
54132
  this.assert();
54019
54133
  const bytes = canonicalJson2(value, 8192) + `
54020
54134
  `;
54021
- const fd = openSync15(join28(this.directory, name), constants12.O_WRONLY | constants12.O_CREAT | constants12.O_EXCL | constants12.O_NOFOLLOW, 384);
54135
+ const fd = openSync15(join29(this.directory, name), constants12.O_WRONLY | constants12.O_CREAT | constants12.O_EXCL | constants12.O_NOFOLLOW, 384);
54022
54136
  try {
54023
54137
  writeFileSync9(fd, bytes);
54024
54138
  fsyncSync4(fd);
@@ -54045,14 +54159,14 @@ class RecoveryOwner {
54045
54159
  if (this.read("state.json") !== expected)
54046
54160
  invalid5();
54047
54161
  this.assert();
54048
- renameSync6(join28(this.directory, name), join28(this.directory, "state.json"));
54162
+ renameSync6(join29(this.directory, name), join29(this.directory, "state.json"));
54049
54163
  this.sync();
54050
54164
  }
54051
54165
  async locked(action) {
54052
54166
  this.assert();
54053
54167
  let fd;
54054
54168
  try {
54055
- fd = openSync15(join28(this.directory, "operation.lock"), constants12.O_WRONLY | constants12.O_CREAT | constants12.O_EXCL | constants12.O_NOFOLLOW, 384);
54169
+ fd = openSync15(join29(this.directory, "operation.lock"), constants12.O_WRONLY | constants12.O_CREAT | constants12.O_EXCL | constants12.O_NOFOLLOW, 384);
54056
54170
  } catch {
54057
54171
  throw new RecurringCustomerError("RECURRING_RECOVERY_BUSY", "Recovery is locked. Confirm the original process has stopped before explicitly reconciling the retained lock; no request was retried.");
54058
54172
  }
@@ -54065,10 +54179,10 @@ class RecoveryOwner {
54065
54179
  } finally {
54066
54180
  closeSync15(fd);
54067
54181
  this.assert();
54068
- const now = lstatSync19(join28(this.directory, "operation.lock"));
54182
+ const now = lstatSync20(join29(this.directory, "operation.lock"));
54069
54183
  if (owner2.dev !== now.dev || owner2.ino !== now.ino || !now.isFile() || now.isSymbolicLink())
54070
54184
  invalid5();
54071
- unlinkSync5(join28(this.directory, "operation.lock"));
54185
+ unlinkSync5(join29(this.directory, "operation.lock"));
54072
54186
  this.sync();
54073
54187
  }
54074
54188
  }
@@ -54101,7 +54215,7 @@ function base(customer, organizationId) {
54101
54215
  };
54102
54216
  }
54103
54217
  function create(directory, intent) {
54104
- if (!isAbsolute15(directory) || resolve16(directory) !== directory || realpathSync6(dirname18(directory)) !== dirname18(directory))
54218
+ if (!isAbsolute15(directory) || resolve17(directory) !== directory || realpathSync7(dirname19(directory)) !== dirname19(directory))
54105
54219
  invalid5();
54106
54220
  mkdirSync10(directory, { mode: 448 });
54107
54221
  const owner2 = new RecoveryOwner(directory), checked = intentSchema.parse(intent), intentSha256 = canonicalJsonSha256(checked);
@@ -56199,20 +56313,20 @@ var init_credential_state = __esm(() => {
56199
56313
 
56200
56314
  // src/lib/run-state.ts
56201
56315
  import { createHash as createHash19, randomBytes } from "crypto";
56202
- import { existsSync as existsSync14, mkdirSync as mkdirSync11, readFileSync as readFileSync19, readdirSync as readdirSync9, statSync as statSync9, writeFileSync as writeFileSync10 } from "fs";
56203
- import { extname, join as join29, relative as relative5 } from "path";
56316
+ import { existsSync as existsSync14, mkdirSync as mkdirSync11, readFileSync as readFileSync19, readdirSync as readdirSync10, statSync as statSync9, writeFileSync as writeFileSync10 } from "fs";
56317
+ import { extname, join as join30, relative as relative6 } from "path";
56204
56318
  function createSkillRun(params, targetDir = process.cwd()) {
56205
56319
  const now = new Date;
56206
56320
  const id = createRunId(now);
56207
56321
  const day = now.toISOString().slice(0, 10);
56208
56322
  const skillName = normalizeSkillName(params.skill);
56209
56323
  const root = getProjectStateDir(targetDir);
56210
- const runDir = join29(root, "runs", day, id);
56211
- const logsDir = join29(runDir, "logs");
56212
- const exportDir = join29(root, "exports", skillName, id);
56324
+ const runDir = join30(root, "runs", day, id);
56325
+ const logsDir = join30(runDir, "logs");
56326
+ const exportDir = join30(root, "exports", skillName, id);
56213
56327
  mkdirSync11(logsDir, { recursive: true });
56214
56328
  mkdirSync11(exportDir, { recursive: true });
56215
- mkdirSync11(join29(root, "tmp"), { recursive: true });
56329
+ mkdirSync11(join30(root, "tmp"), { recursive: true });
56216
56330
  const record10 = {
56217
56331
  id,
56218
56332
  skill: skillName,
@@ -56264,22 +56378,22 @@ function updateSkillRun(context2, patch) {
56264
56378
  return context2.record;
56265
56379
  }
56266
56380
  function writeRunLogs(context2, stdout = "", stderr = "") {
56267
- writeFileSync10(join29(context2.logsDir, "stdout.log"), stdout);
56268
- writeFileSync10(join29(context2.logsDir, "stderr.log"), stderr);
56381
+ writeFileSync10(join30(context2.logsDir, "stdout.log"), stdout);
56382
+ writeFileSync10(join30(context2.logsDir, "stderr.log"), stderr);
56269
56383
  }
56270
56384
  function appendRunEvent(context2, event, data = {}) {
56271
56385
  const line = JSON.stringify({ ts: new Date().toISOString(), event, ...data }) + `
56272
56386
  `;
56273
- const path = join29(context2.runDir, "events.ndjson");
56387
+ const path = join30(context2.runDir, "events.ndjson");
56274
56388
  const previous = existsSync14(path) ? readFileSync19(path, "utf-8") : "";
56275
56389
  writeFileSync10(path, previous + line);
56276
56390
  }
56277
56391
  function findSkillRun(runId, targetDir = process.cwd()) {
56278
- const runsRoot = join29(getProjectStateDir(targetDir), "runs");
56392
+ const runsRoot = join30(getProjectStateDir(targetDir), "runs");
56279
56393
  if (!existsSync14(runsRoot))
56280
56394
  return null;
56281
- for (const day of readdirSync9(runsRoot)) {
56282
- const record10 = readRunRecord(join29(runsRoot, day, runId));
56395
+ for (const day of readdirSync10(runsRoot)) {
56396
+ const record10 = readRunRecord(join30(runsRoot, day, runId));
56283
56397
  if (record10)
56284
56398
  return record10;
56285
56399
  }
@@ -56296,11 +56410,11 @@ function skillRunEnv(context2) {
56296
56410
  };
56297
56411
  }
56298
56412
  function writeRunRecord(context2) {
56299
- writeFileSync10(join29(context2.runDir, "run.json"), JSON.stringify(context2.record, null, 2) + `
56413
+ writeFileSync10(join30(context2.runDir, "run.json"), JSON.stringify(context2.record, null, 2) + `
56300
56414
  `);
56301
56415
  }
56302
56416
  function writeArtifactsManifest(context2, artifacts) {
56303
- writeFileSync10(join29(context2.runDir, "artifacts.json"), JSON.stringify({ runId: context2.record.id, artifacts }, null, 2) + `
56417
+ writeFileSync10(join30(context2.runDir, "artifacts.json"), JSON.stringify({ runId: context2.record.id, artifacts }, null, 2) + `
56304
56418
  `);
56305
56419
  }
56306
56420
  function collectRunArtifacts(context2) {
@@ -56320,7 +56434,7 @@ function collectRunArtifacts(context2) {
56320
56434
  return artifacts.sort((a, b) => a.path.localeCompare(b.path));
56321
56435
  }
56322
56436
  function readRunRecord(runDir) {
56323
- const path = join29(runDir, "run.json");
56437
+ const path = join30(runDir, "run.json");
56324
56438
  if (!existsSync14(path))
56325
56439
  return null;
56326
56440
  try {
@@ -56331,8 +56445,8 @@ function readRunRecord(runDir) {
56331
56445
  }
56332
56446
  function walkFiles(dir) {
56333
56447
  const files = [];
56334
- for (const entry of readdirSync9(dir)) {
56335
- const full = join29(dir, entry);
56448
+ for (const entry of readdirSync10(dir)) {
56449
+ const full = join30(dir, entry);
56336
56450
  if (statSync9(full).isDirectory())
56337
56451
  files.push(...walkFiles(full));
56338
56452
  else
@@ -56344,7 +56458,7 @@ function createRunId(now) {
56344
56458
  return `run_${now.getTime().toString(36)}_${randomBytes(4).toString("hex")}`;
56345
56459
  }
56346
56460
  function toProjectRelative(targetDir, path) {
56347
- const rel = relative5(targetDir, path).split(/[\\/]/).join("/");
56461
+ const rel = relative6(targetDir, path).split(/[\\/]/).join("/");
56348
56462
  return rel.startsWith(".") ? rel : `./${rel}`;
56349
56463
  }
56350
56464
  function mimeForPath(path) {
@@ -56589,7 +56703,7 @@ import { closeSync as closeSync16, fstatSync as fstatSync16, openSync as openSyn
56589
56703
  import { O_NOFOLLOW as O_NOFOLLOW3, O_NONBLOCK as O_NONBLOCK3, O_RDONLY as O_RDONLY3 } from "constants";
56590
56704
  import { createRequire as createRequire2 } from "module";
56591
56705
  import { hostname as osHostname2 } from "os";
56592
- import { isAbsolute as isAbsolute17, join as join30 } from "path";
56706
+ import { isAbsolute as isAbsolute17, join as join31 } from "path";
56593
56707
  import { createRequire as createRequire22 } from "module";
56594
56708
  function envToken2(name) {
56595
56709
  return name.toUpperCase().replace(/-/g, "_");
@@ -56620,14 +56734,14 @@ function hasnaHomeDir2(env) {
56620
56734
  if (override)
56621
56735
  return override;
56622
56736
  const home = homeDir2(env);
56623
- return home ? join30(home, HASNA_HOME_DIR2) : null;
56737
+ return home ? join31(home, HASNA_HOME_DIR2) : null;
56624
56738
  }
56625
56739
  function appConfigDir2(name, env) {
56626
56740
  const configRoot = absoluteOverride2(env, HASNA_CONFIG_HOME_ENV_KEY2);
56627
56741
  if (configRoot)
56628
- return join30(configRoot, name);
56742
+ return join31(configRoot, name);
56629
56743
  const root = hasnaHomeDir2(env);
56630
- return root ? join30(root, name, CONFIG_SUBDIR2) : null;
56744
+ return root ? join31(root, name, CONFIG_SUBDIR2) : null;
56631
56745
  }
56632
56746
  function credentialDiskSourceList2(name, env, profile = null) {
56633
56747
  if (!SAFE_APP_SLUG2.test(name))
@@ -56636,7 +56750,7 @@ function credentialDiskSourceList2(name, env, profile = null) {
56636
56750
  if (!directory2)
56637
56751
  return [];
56638
56752
  const file2 = profile ? `${CREDENTIALS_FILE2}-${profile}` : CREDENTIALS_FILE2;
56639
- return [{ path: join30(directory2, file2), tier: "disk" }];
56753
+ return [{ path: join31(directory2, file2), tier: "disk" }];
56640
56754
  }
56641
56755
  function credentialDiskSources2(name, env) {
56642
56756
  return credentialDiskSourceList2(name, env, null).map((s) => s.path);
@@ -57750,7 +57864,7 @@ function createSecretsClientFromEnv(env = process.env, overrides = {}) {
57750
57864
  });
57751
57865
  return new SecretsClient({ ...clientOverrides, baseUrl, apiKey });
57752
57866
  }
57753
- var __esm2 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), CREDENTIAL_PROFILE_ENV_KEY2 = "HASNA_PROFILE", CredentialResolutionError2, CredentialFileUnsafeError2, HASNA_HOME_ENV_KEY2 = "HASNA_HOME", HASNA_CONFIG_HOME_ENV_KEY2 = "HASNA_CONFIG_HOME", KEYCHAIN_STATION_ENV_KEY2 = "HASNA_STATION", HASNA_HOME_DIR2 = ".hasna", CONFIG_SUBDIR2 = "config", CREDENTIALS_FILE2 = "credentials", KEYCHAIN_SECURITY_BIN2 = "/usr/bin/security", KEYCHAIN_SERVICE_PREFIX2 = "hasna.credentials", KEYCHAIN_ITEM_NOT_FOUND_STATUS2 = 44, KEYCHAIN_SPAWN_TIMEOUT_MS2 = 1e4, MAX_CREDENTIAL_FILE_BYTES2, SAFE_APP_SLUG2, SAFE_PROFILE2, ILLEGAL_IN_HEADER_VALUE2, VAULT_POINTER_SHAPE2, CREDENTIAL_SHAPED_KEY2, INSPECT_CUSTOM2, CREDENTIAL_SEAL2, CALLER_SUPPLIED_CREDENTIAL_PROVIDER_SOURCE = "caller-supplied CredentialProvider", AMBIENT_ENVIRONMENT2, SECRETS_PACKAGE_SPECIFIER, requireSecretsSdk2, DEFAULT_FLEET_GATEWAY_ORIGIN2 = "https://api.hasna.com", DEFAULT_AUTHORITY_SOURCE = "default", ASCII_CONTROL_PATTERN2, DNS_LABEL_PATTERN2, ClientTransportConfigurationError2, HasnaHttpError, DEFAULT_RETRY_STATUSES, IDEMPOTENT_METHODS2, AUTHORITY_OVERRIDE_HEADERS2, defaultSleep = (ms) => new Promise((resolve17) => setTimeout(resolve17, ms)), init_transport2, MAX_CREDENTIAL_FILE_BYTES22, INSPECT_CUSTOM22, CREDENTIAL_SEAL22, AMBIENT_ENVIRONMENT22, SECRETS_PACKAGE_SPECIFIER2, requireSecretsSdk22, IDEMPOTENT_METHODS22, AUTHORITY_OVERRIDE_HEADERS22, init_storage, PATHS_RESOLVER_APP_SLUG_RE2, SQLITE_SIDECAR_FILES, LEGACY_SERVICE_FILES, init_data_dir, SecretsTestIsolationError, TEST_ENTRYPOINT_RE, init_test_isolation, init_client, ApiError;
57867
+ var __esm2 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), CREDENTIAL_PROFILE_ENV_KEY2 = "HASNA_PROFILE", CredentialResolutionError2, CredentialFileUnsafeError2, HASNA_HOME_ENV_KEY2 = "HASNA_HOME", HASNA_CONFIG_HOME_ENV_KEY2 = "HASNA_CONFIG_HOME", KEYCHAIN_STATION_ENV_KEY2 = "HASNA_STATION", HASNA_HOME_DIR2 = ".hasna", CONFIG_SUBDIR2 = "config", CREDENTIALS_FILE2 = "credentials", KEYCHAIN_SECURITY_BIN2 = "/usr/bin/security", KEYCHAIN_SERVICE_PREFIX2 = "hasna.credentials", KEYCHAIN_ITEM_NOT_FOUND_STATUS2 = 44, KEYCHAIN_SPAWN_TIMEOUT_MS2 = 1e4, MAX_CREDENTIAL_FILE_BYTES2, SAFE_APP_SLUG2, SAFE_PROFILE2, ILLEGAL_IN_HEADER_VALUE2, VAULT_POINTER_SHAPE2, CREDENTIAL_SHAPED_KEY2, INSPECT_CUSTOM2, CREDENTIAL_SEAL2, CALLER_SUPPLIED_CREDENTIAL_PROVIDER_SOURCE = "caller-supplied CredentialProvider", AMBIENT_ENVIRONMENT2, SECRETS_PACKAGE_SPECIFIER, requireSecretsSdk2, DEFAULT_FLEET_GATEWAY_ORIGIN2 = "https://api.hasna.com", DEFAULT_AUTHORITY_SOURCE = "default", ASCII_CONTROL_PATTERN2, DNS_LABEL_PATTERN2, ClientTransportConfigurationError2, HasnaHttpError, DEFAULT_RETRY_STATUSES, IDEMPOTENT_METHODS2, AUTHORITY_OVERRIDE_HEADERS2, defaultSleep = (ms) => new Promise((resolve18) => setTimeout(resolve18, ms)), init_transport2, MAX_CREDENTIAL_FILE_BYTES22, INSPECT_CUSTOM22, CREDENTIAL_SEAL22, AMBIENT_ENVIRONMENT22, SECRETS_PACKAGE_SPECIFIER2, requireSecretsSdk22, IDEMPOTENT_METHODS22, AUTHORITY_OVERRIDE_HEADERS22, init_storage, PATHS_RESOLVER_APP_SLUG_RE2, SQLITE_SIDECAR_FILES, LEGACY_SERVICE_FILES, init_data_dir, SecretsTestIsolationError, TEST_ENTRYPOINT_RE, init_test_isolation, init_client, ApiError;
57754
57868
  var init_sdk = __esm(() => {
57755
57869
  init_transport2 = __esm2(() => {
57756
57870
  CredentialResolutionError2 = class CredentialResolutionError3 extends Error {
@@ -57885,25 +57999,25 @@ var init_sdk = __esm(() => {
57885
57999
  });
57886
58000
 
57887
58001
  // src/lib/execution-secrets.ts
57888
- import { constants as constants13, closeSync as closeSync17, fstatSync as fstatSync17, openSync as openSync17, readSync as readSync11, realpathSync as realpathSync7 } from "fs";
58002
+ import { constants as constants13, closeSync as closeSync17, fstatSync as fstatSync17, openSync as openSync17, readSync as readSync11, realpathSync as realpathSync8 } from "fs";
57889
58003
  import { hostname as stationHostname } from "os";
57890
58004
  function selectedSecretBindingsTemplate(scope, names, createClient = createSecretsClientFromEnv) {
57891
58005
  let secretsAuthority;
57892
58006
  try {
57893
58007
  secretsAuthority = createClient().baseUrl;
57894
58008
  } catch {
57895
- return refuse("LOCAL_SECRET_UNAVAILABLE", "Configure the Secrets CLI authority and authentication before preparing execution bindings.");
58009
+ return refuse2("LOCAL_SECRET_UNAVAILABLE", "Configure the Secrets CLI authority and authentication before preparing execution bindings.");
57896
58010
  }
57897
58011
  const { authority, workspaceId, profileRevision, slug: slug2, version: version2, bundleDigest } = scope.selection;
57898
58012
  return {
57899
58013
  schema: "hasna.skills-secret-bindings.v1",
57900
58014
  selection: { authority, workspaceId, profileId: scope.profileId, profileRevision, slug: slug2, version: version2, bundleDigest },
57901
- consumer: { stationId: process.env.HASNA_STATION || stationHostname(), workspaceDirectory: realpathSync7(scope.cwd) },
58015
+ consumer: { stationId: process.env.HASNA_STATION || stationHostname(), workspaceDirectory: realpathSync8(scope.cwd) },
57902
58016
  secretsAuthority,
57903
58017
  bindings: Object.fromEntries(names.map((name) => [name, ""]))
57904
58018
  };
57905
58019
  }
57906
- function refuse(code2, message) {
58020
+ function refuse2(code2, message) {
57907
58021
  throw new SkillSelectionError(code2, message);
57908
58022
  }
57909
58023
  function record10(value) {
@@ -57912,48 +58026,48 @@ function record10(value) {
57912
58026
  function exactKeys2(value, keys) {
57913
58027
  return Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
57914
58028
  }
57915
- function identifier2(value) {
58029
+ function identifier3(value) {
57916
58030
  return typeof value === "string" && value.length > 0 && value.length <= 2048 && !/[\x00-\x20\x7f]/.test(value);
57917
58031
  }
57918
58032
  function declaredSecretNames(value) {
57919
58033
  if (value === undefined)
57920
58034
  return [];
57921
58035
  if (!Array.isArray(value) || value.length > 32 || value.some((name) => typeof name !== "string" || !/^[A-Z][A-Z0-9_]{0,127}$/.test(name)) || new Set(value).size !== value.length) {
57922
- return refuse("INVALID_SKILL_MANIFEST", "Runtime environment references must be unique uppercase identifiers (at most 32).");
58036
+ return refuse2("INVALID_SKILL_MANIFEST", "Runtime environment references must be unique uppercase identifiers (at most 32).");
57923
58037
  }
57924
58038
  if (value.some((name) => /^(?:PATH|HOME|TMPDIR|TEMP|TMP|LANG|LC_ALL|TERM|SHELL|ENV|BASH_ENV|IFS|NODE_OPTIONS|NODE_PATH)$/.test(name) || /^(?:SKILLS_|BUN_|PYTHON|LD_|DYLD_)/.test(name))) {
57925
- return refuse("INVALID_SKILL_MANIFEST", "Runtime environment references cannot override execution controls.");
58039
+ return refuse2("INVALID_SKILL_MANIFEST", "Runtime environment references cannot override execution controls.");
57926
58040
  }
57927
58041
  return value;
57928
58042
  }
57929
58043
  function validateSelectedSecretBindings(value, scope, names) {
57930
58044
  if (!record10(value) || !exactKeys2(value, ["schema", "selection", "consumer", "secretsAuthority", "bindings"]) || value.schema !== "hasna.skills-secret-bindings.v1" || !record10(value.selection) || !exactKeys2(value.selection, ["authority", "workspaceId", "profileId", "profileRevision", "slug", "version", "bundleDigest"]) || !record10(value.consumer) || !exactKeys2(value.consumer, ["stationId", "workspaceDirectory"]) || !record10(value.bindings)) {
57931
- return refuse("INVALID_SECRET_BINDINGS", "Secret bindings do not match the hasna.skills-secret-bindings.v1 contract.");
58045
+ return refuse2("INVALID_SECRET_BINDINGS", "Secret bindings do not match the hasna.skills-secret-bindings.v1 contract.");
57932
58046
  }
57933
58047
  for (const [key, expected] of Object.entries({ authority: scope.selection.authority, workspaceId: scope.selection.workspaceId, profileId: scope.profileId, profileRevision: scope.selection.profileRevision, slug: scope.selection.slug, version: scope.selection.version, bundleDigest: scope.selection.bundleDigest })) {
57934
58048
  if (value.selection[key] !== expected)
57935
- return refuse("SECRET_BINDING_SCOPE_MISMATCH", "Secret bindings do not match the exact selected authority, workspace, profile, revision, version and digest.");
58049
+ return refuse2("SECRET_BINDING_SCOPE_MISMATCH", "Secret bindings do not match the exact selected authority, workspace, profile, revision, version and digest.");
57936
58050
  }
57937
58051
  let workspaceDirectory;
57938
58052
  try {
57939
- workspaceDirectory = realpathSync7(scope.cwd);
58053
+ workspaceDirectory = realpathSync8(scope.cwd);
57940
58054
  } catch {
57941
- return refuse("SECRET_BINDING_CONSUMER_MISMATCH", "The execution workspace cannot be resolved.");
58055
+ return refuse2("SECRET_BINDING_CONSUMER_MISMATCH", "The execution workspace cannot be resolved.");
57942
58056
  }
57943
58057
  if (value.consumer.stationId !== (process.env.HASNA_STATION || stationHostname()) || value.consumer.workspaceDirectory !== workspaceDirectory) {
57944
- return refuse("SECRET_BINDING_CONSUMER_MISMATCH", "Secret bindings do not match this station and canonical workspace directory.");
58058
+ return refuse2("SECRET_BINDING_CONSUMER_MISMATCH", "Secret bindings do not match this station and canonical workspace directory.");
57945
58059
  }
57946
58060
  try {
57947
- if (!identifier2(value.secretsAuthority))
58061
+ if (!identifier3(value.secretsAuthority))
57948
58062
  throw new Error;
57949
58063
  const url2 = new URL(value.secretsAuthority);
57950
58064
  if (url2.protocol !== "https:" && !(url2.protocol === "http:" && ["127.0.0.1", "[::1]", "localhost"].includes(url2.hostname)) || url2.username || url2.password || url2.search || url2.hash || !url2.pathname.endsWith("/v1") || url2.href !== value.secretsAuthority)
57951
58065
  throw new Error;
57952
58066
  } catch {
57953
- return refuse("INVALID_SECRET_BINDINGS", "Secret bindings require a canonical HTTPS Secrets /v1 authority (loopback HTTP is allowed).");
58067
+ return refuse2("INVALID_SECRET_BINDINGS", "Secret bindings require a canonical HTTPS Secrets /v1 authority (loopback HTTP is allowed).");
57954
58068
  }
57955
- if (!exactKeys2(value.bindings, names) || Object.values(value.bindings).some((key) => !identifier2(key) || !/^[A-Za-z0-9][A-Za-z0-9._/-]*$/.test(key) || key.split("/").some((part) => !part || part === "." || part === ".."))) {
57956
- return refuse("INVALID_SECRET_BINDINGS", "Bind every declared environment name exactly once to a vault key; undeclared bindings and values are refused.");
58069
+ if (!exactKeys2(value.bindings, names) || Object.values(value.bindings).some((key) => !identifier3(key) || !/^[A-Za-z0-9][A-Za-z0-9._/-]*$/.test(key) || key.split("/").some((part) => !part || part === "." || part === ".."))) {
58070
+ return refuse2("INVALID_SECRET_BINDINGS", "Bind every declared environment name exactly once to a vault key; undeclared bindings and values are refused.");
57957
58071
  }
57958
58072
  return structuredClone(value);
57959
58073
  }
@@ -57964,10 +58078,10 @@ async function resolveSelectedSecrets(bindings, createClient = createSecretsClie
57964
58078
  try {
57965
58079
  client = createClient();
57966
58080
  } catch {
57967
- return refuse("LOCAL_SECRET_UNAVAILABLE", "The configured Secrets client could not authenticate. No ambient credential fallback was attempted.");
58081
+ return refuse2("LOCAL_SECRET_UNAVAILABLE", "The configured Secrets client could not authenticate. No ambient credential fallback was attempted.");
57968
58082
  }
57969
58083
  if (client.baseUrl !== bindings.secretsAuthority)
57970
- return refuse("SECRET_BINDING_AUTHORITY_MISMATCH", "The configured Secrets authority differs from the reviewed binding. No secret was requested.");
58084
+ return refuse2("SECRET_BINDING_AUTHORITY_MISMATCH", "The configured Secrets authority differs from the reviewed binding. No secret was requested.");
57971
58085
  const env = {};
57972
58086
  const signal = AbortSignal.timeout(15000);
57973
58087
  try {
@@ -57979,7 +58093,7 @@ async function resolveSelectedSecrets(bindings, createClient = createSecretsClie
57979
58093
  }
57980
58094
  return env;
57981
58095
  } catch {
57982
- return refuse("LOCAL_SECRET_UNAVAILABLE", "A declared secret could not be resolved, was invalid, or has expired. The skill was not started; no fallback was attempted.");
58096
+ return refuse2("LOCAL_SECRET_UNAVAILABLE", "A declared secret could not be resolved, was invalid, or has expired. The skill was not started; no fallback was attempted.");
57983
58097
  }
57984
58098
  }
57985
58099
  function redactExecutionSecrets(text3, env) {
@@ -58129,8 +58243,8 @@ __export(exports_selected_run, {
58129
58243
  });
58130
58244
  import { createHash as createHash20 } from "crypto";
58131
58245
  import { spawn } from "child_process";
58132
- import { mkdirSync as mkdirSync12, mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync11, realpathSync as realpathSync8 } from "fs";
58133
- import { dirname as dirname19, join as join31, resolve as resolve17 } from "path";
58246
+ import { mkdirSync as mkdirSync12, mkdtempSync as mkdtempSync3, writeFileSync as writeFileSync11, realpathSync as realpathSync9 } from "fs";
58247
+ import { dirname as dirname20, join as join32, resolve as resolve18 } from "path";
58134
58248
  import { tmpdir, hostname as stationHostname2 } from "os";
58135
58249
  async function resolveSelectedRun(spec, profileId, options = {}) {
58136
58250
  const context2 = await resolveSelectionContext(profileId, options);
@@ -58210,7 +58324,7 @@ async function executeSelectedLocal(selected, options = {}) {
58210
58324
  throw new SkillSelectionError("INVALID_SECRET_BINDINGS", "Explicit environment values must be bounded strings without NUL bytes.");
58211
58325
  secretEnv[name] = value;
58212
58326
  }
58213
- const runDirectory = mkdtempSync3(join31(tmpdir(), "skills-execution-"));
58327
+ const runDirectory = mkdtempSync3(join32(tmpdir(), "skills-execution-"));
58214
58328
  const paths = new SkillEntryPaths;
58215
58329
  for (const entry of entries) {
58216
58330
  paths.add(entry.path, 100, () => {
@@ -58218,12 +58332,12 @@ async function executeSelectedLocal(selected, options = {}) {
58218
58332
  }, () => {
58219
58333
  throw new SkillSelectionError("INVALID_BUNDLE_PATH", "The execution bundle path exceeds its limit.");
58220
58334
  });
58221
- const destination = join31(runDirectory, entry.path);
58222
- mkdirSync12(dirname19(destination), { recursive: true, mode: 448 });
58335
+ const destination = join32(runDirectory, entry.path);
58336
+ mkdirSync12(dirname20(destination), { recursive: true, mode: 448 });
58223
58337
  writeFileSync11(destination, entry.bytes, { flag: "wx", mode: entry.mode & 511 });
58224
58338
  }
58225
58339
  env.SKILLS_INPUT_JSON = input2;
58226
- env.SKILLS_WORKSPACE_DIR = resolve17(options.cwd ?? process.cwd());
58340
+ env.SKILLS_WORKSPACE_DIR = resolve18(options.cwd ?? process.cwd());
58227
58341
  env.SKILLS_RUN_DIR = runDirectory;
58228
58342
  if (runtime.version) {
58229
58343
  const version2 = await subprocess([executable, ...runtimeName === "bun" ? ["--no-env-file"] : [], "--version"], runDirectory, env, "", Math.min(timeoutMs, 5000));
@@ -58236,7 +58350,7 @@ async function executeSelectedLocal(selected, options = {}) {
58236
58350
  const { authority: authority2, workspaceId, profileRevision, slug: slug2, version: version2, bundleDigest } = selection2;
58237
58351
  const request2 = {
58238
58352
  selection: { authority: authority2, workspaceId, profileId, profileRevision, slug: slug2, version: version2, bundleDigest },
58239
- consumer: { stationId: process.env.HASNA_STATION || stationHostname2(), workspaceDirectory: realpathSync8(options.cwd ?? process.cwd()) }
58353
+ consumer: { stationId: process.env.HASNA_STATION || stationHostname2(), workspaceDirectory: realpathSync9(options.cwd ?? process.cwd()) }
58240
58354
  };
58241
58355
  const grant = await (options.resolveExecutionGrant ?? resolveExecutionGrant)(request2);
58242
58356
  if (!grant || !grantIdentifier(grant.policyRevision) || !grantIdentifier(grant.grantId))
@@ -58246,7 +58360,7 @@ async function executeSelectedLocal(selected, options = {}) {
58246
58360
  }
58247
58361
  if (bindings)
58248
58362
  secretEnv = await resolveSelectedSecrets(bindings, options.createSecretsClient);
58249
- const result = await subprocess([executable, ...runtimeName === "bun" ? ["--no-env-file"] : [], join31(runDirectory, declaredEntry), ...args], runDirectory, { ...env, ...secretEnv }, input2, timeoutMs);
58363
+ const result = await subprocess([executable, ...runtimeName === "bun" ? ["--no-env-file"] : [], join32(runDirectory, declaredEntry), ...args], runDirectory, { ...env, ...secretEnv }, input2, timeoutMs);
58250
58364
  result.stdout = redactExecutionSecrets(result.stdout, secretEnv);
58251
58365
  result.stderr = redactExecutionSecrets(result.stderr, secretEnv);
58252
58366
  const receipt = {
@@ -58259,7 +58373,7 @@ async function executeSelectedLocal(selected, options = {}) {
58259
58373
  ...bindings ? { secretBinding: { schema: bindings.schema, selection: bindings.selection, consumer: bindings.consumer, secretsAuthority: bindings.secretsAuthority, bindings: bindings.bindings } } : {},
58260
58374
  ...result
58261
58375
  };
58262
- writeFileSync11(join31(runDirectory, ".execution-receipt.json"), JSON.stringify({ ...receipt, stdout: undefined, stderr: undefined }), { mode: 384 });
58376
+ writeFileSync11(join32(runDirectory, ".execution-receipt.json"), JSON.stringify({ ...receipt, stdout: undefined, stderr: undefined }), { mode: 384 });
58263
58377
  return receipt;
58264
58378
  }
58265
58379
  async function subprocess(command, cwd, env, input2, timeoutMs) {
@@ -58448,8 +58562,8 @@ var init_blog_article = __esm(() => {
58448
58562
  });
58449
58563
 
58450
58564
  // src/mcp/operation-tools.ts
58451
- import { existsSync as existsSync15, readdirSync as readdirSync10, statSync as statSync10 } from "fs";
58452
- import { join as join32 } from "path";
58565
+ import { existsSync as existsSync15, readdirSync as readdirSync11, statSync as statSync10 } from "fs";
58566
+ import { join as join33 } from "path";
58453
58567
  function registerOperationTools(server) {
58454
58568
  server.registerTool("cloud_skill_eligibility", {
58455
58569
  title: "Cloud Skill Eligibility",
@@ -58925,8 +59039,8 @@ function registerOperationTools(server) {
58925
59039
  let skillCount = 0;
58926
59040
  if (exists) {
58927
59041
  try {
58928
- skillCount = readdirSync10(agentSkillsPath).filter((f) => {
58929
- const full = join32(agentSkillsPath, f);
59042
+ skillCount = readdirSync11(agentSkillsPath).filter((f) => {
59043
+ const full = join33(agentSkillsPath, f);
58930
59044
  return !f.startsWith(".") && statSync10(full).isDirectory();
58931
59045
  }).length;
58932
59046
  } catch {}
@@ -58994,14 +59108,14 @@ var init_operation_tools = __esm(() => {
58994
59108
 
58995
59109
  // src/lib/feedback.ts
58996
59110
  import { appendFileSync, existsSync as existsSync16, mkdirSync as mkdirSync13 } from "fs";
58997
- import { dirname as dirname20, join as join33 } from "path";
59111
+ import { dirname as dirname21, join as join34 } from "path";
58998
59112
  import { Database } from "bun:sqlite";
58999
59113
  function getFeedbackDbPath() {
59000
- return join33(getDataDir(), "skills.db");
59114
+ return join34(getDataDir(), "skills.db");
59001
59115
  }
59002
59116
  function getFeedbackDb() {
59003
59117
  const dbPath = getFeedbackDbPath();
59004
- const dir = dirname20(dbPath);
59118
+ const dir = dirname21(dbPath);
59005
59119
  if (!existsSync16(dir))
59006
59120
  mkdirSync13(dir, { recursive: true });
59007
59121
  const db = new Database(dbPath);
@@ -59029,8 +59143,8 @@ function saveFeedback(input2) {
59029
59143
  throw new Error("Feedback message is required");
59030
59144
  const category = input2.category ?? "general";
59031
59145
  if (isApiMode()) {
59032
- const path = join33(getDataDir(), "feedback.jsonl");
59033
- const dir = dirname20(path);
59146
+ const path = join34(getDataDir(), "feedback.jsonl");
59147
+ const dir = dirname21(path);
59034
59148
  if (!existsSync16(dir))
59035
59149
  mkdirSync13(dir, { recursive: true });
59036
59150
  appendFileSync(path, JSON.stringify({ message, category, email: input2.email ?? null, agent: input2.agent ?? null, version: input2.version ?? null, createdAt: new Date().toISOString() }) + `
@@ -59194,9 +59308,9 @@ var init_resource_meta_tools = __esm(() => {
59194
59308
 
59195
59309
  // src/lib/scheduler.ts
59196
59310
  import { existsSync as existsSync17, readFileSync as readFileSync21, writeFileSync as writeFileSync12, mkdirSync as mkdirSync14 } from "fs";
59197
- import { join as join34 } from "path";
59311
+ import { join as join35 } from "path";
59198
59312
  function getSchedulesPath(targetDir = process.cwd()) {
59199
- return join34(targetDir, ".skills", "schedules.json");
59313
+ return join35(targetDir, ".skills", "schedules.json");
59200
59314
  }
59201
59315
  function loadSchedules(targetDir = process.cwd()) {
59202
59316
  const path = getSchedulesPath(targetDir);
@@ -59209,7 +59323,7 @@ function loadSchedules(targetDir = process.cwd()) {
59209
59323
  }
59210
59324
  function saveSchedules(data, targetDir = process.cwd()) {
59211
59325
  const path = getSchedulesPath(targetDir);
59212
- const dir = join34(targetDir, ".skills");
59326
+ const dir = join35(targetDir, ".skills");
59213
59327
  if (!existsSync17(dir))
59214
59328
  mkdirSync14(dir, { recursive: true });
59215
59329
  writeFileSync12(path, JSON.stringify(data, null, 2));
@@ -59486,11 +59600,11 @@ import {
59486
59600
  existsSync as existsSync18,
59487
59601
  mkdirSync as mkdirSync15,
59488
59602
  readFileSync as readFileSync22,
59489
- readdirSync as readdirSync11,
59603
+ readdirSync as readdirSync12,
59490
59604
  statSync as statSync11,
59491
59605
  writeFileSync as writeFileSync13
59492
59606
  } from "fs";
59493
- import { dirname as dirname21, join as join35, normalize as normalize4, relative as relative6, sep as sep7 } from "path";
59607
+ import { dirname as dirname22, join as join36, normalize as normalize4, relative as relative7, sep as sep8 } from "path";
59494
59608
  function resolveSkillsNativeStorageConfig(env = process.env) {
59495
59609
  assertNoRetiredModeEnvVars(env, {
59496
59610
  app: SKILLS_ENV_NAMESPACE,
@@ -59531,7 +59645,7 @@ function getSkillsNativeStorageStatus(options = {}) {
59531
59645
  local: {
59532
59646
  dataDir: getDataDir(),
59533
59647
  projectStateDir: getProjectStateDir(targetDir),
59534
- feedbackDbPath: join35(getDataDir(), "skills.db")
59648
+ feedbackDbPath: join36(getDataDir(), "skills.db")
59535
59649
  },
59536
59650
  remote: {
59537
59651
  databaseConfigured: Boolean(config2.databaseUrl),
@@ -59554,7 +59668,7 @@ function exportSkillsLocalSnapshot(targetDir = process.cwd(), options = {}) {
59554
59668
  if (existsSync18(projectStateDir)) {
59555
59669
  for (const filePath of walkFiles2(projectStateDir)) {
59556
59670
  const bytes = readFileSync22(filePath);
59557
- const relativePath = toPosix(relative6(targetDir, filePath));
59671
+ const relativePath = toPosix(relative7(targetDir, filePath));
59558
59672
  files.push({
59559
59673
  path: relativePath,
59560
59674
  sizeBytes: bytes.byteLength,
@@ -59611,8 +59725,8 @@ function parsePositiveInteger(value) {
59611
59725
  }
59612
59726
  function walkFiles2(dir) {
59613
59727
  const files = [];
59614
- for (const entry of readdirSync11(dir)) {
59615
- const full = join35(dir, entry);
59728
+ for (const entry of readdirSync12(dir)) {
59729
+ const full = join36(dir, entry);
59616
59730
  const stats = statSync11(full);
59617
59731
  if (stats.isDirectory())
59618
59732
  files.push(...walkFiles2(full));
@@ -59850,20 +59964,20 @@ var init_private_publication_customer = __esm(() => {
59850
59964
  });
59851
59965
 
59852
59966
  // src/lib/private-publication-recovery.ts
59853
- import { constants as constants14, closeSync as closeSync18, fsyncSync as fsyncSync5, fstatSync as fstatSync18, lstatSync as lstatSync20, mkdirSync as mkdirSync16, openSync as openSync18, readSync as readSync12, realpathSync as realpathSync9, renameSync as renameSync7, unlinkSync as unlinkSync6, writeFileSync as writeFileSync14 } from "fs";
59854
- import { dirname as dirname22, isAbsolute as isAbsolute18, join as join36, resolve as resolve18 } from "path";
59967
+ import { constants as constants14, closeSync as closeSync18, fsyncSync as fsyncSync5, fstatSync as fstatSync18, lstatSync as lstatSync21, mkdirSync as mkdirSync16, openSync as openSync18, readSync as readSync12, realpathSync as realpathSync10, renameSync as renameSync7, unlinkSync as unlinkSync6, writeFileSync as writeFileSync14 } from "fs";
59968
+ import { dirname as dirname23, isAbsolute as isAbsolute18, join as join37, resolve as resolve19 } from "path";
59855
59969
  import { randomUUID as randomUUID3 } from "crypto";
59856
59970
  function safeDirectory(directory2) {
59857
- if (!isAbsolute18(directory2) || directory2 !== resolve18(directory2) || realpathSync9(directory2) !== directory2)
59971
+ if (!isAbsolute18(directory2) || directory2 !== resolve19(directory2) || realpathSync10(directory2) !== directory2)
59858
59972
  return fail2();
59859
- for (let path = directory2;; path = dirname22(path)) {
59860
- const stat3 = lstatSync20(path);
59973
+ for (let path = directory2;; path = dirname23(path)) {
59974
+ const stat3 = lstatSync21(path);
59861
59975
  if (!stat3.isDirectory() || stat3.isSymbolicLink())
59862
59976
  return fail2();
59863
- if (path === dirname22(path))
59977
+ if (path === dirname23(path))
59864
59978
  break;
59865
59979
  }
59866
- const own2 = lstatSync20(directory2);
59980
+ const own2 = lstatSync21(directory2);
59867
59981
  if ((own2.mode & 63) !== 0 || process.getuid && own2.uid !== process.getuid())
59868
59982
  return fail2();
59869
59983
  return { dev: own2.dev, ino: own2.ino };
@@ -59874,7 +59988,7 @@ function unchangedDirectory(directory2, identity3) {
59874
59988
  return fail2();
59875
59989
  }
59876
59990
  function readOwned(directory2, name, max) {
59877
- const identity3 = safeDirectory(directory2), file2 = join36(directory2, name);
59991
+ const identity3 = safeDirectory(directory2), file2 = join37(directory2, name);
59878
59992
  const fd = openSync18(file2, constants14.O_RDONLY | constants14.O_NOFOLLOW);
59879
59993
  try {
59880
59994
  const stat3 = fstatSync18(fd);
@@ -59898,7 +60012,7 @@ function readOwned(directory2, name, max) {
59898
60012
  }
59899
60013
  }
59900
60014
  function writeOwned(directory2, name, bytes) {
59901
- const fd = openSync18(join36(directory2, name), constants14.O_WRONLY | constants14.O_CREAT | constants14.O_EXCL | constants14.O_NOFOLLOW, 384);
60015
+ const fd = openSync18(join37(directory2, name), constants14.O_WRONLY | constants14.O_CREAT | constants14.O_EXCL | constants14.O_NOFOLLOW, 384);
59902
60016
  try {
59903
60017
  writeFileSync14(fd, bytes);
59904
60018
  fsyncSync5(fd);
@@ -59911,7 +60025,7 @@ function save(directory2, value) {
59911
60025
  writeOwned(directory2, temporary, JSON.stringify(value) + `
59912
60026
  `);
59913
60027
  unchangedDirectory(directory2, identity3);
59914
- renameSync7(join36(directory2, temporary), join36(directory2, "receipt.json"));
60028
+ renameSync7(join37(directory2, temporary), join37(directory2, "receipt.json"));
59915
60029
  const fd = openSync18(directory2, constants14.O_RDONLY | constants14.O_NOFOLLOW);
59916
60030
  try {
59917
60031
  fsyncSync5(fd);
@@ -59924,7 +60038,7 @@ function bind(client, receipt) {
59924
60038
  throw new PrivatePublicationError("PUBLICATION_IDENTITY_CHANGED", "The fresh session does not match the recovery directory's server, account and membership.");
59925
60039
  }
59926
60040
  async function locked(directory2, action) {
59927
- const identity3 = safeDirectory(directory2), file2 = join36(directory2, "operation.lock");
60041
+ const identity3 = safeDirectory(directory2), file2 = join37(directory2, "operation.lock");
59928
60042
  let fd;
59929
60043
  try {
59930
60044
  fd = openSync18(file2, constants14.O_WRONLY | constants14.O_CREAT | constants14.O_EXCL | constants14.O_NOFOLLOW, 384);
@@ -59940,7 +60054,7 @@ async function locked(directory2, action) {
59940
60054
  } finally {
59941
60055
  closeSync18(fd);
59942
60056
  unchangedDirectory(directory2, identity3);
59943
- const now = lstatSync20(file2);
60057
+ const now = lstatSync21(file2);
59944
60058
  if (now.dev !== lock.dev || now.ino !== lock.ino || !now.isFile() || now.isSymbolicLink())
59945
60059
  fail2();
59946
60060
  unlinkSync6(file2);
@@ -59992,11 +60106,11 @@ async function preparePrivatePublication(client, sourceDirectory, recoveryDirect
59992
60106
  phase: "prepared",
59993
60107
  intent: null
59994
60108
  };
59995
- if (!isAbsolute18(recoveryDirectory) || resolve18(recoveryDirectory) !== recoveryDirectory || realpathSync9(dirname22(recoveryDirectory)) !== dirname22(recoveryDirectory))
60109
+ if (!isAbsolute18(recoveryDirectory) || resolve19(recoveryDirectory) !== recoveryDirectory || realpathSync10(dirname23(recoveryDirectory)) !== dirname23(recoveryDirectory))
59996
60110
  return fail2();
59997
60111
  mkdirSync16(recoveryDirectory, { mode: 448 });
59998
60112
  safeDirectory(recoveryDirectory);
59999
- const parent = openSync18(dirname22(recoveryDirectory), constants14.O_RDONLY | constants14.O_NOFOLLOW);
60113
+ const parent = openSync18(dirname23(recoveryDirectory), constants14.O_RDONLY | constants14.O_NOFOLLOW);
60000
60114
  try {
60001
60115
  fsyncSync5(parent);
60002
60116
  } finally {
@@ -60808,7 +60922,7 @@ var RequestError, nonJoinedHeaders, validHeaderName, isHttpWhitespace = (code2)
60808
60922
  request2[bodyBufferKey] = buffered;
60809
60923
  return Promise.resolve(buffered);
60810
60924
  }
60811
- const promise3 = new Promise((resolve19, reject) => {
60925
+ const promise3 = new Promise((resolve20, reject) => {
60812
60926
  const chunks = [];
60813
60927
  let settled = false;
60814
60928
  const finish = (callback) => {
@@ -60830,7 +60944,7 @@ var RequestError, nonJoinedHeaders, validHeaderName, isHttpWhitespace = (code2)
60830
60944
  reject(error61 ?? normalizeAbortError(request2, incoming));
60831
60945
  else {
60832
60946
  request2[bodyBufferKey] = recovered;
60833
- resolve19(recovered);
60947
+ resolve20(recovered);
60834
60948
  }
60835
60949
  });
60836
60950
  return true;
@@ -60842,7 +60956,7 @@ var RequestError, nonJoinedHeaders, validHeaderName, isHttpWhitespace = (code2)
60842
60956
  finish(() => {
60843
60957
  const buffer = chunks.length === 1 ? chunks[0] : Buffer.concat(chunks);
60844
60958
  request2[bodyBufferKey] = buffer;
60845
- resolve19(buffer);
60959
+ resolve20(buffer);
60846
60960
  });
60847
60961
  };
60848
60962
  const onError = (error61) => {
@@ -61116,7 +61230,7 @@ var RequestError, nonJoinedHeaders, validHeaderName, isHttpWhitespace = (code2)
61116
61230
  });
61117
61231
  if (!chunk) {
61118
61232
  if (i === 1) {
61119
- await new Promise((resolve19) => setTimeout(resolve19));
61233
+ await new Promise((resolve20) => setTimeout(resolve20));
61120
61234
  maxReadCount = 3;
61121
61235
  continue;
61122
61236
  }
@@ -62346,9 +62460,9 @@ data:
62346
62460
  const initRequest = messages.find((m) => isInitializeRequest(m));
62347
62461
  const clientProtocolVersion = initRequest ? initRequest.params.protocolVersion : req.headers.get("mcp-protocol-version") ?? DEFAULT_NEGOTIATED_PROTOCOL_VERSION;
62348
62462
  if (this._enableJsonResponse) {
62349
- return new Promise((resolve19) => {
62463
+ return new Promise((resolve20) => {
62350
62464
  this._streamMapping.set(streamId, {
62351
- resolveJson: resolve19,
62465
+ resolveJson: resolve20,
62352
62466
  cleanup: () => {
62353
62467
  this._streamMapping.delete(streamId);
62354
62468
  }
@@ -62717,19 +62831,19 @@ async function connectMcpForNode() {
62717
62831
  return { server: server2, transport };
62718
62832
  }
62719
62833
  function readBody(req) {
62720
- return new Promise((resolve19, reject) => {
62834
+ return new Promise((resolve20, reject) => {
62721
62835
  const chunks = [];
62722
62836
  req.on("data", (chunk) => chunks.push(Buffer.from(chunk)));
62723
62837
  req.on("end", () => {
62724
62838
  const raw = Buffer.concat(chunks).toString("utf-8");
62725
62839
  if (!raw.trim()) {
62726
- resolve19(undefined);
62840
+ resolve20(undefined);
62727
62841
  return;
62728
62842
  }
62729
62843
  try {
62730
- resolve19(JSON.parse(raw));
62844
+ resolve20(JSON.parse(raw));
62731
62845
  } catch {
62732
- resolve19(undefined);
62846
+ resolve20(undefined);
62733
62847
  }
62734
62848
  });
62735
62849
  req.on("error", reject);
@@ -62771,9 +62885,9 @@ async function startSkillsMcpHttpServer(options = {}) {
62771
62885
  }
62772
62886
  }
62773
62887
  });
62774
- await new Promise((resolve19, reject) => {
62888
+ await new Promise((resolve20, reject) => {
62775
62889
  httpServer.once("error", reject);
62776
- httpServer.listen(port, hostname4, () => resolve19());
62890
+ httpServer.listen(port, hostname4, () => resolve20());
62777
62891
  });
62778
62892
  const address = httpServer.address();
62779
62893
  const listenPort = typeof address === "object" && address ? address.port : port;