@hasna/skills 0.8.11 → 0.9.1

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/index.js CHANGED
@@ -36868,7 +36868,7 @@ var package_default;
36868
36868
  var init_package = __esm(() => {
36869
36869
  package_default = {
36870
36870
  name: "@hasna/skills",
36871
- version: "0.8.11",
36871
+ version: "0.9.1",
36872
36872
  description: "Skills library for AI coding agents",
36873
36873
  type: "module",
36874
36874
  bin: {
@@ -39186,6 +39186,7 @@ function readManifest(skillPath, fallbackName, normalizeName) {
39186
39186
  const version = readDeclaredSkillVersion(skillPath) ?? PORTABLE_SKILL_DEFAULT_VERSION;
39187
39187
  const kind = parseSkillKind(stringField(jsonManifest, "kind") ?? frontmatter?.kind);
39188
39188
  const commands = parseManifestCommands(jsonManifest) ?? (kind === "instruction" ? [] : inferPackageCommands(pkg, name)) ?? [];
39189
+ const runtime = parseManifestRuntime(jsonManifest) ?? inferRuntimeFromCommands(commands);
39189
39190
  return {
39190
39191
  $schema: stringField(jsonManifest, "$schema") ?? PORTABLE_SKILL_SCHEMA,
39191
39192
  standard: stringField(jsonManifest, "standard") ?? PORTABLE_SKILL_STANDARD,
@@ -39198,7 +39199,7 @@ function readManifest(skillPath, fallbackName, normalizeName) {
39198
39199
  ...kind ? { kind } : {},
39199
39200
  inputs: kind === "instruction" ? parseManifestInputs(jsonManifest) ?? [] : parseManifestInputs(jsonManifest) ?? DEFAULT_INPUTS,
39200
39201
  commands,
39201
- ...parseManifestRuntime(jsonManifest) ? { runtime: parseManifestRuntime(jsonManifest) } : {},
39202
+ ...runtime ? { runtime } : {},
39202
39203
  ...parseManifestProvenance(jsonManifest) ? { provenance: parseManifestProvenance(jsonManifest) } : {}
39203
39204
  };
39204
39205
  }
@@ -39717,6 +39718,12 @@ function inferPackageCommands(pkg, fallbackName) {
39717
39718
  }
39718
39719
  return;
39719
39720
  }
39721
+ function inferRuntimeFromCommands(commands) {
39722
+ const entrypoint = commands.find((command) => command.entry)?.entry;
39723
+ if (!entrypoint || !entrypoint.toLowerCase().endsWith(".py"))
39724
+ return;
39725
+ return { ...defaultRuntimeContract(entrypoint), runtime: "python3" };
39726
+ }
39720
39727
  function readJsonObject(path) {
39721
39728
  const parsed = JSON.parse(readFileSync6(path, "utf-8"));
39722
39729
  if (!isRecord2(parsed))
@@ -43298,7 +43305,9 @@ function assertAgentPolicyCollections(policy) {
43298
43305
  text(source.path);
43299
43306
  requireBound(source.sha256 === null || typeof source.sha256 === "string" && /^[a-f0-9]{64}$/.test(source.sha256));
43300
43307
  if (source.hashMode !== undefined)
43301
- requireBound(["bytes", "path-bytes", "claude-plugin-registry", "claude-marketplace-registry"].includes(source.hashMode) && source.format === undefined && source.fields === undefined && (source.hashMode === "bytes" || source.sha256 !== null));
43308
+ requireBound(["bytes", "path-bytes", "claude-plugin-registry", "claude-marketplace-registry", "claude-settings-v1"].includes(source.hashMode) && source.format === undefined && source.fields === undefined && (source.hashMode === "bytes" || source.sha256 !== null));
43309
+ if (source.hashMode === "claude-settings-v1")
43310
+ requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute3(source.path) && resolve5(source.path) === source.path && basename3(source.path) === "settings.json");
43302
43311
  if (source.hashMode === "claude-marketplace-registry")
43303
43312
  requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute3(source.path) && resolve5(source.path) === source.path && basename3(source.path) === "known_marketplaces.json");
43304
43313
  if (source.hashMode === "claude-plugin-registry") {
@@ -54505,10 +54514,232 @@ var init_claude_marketplace_registry = __esm(() => {
54505
54514
  CLAUDE_MARKETPLACE_REGISTRY_LIMITS = Object.freeze({ bytes: 1024 * 1024, rows: 1024, depth: 32, nodes: 65536, stringCharacters: 16384, pathCharacters: 4096 });
54506
54515
  });
54507
54516
 
54508
- // src/lib/agent-discovery.ts
54517
+ // src/lib/claude-settings-witness.ts
54509
54518
  import { createHash as createHash12 } from "crypto";
54510
- import { lstatSync as lstatSync16, readFileSync as readFileSync14, readdirSync as readdirSync9, realpathSync as realpathSync4 } from "fs";
54511
- import { dirname as dirname13, isAbsolute as isAbsolute13, join as join28, resolve as resolve14, sep as sep5 } from "path";
54519
+ import { closeSync as closeSync10, constants as constants10, fstatSync as fstatSync10, lstatSync as lstatSync16, openSync as openSync10, readSync as readSync8 } from "fs";
54520
+ import { basename as basename7, dirname as dirname13, isAbsolute as isAbsolute13, resolve as resolve14 } from "path";
54521
+ function need3(value, reason) {
54522
+ if (!value)
54523
+ throw new Error(`Claude settings witness ${reason}`);
54524
+ }
54525
+ function absolutePath2(value) {
54526
+ need3(typeof value === "string" && value.length > 0 && value.length <= CLAUDE_SETTINGS_WITNESS_LIMITS.pathCharacters && !/[\x00-\x1f\x7f]/.test(value) && isAbsolute13(value) && resolve14(value) === value, "requires a normalized absolute path");
54527
+ }
54528
+ function parents2(path) {
54529
+ const result2 = [];
54530
+ for (let at2 = dirname13(path);; at2 = dirname13(at2)) {
54531
+ const stat2 = lstatSync16(at2, { bigint: true });
54532
+ need3(stat2.isDirectory() && !stat2.isSymbolicLink(), "path traverses a symlink or non-directory");
54533
+ result2.push([at2, stat2]);
54534
+ if (at2 === dirname13(at2))
54535
+ return result2;
54536
+ }
54537
+ }
54538
+ function readSettings(path, budget) {
54539
+ absolutePath2(path);
54540
+ need3(basename7(path) === "settings.json", "requires settings.json");
54541
+ need3(Number.isSafeInteger(budget.remaining) && budget.remaining >= 0, "has an invalid byte budget");
54542
+ const ancestors2 = parents2(path), initial2 = lstatSync16(path, { bigint: true });
54543
+ need3(initial2.isFile() && !initial2.isSymbolicLink() && initial2.size <= BigInt(CLAUDE_SETTINGS_WITNESS_LIMITS.bytes), "is not a bounded regular file");
54544
+ need3(initial2.size <= BigInt(budget.remaining), "exceeds its aggregate byte limit");
54545
+ const fd = openSync10(path, constants10.O_RDONLY | constants10.O_NOFOLLOW | constants10.O_NONBLOCK);
54546
+ try {
54547
+ const opened = fstatSync10(fd, { bigint: true });
54548
+ need3(opened.isFile() && sameFile2(initial2, opened), "changed during open");
54549
+ const bytes = Buffer.alloc(Number(opened.size) + 1);
54550
+ let length = 0;
54551
+ while (length < bytes.length) {
54552
+ const count = readSync8(fd, bytes, length, bytes.length - length, null);
54553
+ if (!count)
54554
+ break;
54555
+ length += count;
54556
+ }
54557
+ const after2 = fstatSync10(fd, { bigint: true }), current = lstatSync16(path, { bigint: true });
54558
+ need3(current.isFile() && sameFile2(opened, after2) && sameFile2(after2, current) && BigInt(length) === opened.size, "changed during read");
54559
+ for (const [ancestor, before2] of ancestors2) {
54560
+ const now3 = lstatSync16(ancestor, { bigint: true });
54561
+ need3(now3.isDirectory() && before2.dev === now3.dev && before2.ino === now3.ino && before2.mode === now3.mode, "parent changed during read");
54562
+ }
54563
+ budget.remaining -= length;
54564
+ try {
54565
+ return new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes.subarray(0, length));
54566
+ } catch {
54567
+ throw new Error("Claude settings witness is not strict UTF-8");
54568
+ }
54569
+ } finally {
54570
+ closeSync10(fd);
54571
+ }
54572
+ }
54573
+ function parse6(text2) {
54574
+ let at2 = 0, nodes = 0;
54575
+ const numberPattern = /-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?/y;
54576
+ const space = () => {
54577
+ while (at2 < text2.length && /[\x20\t\r\n]/.test(text2[at2]))
54578
+ at2++;
54579
+ };
54580
+ function string() {
54581
+ need3(text2[at2] === '"', "contains invalid JSON");
54582
+ const start = at2++;
54583
+ while (at2 < text2.length) {
54584
+ const character = text2[at2++];
54585
+ if (character === '"') {
54586
+ let value2;
54587
+ try {
54588
+ value2 = JSON.parse(text2.slice(start, at2));
54589
+ } catch {
54590
+ throw new Error("Claude settings witness contains invalid JSON string");
54591
+ }
54592
+ need3(value2.length <= CLAUDE_SETTINGS_WITNESS_LIMITS.stringCharacters, "exceeds its string limit");
54593
+ return value2;
54594
+ }
54595
+ if (character === "\\")
54596
+ at2++;
54597
+ }
54598
+ throw new Error("Claude settings witness contains an unterminated JSON string");
54599
+ }
54600
+ function value(depth) {
54601
+ need3(depth <= CLAUDE_SETTINGS_WITNESS_LIMITS.depth && ++nodes <= CLAUDE_SETTINGS_WITNESS_LIMITS.nodes, "exceeds its nesting or node limit");
54602
+ space();
54603
+ const character = text2[at2];
54604
+ if (character === '"')
54605
+ return { kind: "string", value: string() };
54606
+ if (character === "{" || character === "[") {
54607
+ at2++;
54608
+ space();
54609
+ const object4 = character === "{", end = object4 ? "}" : "]", entries = [], items = [], keys2 = new Set;
54610
+ if (text2[at2] !== end)
54611
+ while (true) {
54612
+ if (object4) {
54613
+ space();
54614
+ const key = string();
54615
+ need3(!keys2.has(key), "contains a duplicate JSON key");
54616
+ keys2.add(key);
54617
+ space();
54618
+ need3(text2[at2++] === ":", "contains invalid JSON");
54619
+ entries.push([key, value(depth + 1)]);
54620
+ } else
54621
+ items.push(value(depth + 1));
54622
+ space();
54623
+ if (text2[at2] === end)
54624
+ break;
54625
+ need3(text2[at2++] === ",", "contains invalid JSON");
54626
+ }
54627
+ at2++;
54628
+ return object4 ? { kind: "object", entries } : { kind: "array", items };
54629
+ }
54630
+ for (const literal of ["true", "false", "null"])
54631
+ if (text2.startsWith(literal, at2)) {
54632
+ at2 += literal.length;
54633
+ return { kind: "literal", value: literal };
54634
+ }
54635
+ numberPattern.lastIndex = at2;
54636
+ const number = numberPattern.exec(text2);
54637
+ need3(number, "contains invalid JSON");
54638
+ at2 += number[0].length;
54639
+ return { kind: "number", value: number[0] };
54640
+ }
54641
+ const root2 = value(0);
54642
+ space();
54643
+ need3(at2 === text2.length && root2.kind === "object", "requires a JSON object without trailing content");
54644
+ need3(root2.entries.length <= CLAUDE_SETTINGS_WITNESS_LIMITS.rows, "exceeds its settings field limit");
54645
+ return root2;
54646
+ }
54647
+ function canonical3(value) {
54648
+ if (value.kind === "object")
54649
+ return { kind: "object", entries: value.entries.map(([key, child]) => [key, canonical3(child)]).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0) };
54650
+ if (value.kind === "array")
54651
+ return { kind: "array", items: value.items.map(canonical3) };
54652
+ return value;
54653
+ }
54654
+ function settingsDigest(text2) {
54655
+ const value = parse6(text2);
54656
+ value.entries = value.entries.filter(([key, child]) => {
54657
+ if (key === "model") {
54658
+ need3(child.kind === "string", "contains an invalid model selection");
54659
+ return !BUILTIN_MODEL_SELECTIONS.has(child.value);
54660
+ }
54661
+ if (BOOLEAN_PREFERENCES.has(key)) {
54662
+ need3(child.kind === "literal" && (child.value === "true" || child.value === "false"), "contains an invalid display preference");
54663
+ return false;
54664
+ }
54665
+ if (Object.hasOwn(ENUM_PREFERENCES, key)) {
54666
+ need3(child.kind === "string" && ENUM_PREFERENCES[key].includes(child.value), "contains an invalid display preference");
54667
+ return false;
54668
+ }
54669
+ return true;
54670
+ });
54671
+ return createHash12("sha256").update("hasna.skills.claude-settings.v1\x00").update(JSON.stringify(canonical3(value))).digest("hex");
54672
+ }
54673
+ function hashClaudeSettingsReplacement(text2, budget) {
54674
+ need3(typeof text2 === "string", "requires settings text");
54675
+ const bytes = Buffer.byteLength(text2);
54676
+ need3(bytes <= CLAUDE_SETTINGS_WITNESS_LIMITS.bytes && Number.isSafeInteger(budget.remaining) && budget.remaining >= bytes, "exceeds its byte limit");
54677
+ budget.remaining -= bytes;
54678
+ return settingsDigest(text2);
54679
+ }
54680
+ function captureClaudeSettings(path, budget = { remaining: 256 * 1024 * 1024 }) {
54681
+ return { path, hashMode: "claude-settings-v1", sha256: settingsDigest(readSettings(path, budget)) };
54682
+ }
54683
+ var CLAUDE_SETTINGS_WITNESS_LIMITS, sameFile2 = (a, b) => a.dev === b.dev && a.ino === b.ino && a.mode === b.mode && a.uid === b.uid && a.gid === b.gid && a.nlink === b.nlink && a.size === b.size && a.mtimeNs === b.mtimeNs && a.ctimeNs === b.ctimeNs, BOOLEAN_PREFERENCES, ENUM_PREFERENCES, BUILTIN_MODEL_SELECTIONS;
54684
+ var init_claude_settings_witness = __esm(() => {
54685
+ CLAUDE_SETTINGS_WITNESS_LIMITS = Object.freeze({ bytes: 1024 * 1024, rows: 1024, depth: 32, nodes: 65536, stringCharacters: 16384, pathCharacters: 4096 });
54686
+ BOOLEAN_PREFERENCES = new Set([
54687
+ "autoScrollEnabled",
54688
+ "axScreenReader",
54689
+ "emojiCompletionEnabled",
54690
+ "prefersReducedMotion",
54691
+ "showTurnDuration",
54692
+ "spinnerTipsEnabled",
54693
+ "syntaxHighlightingDisabled",
54694
+ "terminalProgressBarEnabled",
54695
+ "terminalTitleFromRename",
54696
+ "verbose",
54697
+ "wheelScrollAccelerationEnabled"
54698
+ ]);
54699
+ ENUM_PREFERENCES = Object.freeze({
54700
+ editorMode: ["normal", "vim"],
54701
+ tui: ["default", "fullscreen"],
54702
+ viewMode: ["default", "verbose", "focus"]
54703
+ });
54704
+ BUILTIN_MODEL_SELECTIONS = new Set([
54705
+ "default",
54706
+ "best",
54707
+ "fable",
54708
+ "fable[1m]",
54709
+ "sonnet",
54710
+ "sonnet[1m]",
54711
+ "opus",
54712
+ "opus[1m]",
54713
+ "haiku",
54714
+ "opusplan",
54715
+ "claude-fable-5-1",
54716
+ "claude-fable-5",
54717
+ "claude-fable-5[1m]",
54718
+ "claude-opus-5",
54719
+ "claude-sonnet-5",
54720
+ "claude-haiku-4-5-20251001",
54721
+ "claude-opus-4-6",
54722
+ "claude-sonnet-4-5",
54723
+ "claude-sonnet-4-5-20250929",
54724
+ "claude-opus-4-8",
54725
+ "claude-opus-4-8[1m]",
54726
+ "claude-opus-4-7",
54727
+ "claude-sonnet-4-6",
54728
+ "claude-opus-4-5-20251101",
54729
+ "claude-opus-4-5",
54730
+ "claude-haiku-4-5",
54731
+ "claude-fable-5-1[1m]",
54732
+ "claude-opus-5[1m]",
54733
+ "claude-opus-4-7[1m]",
54734
+ "claude-opus-4-6[1m]",
54735
+ "claude-sonnet-4-6[1m]"
54736
+ ]);
54737
+ });
54738
+
54739
+ // src/lib/agent-discovery.ts
54740
+ import { createHash as createHash13 } from "crypto";
54741
+ import { lstatSync as lstatSync17, readFileSync as readFileSync14, readdirSync as readdirSync9, realpathSync as realpathSync4 } from "fs";
54742
+ import { basename as basename8, dirname as dirname14, isAbsolute as isAbsolute14, join as join28, resolve as resolve15, sep as sep5 } from "path";
54512
54743
  function parseConfig(text2, path, toml = false) {
54513
54744
  try {
54514
54745
  const value = toml ? Bun.TOML.parse(text2) : JSON.parse(text2);
@@ -54520,12 +54751,12 @@ function parseConfig(text2, path, toml = false) {
54520
54751
  }
54521
54752
  }
54522
54753
  function safe4(path) {
54523
- if (!isAbsolute13(path) || path.includes("\x00"))
54754
+ if (!isAbsolute14(path) || path.includes("\x00"))
54524
54755
  throw new Error("Expected an absolute native discovery path");
54525
- for (let cursor = path;; cursor = dirname13(cursor)) {
54526
- if (lstatSync16(cursor, { throwIfNoEntry: false })?.isSymbolicLink())
54756
+ for (let cursor = path;; cursor = dirname14(cursor)) {
54757
+ if (lstatSync17(cursor, { throwIfNoEntry: false })?.isSymbolicLink())
54527
54758
  throw new Error(`Refusing symlink native discovery input: ${cursor}`);
54528
- if (dirname13(cursor) === cursor)
54759
+ if (dirname14(cursor) === cursor)
54529
54760
  break;
54530
54761
  }
54531
54762
  }
@@ -54533,7 +54764,7 @@ function read2(path, changes) {
54533
54764
  safe4(path);
54534
54765
  if (changes?.has(path))
54535
54766
  return changes.get(path);
54536
- const stat2 = lstatSync16(path, { throwIfNoEntry: false });
54767
+ const stat2 = lstatSync17(path, { throwIfNoEntry: false });
54537
54768
  if (!stat2)
54538
54769
  return null;
54539
54770
  if (!stat2.isFile() || stat2.size > 16 * 1024 * 1024)
@@ -54541,6 +54772,14 @@ function read2(path, changes) {
54541
54772
  return readFileSync14(path, "utf8");
54542
54773
  }
54543
54774
  function projected(source, changes, budget = discoveryByteBudget()) {
54775
+ if (source.hashMode === "claude-settings-v1") {
54776
+ if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
54777
+ throw new Error("Claude settings witnesses require exact typed metadata");
54778
+ const current = captureClaudeSettings(source.path, budget).sha256;
54779
+ if (current !== source.sha256)
54780
+ throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
54781
+ return changes?.has(source.path) ? hashClaudeSettingsReplacement(changes.get(source.path), budget) : current;
54782
+ }
54544
54783
  if (source.hashMode === "claude-marketplace-registry") {
54545
54784
  if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256) || changes?.has(source.path))
54546
54785
  throw new Error("Claude marketplace witnesses require an exact reviewed registry without synthetic changes");
@@ -54598,6 +54837,8 @@ function verifyAgentDiscovery(binding) {
54598
54837
  safe4(root2);
54599
54838
  }
54600
54839
  function assertMarketplaceBinding(binding, source) {
54840
+ if (source.hashMode === "claude-settings-v1" && (binding.agent !== "claude" || binding.method !== "reviewed" || basename8(source.path) !== "settings.json"))
54841
+ throw new Error("Claude settings witnesses require explicit reviewed Claude configuration");
54601
54842
  if (source.hashMode === "claude-marketplace-registry" && (binding.agent !== "claude" || binding.method !== "reviewed"))
54602
54843
  throw new Error("Claude marketplace witnesses require explicit reviewed Claude discovery");
54603
54844
  }
@@ -54608,9 +54849,9 @@ function rebindAgentDiscovery(binding, changes) {
54608
54849
  return { ...source, sha256: projected(source, changes, budget) };
54609
54850
  }) };
54610
54851
  }
54611
- function assertProjectDiscovery(agent, directories, home, canonical3 = resolve14, reviewed) {
54852
+ function assertProjectDiscovery(agent, directories, home, canonical4 = resolve15, reviewed) {
54612
54853
  for (const directory of directories) {
54613
- const isHome = resolve14(directory) === resolve14(home);
54854
+ const isHome = resolve15(directory) === resolve15(home);
54614
54855
  if (agent === "hermes") {
54615
54856
  assertHermesEnvironment(home);
54616
54857
  continue;
@@ -54619,7 +54860,7 @@ function assertProjectDiscovery(agent, directories, home, canonical3 = resolve14
54619
54860
  continue;
54620
54861
  const paths = agent === "claude" ? [...isHome ? [] : [".claude/settings.json"], ".claude/settings.local.json"] : agent === "codex" ? [".codex/config.toml"] : agent === "gemini" ? [".gemini/settings.json"] : agent === "opencode" ? ["opencode.json", "opencode.jsonc", ".opencode/opencode.json", ".opencode/opencode.jsonc"] : [".cursor/hooks.json"];
54621
54862
  for (const suffix of paths) {
54622
- const path = canonical3(join28(directory, suffix)), raw = read2(path);
54863
+ const path = canonical4(join28(directory, suffix)), raw = read2(path);
54623
54864
  if (raw === null)
54624
54865
  continue;
54625
54866
  if (suffix.endsWith(".jsonc"))
@@ -54632,25 +54873,25 @@ function assertProjectDiscovery(agent, directories, home, canonical3 = resolve14
54632
54873
  const managed = reviewed.sources.flatMap((source) => source.hashMode === "claude-plugin-registry" ? source.managedPlugins ?? [] : []);
54633
54874
  if (exact && projected(exact) === exact.sha256 && managed.length) {
54634
54875
  const bindings = managed.map((item) => readPluginBinding(item.storeRoot, item.bindingId));
54635
- admittedPlugins = Object.entries(config.enabledPlugins).every(([id, enabled]) => typeof enabled === "boolean" && bindings.some((binding) => binding.target.pluginId === id && binding.target.registrations.some((scope) => scope.scope === "project" && scope.projectPath === canonical3(directory))));
54876
+ admittedPlugins = Object.entries(config.enabledPlugins).every(([id, enabled]) => typeof enabled === "boolean" && bindings.some((binding) => binding.target.pluginId === id && binding.target.registrations.some((scope) => scope.scope === "project" && scope.projectPath === canonical4(directory))));
54636
54877
  }
54637
54878
  }
54638
54879
  if (keys2.some((key) => config[key] !== undefined && !(key === "enabledPlugins" && admittedPlugins)) || config.disableAllHooks === true || config.disableBundledSkills === false || config.hooksConfig?.enabled === false || config.permission?.skill !== undefined || config.permissions?.deny?.some((rule) => typeof rule === "string" && /^Skill(?:\(|$)/.test(rule)))
54639
54880
  throw new Error(`NATIVE_SKILL_DRIFT: higher-precedence project skill or hook configuration requires review: ${path}`);
54640
54881
  }
54641
54882
  if (agent === "claude") {
54642
- const commands = canonical3(join28(directory, ".claude/commands"));
54883
+ const commands = canonical4(join28(directory, ".claude/commands"));
54643
54884
  safe4(commands);
54644
- if (lstatSync16(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync9(commands).length)
54885
+ if (lstatSync17(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync9(commands).length)
54645
54886
  throw new Error("NATIVE_SKILL_DRIFT: legacy project command discovery requires a dedicated format adapter");
54646
54887
  }
54647
54888
  }
54648
54889
  }
54649
54890
  function resolveAgentDiscovery(options) {
54650
- const canonical3 = options.canonical ?? resolve14, home = resolve14(options.home), agent = options.agent;
54891
+ const canonical4 = options.canonical ?? resolve15, home = resolve15(options.home), agent = options.agent;
54651
54892
  const sources = [], roots = new Set, builtinNames = [];
54652
54893
  const witness = (path, format, fields) => {
54653
- const source = { path: canonical3(path), sha256: null, ...format ? { format, fields } : {} };
54894
+ const source = { path: canonical4(path), sha256: null, ...format ? { format, fields } : {} };
54654
54895
  source.sha256 = projected(source);
54655
54896
  sources.push(source);
54656
54897
  return read2(source.path);
@@ -54678,7 +54919,7 @@ function resolveAgentDiscovery(options) {
54678
54919
  continue;
54679
54920
  if (normalized.startsWith("~") && normalized !== "~" && !normalized.startsWith("~/"))
54680
54921
  unresolved("user-specific tilde expansion requires a separate discovery adapter");
54681
- const path = normalized === "~" ? home : normalized.startsWith("~/") ? join28(home, normalized.slice(2)) : resolve14(home, ".hermes", normalized);
54922
+ const path = normalized === "~" ? home : normalized.startsWith("~/") ? join28(home, normalized.slice(2)) : resolve15(home, ".hermes", normalized);
54682
54923
  safe4(path);
54683
54924
  roots.add(path);
54684
54925
  }
@@ -54687,21 +54928,21 @@ function resolveAgentDiscovery(options) {
54687
54928
  const executable = Bun.which("gemini");
54688
54929
  if (executable) {
54689
54930
  let packageRoot;
54690
- for (let directory = dirname13(realpathSync4(executable)), depth = 0;depth < 8; directory = dirname13(directory), depth++) {
54931
+ for (let directory = dirname14(realpathSync4(executable)), depth = 0;depth < 8; directory = dirname14(directory), depth++) {
54691
54932
  const path = join28(directory, "package.json"), raw = read2(path);
54692
54933
  if (raw !== null && parseConfig(raw, path).name === "@google/gemini-cli") {
54693
54934
  packageRoot = directory;
54694
54935
  witness(path);
54695
54936
  break;
54696
54937
  }
54697
- if (dirname13(directory) === directory)
54938
+ if (dirname14(directory) === directory)
54698
54939
  break;
54699
54940
  }
54700
54941
  if (!packageRoot)
54701
54942
  unresolved("installed Gemini package layout is not recognized");
54702
54943
  const builtinRoot = join28(packageRoot, "bundle/builtin");
54703
54944
  safe4(builtinRoot);
54704
- if (!lstatSync16(builtinRoot, { throwIfNoEntry: false })?.isDirectory())
54945
+ if (!lstatSync17(builtinRoot, { throwIfNoEntry: false })?.isDirectory())
54705
54946
  unresolved("installed Gemini builtin root is missing");
54706
54947
  for (const name of readdirSync9(builtinRoot).sort()) {
54707
54948
  const text2 = witness(join28(builtinRoot, name, "SKILL.md"));
@@ -54722,12 +54963,14 @@ function resolveAgentDiscovery(options) {
54722
54963
  if (review.sources.some((source) => source.format !== undefined || source.fields !== undefined))
54723
54964
  throw new Error("Explicit discovery reviews require full source-file hashes");
54724
54965
  verifyAgentDiscovery(supplied);
54725
- if (!review.sources.some((source) => source.path === canonical3(configPath)))
54966
+ if (review.sources.some((source) => source.hashMode === "claude-settings-v1" && source.path !== canonical4(configPath)))
54967
+ throw new Error("Semantic settings witnesses must name the configured Claude configuration source");
54968
+ if (!review.sources.some((source) => source.path === canonical4(configPath)))
54726
54969
  throw new Error("Discovery review must include the agent configuration source");
54727
54970
  return { ...supplied, roots: [...new Set([...roots, ...supplied.roots])].sort(), sources: [...sources, ...review.sources], ...agent === "gemini" ? { builtinNames } : {} };
54728
54971
  }
54729
54972
  function plugin(root2) {
54730
- root2 = canonical3(root2);
54973
+ root2 = canonical4(root2);
54731
54974
  safe4(root2);
54732
54975
  const manifestPath = join28(root2, agent === "claude" ? ".claude-plugin/plugin.json" : ".codex-plugin/plugin.json");
54733
54976
  const raw = witness(manifestPath);
@@ -54739,7 +54982,7 @@ function resolveAgentDiscovery(options) {
54739
54982
  unresolved("plugin hooks require a separate no-skill-injection review");
54740
54983
  const commands = join28(root2, "commands");
54741
54984
  safe4(commands);
54742
- if (agent === "claude" && (manifest.commands !== undefined || lstatSync16(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync9(commands).length))
54985
+ if (agent === "claude" && (manifest.commands !== undefined || lstatSync17(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync9(commands).length))
54743
54986
  unresolved("legacy command discovery requires retirement or a dedicated format adapter");
54744
54987
  const rootSkill = witness(join28(root2, "SKILL.md"));
54745
54988
  if (rootSkill !== null)
@@ -54750,18 +54993,18 @@ function resolveAgentDiscovery(options) {
54750
54993
  if (agent === "claude")
54751
54994
  roots.add(join28(root2, "skills"));
54752
54995
  for (const value of declared) {
54753
- const path = resolve14(root2, value);
54996
+ const path = resolve15(root2, value);
54754
54997
  if (path !== root2 && !path.startsWith(root2 + sep5))
54755
54998
  unresolved("plugin skill path escapes its root");
54756
- roots.add(path.endsWith(`${sep5}SKILL.md`) ? dirname13(path) : path);
54999
+ roots.add(path.endsWith(`${sep5}SKILL.md`) ? dirname14(path) : path);
54757
55000
  }
54758
55001
  }
54759
55002
  if (agent === "claude") {
54760
55003
  const registrations = witness(join28(home, ".claude/plugins/installed_plugins.json"));
54761
55004
  const installed = registrations === null ? {} : parseConfig(registrations, join28(home, ".claude/plugins/installed_plugins.json")).plugins;
54762
- const commands = canonical3(join28(home, ".claude/commands"));
55005
+ const commands = canonical4(join28(home, ".claude/commands"));
54763
55006
  safe4(commands);
54764
- if (lstatSync16(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync9(commands).length)
55007
+ if (lstatSync17(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync9(commands).length)
54765
55008
  unresolved("legacy home command discovery requires a dedicated format adapter");
54766
55009
  for (const [id, enabled] of Object.entries(config.enabledPlugins ?? {})) {
54767
55010
  if (enabled === false)
@@ -54781,7 +55024,7 @@ function resolveAgentDiscovery(options) {
54781
55024
  unresolved("unsupported plugin enablement");
54782
55025
  const split2 = id.lastIndexOf("@"), name = id.slice(0, split2), marketplace = id.slice(split2 + 1);
54783
55026
  const market = config.marketplaces?.[marketplace] ?? (marketplace === "personal" ? { source_type: "local", source: home } : undefined);
54784
- if (split2 < 1 || market?.source_type !== "local" || typeof market.source !== "string" || !isAbsolute13(market.source))
55027
+ if (split2 < 1 || market?.source_type !== "local" || typeof market.source !== "string" || !isAbsolute14(market.source))
54785
55028
  unresolved("enabled plugin marketplace is not an explicit local source");
54786
55029
  const catalogText = witness(join28(market.source, ".agents/plugins/marketplace.json"));
54787
55030
  if (catalogText === null)
@@ -54789,7 +55032,7 @@ function resolveAgentDiscovery(options) {
54789
55032
  const catalog = parseConfig(catalogText, join28(market.source, ".agents/plugins/marketplace.json")), matches2 = Array.isArray(catalog.plugins) ? catalog.plugins.filter((item) => item.name === name) : [];
54790
55033
  if (matches2.length !== 1 || matches2[0]?.source?.source !== "local" || typeof matches2[0]?.source?.path !== "string")
54791
55034
  unresolved("plugin catalog source is missing or ambiguous");
54792
- plugin(resolve14(market.source, matches2[0].source.path));
55035
+ plugin(resolve15(market.source, matches2[0].source.path));
54793
55036
  }
54794
55037
  } else if (agent === "opencode") {
54795
55038
  if (witness(join28(home, ".config/opencode/opencode.jsonc")) !== null || witness(join28(home, ".config/opencode/config.json")) !== null)
@@ -54797,18 +55040,18 @@ function resolveAgentDiscovery(options) {
54797
55040
  if ((config.plugin?.length ?? 0) > 0 || config.skills?.urls?.length)
54798
55041
  unresolved("external plugin or remote skill source");
54799
55042
  for (const path of config.skills?.paths ?? []) {
54800
- if (typeof path !== "string" || !isAbsolute13(path))
55043
+ if (typeof path !== "string" || !isAbsolute14(path))
54801
55044
  unresolved("relative or malformed added skill root");
54802
55045
  roots.add(path);
54803
55046
  }
54804
55047
  const localPlugins = join28(home, ".config/opencode/plugins");
54805
55048
  safe4(localPlugins);
54806
- if (lstatSync16(localPlugins, { throwIfNoEntry: false }) && readdirSync9(localPlugins).some((name) => name !== "skills-cli.js"))
55049
+ if (lstatSync17(localPlugins, { throwIfNoEntry: false }) && readdirSync9(localPlugins).some((name) => name !== "skills-cli.js"))
54807
55050
  unresolved("additional local plugin hooks require review");
54808
55051
  } else if (agent === "hermes") {
54809
55052
  for (const directory of [join28(home, ".hermes/plugins"), join28(home, ".hermes/hermes-agent")]) {
54810
55053
  safe4(directory);
54811
- if (lstatSync16(directory, { throwIfNoEntry: false }))
55054
+ if (lstatSync17(directory, { throwIfNoEntry: false }))
54812
55055
  unresolved("installed runtime/plugin discovery requires reviewed source bindings");
54813
55056
  }
54814
55057
  if (Bun.which("hermes") || Object.keys(config.plugins ?? {}).length)
@@ -54818,11 +55061,11 @@ function resolveAgentDiscovery(options) {
54818
55061
  unresolved("custom extension or skill paths");
54819
55062
  const directory = join28(home, ".gemini/extensions");
54820
55063
  safe4(directory);
54821
- if (lstatSync16(directory, { throwIfNoEntry: false }))
55064
+ if (lstatSync17(directory, { throwIfNoEntry: false }))
54822
55065
  for (const name of readdirSync9(directory)) {
54823
55066
  const root2 = join28(directory, name);
54824
55067
  safe4(root2);
54825
- if (!lstatSync16(root2)?.isDirectory())
55068
+ if (!lstatSync17(root2)?.isDirectory())
54826
55069
  continue;
54827
55070
  const raw = witness(join28(root2, "gemini-extension.json"));
54828
55071
  if (raw === null)
@@ -54833,9 +55076,9 @@ function resolveAgentDiscovery(options) {
54833
55076
  roots.add(join28(root2, "skills"));
54834
55077
  }
54835
55078
  }
54836
- return { agent, roots: [...roots].sort(), sources, method: "automatic", ...agent === "gemini" ? { builtinNames } : {}, ...agent === "hermes" ? { directories: captureDiscoveryDirectories([join28(home, ".hermes/plugins"), join28(home, ".hermes/hermes-agent")].map((path) => canonical3(path))) } : {} };
55079
+ return { agent, roots: [...roots].sort(), sources, method: "automatic", ...agent === "gemini" ? { builtinNames } : {}, ...agent === "hermes" ? { directories: captureDiscoveryDirectories([join28(home, ".hermes/plugins"), join28(home, ".hermes/hermes-agent")].map((path) => canonical4(path))) } : {} };
54837
55080
  }
54838
- var digest = (text2) => createHash12("sha256").update(text2).digest("hex");
55081
+ var digest = (text2) => createHash13("sha256").update(text2).digest("hex");
54839
55082
  var init_agent_discovery = __esm(() => {
54840
55083
  init_agent_policy_limits();
54841
55084
  init_agent_hermes();
@@ -54845,6 +55088,7 @@ var init_agent_discovery = __esm(() => {
54845
55088
  init_plugin_discovery();
54846
55089
  init_plugin_admission();
54847
55090
  init_claude_marketplace_registry();
55091
+ init_claude_settings_witness();
54848
55092
  init_agent_discovery_directories();
54849
55093
  });
54850
55094
 
@@ -55006,16 +55250,16 @@ var init_agent_codex = __esm(() => {
55006
55250
  });
55007
55251
 
55008
55252
  // src/lib/agent-integration.ts
55009
- import { createHash as createHash13, randomUUID as randomUUID6 } from "crypto";
55010
- import { existsSync as existsSync15, lstatSync as lstatSync17, statSync as statSync8, mkdirSync as mkdirSync7, readFileSync as readFileSync15, readdirSync as readdirSync10, opendirSync as opendirSync5, readlinkSync as readlinkSync2, realpathSync as realpathSync5, renameSync as renameSync4, rmdirSync as rmdirSync3, writeFileSync as writeFileSync5, unlinkSync as unlinkSync4, chmodSync, openSync as openSync10, closeSync as closeSync10, fsyncSync as fsyncSync3, fstatSync as fstatSync10, readSync as readSync8, constants as constants10, linkSync as linkSync2 } from "fs";
55011
- import { dirname as dirname14, join as join29, resolve as resolve15, relative as relative5, isAbsolute as isAbsolute14, sep as sep6 } from "path";
55253
+ import { createHash as createHash14, randomUUID as randomUUID6 } from "crypto";
55254
+ import { existsSync as existsSync15, lstatSync as lstatSync18, statSync as statSync8, mkdirSync as mkdirSync7, readFileSync as readFileSync15, readdirSync as readdirSync10, opendirSync as opendirSync5, readlinkSync as readlinkSync2, realpathSync as realpathSync5, renameSync as renameSync4, rmdirSync as rmdirSync3, writeFileSync as writeFileSync5, unlinkSync as unlinkSync4, chmodSync, openSync as openSync11, closeSync as closeSync11, fsyncSync as fsyncSync3, fstatSync as fstatSync11, readSync as readSync9, constants as constants11, linkSync as linkSync2 } from "fs";
55255
+ import { dirname as dirname15, join as join29, resolve as resolve16, relative as relative5, isAbsolute as isAbsolute15, sep as sep6 } from "path";
55012
55256
  import { homedir as homedir4 } from "os";
55013
55257
  function assertSafePath(path) {
55014
- let cursor = resolve15(path);
55258
+ let cursor = resolve16(path);
55015
55259
  while (true) {
55016
- if (lstatSync17(cursor, { throwIfNoEntry: false })?.isSymbolicLink())
55260
+ if (lstatSync18(cursor, { throwIfNoEntry: false })?.isSymbolicLink())
55017
55261
  throw new Error(`Refusing symlink path: ${cursor}`);
55018
- const parent = dirname14(cursor);
55262
+ const parent = dirname15(cursor);
55019
55263
  if (parent === cursor)
55020
55264
  return;
55021
55265
  cursor = parent;
@@ -55024,16 +55268,16 @@ function assertSafePath(path) {
55024
55268
  function readRootAlias(home, agent) {
55025
55269
  assertSafePath(home);
55026
55270
  const realHome = realpathSync5(home), alias = join29(realHome, `.${agent}`);
55027
- const stat2 = lstatSync17(alias, { throwIfNoEntry: false, bigint: true });
55271
+ const stat2 = lstatSync18(alias, { throwIfNoEntry: false, bigint: true });
55028
55272
  if (!stat2?.isSymbolicLink())
55029
55273
  throw new Error(`Agent root alias changed after planning: ${alias}`);
55030
- const link2 = readlinkSync2(alias), targetPath = resolve15(dirname14(alias), link2);
55274
+ const link2 = readlinkSync2(alias), targetPath = resolve16(dirname15(alias), link2);
55031
55275
  assertSafePath(targetPath);
55032
- const targetStat = lstatSync17(targetPath, { throwIfNoEntry: false });
55276
+ const targetStat = lstatSync18(targetPath, { throwIfNoEntry: false });
55033
55277
  if (!targetStat?.isDirectory())
55034
55278
  throw new Error(`Agent root alias must target an existing directory: ${alias}`);
55035
55279
  const target = realpathSync5(targetPath), inside = relative5(realHome, target);
55036
- if (!inside || inside === ".." || inside.startsWith(`..${sep6}`) || isAbsolute14(inside))
55280
+ if (!inside || inside === ".." || inside.startsWith(`..${sep6}`) || isAbsolute15(inside))
55037
55281
  throw new Error(`Agent root alias target must be inside the real home: ${alias}`);
55038
55282
  return { agent, home: realHome, alias, target, link: link2, aliasIdentity: `${stat2.dev}:${stat2.ino}:${stat2.ctimeNs}`, targetIdentity: `${targetStat.dev}:${targetStat.ino}` };
55039
55283
  }
@@ -55042,14 +55286,14 @@ function rootAliases(home, allowed = false) {
55042
55286
  return [];
55043
55287
  const result2 = [];
55044
55288
  for (const agent of ["claude", "codex"])
55045
- if (lstatSync17(join29(home, `.${agent}`), { throwIfNoEntry: false })?.isSymbolicLink())
55289
+ if (lstatSync18(join29(home, `.${agent}`), { throwIfNoEntry: false })?.isSymbolicLink())
55046
55290
  result2.push(readRootAlias(home, agent));
55047
55291
  if (result2.some((item, index) => result2.slice(index + 1).some((other) => item.target === other.target || item.target.startsWith(other.target + sep6) || other.target.startsWith(item.target + sep6))))
55048
55292
  throw new Error("Agent root alias targets must not overlap");
55049
55293
  return result2;
55050
55294
  }
55051
55295
  function canonicalAgentPath(path, aliases) {
55052
- const absolute = resolve15(path), binding = aliases.find((item) => absolute === item.alias || absolute.startsWith(item.alias + sep6));
55296
+ const absolute = resolve16(path), binding = aliases.find((item) => absolute === item.alias || absolute.startsWith(item.alias + sep6));
55053
55297
  return binding ? join29(binding.target, relative5(binding.alias, absolute)) : absolute;
55054
55298
  }
55055
55299
  function recheckRootAliases(aliases) {
@@ -55063,35 +55307,35 @@ function recheckRootAliases(aliases) {
55063
55307
  }
55064
55308
  function readNativeBytes(path, maximum = 64 * 1024 * 1024) {
55065
55309
  assertSafePath(path);
55066
- const before2 = lstatSync17(path);
55310
+ const before2 = lstatSync18(path);
55067
55311
  if (!before2.isFile() || before2.size > maximum)
55068
55312
  throw new Error("Unsupported or oversized native skill file");
55069
- const descriptor = openSync10(path, constants10.O_RDONLY | constants10.O_NOFOLLOW | constants10.O_NONBLOCK);
55313
+ const descriptor = openSync11(path, constants11.O_RDONLY | constants11.O_NOFOLLOW | constants11.O_NONBLOCK);
55070
55314
  try {
55071
- const opened = fstatSync10(descriptor);
55315
+ const opened = fstatSync11(descriptor);
55072
55316
  if (!opened.isFile() || opened.dev !== before2.dev || opened.ino !== before2.ino || opened.size !== before2.size)
55073
55317
  throw new Error("Native skill file changed while reading");
55074
55318
  const bytes = Buffer.allocUnsafe(before2.size + 1);
55075
55319
  let length = 0;
55076
55320
  while (length < bytes.length) {
55077
- const count = readSync8(descriptor, bytes, length, bytes.length - length, null);
55321
+ const count = readSync9(descriptor, bytes, length, bytes.length - length, null);
55078
55322
  if (!count)
55079
55323
  break;
55080
55324
  length += count;
55081
55325
  }
55082
- const after2 = fstatSync10(descriptor);
55326
+ const after2 = fstatSync11(descriptor);
55083
55327
  if (length !== before2.size || after2.size !== before2.size || after2.mtimeMs !== opened.mtimeMs || after2.ctimeMs !== opened.ctimeMs)
55084
55328
  throw new Error("Native skill file changed while reading");
55085
55329
  return bytes.subarray(0, length);
55086
55330
  } finally {
55087
- closeSync10(descriptor);
55331
+ closeSync11(descriptor);
55088
55332
  }
55089
55333
  }
55090
55334
  function treeHash(root2) {
55091
- const hash2 = createHash13("sha256");
55335
+ const hash2 = createHash14("sha256");
55092
55336
  let bytes = 0, files = 0;
55093
55337
  function visit2(path) {
55094
- const stat2 = lstatSync17(path);
55338
+ const stat2 = lstatSync18(path);
55095
55339
  if (stat2.isSymbolicLink())
55096
55340
  throw new Error(`Refusing symlink in skill: ${path}`);
55097
55341
  const rel = relative5(root2, path);
@@ -55117,11 +55361,11 @@ function treeHash(root2) {
55117
55361
  function projectAncestorDirectories(projects) {
55118
55362
  const directories = new Set;
55119
55363
  for (const project of projects) {
55120
- for (let path = resolve15(project), depth = 0;; depth++) {
55364
+ for (let path = resolve16(project), depth = 0;; depth++) {
55121
55365
  if (depth >= 100)
55122
55366
  throw new Error("NATIVE_SKILL_DRIFT: project ancestor discovery limit exceeded");
55123
55367
  directories.add(path);
55124
- const parent = dirname14(path);
55368
+ const parent = dirname15(path);
55125
55369
  if (parent === path)
55126
55370
  break;
55127
55371
  path = parent;
@@ -55148,10 +55392,10 @@ function inventoryNativeSkills(home = homedir4(), options = {}) {
55148
55392
  throw new Error("Native skill discovery metadata limit exceeded");
55149
55393
  }
55150
55394
  function emptySiblingCacheAlias(path, parent) {
55151
- const link2 = readlinkSync2(path), target = resolve15(parent, link2);
55152
- if (dirname14(target) !== parent || (isAbsolute14(link2) ? link2 !== target : dirname14(link2) !== "."))
55395
+ const link2 = readlinkSync2(path), target = resolve16(parent, link2);
55396
+ if (dirname15(target) !== parent || (isAbsolute15(link2) ? link2 !== target : dirname15(link2) !== "."))
55153
55397
  return false;
55154
- if (!lstatSync17(target, { throwIfNoEntry: false })?.isDirectory())
55398
+ if (!lstatSync18(target, { throwIfNoEntry: false })?.isDirectory())
55155
55399
  return false;
55156
55400
  const scan = cacheScans.get(target);
55157
55401
  return Boolean(scan?.complete && !scan.hasSkills && scan.entries <= maxAliasProofEntries);
@@ -55163,7 +55407,7 @@ function inventoryNativeSkills(home = homedir4(), options = {}) {
55163
55407
  assertSafePath(path);
55164
55408
  if (!existsSync15(path))
55165
55409
  return scan;
55166
- const stat2 = lstatSync17(path);
55410
+ const stat2 = lstatSync18(path);
55167
55411
  if (stat2.isFile())
55168
55412
  return scan;
55169
55413
  if (!stat2.isDirectory())
@@ -55182,7 +55426,7 @@ function inventoryNativeSkills(home = homedir4(), options = {}) {
55182
55426
  }
55183
55427
  const bridge = !vendor && isOwnedCliBridge(path, bridgePaths);
55184
55428
  const rootAlias = aliases.find((item) => path === item.target || path.startsWith(item.target + sep6));
55185
- entries.push({ agent, path, hash: treeHash(path), managed, vendor, ...agent === "codex" && path.startsWith(canonicalAgentPath(join29(home, ".codex", "skills", ".system"), aliases) + sep6) ? { system: true } : {}, ...bridge ? { bridge: true, bridgeHome: resolve15(home) } : {}, ...rootAlias ? { rootAlias } : {} });
55429
+ entries.push({ agent, path, hash: treeHash(path), managed, vendor, ...agent === "codex" && path.startsWith(canonicalAgentPath(join29(home, ".codex", "skills", ".system"), aliases) + sep6) ? { system: true } : {}, ...bridge ? { bridge: true, bridgeHome: resolve16(home) } : {}, ...rootAlias ? { rootAlias } : {} });
55186
55430
  return scan;
55187
55431
  }
55188
55432
  if (depth > (vendor ? 32 : 3))
@@ -55209,7 +55453,7 @@ function inventoryNativeSkills(home = homedir4(), options = {}) {
55209
55453
  if (isVendor && !options.includeVendor)
55210
55454
  continue;
55211
55455
  const child = join29(path, name);
55212
- if (isVendor && lstatSync17(child, { throwIfNoEntry: false })?.isSymbolicLink()) {
55456
+ if (isVendor && lstatSync18(child, { throwIfNoEntry: false })?.isSymbolicLink()) {
55213
55457
  const target = statSync8(child, { throwIfNoEntry: false });
55214
55458
  if (target?.isFile() || pluginCache && target?.isDirectory() && emptySiblingCacheAlias(child, path)) {
55215
55459
  scan.entries++;
@@ -55331,7 +55575,7 @@ function configureHooks(config, agent, command, profileId, nativeReady) {
55331
55575
  function disableCodexSkills(text2, skills, aliases, bridgePath) {
55332
55576
  const bundled = disableCodexBundledSkills(text2);
55333
55577
  let result2 = bundled;
55334
- const bridgeSelector = (entry) => typeof entry.name === "string" && entry.name.trim() === CLI_BRIDGE_NAME || typeof entry.path === "string" && [resolve15(bridgePath), resolve15(join29(bridgePath, "SKILL.md"))].includes(canonicalAgentPath(entry.path, aliases));
55578
+ const bridgeSelector = (entry) => typeof entry.name === "string" && entry.name.trim() === CLI_BRIDGE_NAME || typeof entry.path === "string" && [resolve16(bridgePath), resolve16(join29(bridgePath, "SKILL.md"))].includes(canonicalAgentPath(entry.path, aliases));
55335
55579
  const previousConfig = Bun.TOML.parse(bundled).skills?.config;
55336
55580
  if (previousConfig !== undefined && (!Array.isArray(previousConfig) || previousConfig.some((entry) => !entry || typeof entry !== "object" || entry.path !== undefined && entry.name !== undefined)))
55337
55581
  throw new Error("Codex skill controls require one path or name selector per [[skills.config]] entry; review ambiguous entries before running skills hook install");
@@ -55343,7 +55587,7 @@ function disableCodexSkills(text2, skills, aliases, bridgePath) {
55343
55587
  result2 = result2.replace(CODEX_SKILL_CONFIG_SECTIONS, (section) => {
55344
55588
  const parsed = Bun.TOML.parse(section);
55345
55589
  const declared = parsed.skills?.config?.[0];
55346
- if (!declared || !(skill.enabled && bridgeSelector(declared)) && !(typeof declared.path === "string" && [resolve15(path), resolve15(skill.path)].includes(canonicalAgentPath(declared.path, aliases))))
55590
+ if (!declared || !(skill.enabled && bridgeSelector(declared)) && !(typeof declared.path === "string" && [resolve16(path), resolve16(skill.path)].includes(canonicalAgentPath(declared.path, aliases))))
55347
55591
  return section;
55348
55592
  found = true;
55349
55593
  return /^\s*enabled\s*=/m.test(section) ? section.replace(/^\s*enabled\s*=.*$/m, `enabled = ${skill.enabled}`) : `${section.trimEnd()}
@@ -55461,7 +55705,7 @@ function planAgentIntegration(options) {
55461
55705
  version: CLI_BRIDGE_VERSION,
55462
55706
  digest: CLI_BRIDGE_DIGEST,
55463
55707
  agents: [...new Set([...priorAgents, ...options.agents])].sort(),
55464
- home: resolve15(home),
55708
+ home: resolve16(home),
55465
55709
  includeVendor: true,
55466
55710
  ...options.agents.includes("hermes") ? { supervisors: { ...policy.bridge?.supervisors, hermes: { path: join29(dataDir3, "agent-hooks", "hermes.js"), runtime: process.execPath, sha256: sha(renderHermesSupervisor(bindings.get("hermes").command, bindings.get("hermes").profileId)) } } } : {},
55467
55711
  commands: { ...policy.bridge?.commands, ...Object.fromEntries([...bindings].map(([agent, binding]) => [agent, binding.command])) },
@@ -55478,7 +55722,7 @@ function planAgentIntegration(options) {
55478
55722
  }
55479
55723
  function atomicWrite2(path, content) {
55480
55724
  assertSafePath(path);
55481
- mkdirSync7(dirname14(path), { recursive: true, mode: 448 });
55725
+ mkdirSync7(dirname15(path), { recursive: true, mode: 448 });
55482
55726
  const temporary = `${path}.skills-${randomUUID6()}`;
55483
55727
  try {
55484
55728
  writeFileSync5(temporary, content, { mode: 384, flag: "wx" });
@@ -55491,10 +55735,10 @@ function atomicWrite2(path, content) {
55491
55735
  function applyAgentIntegration(plan) {
55492
55736
  const policyPath = join29(plan.dataDir, "agent-policy.json");
55493
55737
  assertSafePath(policyPath);
55494
- const currentText = (path) => resolve15(path) === resolve15(policyPath) ? readManagedSkillPolicySnapshot(plan.dataDir)?.text ?? null : readOptional(path);
55738
+ const currentText = (path) => resolve16(path) === resolve16(policyPath) ? readManagedSkillPolicySnapshot(plan.dataDir)?.text ?? null : readOptional(path);
55495
55739
  readManagedSkillPolicySnapshot(plan.dataDir);
55496
55740
  for (const change of plan.changes)
55497
- if (resolve15(change.path) === resolve15(policyPath))
55741
+ if (resolve16(change.path) === resolve16(policyPath))
55498
55742
  parseManagedSkillPolicy(change.after);
55499
55743
  const aliases = plan.rootAliases ?? [];
55500
55744
  recheckRootAliases(aliases);
@@ -55524,7 +55768,7 @@ function applyAgentIntegration(plan) {
55524
55768
  recheckRootAliases(aliases);
55525
55769
  if (currentText(change.path) !== change.before)
55526
55770
  throw new Error(`Configuration changed after planning: ${change.path}`);
55527
- for (let directory = dirname14(change.path);!existsSync15(directory); directory = dirname14(directory))
55771
+ for (let directory = dirname15(change.path);!existsSync15(directory); directory = dirname15(directory))
55528
55772
  createdDirectories.add(directory);
55529
55773
  const after2 = change.after;
55530
55774
  atomicWrite2(change.path, after2);
@@ -55564,11 +55808,11 @@ function applyAgentIntegration(plan) {
55564
55808
  }
55565
55809
  function syncArchiveDirectory(path) {
55566
55810
  assertSafePath(path);
55567
- const descriptor = openSync10(path, constants10.O_RDONLY | constants10.O_DIRECTORY | constants10.O_NOFOLLOW | constants10.O_NONBLOCK);
55811
+ const descriptor = openSync11(path, constants11.O_RDONLY | constants11.O_DIRECTORY | constants11.O_NOFOLLOW | constants11.O_NONBLOCK);
55568
55812
  try {
55569
55813
  fsyncSync3(descriptor);
55570
55814
  } finally {
55571
- closeSync10(descriptor);
55815
+ closeSync11(descriptor);
55572
55816
  }
55573
55817
  }
55574
55818
  function writeArchiveJournal(path, value) {
@@ -55576,18 +55820,18 @@ function writeArchiveJournal(path, value) {
55576
55820
  const temporary = `${path}.skills-${randomUUID6()}`;
55577
55821
  let descriptor;
55578
55822
  try {
55579
- descriptor = openSync10(temporary, constants10.O_WRONLY | constants10.O_CREAT | constants10.O_EXCL | constants10.O_NOFOLLOW, 384);
55823
+ descriptor = openSync11(temporary, constants11.O_WRONLY | constants11.O_CREAT | constants11.O_EXCL | constants11.O_NOFOLLOW, 384);
55580
55824
  writeFileSync5(descriptor, `${JSON.stringify(value)}
55581
55825
  `);
55582
55826
  fsyncSync3(descriptor);
55583
- closeSync10(descriptor);
55827
+ closeSync11(descriptor);
55584
55828
  descriptor = undefined;
55585
55829
  renameSync4(temporary, path);
55586
- syncArchiveDirectory(dirname14(path));
55830
+ syncArchiveDirectory(dirname15(path));
55587
55831
  } finally {
55588
55832
  if (descriptor !== undefined)
55589
- closeSync10(descriptor);
55590
- if (lstatSync17(temporary, { throwIfNoEntry: false }))
55833
+ closeSync11(descriptor);
55834
+ if (lstatSync18(temporary, { throwIfNoEntry: false }))
55591
55835
  unlinkSync4(temporary);
55592
55836
  }
55593
55837
  }
@@ -55620,7 +55864,7 @@ function archiveNativeSkills(inventory, options) {
55620
55864
  const moved = [];
55621
55865
  const verifyArchive = (entry) => {
55622
55866
  assertSafePath(entry.archive);
55623
- const stat2 = lstatSync17(entry.archive);
55867
+ const stat2 = lstatSync18(entry.archive);
55624
55868
  if (entry.discoveryOnly ? !stat2.isFile() : !stat2.isDirectory())
55625
55869
  throw new Error("Archive type changed");
55626
55870
  if ((entry.discoveryOnly ? sha(readNativeBytes(entry.archive)) : treeHash(entry.archive)) !== entry.hash)
@@ -55628,14 +55872,14 @@ function archiveNativeSkills(inventory, options) {
55628
55872
  };
55629
55873
  assertSafePath(archiveRoot);
55630
55874
  const created = [];
55631
- for (let path = archiveRoot;!existsSync15(path); path = dirname14(path))
55875
+ for (let path = archiveRoot;!existsSync15(path); path = dirname15(path))
55632
55876
  created.push(path);
55633
55877
  mkdirSync7(archiveRoot, { recursive: true, mode: 448 });
55634
55878
  try {
55635
55879
  for (const directory of created)
55636
55880
  syncArchiveDirectory(directory);
55637
55881
  if (created.length)
55638
- syncArchiveDirectory(dirname14(created.at(-1)));
55882
+ syncArchiveDirectory(dirname15(created.at(-1)));
55639
55883
  writeArchiveJournal(receiptPath, journal);
55640
55884
  for (const [index, entry] of selected.entries()) {
55641
55885
  recheckRootAliases(aliases);
@@ -55647,7 +55891,7 @@ function archiveNativeSkills(inventory, options) {
55647
55891
  writeArchiveJournal(receiptPath, journal);
55648
55892
  renameSync4(move.source, move.archive);
55649
55893
  moved.push(move);
55650
- syncArchiveDirectory(dirname14(move.source));
55894
+ syncArchiveDirectory(dirname15(move.source));
55651
55895
  syncArchiveDirectory(archiveRoot);
55652
55896
  verifyArchive(move);
55653
55897
  move.status = "archived";
@@ -55668,7 +55912,7 @@ function archiveNativeSkills(inventory, options) {
55668
55912
  recheckRootAliases(aliases);
55669
55913
  assertSafePath(entry.source);
55670
55914
  assertSafePath(entry.archive);
55671
- if (lstatSync17(entry.source, { throwIfNoEntry: false })) {
55915
+ if (lstatSync18(entry.source, { throwIfNoEntry: false })) {
55672
55916
  entry.status = "recovery-required";
55673
55917
  entry.conflict = "source-occupied";
55674
55918
  continue;
@@ -55682,10 +55926,10 @@ function archiveNativeSkills(inventory, options) {
55682
55926
  }
55683
55927
  if (entry.discoveryOnly) {
55684
55928
  linkSync2(entry.archive, entry.source);
55685
- syncArchiveDirectory(dirname14(entry.source));
55929
+ syncArchiveDirectory(dirname15(entry.source));
55686
55930
  unlinkSync4(entry.archive);
55687
55931
  } else {
55688
- if (lstatSync17(entry.source, { throwIfNoEntry: false })) {
55932
+ if (lstatSync18(entry.source, { throwIfNoEntry: false })) {
55689
55933
  entry.status = "recovery-required";
55690
55934
  entry.conflict = "source-occupied";
55691
55935
  continue;
@@ -55693,7 +55937,7 @@ function archiveNativeSkills(inventory, options) {
55693
55937
  renameSync4(entry.archive, entry.source);
55694
55938
  }
55695
55939
  entry.status = "restored";
55696
- syncArchiveDirectory(dirname14(entry.source));
55940
+ syncArchiveDirectory(dirname15(entry.source));
55697
55941
  syncArchiveDirectory(archiveRoot);
55698
55942
  } catch {
55699
55943
  entry.status = "recovery-required";
@@ -55713,7 +55957,7 @@ function archiveNativeSkills(inventory, options) {
55713
55957
  return { entries: entries.map(({ status, conflict, ...entry }) => entry), receiptPath, ...aliases.length ? { rootAliases: aliases } : {} };
55714
55958
  }
55715
55959
  function assertManagedAgentBridge(agent, options = {}) {
55716
- const home = resolve15(options.home ?? homedir4()), dataDir3 = options.dataDir ?? getDataDirReadOnly();
55960
+ const home = resolve16(options.home ?? homedir4()), dataDir3 = options.dataDir ?? getDataDirReadOnly();
55717
55961
  assertSafePath(join29(dataDir3, "agent-policy.json"));
55718
55962
  const snapshot = readManagedSkillPolicySnapshot(dataDir3);
55719
55963
  if (!snapshot)
@@ -55836,7 +56080,7 @@ function assertNativeExportAllowed(dataDir3 = getDataDirReadOnly()) {
55836
56080
  if (requiresCliSkillLoading(dataDir3))
55837
56081
  throw new Error("NATIVE_SKILL_EXPORT_DISABLED: this station loads skills through the Skills CLI; use skills sync --selection-profile <id>");
55838
56082
  }
55839
- var sha = (data) => createHash13("sha256").update(data).digest("hex"), HOOK_EVENTS, ROOTS, SKILLS_LOADING_POLICY = "Skills loading policy: discover skills with `skills list` or `skills search`, and read selected instructions with `skills load <slug>`. Use `skills sync` to refresh the shared profile. The only native skill is the owned skills-cli bridge. Create and edit payload skills in the Skills authoring workspace; do not copy payload instructions into native discovery folders. Context loading does not authorize execution; use `skills run` only when the task calls for running a skill.";
56083
+ var sha = (data) => createHash14("sha256").update(data).digest("hex"), HOOK_EVENTS, ROOTS, SKILLS_LOADING_POLICY = "Skills loading policy: discover skills with `skills list` or `skills search`, and read selected instructions with `skills load <slug>`. Use `skills sync` to refresh the shared profile. The only native skill is the owned skills-cli bridge. Create and edit payload skills in the Skills authoring workspace; do not copy payload instructions into native discovery folders. Context loading does not authorize execution; use `skills run` only when the task calls for running a skill.";
55840
56084
  var init_agent_integration = __esm(() => {
55841
56085
  init_config();
55842
56086
  init_managed_policy();
@@ -56004,7 +56248,7 @@ var init_home_migration = __esm(() => {
56004
56248
  import {
56005
56249
  cpSync as cpSync2,
56006
56250
  existsSync as existsSync17,
56007
- lstatSync as lstatSync18,
56251
+ lstatSync as lstatSync19,
56008
56252
  mkdirSync as mkdirSync9,
56009
56253
  mkdtempSync as mkdtempSync2,
56010
56254
  readFileSync as readFileSync16,
@@ -56015,14 +56259,14 @@ import {
56015
56259
  writeFileSync as writeFileSync7
56016
56260
  } from "fs";
56017
56261
  import { homedir as homedir5 } from "os";
56018
- import { basename as basename7, dirname as dirname15, join as join31 } from "path";
56262
+ import { basename as basename9, dirname as dirname16, join as join31 } from "path";
56019
56263
  function isSkillsOwnershipMarker(marker) {
56020
56264
  return typeof marker === "object" && marker !== null && Object.hasOwn(marker, "managedBy") && marker.managedBy === SYNC_MARKER_MANAGED_BY;
56021
56265
  }
56022
56266
  function hasSkillsOwnershipMarker(dir) {
56023
56267
  const path = join31(dir, SYNC_MARKER_FILE);
56024
56268
  try {
56025
- if (!lstatSync18(path).isFile())
56269
+ if (!lstatSync19(path).isFile())
56026
56270
  return false;
56027
56271
  const marker = JSON.parse(readFileSync16(path, "utf8"));
56028
56272
  return isSkillsOwnershipMarker(marker);
@@ -56247,9 +56491,9 @@ function writeManagedSkillDir(dir, skillMd, options) {
56247
56491
  const action = dirExists ? "update" : "create";
56248
56492
  if (options.dryRun)
56249
56493
  return { action, path: skillMdPath };
56250
- const parentDir = dirname15(dir);
56494
+ const parentDir = dirname16(dir);
56251
56495
  mkdirSync9(parentDir, { recursive: true });
56252
- const transactionDir = mkdtempSync2(join31(parentDir, `.hasna-skills-write-${basename7(dir)}-`));
56496
+ const transactionDir = mkdtempSync2(join31(parentDir, `.hasna-skills-write-${basename9(dir)}-`));
56253
56497
  const candidateDir = join31(transactionDir, "candidate");
56254
56498
  const backupDir = join31(transactionDir, "backup");
56255
56499
  const candidateSkillMdPath = join31(candidateDir, "SKILL.md");
@@ -58099,7 +58343,7 @@ var _parse = (_Err) => {
58099
58343
  return result2.value;
58100
58344
  };
58101
58345
  return fn;
58102
- }, parse6, _parseAsync = (_Err) => {
58346
+ }, parse7, _parseAsync = (_Err) => {
58103
58347
  const fn = async (schema, value, _ctx, params) => {
58104
58348
  const ctx = _ctx ? { ..._ctx, async: true } : { async: true };
58105
58349
  let result2 = schema._zod.run({ value, issues: [] }, ctx);
@@ -58144,16 +58388,16 @@ var _parse = (_Err) => {
58144
58388
  result2 = await result2;
58145
58389
  return result2.issues.length === 0;
58146
58390
  }, _encode = (_Err) => {
58147
- const parse7 = _parse(_Err);
58391
+ const parse8 = _parse(_Err);
58148
58392
  const fn = (schema, value, _ctx, _params) => {
58149
58393
  const ctx = _ctx ? { ..._ctx, direction: "backward" } : { direction: "backward" };
58150
- return parse7(schema, value, ctx, finalizeParams(fn, _params));
58394
+ return parse8(schema, value, ctx, finalizeParams(fn, _params));
58151
58395
  };
58152
58396
  return fn;
58153
58397
  }, encode, _decode = (_Err) => {
58154
- const parse7 = _parse(_Err);
58398
+ const parse8 = _parse(_Err);
58155
58399
  const fn = (schema, value, _ctx, _params) => {
58156
- return parse7(schema, value, _ctx, finalizeParams(fn, _params));
58400
+ return parse8(schema, value, _ctx, finalizeParams(fn, _params));
58157
58401
  };
58158
58402
  return fn;
58159
58403
  }, decode, _encodeAsync = (_Err) => {
@@ -58184,7 +58428,7 @@ var init_parse = __esm(() => {
58184
58428
  init_core();
58185
58429
  init_errors();
58186
58430
  init_util();
58187
- parse6 = /* @__PURE__ */ _parse($ZodRealError);
58431
+ parse7 = /* @__PURE__ */ _parse($ZodRealError);
58188
58432
  parseAsync = /* @__PURE__ */ _parseAsync($ZodRealError);
58189
58433
  safeParse = /* @__PURE__ */ _safeParse($ZodRealError);
58190
58434
  safeParseAsync = /* @__PURE__ */ _safeParseAsync($ZodRealError);
@@ -61109,10 +61353,10 @@ var init_schemas = __esm(() => {
61109
61353
  throw new Error("implement() must be called with a function");
61110
61354
  }
61111
61355
  return Object.defineProperty(function(...args) {
61112
- const parsedArgs = inst._def.input ? parse6(inst._def.input, args) : args;
61356
+ const parsedArgs = inst._def.input ? parse7(inst._def.input, args) : args;
61113
61357
  const result2 = Reflect.apply(func, this, parsedArgs);
61114
61358
  if (inst._def.output) {
61115
- return parse6(inst._def.output, result2);
61359
+ return parse7(inst._def.output, result2);
61116
61360
  }
61117
61361
  return result2;
61118
61362
  }, "_zod", { value: inst._zod, enumerable: false });
@@ -72813,7 +73057,7 @@ __export(exports_core2, {
72813
73057
  prettifyError: () => prettifyError,
72814
73058
  parseURLObject: () => parseURLObject,
72815
73059
  parseAsync: () => parseAsync,
72816
- parse: () => parse6,
73060
+ parse: () => parse7,
72817
73061
  meta: () => meta,
72818
73062
  mergeValues: () => mergeValues,
72819
73063
  memoizer: () => memoizer,
@@ -73203,12 +73447,12 @@ var init_errors2 = __esm(() => {
73203
73447
  });
73204
73448
 
73205
73449
  // node_modules/zod/v4/classic/parse.js
73206
- var parse8, parseAsync2, safeParse2, safeParseAsync2, encode2, decode2, encodeAsync2, decodeAsync2, safeEncode2, safeDecode2, safeEncodeAsync2, safeDecodeAsync2;
73450
+ var parse9, parseAsync2, safeParse2, safeParseAsync2, encode2, decode2, encodeAsync2, decodeAsync2, safeEncode2, safeDecode2, safeEncodeAsync2, safeDecodeAsync2;
73207
73451
  var init_parse2 = __esm(() => {
73208
73452
  init_core2();
73209
73453
  init_errors2();
73210
73454
  init_core2();
73211
- parse8 = /* @__PURE__ */ _parse(ZodRealError);
73455
+ parse9 = /* @__PURE__ */ _parse(ZodRealError);
73212
73456
  parseAsync2 = /* @__PURE__ */ _parseAsync(ZodRealError);
73213
73457
  safeParse2 = /* @__PURE__ */ _safeParse(ZodRealError);
73214
73458
  safeParseAsync2 = /* @__PURE__ */ _safeParseAsync(ZodRealError);
@@ -74009,7 +74253,7 @@ var init_schemas2 = __esm(() => {
74009
74253
  exports_util.own(this, "~standard", value);
74010
74254
  },
74011
74255
  parse: function _parse2(data, params) {
74012
- return parse8(this, data, params, { callee: _parse2 });
74256
+ return parse9(this, data, params, { callee: _parse2 });
74013
74257
  },
74014
74258
  parseAsync: async function _parseAsync2(data, params) {
74015
74259
  return await parseAsync2(this, data, params, { callee: _parseAsync2 });
@@ -75702,7 +75946,7 @@ __export(exports_external, {
75702
75946
  pipe: () => pipe,
75703
75947
  partialRecord: () => partialRecord,
75704
75948
  parseAsync: () => parseAsync2,
75705
- parse: () => parse8,
75949
+ parse: () => parse9,
75706
75950
  overwrite: () => _overwrite,
75707
75951
  output: () => output,
75708
75952
  optional: () => optional,
@@ -75969,6 +76213,8 @@ function normalizeRemoteSkill(skill) {
75969
76213
  tags: skill.tags || ["remote"],
75970
76214
  dependencies: skill.dependencies,
75971
76215
  ...skill.version ? { version: skill.version } : {},
76216
+ ...skill.revisionId !== undefined ? { revisionId: skill.revisionId } : {},
76217
+ ...skill.lifecycle ? { lifecycle: skill.lifecycle } : {},
75972
76218
  availability: normalizeRemoteAvailability(skill.availability),
75973
76219
  source: "remote"
75974
76220
  };
@@ -76086,6 +76332,8 @@ var init_remote_registry = __esm(() => {
76086
76332
  tags: exports_external.array(exports_external.string()).optional(),
76087
76333
  dependencies: exports_external.array(exports_external.string()).optional(),
76088
76334
  version: exports_external.string().optional(),
76335
+ revisionId: exports_external.union([exports_external.string().regex(/^[\x21-\x7e]+$/), exports_external.null()]).optional(),
76336
+ lifecycle: exports_external.enum(["active", "archived"]).optional(),
76089
76337
  availability: remoteAvailabilitySchema.optional()
76090
76338
  }).passthrough().refine((skill) => skill.name || skill.slug, {
76091
76339
  message: "Remote skill requires name or slug"
@@ -76183,7 +76431,7 @@ var init_v4 = __esm(() => {
76183
76431
  });
76184
76432
 
76185
76433
  // src/lib/canonical-json.ts
76186
- import { createHash as createHash14 } from "crypto";
76434
+ import { createHash as createHash15 } from "crypto";
76187
76435
  function canonicalJson2(value, maximumBytes = 2 * 1024 * 1024) {
76188
76436
  return canonicalJsonAtDepth(value, maximumBytes, 64);
76189
76437
  }
@@ -76227,7 +76475,7 @@ function canonicalJsonAtDepth(value, maximumBytes, maximumDepth) {
76227
76475
  return visit3(value, 0);
76228
76476
  }
76229
76477
  function canonicalJsonSha256(value, maximumBytes) {
76230
- return createHash14("sha256").update(canonicalJson2(value, maximumBytes)).digest("hex");
76478
+ return createHash15("sha256").update(canonicalJson2(value, maximumBytes)).digest("hex");
76231
76479
  }
76232
76480
  var init_canonical_json = () => {};
76233
76481
 
@@ -76981,13 +77229,13 @@ var init_remote_workspace_leave = __esm(() => {
76981
77229
 
76982
77230
  // src/lib/auth-store.ts
76983
77231
  import { chmodSync as chmodSync2, existsSync as existsSync20, mkdirSync as mkdirSync11, readFileSync as readFileSync19, renameSync as renameSync7, statSync as statSync11, unlinkSync as unlinkSync5, writeFileSync as writeFileSync9 } from "fs";
76984
- import { basename as basename8, dirname as dirname16, join as join34 } from "path";
77232
+ import { basename as basename10, dirname as dirname17, join as join34 } from "path";
76985
77233
  function getAuthFilePath(env3 = process.env) {
76986
77234
  return skillsCredentialFilePath(env3);
76987
77235
  }
76988
77236
  function getIdentityFilePath(env3 = process.env) {
76989
77237
  const file2 = skillsCredentialFilePath(env3);
76990
- return join34(dirname16(file2), basename8(file2).replace(/^credentials/, "identity") + ".json");
77238
+ return join34(dirname17(file2), basename10(file2).replace(/^credentials/, "identity") + ".json");
76991
77239
  }
76992
77240
  function getAuthIdentity(env3 = process.env) {
76993
77241
  return readIdentity(env3);
@@ -77021,7 +77269,7 @@ function getAuthConfig(env3 = process.env, options = {}) {
77021
77269
  }
77022
77270
  function writeCredentialValues(values2, env3 = process.env) {
77023
77271
  const file2 = skillsCredentialFilePath(env3);
77024
- mkdirSync11(dirname16(file2), { recursive: true, mode: 448 });
77272
+ mkdirSync11(dirname17(file2), { recursive: true, mode: 448 });
77025
77273
  const lines = [];
77026
77274
  const written = new Set;
77027
77275
  if (existsSync20(file2)) {
@@ -77359,10 +77607,10 @@ async function readQuoteUnavailableCode(response) {
77359
77607
  let timer;
77360
77608
  let deadlineExceeded = false;
77361
77609
  const expired = Symbol("quote body deadline");
77362
- const deadline = new Promise((resolve16) => {
77610
+ const deadline = new Promise((resolve17) => {
77363
77611
  timer = setTimeout(() => {
77364
77612
  deadlineExceeded = true;
77365
- resolve16(expired);
77613
+ resolve17(expired);
77366
77614
  reader.cancel().catch(() => {});
77367
77615
  }, 1500);
77368
77616
  });
@@ -77474,6 +77722,7 @@ __export(exports_remote_client, {
77474
77722
  RemoteWorkspaceSelectionError: () => RemoteWorkspaceSelectionError,
77475
77723
  RemoteWorkspaceMemberError: () => RemoteWorkspaceMemberError,
77476
77724
  RemoteSkillsClient: () => RemoteSkillsClient,
77725
+ RemoteSkillLifecycleError: () => RemoteSkillLifecycleError,
77477
77726
  RemoteRouteUnsupportedError: () => RemoteRouteUnsupportedError,
77478
77727
  RemoteRequestError: () => RemoteRequestError,
77479
77728
  RemoteQuoteUnavailableError: () => RemoteQuoteUnavailableError,
@@ -77605,6 +77854,39 @@ class RemoteSkillsClient {
77605
77854
  })();
77606
77855
  return this.capabilities;
77607
77856
  }
77857
+ async addSkillPublishScope(keyId, expectedScopes, expectedOrgId) {
77858
+ if (!/^[A-Za-z0-9_-]+$/.test(keyId))
77859
+ throw new Error("Invalid API key id");
77860
+ if (!/^[A-Za-z0-9_-]{1,256}$/.test(expectedOrgId))
77861
+ throw new Error("Invalid expected organization id");
77862
+ if (!Array.isArray(expectedScopes) || expectedScopes.length > 32 || expectedScopes.some((scope) => typeof scope !== "string" || scope.length > 128 || !/^(?:\*|[a-z][a-z0-9_-]*:(?:\*|[a-z][a-z0-9_-]*))$/.test(scope)) || new Set(expectedScopes).size !== expectedScopes.length)
77863
+ throw new Error("Invalid expected API key scopes");
77864
+ const path = `/api/v1/admin/keys/${encodeURIComponent(keyId)}/scopes`;
77865
+ const response = await this.request(path, { method: "PATCH", body: JSON.stringify({ expected_scopes: expectedScopes, add_scopes: ["skills:publish"] }) });
77866
+ if (!response.ok)
77867
+ throw new RemoteRequestError(path, response.status);
77868
+ let value;
77869
+ try {
77870
+ value = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(await readBoundedResponse(response, 64 * 1024)));
77871
+ } catch {
77872
+ throw new Error("Invalid API key scope update response");
77873
+ }
77874
+ if (!value || typeof value !== "object" || Array.isArray(value))
77875
+ throw new Error("Invalid API key scope update response");
77876
+ const body = value;
77877
+ const returnedId = body.keyId;
77878
+ const orgId = body.orgId;
77879
+ const scopes = body.scopes;
77880
+ if (returnedId !== keyId || typeof orgId !== "string" || !orgId || expectedOrgId !== undefined && orgId !== expectedOrgId || !Array.isArray(scopes) || scopes.some((scope) => typeof scope !== "string") || body.updated !== true) {
77881
+ throw new Error("Invalid API key scope update response");
77882
+ }
77883
+ const returnedScopes = scopes;
77884
+ const expectedResult = expectedScopes.includes("skills:publish") ? expectedScopes : [...expectedScopes, "skills:publish"];
77885
+ if (returnedScopes.length !== expectedResult.length || expectedResult.some((scope, index) => returnedScopes[index] !== scope)) {
77886
+ throw new Error("API key scope update response did not preserve the expected scopes");
77887
+ }
77888
+ return { keyId, orgId, scopes: [...returnedScopes], updated: true };
77889
+ }
77608
77890
  async submitQuotedRun(slug2, input2 = {}, args = [], approval = {}) {
77609
77891
  runQuoteReceipt(approval.quoteReceipt);
77610
77892
  ({ input: input2, args, approval } = JSON.parse(JSON.stringify({ input: input2, args, approval })));
@@ -78122,6 +78404,19 @@ class RemoteSkillsClient {
78122
78404
  async deleteSkill(slug2) {
78123
78405
  return this.request(`/api/v1/skills/${encodeURIComponent(slug2)}`, { method: "DELETE" });
78124
78406
  }
78407
+ async setSkillLifecycle(slug2, lifecycle, options) {
78408
+ const path = `/api/v1/skills/${encodeURIComponent(slug2)}/lifecycle`;
78409
+ const response = await this.request(path, {
78410
+ method: "PATCH",
78411
+ headers: { "If-Match": options.expectedRevisionId },
78412
+ body: JSON.stringify({ lifecycle, ...options.reason ? { reason: options.reason } : {}, ...options.replacementSlug ? { replacementSlug: options.replacementSlug } : {} })
78413
+ });
78414
+ if (!response.ok) {
78415
+ const code = await readResponseCode(response);
78416
+ throw new RemoteSkillLifecycleError(path, response.status, code);
78417
+ }
78418
+ return response.json();
78419
+ }
78125
78420
  async downloadSkillBundle(slug2) {
78126
78421
  return this.request(`/api/v1/skills/${encodeURIComponent(slug2)}/bundle`, { method: "GET" });
78127
78422
  }
@@ -78273,9 +78568,13 @@ function normalizeSkillSummaryList(payload) {
78273
78568
  return payload.map(normalizeSkillSummary);
78274
78569
  }
78275
78570
  async function responseBodyCarriesCode(response, codes) {
78571
+ const code = await readResponseCode(response);
78572
+ return code !== undefined && codes.includes(code);
78573
+ }
78574
+ async function readResponseCode(response) {
78276
78575
  const reader = response.body?.getReader();
78277
78576
  if (!reader)
78278
- return false;
78577
+ return;
78279
78578
  const maximum = 8 * 1024;
78280
78579
  let deadline;
78281
78580
  const expired = new Promise((_, reject2) => {
@@ -78290,7 +78589,7 @@ async function responseBodyCarriesCode(response, codes) {
78290
78589
  break;
78291
78590
  size2 += next.value.byteLength;
78292
78591
  if (size2 > maximum)
78293
- return false;
78592
+ return;
78294
78593
  chunks.push(next.value);
78295
78594
  }
78296
78595
  const bytes = new Uint8Array(size2);
@@ -78301,11 +78600,11 @@ async function responseBodyCarriesCode(response, codes) {
78301
78600
  }
78302
78601
  const payload = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
78303
78602
  if (!payload || typeof payload !== "object" || Array.isArray(payload) || !Object.hasOwn(payload, "code"))
78304
- return false;
78603
+ return;
78305
78604
  const code = payload.code;
78306
- return typeof code === "string" && codes.includes(code);
78605
+ return typeof code === "string" && /^[A-Z][A-Z0-9_:-]{0,127}$/.test(code) ? code : undefined;
78307
78606
  } catch {
78308
- return false;
78607
+ return;
78309
78608
  } finally {
78310
78609
  clearTimeout(deadline);
78311
78610
  reader.cancel().catch(() => {});
@@ -78334,7 +78633,7 @@ async function createRemoteSkillsClient(env3 = process.env) {
78334
78633
  function createRemoteSkillsClientReadOnly(env3 = process.env) {
78335
78634
  return createRemoteSkillsClient(env3);
78336
78635
  }
78337
- var RemoteRouteUnsupportedError, RemoteRequestError, RemoteCreditCheckoutError, RemoteQuoteUnavailableError, RemoteWorkspaceMemberError, RemoteWorkspaceSelectionError, RemoteCapabilityUnavailableError, INVALID_SKILL_VERSION_RESPONSE = "Remote skill version payload did not match the expected contract.";
78636
+ var RemoteRouteUnsupportedError, RemoteRequestError, KNOWN_SKILL_LIFECYCLE_CODES, RemoteSkillLifecycleError, RemoteCreditCheckoutError, RemoteQuoteUnavailableError, RemoteWorkspaceMemberError, RemoteWorkspaceSelectionError, RemoteCapabilityUnavailableError, INVALID_SKILL_VERSION_RESPONSE = "Remote skill version payload did not match the expected contract.";
78338
78637
  var init_remote_client = __esm(() => {
78339
78638
  init_remote_recurring();
78340
78639
  init_remote_invitations();
@@ -78371,6 +78670,17 @@ var init_remote_client = __esm(() => {
78371
78670
  this.name = "RemoteRequestError";
78372
78671
  }
78373
78672
  };
78673
+ KNOWN_SKILL_LIFECYCLE_CODES = new Set(["SKILL_ARCHIVE_PROFILE_CONFLICT", "LIFECYCLE_ROLE_REQUIRED"]);
78674
+ RemoteSkillLifecycleError = class RemoteSkillLifecycleError extends RemoteRequestError {
78675
+ code;
78676
+ constructor(path, status, code) {
78677
+ super(path, status);
78678
+ this.name = "RemoteSkillLifecycleError";
78679
+ const safeCode = code !== undefined && KNOWN_SKILL_LIFECYCLE_CODES.has(code) ? code : undefined;
78680
+ this.code = safeCode;
78681
+ this.message = `Skill lifecycle update was refused (HTTP ${status}${safeCode ? `, code ${safeCode}` : ""})`;
78682
+ }
78683
+ };
78374
78684
  RemoteCreditCheckoutError = class RemoteCreditCheckoutError extends RemoteRequestError {
78375
78685
  code;
78376
78686
  requestIdempotencyKey;
@@ -78424,9 +78734,9 @@ var init_remote_client = __esm(() => {
78424
78734
  });
78425
78735
 
78426
78736
  // src/lib/revision.ts
78427
- import { createHash as createHash15 } from "crypto";
78737
+ import { createHash as createHash16 } from "crypto";
78428
78738
  function revisionIdOf(content) {
78429
- const canonical3 = JSON.stringify({
78739
+ const canonicalContent = {
78430
78740
  slug: content.slug,
78431
78741
  displayName: content.displayName,
78432
78742
  description: content.description,
@@ -78438,8 +78748,14 @@ function revisionIdOf(content) {
78438
78748
  skillMd: content.skillMd ?? null,
78439
78749
  bundleSha256: content.bundleSha256 ?? null,
78440
78750
  bundleByteSize: content.bundleByteSize ?? null
78441
- });
78442
- return createHash15("sha256").update(canonical3).digest("hex");
78751
+ };
78752
+ if (content.lifecycle === "archived" || content.archiveReason !== undefined || content.replacementSlug !== undefined) {
78753
+ canonicalContent.lifecycle = content.lifecycle ?? "active";
78754
+ canonicalContent.archiveReason = content.archiveReason ?? null;
78755
+ canonicalContent.replacementSlug = content.replacementSlug ?? null;
78756
+ }
78757
+ const canonical4 = JSON.stringify(canonicalContent);
78758
+ return createHash16("sha256").update(canonical4).digest("hex");
78443
78759
  }
78444
78760
  var REVISION_ID_PATTERN;
78445
78761
  var init_revision = __esm(() => {
@@ -78469,7 +78785,7 @@ var init_skill_bundles = __esm(() => {
78469
78785
 
78470
78786
  // src/lib/pull.ts
78471
78787
  import { existsSync as existsSync21, mkdirSync as mkdirSync12, mkdtempSync as mkdtempSync3, readFileSync as readFileSync20, renameSync as renameSync8, rmSync as rmSync6, writeFileSync as writeFileSync10 } from "fs";
78472
- import { dirname as dirname17, join as join35 } from "path";
78788
+ import { dirname as dirname18, join as join35 } from "path";
78473
78789
  async function pullSkills(options = {}) {
78474
78790
  const client2 = options.client !== undefined ? options.client : await createRemoteSkillsClient();
78475
78791
  if (!client2) {
@@ -78773,7 +79089,7 @@ function installBundleAtomically(name, entries, options = {}, marker = {}) {
78773
79089
  try {
78774
79090
  for (const entry of entries) {
78775
79091
  const destination = join35(staging, entry.path);
78776
- mkdirSync12(dirname17(destination), { recursive: true });
79092
+ mkdirSync12(dirname18(destination), { recursive: true });
78777
79093
  writeFileSync10(destination, entry.bytes, { mode: entry.mode });
78778
79094
  }
78779
79095
  writePullMarker(staging, {
@@ -78888,8 +79204,8 @@ var init_pull = __esm(() => {
78888
79204
  });
78889
79205
 
78890
79206
  // src/lib/skill-context.ts
78891
- import { createHash as createHash16 } from "crypto";
78892
- import { resolve as resolve16 } from "path";
79207
+ import { createHash as createHash17 } from "crypto";
79208
+ import { resolve as resolve17 } from "path";
78893
79209
  function words2(value) {
78894
79210
  return new Set(value.toLowerCase().match(/[a-z0-9]+/g) ?? []);
78895
79211
  }
@@ -78924,7 +79240,7 @@ async function buildSkillContext(input2, options = {}) {
78924
79240
  const promptWords = words2(prompt);
78925
79241
  const promptNames = new Set(prompt.toLowerCase().match(/[a-z0-9]+(?:-[a-z0-9]+)*/g) ?? []);
78926
79242
  const loaded = new Set(resolved.session?.loaded ?? []);
78927
- const paths = [...input2.paths ?? [], ...input2.cwd ? [input2.cwd, resolve16(input2.cwd)] : []];
79243
+ const paths = [...input2.paths ?? [], ...input2.cwd ? [input2.cwd, resolve17(input2.cwd)] : []];
78928
79244
  const candidates = profile.selections.map((selection) => {
78929
79245
  const key = selectionKey(selection);
78930
79246
  if (input2.restore && loaded.has(key))
@@ -78977,7 +79293,7 @@ ${content}`;
78977
79293
  `);
78978
79294
  const receipt = {
78979
79295
  schemaVersion: 1,
78980
- id: createHash16("sha256").update(JSON.stringify({ profile: profile.profileRevision, sessionId, selections, omitted })).digest("hex"),
79296
+ id: createHash17("sha256").update(JSON.stringify({ profile: profile.profileRevision, sessionId, selections, omitted })).digest("hex"),
78981
79297
  profileId: profile.profileId,
78982
79298
  profileRevision: profile.profileRevision,
78983
79299
  authority: profile.authority,
@@ -78999,7 +79315,7 @@ var init_skill_context = __esm(() => {
78999
79315
  });
79000
79316
 
79001
79317
  // src/lib/session-reconciliation.ts
79002
- import { createHash as createHash17 } from "crypto";
79318
+ import { createHash as createHash18 } from "crypto";
79003
79319
  function exactTimestamp(value) {
79004
79320
  const parsed = value === undefined ? Number.NaN : Date.parse(value);
79005
79321
  if (!Number.isFinite(parsed) || new Date(parsed).toISOString() !== value) {
@@ -79092,7 +79408,7 @@ async function reconcileSkillSession(input2, options = {}) {
79092
79408
  const result2 = replaceSkillSession(skillSessionSnapshotBinding(snapshot), replacement, { ...plan, planDigest }, options, () => assertPlanWindow(issuedAt, expiresAt, (options.now ?? Date.now)()));
79093
79409
  return { applied: true, plan, planDigest, ...result2 };
79094
79410
  }
79095
- var SESSION_RECONCILIATION_PLAN_TTL_MS, digest3 = (value) => createHash17("sha256").update(JSON.stringify(value)).digest("hex");
79411
+ var SESSION_RECONCILIATION_PLAN_TTL_MS, digest3 = (value) => createHash18("sha256").update(JSON.stringify(value)).digest("hex");
79096
79412
  var init_session_reconciliation = __esm(() => {
79097
79413
  init_profile_client();
79098
79414
  init_selection_cache();
@@ -79108,7 +79424,7 @@ __export(exports_context, {
79108
79424
  parseSkillContextInput: () => parseSkillContextInput,
79109
79425
  contextResolverOptions: () => contextResolverOptions
79110
79426
  });
79111
- import { readSync as readSync9 } from "fs";
79427
+ import { readSync as readSync10 } from "fs";
79112
79428
  function selectedProfileId(explicit) {
79113
79429
  return explicit ?? process.env.HASNA_SKILLS_SELECTION_PROFILE ?? readManagedSkillPolicy()?.profileId ?? "default";
79114
79430
  }
@@ -79186,7 +79502,7 @@ async function readContextStdin() {
79186
79502
  let size2 = 0;
79187
79503
  while (true) {
79188
79504
  const chunk2 = Buffer.allocUnsafe(8192);
79189
- const count = readSync9(0, chunk2, 0, chunk2.length, null);
79505
+ const count = readSync10(0, chunk2, 0, chunk2.length, null);
79190
79506
  if (count === 0)
79191
79507
  break;
79192
79508
  size2 += count;
@@ -79663,12 +79979,12 @@ function handleBrowseError(error61) {
79663
79979
  async function writeJson(value, space) {
79664
79980
  const text3 = `${JSON.stringify(value, null, space)}
79665
79981
  `;
79666
- await new Promise((resolve17, reject2) => {
79982
+ await new Promise((resolve18, reject2) => {
79667
79983
  process.stdout.write(text3, (error61) => {
79668
79984
  if (error61)
79669
79985
  reject2(error61);
79670
79986
  else
79671
- resolve17();
79987
+ resolve18();
79672
79988
  });
79673
79989
  });
79674
79990
  }
@@ -80200,7 +80516,7 @@ function handleDiff(name, options) {
80200
80516
  const sourcePath = getSkillPath(bare);
80201
80517
  const canonicalDir = join36(resolveCorpusRoot(), normalized);
80202
80518
  const canonicalSkillMd = join36(canonicalDir, "SKILL.md");
80203
- const canonical3 = {
80519
+ const canonical4 = {
80204
80520
  present: existsSync22(canonicalSkillMd),
80205
80521
  path: canonicalDir,
80206
80522
  ...existsSync22(canonicalSkillMd) ? { hash: hashSkillMarkdownFile(canonicalSkillMd) } : {},
@@ -80232,7 +80548,7 @@ function handleDiff(name, options) {
80232
80548
  stub = undefined;
80233
80549
  }
80234
80550
  }
80235
- const diverged = present && canonical3.present && managed && hash3 !== canonical3.hash;
80551
+ const diverged = present && canonical4.present && managed && hash3 !== canonical4.hash;
80236
80552
  homes.push({
80237
80553
  agent,
80238
80554
  path: dir,
@@ -80247,7 +80563,7 @@ function handleDiff(name, options) {
80247
80563
  if (options.json) {
80248
80564
  console.log(JSON.stringify({
80249
80565
  name: bare,
80250
- canonical: canonical3,
80566
+ canonical: canonical4,
80251
80567
  pinned,
80252
80568
  installedVersion,
80253
80569
  registryVersion,
@@ -80255,10 +80571,10 @@ function handleDiff(name, options) {
80255
80571
  homes
80256
80572
  }, null, 2));
80257
80573
  } else {
80258
- if (!canonical3.present) {
80574
+ if (!canonical4.present) {
80259
80575
  console.log(source_default.yellow(`${bare}: no canonical corpus entry`));
80260
80576
  } else {
80261
- console.log(source_default.dim(`${bare} canonical: ${canonical3.hash?.slice(0, 12)}\u2026`));
80577
+ console.log(source_default.dim(`${bare} canonical: ${canonical4.hash?.slice(0, 12)}\u2026`));
80262
80578
  }
80263
80579
  if (pinned) {
80264
80580
  console.log(upToDate ? source_default.green(`\u2713 pin is up to date (${installedVersion})`) : source_default.yellow(`pin metadata differs: ${installedVersion} \u2192 ${registryVersion}`));
@@ -80269,14 +80585,14 @@ function handleDiff(name, options) {
80269
80585
  } else if (!home.managed) {
80270
80586
  console.log(`${source_default.dim("\u2022")} ${home.agent}: ${source_default.yellow("unmarked (adoption candidate)")}`);
80271
80587
  } else if (home.diverged) {
80272
- const stubNote = home.stub === true ? " (home is a pointer stub; canonical holds content)" : canonical3.stub === true ? " (home holds content; canonical renders a pointer stub \u2014 sync refuses to replace it)" : "";
80273
- console.log(`${source_default.red("\u2717")} ${home.agent}: ${source_default.red("diverged")} ${source_default.dim(home.hash?.slice(0, 12))} \u2260 ${source_default.dim(canonical3.hash?.slice(0, 12))}${stubNote}`);
80588
+ const stubNote = home.stub === true ? " (home is a pointer stub; canonical holds content)" : canonical4.stub === true ? " (home holds content; canonical renders a pointer stub \u2014 sync refuses to replace it)" : "";
80589
+ console.log(`${source_default.red("\u2717")} ${home.agent}: ${source_default.red("diverged")} ${source_default.dim(home.hash?.slice(0, 12))} \u2260 ${source_default.dim(canonical4.hash?.slice(0, 12))}${stubNote}`);
80274
80590
  } else {
80275
80591
  console.log(`${source_default.green("\u2713")} ${home.agent}: ${source_default.green("matches canonical")}`);
80276
80592
  }
80277
80593
  }
80278
80594
  }
80279
- if (divergedHomes.length > 0 || homes.length > 0 && !canonical3.present)
80595
+ if (divergedHomes.length > 0 || homes.length > 0 && !canonical4.present)
80280
80596
  process.exitCode = 1;
80281
80597
  }
80282
80598
  var init_introspect = __esm(() => {
@@ -81012,7 +81328,7 @@ var init_init = __esm(() => {
81012
81328
  });
81013
81329
 
81014
81330
  // src/lib/home-adoption.ts
81015
- import { constants as constants11, closeSync as closeSync11, fstatSync as fstatSync11, lstatSync as lstatSync19, openSync as openSync11, readSync as readSync10, existsSync as existsSync24, mkdirSync as mkdirSync13, readdirSync as readdirSync13, readFileSync as readFileSync25, rmSync as rmSync7, statSync as statSync12, writeFileSync as writeFileSync12 } from "fs";
81331
+ import { constants as constants12, closeSync as closeSync12, fstatSync as fstatSync12, lstatSync as lstatSync20, openSync as openSync12, readSync as readSync11, existsSync as existsSync24, mkdirSync as mkdirSync13, readdirSync as readdirSync13, readFileSync as readFileSync25, rmSync as rmSync7, statSync as statSync12, writeFileSync as writeFileSync12 } from "fs";
81016
81332
  import { homedir as homedir7 } from "os";
81017
81333
  import { join as join38 } from "path";
81018
81334
  function indexCanonicalCorpus(corpusRoot) {
@@ -81167,25 +81483,25 @@ function adoptUnmarkedHomes(options = {}) {
81167
81483
  function pruneOwnership(dir) {
81168
81484
  let descriptor;
81169
81485
  try {
81170
- const directory = lstatSync19(dir);
81486
+ const directory = lstatSync20(dir);
81171
81487
  if (!directory.isDirectory())
81172
81488
  return;
81173
- const markerPath = join38(dir, SYNC_MARKER_FILE), markerPathBefore = lstatSync19(markerPath);
81489
+ const markerPath = join38(dir, SYNC_MARKER_FILE), markerPathBefore = lstatSync20(markerPath);
81174
81490
  if (!markerPathBefore.isFile())
81175
81491
  return;
81176
- descriptor = openSync11(markerPath, constants11.O_RDONLY | constants11.O_NOFOLLOW | constants11.O_NONBLOCK);
81177
- const before2 = fstatSync11(descriptor);
81492
+ descriptor = openSync12(markerPath, constants12.O_RDONLY | constants12.O_NOFOLLOW | constants12.O_NONBLOCK);
81493
+ const before2 = fstatSync12(descriptor);
81178
81494
  if (!before2.isFile() || before2.dev !== markerPathBefore.dev || before2.ino !== markerPathBefore.ino || before2.size !== markerPathBefore.size || before2.mtimeMs !== markerPathBefore.mtimeMs || before2.ctimeMs !== markerPathBefore.ctimeMs || before2.size < 1 || before2.size > 65536)
81179
81495
  return;
81180
81496
  const bytes = Buffer.alloc(before2.size + 1);
81181
81497
  let length = 0;
81182
81498
  while (length < bytes.length) {
81183
- const count = readSync10(descriptor, bytes, length, bytes.length - length, length);
81499
+ const count = readSync11(descriptor, bytes, length, bytes.length - length, length);
81184
81500
  if (!count)
81185
81501
  break;
81186
81502
  length += count;
81187
81503
  }
81188
- const after2 = fstatSync11(descriptor), current = lstatSync19(dir), markerPathAfter = lstatSync19(markerPath);
81504
+ const after2 = fstatSync12(descriptor), current = lstatSync20(dir), markerPathAfter = lstatSync20(markerPath);
81189
81505
  if (!markerPathAfter.isFile() || markerPathAfter.dev !== before2.dev || markerPathAfter.ino !== before2.ino || markerPathAfter.size !== before2.size || markerPathAfter.mtimeMs !== before2.mtimeMs || markerPathAfter.ctimeMs !== before2.ctimeMs || length !== before2.size || after2.size !== before2.size || after2.mtimeMs !== before2.mtimeMs || after2.ctimeMs !== before2.ctimeMs || !current.isDirectory() || current.dev !== directory.dev || current.ino !== directory.ino)
81190
81506
  return;
81191
81507
  const text3 = bytes.subarray(0, length).toString("utf8"), marker = JSON.parse(text3);
@@ -81196,7 +81512,7 @@ function pruneOwnership(dir) {
81196
81512
  return;
81197
81513
  } finally {
81198
81514
  if (descriptor !== undefined)
81199
- closeSync11(descriptor);
81515
+ closeSync12(descriptor);
81200
81516
  }
81201
81517
  }
81202
81518
  function pruneStrayHomes(options = {}) {
@@ -81381,7 +81697,7 @@ var init_home_census = __esm(() => {
81381
81697
  });
81382
81698
 
81383
81699
  // src/cli/env-assignment.ts
81384
- import { closeSync as closeSync12, constants as constants12, fstatSync as fstatSync12, ftruncateSync as ftruncateSync2, lstatSync as lstatSync20, openSync as openSync12, readFileSync as readFileSync27, writeSync as writeSync3 } from "fs";
81700
+ import { closeSync as closeSync13, constants as constants13, fstatSync as fstatSync13, ftruncateSync as ftruncateSync2, lstatSync as lstatSync21, openSync as openSync13, readFileSync as readFileSync27, writeSync as writeSync3 } from "fs";
81385
81701
  function serializeValue(value) {
81386
81702
  if (controls.test(value))
81387
81703
  throw new EnvAssignmentError("Environment values cannot contain control characters or newlines.");
@@ -81460,7 +81776,7 @@ function setEnvAssignment(path, assignment) {
81460
81776
  try {
81461
81777
  const previous = (() => {
81462
81778
  try {
81463
- return lstatSync20(path);
81779
+ return lstatSync21(path);
81464
81780
  } catch (error61) {
81465
81781
  if (error61.code === "ENOENT")
81466
81782
  return;
@@ -81469,8 +81785,8 @@ function setEnvAssignment(path, assignment) {
81469
81785
  })();
81470
81786
  if (previous && !previous.isFile())
81471
81787
  throw new EnvAssignmentError("The project .env must be a regular file, not a symlink or special file.");
81472
- descriptor = openSync12(path, previous ? constants12.O_RDWR | constants12.O_NOFOLLOW | constants12.O_NONBLOCK : constants12.O_WRONLY | constants12.O_CREAT | constants12.O_EXCL | constants12.O_NOFOLLOW, 384);
81473
- const opened = fstatSync12(descriptor);
81788
+ descriptor = openSync13(path, previous ? constants13.O_RDWR | constants13.O_NOFOLLOW | constants13.O_NONBLOCK : constants13.O_WRONLY | constants13.O_CREAT | constants13.O_EXCL | constants13.O_NOFOLLOW, 384);
81789
+ const opened = fstatSync13(descriptor);
81474
81790
  if (!opened.isFile() || previous && (opened.ino !== previous.ino || opened.dev !== previous.dev)) {
81475
81791
  throw new EnvAssignmentError("The project .env changed while opening it; retry with a regular file.");
81476
81792
  }
@@ -81497,7 +81813,7 @@ function setEnvAssignment(path, assignment) {
81497
81813
  throw new EnvAssignmentError("Cannot safely read or write the project .env file.");
81498
81814
  } finally {
81499
81815
  if (descriptor !== undefined)
81500
- closeSync12(descriptor);
81816
+ closeSync13(descriptor);
81501
81817
  }
81502
81818
  }
81503
81819
  var INVALID_LAYOUT = "Cannot safely update .env with multiline or unsupported assignments. Use single-line KEY=VALUE entries or edit the file manually.", controls, EnvAssignmentError;
@@ -81894,6 +82210,15 @@ class CloudExecutionClient {
81894
82210
  }
81895
82211
  return response;
81896
82212
  }
82213
+ async eligibility(slug2, version2, bundleDigest) {
82214
+ if (!/^[a-z0-9-]+$/.test(slug2) || !/^\d+\.\d+\.\d+$/.test(version2) || bundleDigest !== undefined && !/^(sha256:)?[a-f0-9]{64}$/.test(bundleDigest))
82215
+ throw Error("Cloud eligibility requires an exact skill version and valid digest");
82216
+ const query = new URLSearchParams({ version: version2, ...bundleDigest ? { bundleDigest } : {} });
82217
+ const v = await jsonBody(await this.request(`${slug2}/eligibility?${query}`));
82218
+ if (!v || v.contractVersion !== 1 || typeof v.eligible !== "boolean" || v.skill !== slug2 || v.version !== version2 || !/^[a-f0-9]{64}$/.test(v.bundleDigest) || bundleDigest && bundleDigest.replace(/^sha256:/, "") !== v.bundleDigest || v.eligible && (!v.executionContract || !["pdf.v1", "regex-test.v1"].includes(v.executionContract.id)))
82219
+ throw Error("Invalid cloud eligibility receipt");
82220
+ return v;
82221
+ }
81897
82222
  async submit(slug2, version2, input2, key, selection) {
81898
82223
  if (!/^[a-z0-9-]+$/.test(slug2) || !/^\d+\.\d+\.\d+$/.test(version2))
81899
82224
  throw Error("Cloud execution requires skill@exact-version");
@@ -82006,11 +82331,11 @@ var init_cloud_executions = __esm(() => {
82006
82331
  // node_modules/@hasna/secrets/dist/sdk.js
82007
82332
  import { isIP as isIP3 } from "net";
82008
82333
  import { spawnSync as spawnSync2 } from "child_process";
82009
- import { closeSync as closeSync13, fstatSync as fstatSync13, openSync as openSync13, readFileSync as readFileSync29 } from "fs";
82334
+ import { closeSync as closeSync14, fstatSync as fstatSync14, openSync as openSync14, readFileSync as readFileSync29 } from "fs";
82010
82335
  import { O_NOFOLLOW as O_NOFOLLOW3, O_NONBLOCK as O_NONBLOCK3, O_RDONLY as O_RDONLY3 } from "constants";
82011
82336
  import { createRequire as createRequire2 } from "module";
82012
82337
  import { hostname as osHostname2 } from "os";
82013
- import { isAbsolute as isAbsolute15, join as join41 } from "path";
82338
+ import { isAbsolute as isAbsolute16, join as join41 } from "path";
82014
82339
  import { createRequire as createRequire22 } from "module";
82015
82340
  function envToken2(name) {
82016
82341
  return name.toUpperCase().replace(/-/g, "_");
@@ -82034,7 +82359,7 @@ function homeDir2(env3) {
82034
82359
  }
82035
82360
  function absoluteOverride2(env3, key) {
82036
82361
  const value = env3[key]?.trim();
82037
- return value && isAbsolute15(value) ? value : null;
82362
+ return value && isAbsolute16(value) ? value : null;
82038
82363
  }
82039
82364
  function hasnaHomeDir2(env3) {
82040
82365
  const override = absoluteOverride2(env3, HASNA_HOME_ENV_KEY2);
@@ -82111,7 +82436,7 @@ function readAppConfigFile2(path) {
82111
82436
  };
82112
82437
  let fd = -1;
82113
82438
  try {
82114
- fd = openSync13(path, O_RDONLY3 | O_NOFOLLOW3 | O_NONBLOCK3);
82439
+ fd = openSync14(path, O_RDONLY3 | O_NOFOLLOW3 | O_NONBLOCK3);
82115
82440
  } catch (error61) {
82116
82441
  const code = error61.code;
82117
82442
  if (code === "ENOENT" || code === "ENOTDIR")
@@ -82121,7 +82446,7 @@ function readAppConfigFile2(path) {
82121
82446
  unsafe(`the path could not be opened (${code ?? "unknown error"})`);
82122
82447
  }
82123
82448
  try {
82124
- const before2 = fstatSync13(fd);
82449
+ const before2 = fstatSync14(fd);
82125
82450
  if (!before2.isFile())
82126
82451
  unsafe("the path is not a regular file");
82127
82452
  if (!configFileModeAllowed2(before2.mode)) {
@@ -82133,14 +82458,14 @@ function readAppConfigFile2(path) {
82133
82458
  if (before2.size > MAX_CREDENTIAL_FILE_BYTES2)
82134
82459
  unsafe("the file exceeds the size limit");
82135
82460
  const bytes = readFileSync29(fd);
82136
- const after2 = fstatSync13(fd);
82461
+ const after2 = fstatSync14(fd);
82137
82462
  if (!configFileReadsCoherent2(before2, after2)) {
82138
82463
  unsafe("the file changed while being read");
82139
82464
  }
82140
82465
  return parseEnvFile2(bytes.toString("utf8"));
82141
82466
  } finally {
82142
82467
  if (fd !== -1)
82143
- closeSync13(fd);
82468
+ closeSync14(fd);
82144
82469
  }
82145
82470
  }
82146
82471
  function readCredentialFile2(path, apiKeyKeys) {
@@ -83171,7 +83496,7 @@ function createSecretsClientFromEnv(env3 = process.env, overrides = {}) {
83171
83496
  });
83172
83497
  return new SecretsClient({ ...clientOverrides, baseUrl, apiKey });
83173
83498
  }
83174
- 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_RE3, SQLITE_SIDECAR_FILES, LEGACY_SERVICE_FILES, init_data_dir, SecretsTestIsolationError, TEST_ENTRYPOINT_RE, init_test_isolation, init_client, ApiError;
83499
+ 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_RE3, SQLITE_SIDECAR_FILES, LEGACY_SERVICE_FILES, init_data_dir, SecretsTestIsolationError, TEST_ENTRYPOINT_RE, init_test_isolation, init_client, ApiError;
83175
83500
  var init_sdk = __esm(() => {
83176
83501
  init_transport2 = __esm2(() => {
83177
83502
  CredentialResolutionError2 = class CredentialResolutionError3 extends Error {
@@ -83306,7 +83631,7 @@ var init_sdk = __esm(() => {
83306
83631
  });
83307
83632
 
83308
83633
  // src/lib/execution-secrets.ts
83309
- import { constants as constants13, closeSync as closeSync14, fstatSync as fstatSync14, openSync as openSync14, readSync as readSync11, realpathSync as realpathSync6 } from "fs";
83634
+ import { constants as constants14, closeSync as closeSync15, fstatSync as fstatSync15, openSync as openSync15, readSync as readSync12, realpathSync as realpathSync6 } from "fs";
83310
83635
  import { hostname as stationHostname } from "os";
83311
83636
  function selectedSecretBindingsTemplate(scope, names, createClient2 = createSecretsClientFromEnv) {
83312
83637
  let secretsAuthority;
@@ -83350,13 +83675,13 @@ function declaredSecretNames(value) {
83350
83675
  function readSelectedSecretBindings(path) {
83351
83676
  let fd;
83352
83677
  try {
83353
- fd = openSync14(path, constants13.O_RDONLY | constants13.O_NOFOLLOW | constants13.O_NONBLOCK);
83354
- const stat2 = fstatSync14(fd);
83678
+ fd = openSync15(path, constants14.O_RDONLY | constants14.O_NOFOLLOW | constants14.O_NONBLOCK);
83679
+ const stat2 = fstatSync15(fd);
83355
83680
  if (!stat2.isFile() || stat2.size > 65536)
83356
83681
  throw new Error;
83357
83682
  const bytes = Buffer.alloc(65537);
83358
83683
  let size2 = 0, count;
83359
- while ((count = readSync11(fd, bytes, size2, bytes.length - size2, null)) > 0) {
83684
+ while ((count = readSync12(fd, bytes, size2, bytes.length - size2, null)) > 0) {
83360
83685
  size2 += count;
83361
83686
  if (size2 > 65536)
83362
83687
  throw new Error;
@@ -83366,7 +83691,7 @@ function readSelectedSecretBindings(path) {
83366
83691
  return refuse("INVALID_SECRET_BINDINGS", "Secret bindings must be a regular JSON file of at most 64 KiB, containing reference names only.");
83367
83692
  } finally {
83368
83693
  if (fd !== undefined)
83369
- closeSync14(fd);
83694
+ closeSync15(fd);
83370
83695
  }
83371
83696
  }
83372
83697
  function validateSelectedSecretBindings(value, scope, names) {
@@ -83655,10 +83980,10 @@ __export(exports_selected_run, {
83655
83980
  prepareSelectedSecretBindings: () => prepareSelectedSecretBindings,
83656
83981
  executeSelectedLocal: () => executeSelectedLocal
83657
83982
  });
83658
- import { createHash as createHash18 } from "crypto";
83983
+ import { createHash as createHash19 } from "crypto";
83659
83984
  import { spawn as spawn2 } from "child_process";
83660
83985
  import { mkdirSync as mkdirSync14, mkdtempSync as mkdtempSync4, writeFileSync as writeFileSync13, realpathSync as realpathSync7 } from "fs";
83661
- import { dirname as dirname18, join as join42, resolve as resolve17 } from "path";
83986
+ import { dirname as dirname19, join as join42, resolve as resolve18 } from "path";
83662
83987
  import { tmpdir, hostname as stationHostname2 } from "os";
83663
83988
  async function resolveSelectedRun(spec, profileId, options = {}) {
83664
83989
  const context = await resolveSelectionContext(profileId, options);
@@ -83747,11 +84072,11 @@ async function executeSelectedLocal(selected, options = {}) {
83747
84072
  throw new SkillSelectionError("INVALID_BUNDLE_PATH", "The execution bundle path exceeds its limit.");
83748
84073
  });
83749
84074
  const destination = join42(runDirectory, entry.path);
83750
- mkdirSync14(dirname18(destination), { recursive: true, mode: 448 });
84075
+ mkdirSync14(dirname19(destination), { recursive: true, mode: 448 });
83751
84076
  writeFileSync13(destination, entry.bytes, { flag: "wx", mode: entry.mode & 511 });
83752
84077
  }
83753
84078
  env3.SKILLS_INPUT_JSON = input2;
83754
- env3.SKILLS_WORKSPACE_DIR = resolve17(options.cwd ?? process.cwd());
84079
+ env3.SKILLS_WORKSPACE_DIR = resolve18(options.cwd ?? process.cwd());
83755
84080
  env3.SKILLS_RUN_DIR = runDirectory;
83756
84081
  if (runtime.version) {
83757
84082
  const version2 = await subprocess([executable, ...runtimeName === "bun" ? ["--no-env-file"] : [], "--version"], runDirectory, env3, "", Math.min(timeoutMs, 5000));
@@ -83781,7 +84106,7 @@ async function executeSelectedLocal(selected, options = {}) {
83781
84106
  selection: selection2,
83782
84107
  target: "local",
83783
84108
  runtime: runtimeName,
83784
- inputDigest: `sha256:${createHash18("sha256").update(input2).digest("hex")}`,
84109
+ inputDigest: `sha256:${createHash19("sha256").update(input2).digest("hex")}`,
83785
84110
  runDirectory,
83786
84111
  ...executionGrant ? { executionGrant } : {},
83787
84112
  ...bindings ? { secretBinding: { schema: bindings.schema, selection: bindings.selection, consumer: bindings.consumer, secretsAuthority: bindings.secretsAuthority, bindings: bindings.bindings } } : {},
@@ -87998,7 +88323,7 @@ var init_runs = __esm(() => {
87998
88323
  });
87999
88324
 
88000
88325
  // src/lib/run-state.ts
88001
- import { createHash as createHash19, randomBytes } from "crypto";
88326
+ import { createHash as createHash20, randomBytes } from "crypto";
88002
88327
  import { existsSync as existsSync27, mkdirSync as mkdirSync15, readFileSync as readFileSync30, readdirSync as readdirSync16, statSync as statSync15, writeFileSync as writeFileSync14 } from "fs";
88003
88328
  import { extname, join as join43, relative as relative6 } from "path";
88004
88329
  function createSkillRun(params, targetDir = process.cwd()) {
@@ -88135,7 +88460,7 @@ function collectRunArtifacts(context) {
88135
88460
  artifacts.push({
88136
88461
  path: toProjectRelative(context.targetDir, path),
88137
88462
  mime: mimeForPath(path),
88138
- sha256: createHash19("sha256").update(bytes).digest("hex"),
88463
+ sha256: createHash20("sha256").update(bytes).digest("hex"),
88139
88464
  sizeBytes: stat2.size
88140
88465
  });
88141
88466
  }
@@ -89138,12 +89463,12 @@ class StdioServerTransport {
89138
89463
  this.onclose?.();
89139
89464
  }
89140
89465
  send(message) {
89141
- return new Promise((resolve18) => {
89466
+ return new Promise((resolve19) => {
89142
89467
  const json2 = serializeMessage(message);
89143
89468
  if (this._stdout.write(json2)) {
89144
- resolve18();
89469
+ resolve19();
89145
89470
  } else {
89146
- this._stdout.once("drain", resolve18);
89471
+ this._stdout.once("drain", resolve19);
89147
89472
  }
89148
89473
  });
89149
89474
  }
@@ -89185,7 +89510,7 @@ var init_schemas3 = __esm(() => {
89185
89510
  own(this, "with", value);
89186
89511
  },
89187
89512
  parse(data, params) {
89188
- return parse6(this, data, params, { callee: this.parse });
89513
+ return parse7(this, data, params, { callee: this.parse });
89189
89514
  },
89190
89515
  parseAsync(data, params) {
89191
89516
  return parseAsync(this, data, params, { callee: this.parseAsync });
@@ -91329,7 +91654,7 @@ class Protocol {
91329
91654
  return;
91330
91655
  }
91331
91656
  const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1000;
91332
- await new Promise((resolve18) => setTimeout(resolve18, pollInterval));
91657
+ await new Promise((resolve19) => setTimeout(resolve19, pollInterval));
91333
91658
  options?.signal?.throwIfAborted();
91334
91659
  }
91335
91660
  } catch (error61) {
@@ -91341,7 +91666,7 @@ class Protocol {
91341
91666
  }
91342
91667
  request(request2, resultSchema, options) {
91343
91668
  const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
91344
- return new Promise((resolve18, reject2) => {
91669
+ return new Promise((resolve19, reject2) => {
91345
91670
  const earlyReject = (error61) => {
91346
91671
  reject2(error61);
91347
91672
  };
@@ -91419,7 +91744,7 @@ class Protocol {
91419
91744
  if (!parseResult.success) {
91420
91745
  reject2(parseResult.error);
91421
91746
  } else {
91422
- resolve18(parseResult.data);
91747
+ resolve19(parseResult.data);
91423
91748
  }
91424
91749
  } catch (error61) {
91425
91750
  reject2(error61);
@@ -91610,12 +91935,12 @@ class Protocol {
91610
91935
  interval = task.pollInterval;
91611
91936
  }
91612
91937
  } catch {}
91613
- return new Promise((resolve18, reject2) => {
91938
+ return new Promise((resolve19, reject2) => {
91614
91939
  if (signal.aborted) {
91615
91940
  reject2(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
91616
91941
  return;
91617
91942
  }
91618
- const timeoutId = setTimeout(resolve18, interval);
91943
+ const timeoutId = setTimeout(resolve19, interval);
91619
91944
  signal.addEventListener("abort", () => {
91620
91945
  clearTimeout(timeoutId);
91621
91946
  reject2(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
@@ -92092,11 +92417,11 @@ var require_codegen = __commonJS((exports) => {
92092
92417
  const rhs = this.rhs === undefined ? "" : ` = ${this.rhs}`;
92093
92418
  return `${varKind} ${this.name}${rhs};` + _n;
92094
92419
  }
92095
- optimizeNames(names, constants14) {
92420
+ optimizeNames(names, constants15) {
92096
92421
  if (!names[this.name.str])
92097
92422
  return;
92098
92423
  if (this.rhs)
92099
- this.rhs = optimizeExpr(this.rhs, names, constants14);
92424
+ this.rhs = optimizeExpr(this.rhs, names, constants15);
92100
92425
  return this;
92101
92426
  }
92102
92427
  get names() {
@@ -92114,10 +92439,10 @@ var require_codegen = __commonJS((exports) => {
92114
92439
  render({ _n }) {
92115
92440
  return `${this.lhs} = ${this.rhs};` + _n;
92116
92441
  }
92117
- optimizeNames(names, constants14) {
92442
+ optimizeNames(names, constants15) {
92118
92443
  if (this.lhs instanceof code_1.Name && !names[this.lhs.str] && !this.sideEffects)
92119
92444
  return;
92120
- this.rhs = optimizeExpr(this.rhs, names, constants14);
92445
+ this.rhs = optimizeExpr(this.rhs, names, constants15);
92121
92446
  return this;
92122
92447
  }
92123
92448
  get names() {
@@ -92183,8 +92508,8 @@ var require_codegen = __commonJS((exports) => {
92183
92508
  optimizeNodes() {
92184
92509
  return `${this.code}` ? this : undefined;
92185
92510
  }
92186
- optimizeNames(names, constants14) {
92187
- this.code = optimizeExpr(this.code, names, constants14);
92511
+ optimizeNames(names, constants15) {
92512
+ this.code = optimizeExpr(this.code, names, constants15);
92188
92513
  return this;
92189
92514
  }
92190
92515
  get names() {
@@ -92214,12 +92539,12 @@ var require_codegen = __commonJS((exports) => {
92214
92539
  }
92215
92540
  return nodes.length > 0 ? this : undefined;
92216
92541
  }
92217
- optimizeNames(names, constants14) {
92542
+ optimizeNames(names, constants15) {
92218
92543
  const { nodes } = this;
92219
92544
  let i = nodes.length;
92220
92545
  while (i--) {
92221
92546
  const n2 = nodes[i];
92222
- if (n2.optimizeNames(names, constants14))
92547
+ if (n2.optimizeNames(names, constants15))
92223
92548
  continue;
92224
92549
  subtractNames(names, n2.names);
92225
92550
  nodes.splice(i, 1);
@@ -92276,12 +92601,12 @@ var require_codegen = __commonJS((exports) => {
92276
92601
  return;
92277
92602
  return this;
92278
92603
  }
92279
- optimizeNames(names, constants14) {
92604
+ optimizeNames(names, constants15) {
92280
92605
  var _a3;
92281
- this.else = (_a3 = this.else) === null || _a3 === undefined ? undefined : _a3.optimizeNames(names, constants14);
92282
- if (!(super.optimizeNames(names, constants14) || this.else))
92606
+ this.else = (_a3 = this.else) === null || _a3 === undefined ? undefined : _a3.optimizeNames(names, constants15);
92607
+ if (!(super.optimizeNames(names, constants15) || this.else))
92283
92608
  return;
92284
- this.condition = optimizeExpr(this.condition, names, constants14);
92609
+ this.condition = optimizeExpr(this.condition, names, constants15);
92285
92610
  return this;
92286
92611
  }
92287
92612
  get names() {
@@ -92306,10 +92631,10 @@ var require_codegen = __commonJS((exports) => {
92306
92631
  render(opts) {
92307
92632
  return `for(${this.iteration})` + super.render(opts);
92308
92633
  }
92309
- optimizeNames(names, constants14) {
92310
- if (!super.optimizeNames(names, constants14))
92634
+ optimizeNames(names, constants15) {
92635
+ if (!super.optimizeNames(names, constants15))
92311
92636
  return;
92312
- this.iteration = optimizeExpr(this.iteration, names, constants14);
92637
+ this.iteration = optimizeExpr(this.iteration, names, constants15);
92313
92638
  return this;
92314
92639
  }
92315
92640
  get names() {
@@ -92347,10 +92672,10 @@ var require_codegen = __commonJS((exports) => {
92347
92672
  render(opts) {
92348
92673
  return `for(${this.varKind} ${this.name} ${this.loop} ${this.iterable})` + super.render(opts);
92349
92674
  }
92350
- optimizeNames(names, constants14) {
92351
- if (!super.optimizeNames(names, constants14))
92675
+ optimizeNames(names, constants15) {
92676
+ if (!super.optimizeNames(names, constants15))
92352
92677
  return;
92353
- this.iterable = optimizeExpr(this.iterable, names, constants14);
92678
+ this.iterable = optimizeExpr(this.iterable, names, constants15);
92354
92679
  return this;
92355
92680
  }
92356
92681
  get names() {
@@ -92395,11 +92720,11 @@ var require_codegen = __commonJS((exports) => {
92395
92720
  (_b = this.finally) === null || _b === undefined || _b.optimizeNodes();
92396
92721
  return this;
92397
92722
  }
92398
- optimizeNames(names, constants14) {
92723
+ optimizeNames(names, constants15) {
92399
92724
  var _a3, _b;
92400
- super.optimizeNames(names, constants14);
92401
- (_a3 = this.catch) === null || _a3 === undefined || _a3.optimizeNames(names, constants14);
92402
- (_b = this.finally) === null || _b === undefined || _b.optimizeNames(names, constants14);
92725
+ super.optimizeNames(names, constants15);
92726
+ (_a3 = this.catch) === null || _a3 === undefined || _a3.optimizeNames(names, constants15);
92727
+ (_b = this.finally) === null || _b === undefined || _b.optimizeNames(names, constants15);
92403
92728
  return this;
92404
92729
  }
92405
92730
  get names() {
@@ -92673,7 +92998,7 @@ var require_codegen = __commonJS((exports) => {
92673
92998
  function addExprNames(names, from) {
92674
92999
  return from instanceof code_1._CodeOrName ? addNames(names, from.names) : names;
92675
93000
  }
92676
- function optimizeExpr(expr, names, constants14) {
93001
+ function optimizeExpr(expr, names, constants15) {
92677
93002
  if (expr instanceof code_1.Name)
92678
93003
  return replaceName(expr);
92679
93004
  if (!canOptimize(expr))
@@ -92688,14 +93013,14 @@ var require_codegen = __commonJS((exports) => {
92688
93013
  return items;
92689
93014
  }, []));
92690
93015
  function replaceName(n2) {
92691
- const c = constants14[n2.str];
93016
+ const c = constants15[n2.str];
92692
93017
  if (c === undefined || names[n2.str] !== 1)
92693
93018
  return n2;
92694
93019
  delete names[n2.str];
92695
93020
  return c;
92696
93021
  }
92697
93022
  function canOptimize(e2) {
92698
- return e2 instanceof code_1._Code && e2._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 && constants14[c.str] !== undefined);
93023
+ return e2 instanceof code_1._Code && e2._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 && constants15[c.str] !== undefined);
92699
93024
  }
92700
93025
  }
92701
93026
  function subtractNames(names, from) {
@@ -94600,7 +94925,7 @@ var require_compile = __commonJS((exports) => {
94600
94925
  const schOrFunc = root2.refs[ref];
94601
94926
  if (schOrFunc)
94602
94927
  return schOrFunc;
94603
- let _sch = resolve18.call(this, root2, ref);
94928
+ let _sch = resolve19.call(this, root2, ref);
94604
94929
  if (_sch === undefined) {
94605
94930
  const schema = (_a3 = root2.localRefs) === null || _a3 === undefined ? undefined : _a3[ref];
94606
94931
  const { schemaId } = this.opts;
@@ -94627,7 +94952,7 @@ var require_compile = __commonJS((exports) => {
94627
94952
  function sameSchemaEnv(s1, s2) {
94628
94953
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
94629
94954
  }
94630
- function resolve18(root2, ref) {
94955
+ function resolve19(root2, ref) {
94631
94956
  let sch;
94632
94957
  while (typeof (sch = this.refs[ref]) == "string")
94633
94958
  ref = sch;
@@ -95425,11 +95750,11 @@ var require_fast_uri = __commonJS((exports, module) => {
95425
95750
  if (typeof uri === "string") {
95426
95751
  uri = normalizeString(uri, options);
95427
95752
  } else if (typeof uri === "object") {
95428
- uri = parse11(serialize(uri, options), options);
95753
+ uri = parse12(serialize(uri, options), options);
95429
95754
  }
95430
95755
  return uri;
95431
95756
  }
95432
- function resolve18(baseURI, relativeURI, options) {
95757
+ function resolve19(baseURI, relativeURI, options) {
95433
95758
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
95434
95759
  const {
95435
95760
  parsed: baseParsed,
@@ -95465,8 +95790,8 @@ var require_fast_uri = __commonJS((exports, module) => {
95465
95790
  function resolveComponent(base2, relative7, options, skipNormalization) {
95466
95791
  const target = {};
95467
95792
  if (!skipNormalization) {
95468
- base2 = parse11(serialize(base2, options), options);
95469
- relative7 = parse11(serialize(relative7, options), options);
95793
+ base2 = parse12(serialize(base2, options), options);
95794
+ relative7 = parse12(serialize(relative7, options), options);
95470
95795
  }
95471
95796
  options = options || {};
95472
95797
  if (!options.tolerant && relative7.scheme) {
@@ -95766,7 +96091,7 @@ var require_fast_uri = __commonJS((exports, module) => {
95766
96091
  }
95767
96092
  return { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme };
95768
96093
  }
95769
- function parse11(uri, opts) {
96094
+ function parse12(uri, opts) {
95770
96095
  return parseWithStatus(uri, opts).parsed;
95771
96096
  }
95772
96097
  function normalizeString(uri, opts) {
@@ -95799,11 +96124,11 @@ var require_fast_uri = __commonJS((exports, module) => {
95799
96124
  var fastUri = {
95800
96125
  SCHEMES,
95801
96126
  normalize: normalize3,
95802
- resolve: resolve18,
96127
+ resolve: resolve19,
95803
96128
  resolveComponent,
95804
96129
  equal,
95805
96130
  serialize,
95806
- parse: parse11
96131
+ parse: parse12
95807
96132
  };
95808
96133
  module.exports = fastUri;
95809
96134
  module.exports.default = fastUri;
@@ -99585,7 +99910,7 @@ class McpServer {
99585
99910
  let task = createTaskResult.task;
99586
99911
  const pollInterval = task.pollInterval ?? 5000;
99587
99912
  while (task.status !== "completed" && task.status !== "failed" && task.status !== "cancelled") {
99588
- await new Promise((resolve18) => setTimeout(resolve18, pollInterval));
99913
+ await new Promise((resolve19) => setTimeout(resolve19, pollInterval));
99589
99914
  const updatedTask = await extra.taskStore.getTask(taskId);
99590
99915
  if (!updatedTask) {
99591
99916
  throw new McpError(ErrorCode.InternalError, `Task ${taskId} not found during polling`);
@@ -100272,7 +100597,7 @@ var init_remote_invitation_recovery = __esm(() => {
100272
100597
  });
100273
100598
 
100274
100599
  // src/lib/remote-private-publications.ts
100275
- import { createHash as createHash20 } from "crypto";
100600
+ import { createHash as createHash21 } from "crypto";
100276
100601
  function checkedPublicationDeclaration(value) {
100277
100602
  if (!exact(value, ["idempotencyKey", "version", "expectedCurrentVersionId", "manifestText", "archiveSha256", "archiveByteSize"]) || !publicationUuid(value.idempotencyKey) || !(value.expectedCurrentVersionId === null || publicationUuid(value.expectedCurrentVersionId)) || typeof value.version !== "string" || !value.version || value.version.length > 128 || /[\p{Cc}\p{Cs}]/u.test(value.version) || typeof value.manifestText !== "string" || Buffer.byteLength(value.manifestText) > 16384 || !hash3(value.archiveSha256) || !Number.isSafeInteger(value.archiveByteSize) || Number(value.archiveByteSize) < 1 || Number(value.archiveByteSize) > PRIVATE_PUBLICATION_MAX_BYTES)
100278
100603
  return bad();
@@ -100517,12 +100842,12 @@ class RemotePrivatePublicationsClient {
100517
100842
  previous = view;
100518
100843
  if (!["queued", "verifying"].includes(view.state) || Date.now() >= until)
100519
100844
  return view;
100520
- await new Promise((resolve18) => {
100845
+ await new Promise((resolve19) => {
100521
100846
  const timer = setTimeout(done, Math.min(1000, until - Date.now()));
100522
100847
  function done() {
100523
100848
  clearTimeout(timer);
100524
100849
  options.signal?.removeEventListener("abort", done);
100525
- resolve18();
100850
+ resolve19();
100526
100851
  }
100527
100852
  options.signal?.addEventListener("abort", done, { once: true });
100528
100853
  });
@@ -100533,7 +100858,7 @@ var PRIVATE_PUBLICATION_MAX_BYTES, failures2, PrivatePublicationError, bad = ()
100533
100858
  throw new PrivatePublicationError("INVALID_PUBLICATION_INPUT", "Invalid publication input or recovery data.");
100534
100859
  }, invalid5 = () => {
100535
100860
  throw new PrivatePublicationError("INVALID_PUBLICATION_RESPONSE", "The server returned an invalid publication result.");
100536
- }, publicationUuid = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), hash3 = (v) => typeof v === "string" && /^[a-f0-9]{64}$/.test(v), record10 = (v) => !!v && typeof v === "object" && !Array.isArray(v), exact = (v, keys3) => record10(v) && Object.keys(v).sort().join(",") === keys3.sort().join(","), date6 = (v) => typeof v === "string" && /^\d{4}-\d\d-\d\dT[0-9:.]+(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(v) && Number.isFinite(Date.parse(v)), publicationSha256 = (bytes) => createHash20("sha256").update(bytes).digest("hex");
100861
+ }, publicationUuid = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), hash3 = (v) => typeof v === "string" && /^[a-f0-9]{64}$/.test(v), record10 = (v) => !!v && typeof v === "object" && !Array.isArray(v), exact = (v, keys3) => record10(v) && Object.keys(v).sort().join(",") === keys3.sort().join(","), date6 = (v) => typeof v === "string" && /^\d{4}-\d\d-\d\dT[0-9:.]+(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(v) && Number.isFinite(Date.parse(v)), publicationSha256 = (bytes) => createHash21("sha256").update(bytes).digest("hex");
100537
100862
  var init_remote_private_publications = __esm(() => {
100538
100863
  init_fleet_credentials();
100539
100864
  init_remote_workspace_selection();
@@ -100810,11 +101135,11 @@ var init_remote_auth = __esm(() => {
100810
101135
  });
100811
101136
 
100812
101137
  // src/lib/workspace-profile.ts
100813
- import { constants as constants14, closeSync as closeSync15, fstatSync as fstatSync15, lstatSync as lstatSync21, mkdirSync as mkdirSync16, mkdtempSync as mkdtempSync5, openSync as openSync15, readFileSync as readFileSync31, renameSync as renameSync9, rmSync as rmSync8, writeFileSync as writeFileSync15 } from "fs";
100814
- import { dirname as dirname19, join as join44 } from "path";
101138
+ import { constants as constants15, closeSync as closeSync16, fstatSync as fstatSync16, lstatSync as lstatSync22, mkdirSync as mkdirSync16, mkdtempSync as mkdtempSync5, openSync as openSync16, readFileSync as readFileSync31, renameSync as renameSync9, rmSync as rmSync8, writeFileSync as writeFileSync15 } from "fs";
101139
+ import { dirname as dirname20, join as join44 } from "path";
100815
101140
  function stat2(path) {
100816
101141
  try {
100817
- return lstatSync21(path);
101142
+ return lstatSync22(path);
100818
101143
  } catch (error61) {
100819
101144
  if (error61.code === "ENOENT")
100820
101145
  return null;
@@ -100824,14 +101149,14 @@ function stat2(path) {
100824
101149
  function safeText(file2) {
100825
101150
  if (stat2(file2) === null)
100826
101151
  return null;
100827
- const fd = openSync15(file2, constants14.O_RDONLY | constants14.O_NOFOLLOW | constants14.O_NONBLOCK);
101152
+ const fd = openSync16(file2, constants15.O_RDONLY | constants15.O_NOFOLLOW | constants15.O_NONBLOCK);
100828
101153
  try {
100829
- const s = fstatSync15(fd);
101154
+ const s = fstatSync16(fd);
100830
101155
  if (!s.isFile() || s.size > 65536 || ![256, 384].includes(s.mode & 4095) || process.getuid && s.uid !== process.getuid())
100831
101156
  return fail2("The selected profile must use bounded owner-only regular files.");
100832
101157
  return readFileSync31(fd, "utf8");
100833
101158
  } finally {
100834
- closeSync15(fd);
101159
+ closeSync16(fd);
100835
101160
  }
100836
101161
  }
100837
101162
  function checkIdentityMetadata(file2, identity4) {
@@ -100896,18 +101221,18 @@ async function prepareWorkspaceEnrollment(membershipId, source = process.env) {
100896
101221
  `);
100897
101222
  if (Buffer.byteLength(credentialBody("x".repeat(8192)), "utf8") > 65536)
100898
101223
  return fail2("The selected profile has insufficient space for a bounded credential. Reduce its unrelated configuration before signing in.");
100899
- const parents2 = [];
100900
- for (let path = dirname19(file2);; path = dirname19(path)) {
101224
+ const parents3 = [];
101225
+ for (let path = dirname20(file2);; path = dirname20(path)) {
100901
101226
  const before2 = stat2(path);
100902
101227
  if (before2 && (!before2.isDirectory() || before2.isSymbolicLink()))
100903
101228
  return fail2("The profile directory must not be a symbolic link.");
100904
- parents2.push([path, before2]);
100905
- if (path === dirname19(path))
101229
+ parents3.push([path, before2]);
101230
+ if (path === dirname20(path))
100906
101231
  break;
100907
101232
  }
100908
101233
  const unchanged2 = () => {
100909
101234
  unchangedFiles();
100910
- for (const [path, before2] of parents2) {
101235
+ for (const [path, before2] of parents3) {
100911
101236
  const now3 = stat2(path);
100912
101237
  if (!before2 ? now3 !== null : !now3 || !now3.isDirectory() || before2.dev !== now3.dev || before2.ino !== now3.ino)
100913
101238
  changed();
@@ -100961,14 +101286,14 @@ async function prepareWorkspaceEnrollment(membershipId, source = process.env) {
100961
101286
  return fail2("The new profile exceeds the credential reader size limit.");
100962
101287
  const identity4 = JSON.stringify({ email: verified.user.email, userId: verified.user.id, orgId: verified.organization.id, orgSlug: verified.organization.slug, apiUrl: origin }, null, 2) + `
100963
101288
  `;
100964
- mkdirSync16(dirname19(file2), { recursive: true, mode: 448 });
100965
- const temp = mkdtempSync5(join44(dirname19(file2), ".workspace-login-"));
101289
+ mkdirSync16(dirname20(file2), { recursive: true, mode: 448 });
101290
+ const temp = mkdtempSync5(join44(dirname20(file2), ".workspace-login-"));
100966
101291
  let identityInstalled = false;
100967
101292
  try {
100968
101293
  writeFileSync15(join44(temp, "credentials"), body, { mode: 384, flag: "wx" });
100969
101294
  writeFileSync15(join44(temp, "identity"), identity4, { mode: 384, flag: "wx" });
100970
101295
  unchangedFiles();
100971
- for (const [path, before2] of parents2) {
101296
+ for (const [path, before2] of parents3) {
100972
101297
  const now3 = stat2(path);
100973
101298
  if (!now3 || !now3.isDirectory() || now3.isSymbolicLink() || before2 && (before2.dev !== now3.dev || before2.ino !== now3.ino))
100974
101299
  changed();
@@ -101178,8 +101503,8 @@ var init_recurring_customer = __esm(() => {
101178
101503
  });
101179
101504
 
101180
101505
  // src/lib/recurring-recovery.ts
101181
- import { constants as constants15, closeSync as closeSync16, fsyncSync as fsyncSync4, fstatSync as fstatSync16, lstatSync as lstatSync22, mkdirSync as mkdirSync17, openSync as openSync16, readSync as readSync12, realpathSync as realpathSync8, renameSync as renameSync10, unlinkSync as unlinkSync6, writeFileSync as writeFileSync16 } from "fs";
101182
- import { dirname as dirname20, isAbsolute as isAbsolute16, join as join45, resolve as resolve18 } from "path";
101506
+ import { constants as constants16, closeSync as closeSync17, fsyncSync as fsyncSync4, fstatSync as fstatSync17, lstatSync as lstatSync23, mkdirSync as mkdirSync17, openSync as openSync17, readSync as readSync13, realpathSync as realpathSync8, renameSync as renameSync10, unlinkSync as unlinkSync6, writeFileSync as writeFileSync16 } from "fs";
101507
+ import { dirname as dirname21, isAbsolute as isAbsolute17, join as join45, resolve as resolve19 } from "path";
101183
101508
  import { randomUUID as randomUUID7 } from "crypto";
101184
101509
 
101185
101510
  class RecoveryOwner {
@@ -101187,14 +101512,14 @@ class RecoveryOwner {
101187
101512
  parents = [];
101188
101513
  constructor(directory) {
101189
101514
  this.directory = directory;
101190
- if (!isAbsolute16(directory) || resolve18(directory) !== directory || realpathSync8(directory) !== directory)
101515
+ if (!isAbsolute17(directory) || resolve19(directory) !== directory || realpathSync8(directory) !== directory)
101191
101516
  invalid6();
101192
- for (let path = directory;; path = dirname20(path)) {
101193
- const stat3 = lstatSync22(path);
101517
+ for (let path = directory;; path = dirname21(path)) {
101518
+ const stat3 = lstatSync23(path);
101194
101519
  if (!stat3.isDirectory() || stat3.isSymbolicLink())
101195
101520
  invalid6();
101196
101521
  this.parents.push({ path, dev: stat3.dev, ino: stat3.ino });
101197
- if (path === dirname20(path))
101522
+ if (path === dirname21(path))
101198
101523
  break;
101199
101524
  }
101200
101525
  this.assert();
@@ -101203,59 +101528,59 @@ class RecoveryOwner {
101203
101528
  if (realpathSync8(this.directory) !== this.directory)
101204
101529
  invalid6();
101205
101530
  for (const prior of this.parents) {
101206
- const now3 = lstatSync22(prior.path);
101531
+ const now3 = lstatSync23(prior.path);
101207
101532
  if (!now3.isDirectory() || now3.isSymbolicLink() || now3.dev !== prior.dev || now3.ino !== prior.ino)
101208
101533
  invalid6();
101209
101534
  }
101210
- const own2 = lstatSync22(this.directory);
101535
+ const own2 = lstatSync23(this.directory);
101211
101536
  if ((own2.mode & 511) !== 448 || (own2.mode & 3584) !== 0 || process.getuid && own2.uid !== process.getuid())
101212
101537
  invalid6();
101213
101538
  }
101214
101539
  read(name) {
101215
101540
  this.assert();
101216
- const fd = openSync16(join45(this.directory, name), constants15.O_RDONLY | constants15.O_NOFOLLOW | constants15.O_NONBLOCK);
101541
+ const fd = openSync17(join45(this.directory, name), constants16.O_RDONLY | constants16.O_NOFOLLOW | constants16.O_NONBLOCK);
101217
101542
  try {
101218
- const before2 = fstatSync16(fd);
101543
+ const before2 = fstatSync17(fd);
101219
101544
  if (!before2.isFile() || before2.nlink !== 1 || (before2.mode & 4095) !== 384 || before2.size < 1 || before2.size > 8192 || process.getuid && before2.uid !== process.getuid())
101220
101545
  invalid6();
101221
101546
  const bytes = Buffer.alloc(before2.size + 1);
101222
101547
  let size2 = 0;
101223
101548
  while (size2 < bytes.length) {
101224
- const n2 = readSync12(fd, bytes, size2, bytes.length - size2, size2);
101549
+ const n2 = readSync13(fd, bytes, size2, bytes.length - size2, size2);
101225
101550
  if (!n2)
101226
101551
  break;
101227
101552
  size2 += n2;
101228
101553
  }
101229
- const after2 = fstatSync16(fd), path = lstatSync22(join45(this.directory, name));
101554
+ const after2 = fstatSync17(fd), path = lstatSync23(join45(this.directory, name));
101230
101555
  if (size2 !== before2.size || after2.size !== before2.size || before2.mtimeMs !== after2.mtimeMs || before2.ctimeMs !== after2.ctimeMs || path.dev !== before2.dev || path.ino !== before2.ino || !path.isFile() || path.isSymbolicLink())
101231
101556
  invalid6();
101232
101557
  this.assert();
101233
101558
  return new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(0, size2));
101234
101559
  } finally {
101235
- closeSync16(fd);
101560
+ closeSync17(fd);
101236
101561
  }
101237
101562
  }
101238
101563
  write(name, value) {
101239
101564
  this.assert();
101240
101565
  const bytes = canonicalJson2(value, 8192) + `
101241
101566
  `;
101242
- const fd = openSync16(join45(this.directory, name), constants15.O_WRONLY | constants15.O_CREAT | constants15.O_EXCL | constants15.O_NOFOLLOW, 384);
101567
+ const fd = openSync17(join45(this.directory, name), constants16.O_WRONLY | constants16.O_CREAT | constants16.O_EXCL | constants16.O_NOFOLLOW, 384);
101243
101568
  try {
101244
101569
  writeFileSync16(fd, bytes);
101245
101570
  fsyncSync4(fd);
101246
101571
  } finally {
101247
- closeSync16(fd);
101572
+ closeSync17(fd);
101248
101573
  }
101249
101574
  this.assert();
101250
101575
  this.sync();
101251
101576
  }
101252
101577
  sync() {
101253
101578
  this.assert();
101254
- const fd = openSync16(this.directory, constants15.O_RDONLY | constants15.O_NOFOLLOW);
101579
+ const fd = openSync17(this.directory, constants16.O_RDONLY | constants16.O_NOFOLLOW);
101255
101580
  try {
101256
101581
  fsyncSync4(fd);
101257
101582
  } finally {
101258
- closeSync16(fd);
101583
+ closeSync17(fd);
101259
101584
  }
101260
101585
  }
101261
101586
  saveState(state, expected) {
@@ -101273,20 +101598,20 @@ class RecoveryOwner {
101273
101598
  this.assert();
101274
101599
  let fd;
101275
101600
  try {
101276
- fd = openSync16(join45(this.directory, "operation.lock"), constants15.O_WRONLY | constants15.O_CREAT | constants15.O_EXCL | constants15.O_NOFOLLOW, 384);
101601
+ fd = openSync17(join45(this.directory, "operation.lock"), constants16.O_WRONLY | constants16.O_CREAT | constants16.O_EXCL | constants16.O_NOFOLLOW, 384);
101277
101602
  } catch {
101278
101603
  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.");
101279
101604
  }
101280
- const owner2 = fstatSync16(fd);
101605
+ const owner2 = fstatSync17(fd);
101281
101606
  try {
101282
101607
  writeFileSync16(fd, JSON.stringify({ pid: process.pid }));
101283
101608
  fsyncSync4(fd);
101284
101609
  this.sync();
101285
101610
  return await action();
101286
101611
  } finally {
101287
- closeSync16(fd);
101612
+ closeSync17(fd);
101288
101613
  this.assert();
101289
- const now3 = lstatSync22(join45(this.directory, "operation.lock"));
101614
+ const now3 = lstatSync23(join45(this.directory, "operation.lock"));
101290
101615
  if (owner2.dev !== now3.dev || owner2.ino !== now3.ino || !now3.isFile() || now3.isSymbolicLink())
101291
101616
  invalid6();
101292
101617
  unlinkSync6(join45(this.directory, "operation.lock"));
@@ -101322,7 +101647,7 @@ function base2(customer, organizationId) {
101322
101647
  };
101323
101648
  }
101324
101649
  function create3(directory, intent) {
101325
- if (!isAbsolute16(directory) || resolve18(directory) !== directory || realpathSync8(dirname20(directory)) !== dirname20(directory))
101650
+ if (!isAbsolute17(directory) || resolve19(directory) !== directory || realpathSync8(dirname21(directory)) !== dirname21(directory))
101326
101651
  invalid6();
101327
101652
  mkdirSync17(directory, { mode: 448 });
101328
101653
  const owner2 = new RecoveryOwner(directory), checked = intentSchema.parse(intent), intentSha256 = canonicalJsonSha256(checked);
@@ -101485,7 +101810,7 @@ var init_recurring_recovery = __esm(() => {
101485
101810
  });
101486
101811
 
101487
101812
  // src/lib/recurring-surface.ts
101488
- import { isAbsolute as isAbsolute17 } from "path";
101813
+ import { isAbsolute as isAbsolute18 } from "path";
101489
101814
  function recurringMcpSchema(action) {
101490
101815
  return action === "activate" ? recurringSurfaceSchemas.activate.extend({ code, confirm: exports_external.literal(true) }) : recurringSurfaceSchemas[action];
101491
101816
  }
@@ -101590,7 +101915,7 @@ var init_recurring_surface = __esm(() => {
101590
101915
  uuid13 = exports_external.string().regex(/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/);
101591
101916
  context = { userId: uuid13.optional(), membershipId: uuid13.optional() };
101592
101917
  page2 = { limit: exports_external.number().int().min(1).max(100).optional(), cursor: exports_external.string().min(1).max(2048).optional() };
101593
- directory = exports_external.string().max(4096).refine(isAbsolute17, "Use an absolute recovery directory");
101918
+ directory = exports_external.string().max(4096).refine(isAbsolute18, "Use an absolute recovery directory");
101594
101919
  email4 = exports_external.string().trim().toLowerCase().email().max(254);
101595
101920
  code = exports_external.string().regex(/^\d{6}$/);
101596
101921
  recurringSurfaceSchemas = {
@@ -102965,6 +103290,18 @@ var init_run_routing = __esm(() => {
102965
103290
  import { existsSync as existsSync28, readdirSync as readdirSync17, statSync as statSync16 } from "fs";
102966
103291
  import { join as join46 } from "path";
102967
103292
  function registerOperationTools(server) {
103293
+ server.registerTool("cloud_skill_eligibility", {
103294
+ title: "Cloud Skill Eligibility",
103295
+ description: "Inspect the authenticated workspace's exact reviewed cloud contract. Does not execute or admit a skill.",
103296
+ inputSchema: { name: exports_external.string(), version: exports_external.string(), bundleDigest: exports_external.string().optional() }
103297
+ }, async ({ name, version: version2, bundleDigest }) => {
103298
+ try {
103299
+ const { CloudExecutionClient: CloudExecutionClient2 } = await Promise.resolve().then(() => (init_cloud_executions(), exports_cloud_executions));
103300
+ return mcpJson(await (await CloudExecutionClient2.configured()).eligibility(name, version2, bundleDigest));
103301
+ } catch (error61) {
103302
+ return mcpError("CLOUD_ELIGIBILITY_FAILED", error61.message);
103303
+ }
103304
+ });
102968
103305
  server.registerTool("scaffold_skill", {
102969
103306
  title: "Scaffold Skill",
102970
103307
  description: "Create a portable skill folder under ~/.hasna/skills/installed/<name> with SKILL.md, skill.json, AGENTS.md, package.json, and src/index.ts.",
@@ -103496,14 +103833,14 @@ var init_operation_tools = __esm(() => {
103496
103833
 
103497
103834
  // src/lib/feedback.ts
103498
103835
  import { appendFileSync as appendFileSync2, existsSync as existsSync29, mkdirSync as mkdirSync18 } from "fs";
103499
- import { dirname as dirname21, join as join47 } from "path";
103836
+ import { dirname as dirname22, join as join47 } from "path";
103500
103837
  import { Database } from "bun:sqlite";
103501
103838
  function getFeedbackDbPath() {
103502
103839
  return join47(getDataDir(), "skills.db");
103503
103840
  }
103504
103841
  function getFeedbackDb() {
103505
103842
  const dbPath = getFeedbackDbPath();
103506
- const dir = dirname21(dbPath);
103843
+ const dir = dirname22(dbPath);
103507
103844
  if (!existsSync29(dir))
103508
103845
  mkdirSync18(dir, { recursive: true });
103509
103846
  const db = new Database(dbPath);
@@ -103532,7 +103869,7 @@ function saveFeedback(input2) {
103532
103869
  const category = input2.category ?? "general";
103533
103870
  if (isApiMode()) {
103534
103871
  const path = join47(getDataDir(), "feedback.jsonl");
103535
- const dir = dirname21(path);
103872
+ const dir = dirname22(path);
103536
103873
  if (!existsSync29(dir))
103537
103874
  mkdirSync18(dir, { recursive: true });
103538
103875
  appendFileSync2(path, JSON.stringify({ message, category, email: input2.email ?? null, agent: input2.agent ?? null, version: input2.version ?? null, createdAt: new Date().toISOString() }) + `
@@ -104010,7 +104347,7 @@ var init_schedule_tools = __esm(() => {
104010
104347
  });
104011
104348
 
104012
104349
  // src/lib/native-storage.ts
104013
- import { createHash as createHash21, createHmac as createHmac3 } from "crypto";
104350
+ import { createHash as createHash22, createHmac as createHmac3 } from "crypto";
104014
104351
  import {
104015
104352
  existsSync as existsSync31,
104016
104353
  mkdirSync as mkdirSync20,
@@ -104019,7 +104356,7 @@ import {
104019
104356
  statSync as statSync17,
104020
104357
  writeFileSync as writeFileSync18
104021
104358
  } from "fs";
104022
- import { dirname as dirname22, join as join49, normalize as normalize3, relative as relative7, sep as sep7 } from "path";
104359
+ import { dirname as dirname23, join as join49, normalize as normalize3, relative as relative7, sep as sep7 } from "path";
104023
104360
  function resolveSkillsNativeStorageConfig(env3 = process.env) {
104024
104361
  assertNoRetiredModeEnvVars(env3, {
104025
104362
  app: SKILLS_ENV_NAMESPACE,
@@ -104087,7 +104424,7 @@ function exportSkillsLocalSnapshot(targetDir = process.cwd(), options = {}) {
104087
104424
  files.push({
104088
104425
  path: relativePath,
104089
104426
  sizeBytes: bytes.byteLength,
104090
- sha256: createHash21("sha256").update(bytes).digest("hex"),
104427
+ sha256: createHash22("sha256").update(bytes).digest("hex"),
104091
104428
  ...options.includeFileContents ? { contentBase64: Buffer.from(bytes).toString("base64") } : {}
104092
104429
  });
104093
104430
  }
@@ -104379,20 +104716,20 @@ var init_private_publication_customer = __esm(() => {
104379
104716
  });
104380
104717
 
104381
104718
  // src/lib/private-publication-recovery.ts
104382
- import { constants as constants16, closeSync as closeSync17, fsyncSync as fsyncSync5, fstatSync as fstatSync17, lstatSync as lstatSync23, mkdirSync as mkdirSync21, openSync as openSync17, readSync as readSync13, realpathSync as realpathSync9, renameSync as renameSync11, unlinkSync as unlinkSync7, writeFileSync as writeFileSync19 } from "fs";
104383
- import { dirname as dirname23, isAbsolute as isAbsolute18, join as join50, resolve as resolve19 } from "path";
104719
+ import { constants as constants17, closeSync as closeSync18, fsyncSync as fsyncSync5, fstatSync as fstatSync18, lstatSync as lstatSync24, mkdirSync as mkdirSync21, openSync as openSync18, readSync as readSync14, realpathSync as realpathSync9, renameSync as renameSync11, unlinkSync as unlinkSync7, writeFileSync as writeFileSync19 } from "fs";
104720
+ import { dirname as dirname24, isAbsolute as isAbsolute19, join as join50, resolve as resolve20 } from "path";
104384
104721
  import { randomUUID as randomUUID8 } from "crypto";
104385
104722
  function safeDirectory(directory2) {
104386
- if (!isAbsolute18(directory2) || directory2 !== resolve19(directory2) || realpathSync9(directory2) !== directory2)
104723
+ if (!isAbsolute19(directory2) || directory2 !== resolve20(directory2) || realpathSync9(directory2) !== directory2)
104387
104724
  return fail3();
104388
- for (let path = directory2;; path = dirname23(path)) {
104389
- const stat3 = lstatSync23(path);
104725
+ for (let path = directory2;; path = dirname24(path)) {
104726
+ const stat3 = lstatSync24(path);
104390
104727
  if (!stat3.isDirectory() || stat3.isSymbolicLink())
104391
104728
  return fail3();
104392
- if (path === dirname23(path))
104729
+ if (path === dirname24(path))
104393
104730
  break;
104394
104731
  }
104395
- const own2 = lstatSync23(directory2);
104732
+ const own2 = lstatSync24(directory2);
104396
104733
  if ((own2.mode & 63) !== 0 || process.getuid && own2.uid !== process.getuid())
104397
104734
  return fail3();
104398
104735
  return { dev: own2.dev, ino: own2.ino };
@@ -104404,35 +104741,35 @@ function unchangedDirectory(directory2, identity4) {
104404
104741
  }
104405
104742
  function readOwned(directory2, name, max2) {
104406
104743
  const identity4 = safeDirectory(directory2), file2 = join50(directory2, name);
104407
- const fd = openSync17(file2, constants16.O_RDONLY | constants16.O_NOFOLLOW);
104744
+ const fd = openSync18(file2, constants17.O_RDONLY | constants17.O_NOFOLLOW);
104408
104745
  try {
104409
- const stat3 = fstatSync17(fd);
104746
+ const stat3 = fstatSync18(fd);
104410
104747
  if (!stat3.isFile() || stat3.nlink !== 1 || stat3.size > max2 || stat3.size < 1 || (stat3.mode & 63) !== 0 || process.getuid && stat3.uid !== process.getuid())
104411
104748
  return fail3();
104412
104749
  const buffer = Buffer.alloc(Math.min(max2, stat3.size) + 1);
104413
104750
  let length = 0;
104414
104751
  while (length < buffer.length) {
104415
- const count = readSync13(fd, buffer, length, buffer.length - length, length);
104752
+ const count = readSync14(fd, buffer, length, buffer.length - length, length);
104416
104753
  if (count === 0)
104417
104754
  break;
104418
104755
  length += count;
104419
104756
  }
104420
- const bytes = buffer.subarray(0, length), after2 = fstatSync17(fd);
104757
+ const bytes = buffer.subarray(0, length), after2 = fstatSync18(fd);
104421
104758
  unchangedDirectory(directory2, identity4);
104422
104759
  if (bytes.length !== stat3.size || stat3.size !== after2.size || stat3.mtimeMs !== after2.mtimeMs || stat3.ctimeMs !== after2.ctimeMs)
104423
104760
  return fail3();
104424
104761
  return bytes;
104425
104762
  } finally {
104426
- closeSync17(fd);
104763
+ closeSync18(fd);
104427
104764
  }
104428
104765
  }
104429
104766
  function writeOwned(directory2, name, bytes) {
104430
- const fd = openSync17(join50(directory2, name), constants16.O_WRONLY | constants16.O_CREAT | constants16.O_EXCL | constants16.O_NOFOLLOW, 384);
104767
+ const fd = openSync18(join50(directory2, name), constants17.O_WRONLY | constants17.O_CREAT | constants17.O_EXCL | constants17.O_NOFOLLOW, 384);
104431
104768
  try {
104432
104769
  writeFileSync19(fd, bytes);
104433
104770
  fsyncSync5(fd);
104434
104771
  } finally {
104435
- closeSync17(fd);
104772
+ closeSync18(fd);
104436
104773
  }
104437
104774
  }
104438
104775
  function save(directory2, value) {
@@ -104441,11 +104778,11 @@ function save(directory2, value) {
104441
104778
  `);
104442
104779
  unchangedDirectory(directory2, identity4);
104443
104780
  renameSync11(join50(directory2, temporary), join50(directory2, "receipt.json"));
104444
- const fd = openSync17(directory2, constants16.O_RDONLY | constants16.O_NOFOLLOW);
104781
+ const fd = openSync18(directory2, constants17.O_RDONLY | constants17.O_NOFOLLOW);
104445
104782
  try {
104446
104783
  fsyncSync5(fd);
104447
104784
  } finally {
104448
- closeSync17(fd);
104785
+ closeSync18(fd);
104449
104786
  }
104450
104787
  }
104451
104788
  function bind2(client2, receipt) {
@@ -104456,20 +104793,20 @@ async function locked(directory2, action) {
104456
104793
  const identity4 = safeDirectory(directory2), file2 = join50(directory2, "operation.lock");
104457
104794
  let fd;
104458
104795
  try {
104459
- fd = openSync17(file2, constants16.O_WRONLY | constants16.O_CREAT | constants16.O_EXCL | constants16.O_NOFOLLOW, 384);
104796
+ fd = openSync18(file2, constants17.O_WRONLY | constants17.O_CREAT | constants17.O_EXCL | constants17.O_NOFOLLOW, 384);
104460
104797
  } catch {
104461
104798
  throw new PrivatePublicationError("PUBLICATION_RECOVERY_BUSY", "Another operation holds this recovery directory. If it crashed, confirm that process has stopped before explicitly removing operation.lock and resuming.");
104462
104799
  }
104463
- const lock = fstatSync17(fd);
104800
+ const lock = fstatSync18(fd);
104464
104801
  try {
104465
104802
  writeFileSync19(fd, JSON.stringify({ pid: process.pid }) + `
104466
104803
  `);
104467
104804
  fsyncSync5(fd);
104468
104805
  return await action();
104469
104806
  } finally {
104470
- closeSync17(fd);
104807
+ closeSync18(fd);
104471
104808
  unchangedDirectory(directory2, identity4);
104472
- const now3 = lstatSync23(file2);
104809
+ const now3 = lstatSync24(file2);
104473
104810
  if (now3.dev !== lock.dev || now3.ino !== lock.ino || !now3.isFile() || now3.isSymbolicLink())
104474
104811
  fail3();
104475
104812
  unlinkSync7(file2);
@@ -104521,15 +104858,15 @@ async function preparePrivatePublication(client2, sourceDirectory, recoveryDirec
104521
104858
  phase: "prepared",
104522
104859
  intent: null
104523
104860
  };
104524
- if (!isAbsolute18(recoveryDirectory) || resolve19(recoveryDirectory) !== recoveryDirectory || realpathSync9(dirname23(recoveryDirectory)) !== dirname23(recoveryDirectory))
104861
+ if (!isAbsolute19(recoveryDirectory) || resolve20(recoveryDirectory) !== recoveryDirectory || realpathSync9(dirname24(recoveryDirectory)) !== dirname24(recoveryDirectory))
104525
104862
  return fail3();
104526
104863
  mkdirSync21(recoveryDirectory, { mode: 448 });
104527
104864
  safeDirectory(recoveryDirectory);
104528
- const parent = openSync17(dirname23(recoveryDirectory), constants16.O_RDONLY | constants16.O_NOFOLLOW);
104865
+ const parent = openSync18(dirname24(recoveryDirectory), constants17.O_RDONLY | constants17.O_NOFOLLOW);
104529
104866
  try {
104530
104867
  fsyncSync5(parent);
104531
104868
  } finally {
104532
- closeSync17(parent);
104869
+ closeSync18(parent);
104533
104870
  }
104534
104871
  writeOwned(recoveryDirectory, "bundle.tgz", packed.bytes);
104535
104872
  save(recoveryDirectory, receipt);
@@ -104622,10 +104959,10 @@ var init_private_publication_recovery = __esm(() => {
104622
104959
  });
104623
104960
 
104624
104961
  // src/mcp/private-publication-tools.ts
104625
- import { isAbsolute as isAbsolute19 } from "path";
104962
+ import { isAbsolute as isAbsolute20 } from "path";
104626
104963
  function registerPrivatePublicationTools(server) {
104627
104964
  const uuid9 = exports_external.string().regex(/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/);
104628
- const directory2 = exports_external.string().max(4096).refine(isAbsolute19, "Use an absolute local directory");
104965
+ const directory2 = exports_external.string().max(4096).refine(isAbsolute20, "Use an absolute local directory");
104629
104966
  const verification2 = { email: exports_external.string().email().max(254), code: exports_external.string().regex(/^\d{6}$/), userId: uuid9, membershipId: uuid9, recoveryDirectory: directory2 };
104630
104967
  const description = "Manage a private source publication using fresh workspace-bound verification and a host-local recovery directory. Publishing requires explicit UUID current-version comparison and upload consent. Resume reuses immutable saved bytes and intent; an uncertain PUT is finalized for server verification, never uploaded twice. Sessions and signed URLs are not returned or persisted. Private execution is unavailable. Host request history may contain the supplied verification code.";
104631
104968
  const handler = (action) => async (value) => {
@@ -104985,7 +105322,7 @@ var init_mcp2 = __esm(() => {
104985
105322
  // src/cli/commands/runtime-mcp.ts
104986
105323
  import { existsSync as existsSync32, mkdirSync as mkdirSync22, readFileSync as readFileSync34, writeFileSync as writeFileSync20 } from "fs";
104987
105324
  import { homedir as homedir9 } from "os";
104988
- import { dirname as dirname24, join as join51 } from "path";
105325
+ import { dirname as dirname25, join as join51 } from "path";
104989
105326
  async function handleMcp(options) {
104990
105327
  if (options.register) {
104991
105328
  let agents;
@@ -105159,7 +105496,7 @@ function writeJsonObject(path, data) {
105159
105496
  `);
105160
105497
  }
105161
105498
  function writeTextFile(path, content) {
105162
- mkdirSync22(dirname24(path), { recursive: true });
105499
+ mkdirSync22(dirname25(path), { recursive: true });
105163
105500
  writeFileSync20(path, content.endsWith(`
105164
105501
  `) ? content : `${content}
105165
105502
  `);
@@ -105269,9 +105606,9 @@ var exports_runtime = {};
105269
105606
  __export(exports_runtime, {
105270
105607
  registerRuntime: () => registerRuntime
105271
105608
  });
105272
- import { createHash as createHash22, randomUUID as randomUUID9 } from "crypto";
105273
- import { lstatSync as lstatSync24, mkdirSync as mkdirSync23, readFileSync as readFileSync35, realpathSync as realpathSync10, writeFileSync as writeFileSync21 } from "fs";
105274
- import { basename as basename9, isAbsolute as isAbsolute20, join as join52 } from "path";
105609
+ import { createHash as createHash23, randomUUID as randomUUID9 } from "crypto";
105610
+ import { lstatSync as lstatSync25, mkdirSync as mkdirSync23, readFileSync as readFileSync35, realpathSync as realpathSync10, writeFileSync as writeFileSync21 } from "fs";
105611
+ import { basename as basename11, isAbsolute as isAbsolute21, join as join52 } from "path";
105275
105612
  import { createInterface } from "readline";
105276
105613
  function registerRuntime(parent) {
105277
105614
  parent.command("run").argument("<skill>", "Skill name").argument("[args...]", "Arguments to pass to the skill; use -- to end Skills options").allowUnknownOption(true).passThroughOptions(true).option("--json", "Output result as JSON", false).option("--remote", "Run on the configured server, using its catalog and quote", false).option("--target <target>", "Execution target: local or cloud").option("--secret-bindings <path>", "Reviewed, exact-selection local execution vault bindings (JSON file)").option("--secret-bindings-template", "Print a scoped bindings template without resolving secrets or running the skill", false).option("--input <json>", "Structured cloud execution input").option("--skill-version <version>", "Exact selected skill version").option("--selection-profile <id>", "Selected Skills profile").option("--session <id>", "Pinned Skills session").option("--cached", "Use the explicit verified selected cache", false).option("--yes", "Approve the server's quoted credit cost for this run", false).option("--idempotency-key <key>", "Reuse this key when retrying the same remote submission").option("--file <path>", "Attach a local input file to a remote run (repeatable)", (value, prior) => [...prior, value], []).option("--wait", "Poll remote runs until a terminal status", false).option("--poll-interval-ms <ms>", "Remote polling interval in milliseconds", "1000").option("--poll-timeout-ms <ms>", "Maximum time to wait for a remote run", "300000").description("Run a skill directly").action(async (name, args2, options, command) => {
@@ -105281,6 +105618,15 @@ function registerRuntime(parent) {
105281
105618
  await handleRun(name, args2, options, separatorBeforeSkill);
105282
105619
  });
105283
105620
  const executions = parent.command("executions").description("Inspect isolated cloud executions");
105621
+ executions.command("eligibility").argument("<skill>").requiredOption("--skill-version <version>", "Exact published version").option("--bundle-digest <digest>", "Expected published bundle SHA256").option("--json", "Output as JSON", false).description("Inspect reviewed cloud eligibility without executing a skill").action(async (slug2, options) => {
105622
+ try {
105623
+ const client2 = await CloudExecutionClient.configured();
105624
+ await writeCliOutput(JSON.stringify(await client2.eligibility(slug2, options.skillVersion, options.bundleDigest), null, 2));
105625
+ } catch (error61) {
105626
+ console.error(JSON.stringify({ error: error61.message }));
105627
+ process.exitCode = 1;
105628
+ }
105629
+ });
105284
105630
  for (const operation of ["show", "logs", "artifacts", "cancel"]) {
105285
105631
  executions.command(operation).argument("<execution-id>").option("--json", "Output as JSON", false).action(async (id2) => {
105286
105632
  try {
@@ -105301,7 +105647,7 @@ function registerRuntime(parent) {
105301
105647
  if (!expected)
105302
105648
  throw new Error("Cloud artifact not found");
105303
105649
  const bytes = await client2.download(id2, name);
105304
- if (bytes.length !== expected.byteSize || createHash22("sha256").update(bytes).digest("hex") !== expected.sha256)
105650
+ if (bytes.length !== expected.byteSize || createHash23("sha256").update(bytes).digest("hex") !== expected.sha256)
105305
105651
  throw new Error("Cloud artifact integrity verification failed");
105306
105652
  writeFileSync21(options.output, bytes, { flag: "wx", mode: 384 });
105307
105653
  console.log(JSON.stringify({ path: options.output, sha256: expected.sha256, byteSize: bytes.length }));
@@ -105389,7 +105735,7 @@ Updating ${name}...
105389
105735
  async function readUpdatedVersion(bunExecutable) {
105390
105736
  const output2 = await readUpdateCommand([bunExecutable, "pm", "bin", "-g"]);
105391
105737
  const globalBin = output2.replace(/\r?\n$/, "");
105392
- if (!globalBin || !isAbsolute20(globalBin) || /[\r\n\0]/.test(globalBin))
105738
+ if (!globalBin || !isAbsolute21(globalBin) || /[\r\n\0]/.test(globalBin))
105393
105739
  throw new Error("Update bin discovery failed");
105394
105740
  const installed = Bun.which("skills", { PATH: globalBin, cwd: globalBin });
105395
105741
  const selected = Bun.which("skills");
@@ -105525,14 +105871,14 @@ function requireHttpUrl(value) {
105525
105871
  }
105526
105872
  function promptLine(question) {
105527
105873
  const rl = createInterface({ input: process.stdin, output: process.stdout });
105528
- return new Promise((resolve20) => {
105874
+ return new Promise((resolve21) => {
105529
105875
  let settled = false;
105530
105876
  const finish = (answer) => {
105531
105877
  if (settled)
105532
105878
  return;
105533
105879
  settled = true;
105534
105880
  rl.close();
105535
- resolve20(answer);
105881
+ resolve21(answer);
105536
105882
  };
105537
105883
  rl.once("SIGINT", () => finish(null));
105538
105884
  rl.once("close", () => finish(null));
@@ -105709,10 +106055,10 @@ async function handleRun(name, args2, options, separatorBeforeSkill) {
105709
106055
  try {
105710
106056
  parsePollingOptions(options);
105711
106057
  inputFiles = (options.file ?? []).map((path) => {
105712
- const info = lstatSync24(path);
106058
+ const info = lstatSync25(path);
105713
106059
  if (!info.isFile() || info.size > 20 * 1024 * 1024)
105714
106060
  throw new Error("Input must be a regular file no larger than 20 MiB");
105715
- return { name: basename9(path), bytes: new Uint8Array(readFileSync35(path)) };
106061
+ return { name: basename11(path), bytes: new Uint8Array(readFileSync35(path)) };
105716
106062
  });
105717
106063
  describeRemoteFiles(inputFiles);
105718
106064
  client2 = new RemoteSkillsClient(routing.apiKey, routing.apiOrigin);
@@ -106139,7 +106485,7 @@ function ensureSafeExportParent(root2, relativePath) {
106139
106485
  if (part)
106140
106486
  parent = join52(parent, part);
106141
106487
  try {
106142
- if (!lstatSync24(parent).isDirectory() || lstatSync24(parent).isSymbolicLink())
106488
+ if (!lstatSync25(parent).isDirectory() || lstatSync25(parent).isSymbolicLink())
106143
106489
  throw new Error("Unsafe artifact directory");
106144
106490
  } catch (error61) {
106145
106491
  if (error61.code !== "ENOENT")
@@ -106177,7 +106523,7 @@ async function pollRemoteRun(client2, runId2, options) {
106177
106523
  const remaining = deadline - Date.now();
106178
106524
  if (remaining <= 0)
106179
106525
  break;
106180
- await new Promise((resolve20) => setTimeout(resolve20, Math.min(options.intervalMs, remaining)));
106526
+ await new Promise((resolve21) => setTimeout(resolve21, Math.min(options.intervalMs, remaining)));
106181
106527
  }
106182
106528
  return {
106183
106529
  run: current ?? { id: runId2, status: "queued" },
@@ -106369,7 +106715,7 @@ async function readCode() {
106369
106715
  function promptCode() {
106370
106716
  const { stdin, stderr: output2 } = process;
106371
106717
  const { isRaw: wasRaw, readableFlowing: wasFlowing } = stdin;
106372
- return new Promise((resolve20) => {
106718
+ return new Promise((resolve21) => {
106373
106719
  let value = "", settled = false;
106374
106720
  const finish = (answer) => {
106375
106721
  if (settled)
@@ -106386,7 +106732,7 @@ function promptCode() {
106386
106732
  `);
106387
106733
  if (answer === null)
106388
106734
  process.exitCode = 130;
106389
- resolve20(answer);
106735
+ resolve21(answer);
106390
106736
  };
106391
106737
  const cancel = () => finish(null);
106392
106738
  const keypress = (text3, key) => {
@@ -106431,37 +106777,37 @@ var exports_recurring = {};
106431
106777
  __export(exports_recurring, {
106432
106778
  registerRecurringCommands: () => registerRecurringCommands
106433
106779
  });
106434
- import { constants as constants17, closeSync as closeSync18, fstatSync as fstatSync18, lstatSync as lstatSync25, openSync as openSync18, readSync as readSync14 } from "fs";
106780
+ import { constants as constants18, closeSync as closeSync19, fstatSync as fstatSync19, lstatSync as lstatSync26, openSync as openSync19, readSync as readSync15 } from "fs";
106435
106781
  import { createInterface as createInterface2 } from "readline";
106436
106782
  function readRequest(path) {
106437
- const fd = openSync18(path, constants17.O_RDONLY | constants17.O_NOFOLLOW | constants17.O_NONBLOCK);
106783
+ const fd = openSync19(path, constants18.O_RDONLY | constants18.O_NOFOLLOW | constants18.O_NONBLOCK);
106438
106784
  try {
106439
- const before2 = fstatSync18(fd);
106785
+ const before2 = fstatSync19(fd);
106440
106786
  if (!before2.isFile() || before2.size > 1048576 || before2.size < 1)
106441
106787
  throw new RecurringInputError;
106442
106788
  const bytes = Buffer.alloc(before2.size + 1);
106443
106789
  let length = 0;
106444
106790
  while (length < bytes.length) {
106445
- const n2 = readSync14(fd, bytes, length, bytes.length - length, length);
106791
+ const n2 = readSync15(fd, bytes, length, bytes.length - length, length);
106446
106792
  if (!n2)
106447
106793
  break;
106448
106794
  length += n2;
106449
106795
  }
106450
- const after2 = fstatSync18(fd), current = lstatSync25(path);
106796
+ const after2 = fstatSync19(fd), current = lstatSync26(path);
106451
106797
  if (length !== before2.size || after2.size !== before2.size || before2.mtimeMs !== after2.mtimeMs || before2.ctimeMs !== after2.ctimeMs || current.dev !== before2.dev || current.ino !== before2.ino || !current.isFile() || current.isSymbolicLink())
106452
106798
  throw new RecurringInputError;
106453
106799
  return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(0, length)));
106454
106800
  } catch {
106455
106801
  throw new RecurringInputError;
106456
106802
  } finally {
106457
- closeSync18(fd);
106803
+ closeSync19(fd);
106458
106804
  }
106459
106805
  }
106460
106806
  async function acceptAtTerminal(draft) {
106461
- await new Promise((resolve20, reject2) => process.stderr.write(`${jsonText(draft)}
106807
+ await new Promise((resolve21, reject2) => process.stderr.write(`${jsonText(draft)}
106462
106808
  This grants an additional recurring budget. Each occurrence reprices within the approved ceilings. Revocation prevents new authority; an already-authorized attempt may finish, and cancellation is separate.
106463
- `, (error61) => error61 ? reject2(error61) : resolve20()));
106464
- return new Promise((resolve20) => {
106809
+ `, (error61) => error61 ? reject2(error61) : resolve21()));
106810
+ return new Promise((resolve21) => {
106465
106811
  const rl = createInterface2({ input: process.stdin, output: process.stderr });
106466
106812
  let settled = false;
106467
106813
  const finish = (accepted) => {
@@ -106472,7 +106818,7 @@ This grants an additional recurring budget. Each occurrence reprices within the
106472
106818
  rl.close();
106473
106819
  if (!accepted)
106474
106820
  process.exitCode = 130;
106475
- resolve20(accepted);
106821
+ resolve21(accepted);
106476
106822
  };
106477
106823
  const timer = setTimeout(() => finish(false), 5 * 60 * 1000);
106478
106824
  rl.once("SIGINT", () => finish(false));
@@ -106880,7 +107226,7 @@ var init_portable_snapshot_filter = __esm(() => {
106880
107226
  });
106881
107227
 
106882
107228
  // src/lib/station-snapshot.ts
106883
- import { createHash as createHash23 } from "crypto";
107229
+ import { createHash as createHash24 } from "crypto";
106884
107230
  import {
106885
107231
  copyFileSync,
106886
107232
  mkdirSync as mkdirSync24,
@@ -106888,14 +107234,14 @@ import {
106888
107234
  statSync as statSync19,
106889
107235
  writeFileSync as writeFileSync22
106890
107236
  } from "fs";
106891
- import { dirname as dirname26, isAbsolute as isAbsolute21, relative as relative8, resolve as resolve20, sep as sep9 } from "path";
107237
+ import { dirname as dirname27, isAbsolute as isAbsolute22, relative as relative8, resolve as resolve21, sep as sep9 } from "path";
106892
107238
  function validateStationId(stationId) {
106893
107239
  if (!/^[a-z0-9-]+$/.test(stationId)) {
106894
107240
  throw new StationSnapshotError("INVALID_STATION", `station id must be a slug, got: ${stationId}`);
106895
107241
  }
106896
107242
  }
106897
107243
  function sha256File(filePath) {
106898
- return createHash23("sha256").update(readFileSync36(filePath)).digest("hex");
107244
+ return createHash24("sha256").update(readFileSync36(filePath)).digest("hex");
106899
107245
  }
106900
107246
  function scanHome(definition, homesRoot) {
106901
107247
  const homePath = homePathFor(definition, homesRoot);
@@ -106966,7 +107312,7 @@ function humanHomes(scanned) {
106966
107312
  }));
106967
107313
  }
106968
107314
  function writeStationSnapshot(options) {
106969
- const repoRoot = resolve20(options.repoRoot ?? process.cwd());
107315
+ const repoRoot = resolve21(options.repoRoot ?? process.cwd());
106970
107316
  const { scanned, plans, totalBytes } = planStationSnapshot(options);
106971
107317
  const manifestFiles = plans.map((plan) => ({
106972
107318
  relativePath: plan.source.relativePath,
@@ -106992,9 +107338,9 @@ function writeStationSnapshot(options) {
106992
107338
  const conflicts = [];
106993
107339
  const untouched = [];
106994
107340
  for (const plan of plans) {
106995
- const destination = resolve20(repoRoot, plan.destination);
107341
+ const destination = resolve21(repoRoot, plan.destination);
106996
107342
  const destinationRelative = relative8(repoRoot, destination);
106997
- if (destinationRelative.startsWith("..") || destinationRelative.startsWith(sep9) || isAbsolute21(destinationRelative)) {
107343
+ if (destinationRelative.startsWith("..") || destinationRelative.startsWith(sep9) || isAbsolute22(destinationRelative)) {
106998
107344
  throw new StationSnapshotError("DESTINATION_ESCAPE", `destination escapes repo root: ${plan.destination}`);
106999
107345
  }
107000
107346
  let existingDigest = null;
@@ -107015,8 +107361,8 @@ function writeStationSnapshot(options) {
107015
107361
  }
107016
107362
  let written = 0;
107017
107363
  for (const plan of untouched) {
107018
- const destination = resolve20(repoRoot, plan.destination);
107019
- mkdirSync24(dirname26(destination), { recursive: true });
107364
+ const destination = resolve21(repoRoot, plan.destination);
107365
+ mkdirSync24(dirname27(destination), { recursive: true });
107020
107366
  copyFileSync(plan.source.fullPath, destination);
107021
107367
  written += 1;
107022
107368
  }
@@ -107034,8 +107380,8 @@ function writeStationSnapshot(options) {
107034
107380
  },
107035
107381
  files: manifestFiles
107036
107382
  };
107037
- const manifestPath = resolve20(repoRoot, "resources", options.stationId, "skills", "sync-manifest.json");
107038
- mkdirSync24(dirname26(manifestPath), { recursive: true });
107383
+ const manifestPath = resolve21(repoRoot, "resources", options.stationId, "skills", "sync-manifest.json");
107384
+ mkdirSync24(dirname27(manifestPath), { recursive: true });
107039
107385
  writeFileSync22(manifestPath, `${JSON.stringify(manifest, null, 2)}
107040
107386
  `);
107041
107387
  return {
@@ -107469,10 +107815,10 @@ var init_create_sync_config = __esm(() => {
107469
107815
  // src/lib/codex-hook-rpc.ts
107470
107816
  import { execFile, spawn as spawn3 } from "child_process";
107471
107817
  import { realpathSync as realpathSync11, statSync as statSync20 } from "fs";
107472
- import { isAbsolute as isAbsolute22 } from "path";
107818
+ import { isAbsolute as isAbsolute23 } from "path";
107473
107819
  import { promisify } from "util";
107474
107820
  async function connectCodexHookRpc(options) {
107475
- const found = isAbsolute22(options.command) ? options.command : Bun.which(options.command, { PATH: process.env.PATH });
107821
+ const found = isAbsolute23(options.command) ? options.command : Bun.which(options.command, { PATH: process.env.PATH });
107476
107822
  if (!found)
107477
107823
  throw new Error("CODEX_HOOK_TRUST_NATIVE_UNAVAILABLE: install Codex or pass --codex-command");
107478
107824
  const binary = realpathSync11(found), stat3 = statSync20(binary);
@@ -107558,13 +107904,13 @@ async function connectCodexHookRpc(options) {
107558
107904
  request(method2, params) {
107559
107905
  if (stopped)
107560
107906
  return Promise.reject(new Error("CODEX_HOOK_TRUST_NATIVE_RPC_CLOSED"));
107561
- return new Promise((resolve21, reject2) => {
107907
+ return new Promise((resolve22, reject2) => {
107562
107908
  const id2 = nextId++;
107563
107909
  const timer = setTimeout(() => {
107564
107910
  fail4();
107565
107911
  child.kill();
107566
107912
  }, 20000);
107567
- pending.set(id2, { resolve: resolve21, reject: reject2, timer });
107913
+ pending.set(id2, { resolve: resolve22, reject: reject2, timer });
107568
107914
  child.stdin.write(JSON.stringify({ id: id2, method: method2, params }) + `
107569
107915
  `);
107570
107916
  });
@@ -107574,14 +107920,14 @@ async function connectCodexHookRpc(options) {
107574
107920
  child.stdin.end();
107575
107921
  if (child.exitCode !== null || child.signalCode !== null)
107576
107922
  return;
107577
- await new Promise((resolve21) => {
107923
+ await new Promise((resolve22) => {
107578
107924
  const timer = setTimeout(() => {
107579
107925
  child.kill();
107580
- resolve21();
107926
+ resolve22();
107581
107927
  }, 1000);
107582
107928
  child.once("exit", () => {
107583
107929
  clearTimeout(timer);
107584
- resolve21();
107930
+ resolve22();
107585
107931
  });
107586
107932
  });
107587
107933
  }
@@ -107688,59 +108034,59 @@ var fail4 = () => new Error('CODEX_HOOK_TRUST_UNSUPPORTED_LAYOUT: preserve and c
107688
108034
  var init_codex_hook_trust_layout = () => {};
107689
108035
 
107690
108036
  // src/lib/codex-hook-trust-files.ts
107691
- import { closeSync as closeSync19, constants as constants18, fstatSync as fstatSync19, fsyncSync as fsyncSync6, lstatSync as lstatSync26, openSync as openSync19, readSync as readSync15, writeFileSync as writeFileSync23 } from "fs";
107692
- import { createHash as createHash24 } from "crypto";
107693
- import { dirname as dirname27 } from "path";
107694
- function need3(value, code2) {
108037
+ import { closeSync as closeSync20, constants as constants19, fstatSync as fstatSync20, fsyncSync as fsyncSync6, lstatSync as lstatSync27, openSync as openSync20, readSync as readSync16, writeFileSync as writeFileSync23 } from "fs";
108038
+ import { createHash as createHash25 } from "crypto";
108039
+ import { dirname as dirname28 } from "path";
108040
+ function need4(value, code2) {
107695
108041
  if (!value)
107696
108042
  throw new Error(`CODEX_HOOK_TRUST_${code2}`);
107697
108043
  }
107698
108044
  function safeParents(file2) {
107699
- for (let p = dirname27(file2);; p = dirname27(p)) {
107700
- const s = lstatSync26(p);
107701
- need3(s.isDirectory() && !s.isSymbolicLink(), "UNSAFE_PARENT");
107702
- need3((s.mode & 18) === 0 || s.uid === 0 && (s.mode & 512) !== 0, "UNSAFE_PARENT");
107703
- if (dirname27(p) === p)
108045
+ for (let p = dirname28(file2);; p = dirname28(p)) {
108046
+ const s = lstatSync27(p);
108047
+ need4(s.isDirectory() && !s.isSymbolicLink(), "UNSAFE_PARENT");
108048
+ need4((s.mode & 18) === 0 || s.uid === 0 && (s.mode & 512) !== 0, "UNSAFE_PARENT");
108049
+ if (dirname28(p) === p)
107704
108050
  break;
107705
108051
  }
107706
108052
  }
107707
108053
  function snapshot(file2, privateFile = false, options = {}) {
107708
108054
  const readOnlyPackage = options.readOnlyPackage === true && !privateFile;
107709
108055
  safeParents(file2);
107710
- const initial2 = lstatSync26(file2, { bigint: true });
107711
- need3(initial2.isFile() && initial2.uid === BigInt(process.getuid()) && (initial2.nlink === 1n || readOnlyPackage && initial2.nlink > 1n) && (initial2.mode & 0o022n) === 0n && (!privateFile || (initial2.mode & 0o777n) === 0o600n), "UNSAFE_FILE");
107712
- need3(initial2.size <= 8n * 1024n * 1024n, "FILE_BOUND");
107713
- const fd = openSync19(file2, constants18.O_RDONLY | constants18.O_NOFOLLOW | constants18.O_NONBLOCK);
108056
+ const initial2 = lstatSync27(file2, { bigint: true });
108057
+ need4(initial2.isFile() && initial2.uid === BigInt(process.getuid()) && (initial2.nlink === 1n || readOnlyPackage && initial2.nlink > 1n) && (initial2.mode & 0o022n) === 0n && (!privateFile || (initial2.mode & 0o777n) === 0o600n), "UNSAFE_FILE");
108058
+ need4(initial2.size <= 8n * 1024n * 1024n, "FILE_BOUND");
108059
+ const fd = openSync20(file2, constants19.O_RDONLY | constants19.O_NOFOLLOW | constants19.O_NONBLOCK);
107714
108060
  try {
107715
- const before2 = fstatSync19(fd, { bigint: true });
107716
- need3(sameStat(initial2, before2), "INPUT_CHANGED");
108061
+ const before2 = fstatSync20(fd, { bigint: true });
108062
+ need4(sameStat(initial2, before2), "INPUT_CHANGED");
107717
108063
  const bytes = Buffer.alloc(Number(before2.size) + 1);
107718
108064
  let length = 0;
107719
108065
  while (length < bytes.length) {
107720
- const n2 = readSync15(fd, bytes, length, bytes.length - length, null);
108066
+ const n2 = readSync16(fd, bytes, length, bytes.length - length, null);
107721
108067
  if (!n2)
107722
108068
  break;
107723
108069
  length += n2;
107724
108070
  }
107725
- need3(length === Number(before2.size) && sameStat(before2, fstatSync19(fd, { bigint: true })) && sameStat(before2, lstatSync26(file2, { bigint: true })), "INPUT_CHANGED");
108071
+ need4(length === Number(before2.size) && sameStat(before2, fstatSync20(fd, { bigint: true })) && sameStat(before2, lstatSync27(file2, { bigint: true })), "INPUT_CHANGED");
107726
108072
  const content = bytes.subarray(0, length), text3 = new TextDecoder("utf-8", { fatal: true }).decode(content);
107727
- return { file: file2, privateFile, readOnlyPackage, text: text3, bytes: content, stat: before2, sha256: createHash24("sha256").update(content).digest("hex") };
108073
+ return { file: file2, privateFile, readOnlyPackage, text: text3, bytes: content, stat: before2, sha256: createHash25("sha256").update(content).digest("hex") };
107728
108074
  } finally {
107729
- closeSync19(fd);
108075
+ closeSync20(fd);
107730
108076
  }
107731
108077
  }
107732
108078
  function unchanged2(before2) {
107733
108079
  const after2 = snapshot(before2.file, before2.privateFile, before2.readOnlyPackage ? { readOnlyPackage: true } : {});
107734
- need3(sameStat(before2.stat, after2.stat) && after2.sha256 === before2.sha256, "INPUT_CHANGED");
108080
+ need4(sameStat(before2.stat, after2.stat) && after2.sha256 === before2.sha256, "INPUT_CHANGED");
107735
108081
  }
107736
108082
  function save2(file2, content) {
107737
108083
  safeParents(file2);
107738
- const fd = openSync19(file2, constants18.O_WRONLY | constants18.O_CREAT | constants18.O_EXCL | constants18.O_NOFOLLOW, 384);
108084
+ const fd = openSync20(file2, constants19.O_WRONLY | constants19.O_CREAT | constants19.O_EXCL | constants19.O_NOFOLLOW, 384);
107739
108085
  try {
107740
108086
  writeFileSync23(fd, content);
107741
108087
  fsyncSync6(fd);
107742
108088
  } finally {
107743
- closeSync19(fd);
108089
+ closeSync20(fd);
107744
108090
  }
107745
108091
  }
107746
108092
  var sameStat = (a, b) => ["dev", "ino", "uid", "nlink", "mode", "size", "mtimeNs", "ctimeNs"].every((key) => a[key] === b[key]);
@@ -107748,26 +108094,26 @@ var init_codex_hook_trust_files = () => {};
107748
108094
 
107749
108095
  // src/lib/codex-hook-trust-identity.ts
107750
108096
  import { realpathSync as realpathSync12 } from "fs";
107751
- import { dirname as dirname28, isAbsolute as isAbsolute23, join as join55 } from "path";
108097
+ import { dirname as dirname29, isAbsolute as isAbsolute24, join as join55 } from "path";
107752
108098
  function bindSkillsCli(command, reviewed) {
107753
108099
  const normal = Bun.which("skills", { PATH: process.env.PATH });
107754
- need3(normal, "SKILLS_COMMAND_UNAVAILABLE");
108100
+ need4(normal, "SKILLS_COMMAND_UNAVAILABLE");
107755
108101
  const resolved = realpathSync12(normal);
107756
- const bound = isAbsolute23(command) ? command : command === "skills" ? normal : undefined;
107757
- need3(bound && realpathSync12(bound) === resolved, "SKILLS_COMMAND_MISMATCH");
108102
+ const bound = isAbsolute24(command) ? command : command === "skills" ? normal : undefined;
108103
+ need4(bound && realpathSync12(bound) === resolved, "SKILLS_COMMAND_MISMATCH");
107758
108104
  const entrypoint = reviewed?.path ?? process.argv[1];
107759
- need3(entrypoint && realpathSync12(entrypoint) === resolved, "SKILLS_ENTRYPOINT_MISMATCH");
108105
+ need4(entrypoint && realpathSync12(entrypoint) === resolved, "SKILLS_ENTRYPOINT_MISMATCH");
107760
108106
  const cli = snapshot(resolved, false, { readOnlyPackage: true });
107761
- const manifest = snapshot(join55(dirname28(dirname28(resolved)), "package.json"), false, { readOnlyPackage: true });
108107
+ const manifest = snapshot(join55(dirname29(dirname29(resolved)), "package.json"), false, { readOnlyPackage: true });
107762
108108
  const pkg = JSON.parse(manifest.text);
107763
- need3(pkg.name === "@hasna/skills" && /^\d+\.\d+\.\d+$/.test(pkg.version) && pkg.bin?.skills === "bin/index.js" && resolved === join55(dirname28(manifest.file), "bin/index.js"), "SKILLS_PACKAGE_MISMATCH");
108109
+ need4(pkg.name === "@hasna/skills" && /^\d+\.\d+\.\d+$/.test(pkg.version) && pkg.bin?.skills === "bin/index.js" && resolved === join55(dirname29(manifest.file), "bin/index.js"), "SKILLS_PACKAGE_MISMATCH");
107764
108110
  if (reviewed)
107765
- need3(/^[a-f0-9]{64}$/.test(reviewed.sha256) && reviewed.sha256 === cli.sha256 && reviewed.version === pkg.version, "SKILLS_RELEASE_MISMATCH");
107766
- need3((cli.stat.mode & 0o100n) !== 0n, "SKILLS_COMMAND_NOT_EXECUTABLE");
108111
+ need4(/^[a-f0-9]{64}$/.test(reviewed.sha256) && reviewed.sha256 === cli.sha256 && reviewed.version === pkg.version, "SKILLS_RELEASE_MISMATCH");
108112
+ need4((cli.stat.mode & 0o100n) !== 0n, "SKILLS_COMMAND_NOT_EXECUTABLE");
107767
108113
  return {
107768
108114
  receipt: { path: resolved, version: pkg.version, sha256: cli.sha256, manifestSha256: manifest.sha256 },
107769
108115
  recheck() {
107770
- need3(Bun.which("skills", { PATH: process.env.PATH }) === normal && realpathSync12(normal) === resolved && realpathSync12(bound) === resolved && realpathSync12(entrypoint) === resolved, "SKILLS_COMMAND_CHANGED");
108116
+ need4(Bun.which("skills", { PATH: process.env.PATH }) === normal && realpathSync12(normal) === resolved && realpathSync12(bound) === resolved && realpathSync12(entrypoint) === resolved, "SKILLS_COMMAND_CHANGED");
107771
108117
  unchanged2(cli);
107772
108118
  unchanged2(manifest);
107773
108119
  }
@@ -107778,15 +108124,15 @@ var init_codex_hook_trust_identity = __esm(() => {
107778
108124
  });
107779
108125
 
107780
108126
  // src/lib/agent-codex-trust.ts
107781
- import { lstatSync as lstatSync27, mkdirSync as mkdirSync25, readdirSync as readdirSync20 } from "fs";
107782
- import { createHash as createHash25, randomUUID as randomUUID10 } from "crypto";
107783
- import { join as join56, resolve as resolve21 } from "path";
108127
+ import { lstatSync as lstatSync28, mkdirSync as mkdirSync25, readdirSync as readdirSync20 } from "fs";
108128
+ import { createHash as createHash26, randomUUID as randomUUID10 } from "crypto";
108129
+ import { join as join56, resolve as resolve22 } from "path";
107784
108130
  import { homedir as homedir11 } from "os";
107785
108131
  import { isDeepStrictEqual as isDeepStrictEqual6 } from "util";
107786
108132
  async function enrollCodexNativeHooks(options = {}, connect = connectCodexHookRpc) {
107787
108133
  let rpc, journal;
107788
108134
  try {
107789
- const home = resolve21(options.home ?? homedir11()), dataDir3 = resolve21(options.dataDir ?? getDataDirReadOnly());
108135
+ const home = resolve22(options.home ?? homedir11()), dataDir3 = resolve22(options.dataDir ?? getDataDirReadOnly());
107790
108136
  assertManagedAgentBridge("codex", { home, dataDir: dataDir3, projectDir: home });
107791
108137
  const policyFile = snapshot(join56(dataDir3, "agent-policy.json"), true), policy = parseManagedSkillPolicy(policyFile.text);
107792
108138
  const binding = policy.bridge, alias = binding.rootAliases?.find((item) => item.agent === "codex");
@@ -107797,35 +108143,35 @@ async function enrollCodexNativeHooks(options = {}, connect = connectCodexHookRp
107797
108143
  for (const [event, [nativeEvent, label]] of Object.entries(eventNames)) {
107798
108144
  const command = renderAgentHookCommand(binding.commands.codex, "codex", binding.profiles.codex, event);
107799
108145
  const groups = declarations[event];
107800
- need3(Array.isArray(groups), "DECLARATION_CHANGED");
108146
+ need4(Array.isArray(groups), "DECLARATION_CHANGED");
107801
108147
  const matches2 = groups.flatMap((group, gi) => (group.hooks ?? []).flatMap((entry, hi) => entry.command === command ? [{ group, entry, gi, hi }] : []));
107802
- need3(matches2.length === 1 && isDeepStrictEqual6(matches2[0].group, { hooks: [{ type: "command", command, timeout: 15 }] }), "DECLARATION_CHANGED");
108148
+ need4(matches2.length === 1 && isDeepStrictEqual6(matches2[0].group, { hooks: [{ type: "command", command, timeout: 15 }] }), "DECLARATION_CHANGED");
107803
108149
  expected.push({ event: nativeEvent, key: `${join56(home, ".codex/hooks.json")}:${label}:${matches2[0].gi}:${matches2[0].hi}`, command });
107804
108150
  }
107805
108151
  codexTrustTextWitness(configFile.text, expected.map((h) => h.key));
107806
108152
  rpc = await connect({ command: options.codexCommand ?? "codex", home, codexHome });
107807
- need3(SUPPORTED_CODEX_HOOK_VERSIONS.includes(rpc.version), "NATIVE_UNSUPPORTED_VERSION");
108153
+ need4(SUPPORTED_CODEX_HOOK_VERSIONS.includes(rpc.version), "NATIVE_UNSUPPORTED_VERSION");
107808
108154
  const list2 = async () => {
107809
108155
  const response = await rpc.request("hooks/list", { cwds: [home] });
107810
- need3(Array.isArray(response?.data) && response.data.length === 1 && response.data[0].cwd === home && Array.isArray(response.data[0].hooks) && response.data[0].hooks.length <= 1e4 && !response.data[0].errors?.length && !response.data[0].warnings?.length, "NATIVE_DISCOVERY_REFUSED");
108156
+ need4(Array.isArray(response?.data) && response.data.length === 1 && response.data[0].cwd === home && Array.isArray(response.data[0].hooks) && response.data[0].hooks.length <= 1e4 && !response.data[0].errors?.length && !response.data[0].warnings?.length, "NATIVE_DISCOVERY_REFUSED");
107811
108157
  return response.data[0].hooks;
107812
108158
  };
107813
108159
  const admit = (hooks) => expected.map((wanted) => {
107814
108160
  const canonicalKey = wanted.key.replace(join56(home, ".codex/hooks.json"), hooksPath);
107815
108161
  const matches2 = hooks.filter((h2) => h2.key === wanted.key || h2.key === canonicalKey);
107816
- need3(matches2.length === 1, "AMBIGUOUS_IDENTITY");
108162
+ need4(matches2.length === 1, "AMBIGUOUS_IDENTITY");
107817
108163
  const h = matches2[0];
107818
- need3(h.eventName === wanted.event && h.handlerType === "command" && h.command === wanted.command && h.matcher === null && h.timeoutSec === 15 && h.async === false && h.statusMessage === null && h.additionalContextLimit === null && [hooksPath, join56(home, ".codex/hooks.json")].includes(h.sourcePath) && h.source === "user" && h.pluginId === null && h.isManaged === false && /^sha256:[a-f0-9]{64}$/.test(h.currentHash) && typeof h.enabled === "boolean", "NATIVE_IDENTITY_CHANGED");
107819
- need3(hooks.filter((other) => other.command === wanted.command).length === 1, "AMBIGUOUS_IDENTITY");
107820
- need3(["trusted", "untrusted", "modified"].includes(h.trustStatus), "UNKNOWN_TRUST_STATUS");
108164
+ need4(h.eventName === wanted.event && h.handlerType === "command" && h.command === wanted.command && h.matcher === null && h.timeoutSec === 15 && h.async === false && h.statusMessage === null && h.additionalContextLimit === null && [hooksPath, join56(home, ".codex/hooks.json")].includes(h.sourcePath) && h.source === "user" && h.pluginId === null && h.isManaged === false && /^sha256:[a-f0-9]{64}$/.test(h.currentHash) && typeof h.enabled === "boolean", "NATIVE_IDENTITY_CHANGED");
108165
+ need4(hooks.filter((other) => other.command === wanted.command).length === 1, "AMBIGUOUS_IDENTITY");
108166
+ need4(["trusted", "untrusted", "modified"].includes(h.trustStatus), "UNKNOWN_TRUST_STATUS");
107821
108167
  return { key: h.key, event: wanted.event, command: wanted.command, handlerType: h.handlerType, timeoutSec: h.timeoutSec, sourcePath: h.sourcePath, currentHash: h.currentHash, enabled: h.enabled, trustStatus: h.trustStatus };
107822
108168
  });
107823
108169
  const discovered = await list2(), admitted = admit(discovered);
107824
108170
  const config2 = await rpc.request("config/read", { includeLayers: true, cwd: home });
107825
108171
  const layers = config2?.layers?.filter((layer) => layer.name?.type === "user" && layer.name.file === configPath && !layer.name.profile);
107826
- need3(layers?.length === 1 && /^sha256:[a-f0-9]{64}$/.test(layers[0].version) && !layers[0].disabledReason && isDeepStrictEqual6(layers[0].config, original), "NATIVE_CONFIG_MISMATCH");
107827
- need3(config2.config && config2.config.features?.hooks !== false, "NATIVE_HOOKS_DISABLED");
107828
- need3(config2.layers.slice(0, config2.layers.indexOf(layers[0])).every((layer) => layer.config?.hooks === undefined && layer.config?.features?.hooks === undefined), "NATIVE_CONFIG_OVERRIDDEN");
108172
+ need4(layers?.length === 1 && /^sha256:[a-f0-9]{64}$/.test(layers[0].version) && !layers[0].disabledReason && isDeepStrictEqual6(layers[0].config, original), "NATIVE_CONFIG_MISMATCH");
108173
+ need4(config2.config && config2.config.features?.hooks !== false, "NATIVE_HOOKS_DISABLED");
108174
+ need4(config2.layers.slice(0, config2.layers.indexOf(layers[0])).every((layer) => layer.config?.hooks === undefined && layer.config?.features?.hooks === undefined), "NATIVE_CONFIG_OVERRIDDEN");
107829
108175
  const keys3 = admitted.map((h) => h.key), planned = admitted.filter((h) => !h.enabled || h.trustStatus !== "trusted");
107830
108176
  const preservationText = codexTrustTextWitness(configFile.text, keys3);
107831
108177
  const checkInputs = () => {
@@ -107836,19 +108182,19 @@ async function enrollCodexNativeHooks(options = {}, connect = connectCodexHookRp
107836
108182
  unchanged2(configFile);
107837
108183
  };
107838
108184
  checkInputs();
107839
- const planDigest = createHash25("sha256").update(json2({ version: 1, home, configPath, configSha256: configFile.sha256, configVersion: layers[0].version, policySha256: policyFile.sha256, hooksSha256: hooksFile.sha256, skillsCli: skillsCli.receipt, nativeVersion: rpc.version, declarations: expected, admitted })).digest("hex");
108185
+ const planDigest = createHash26("sha256").update(json2({ version: 1, home, configPath, configSha256: configFile.sha256, configVersion: layers[0].version, policySha256: policyFile.sha256, hooksSha256: hooksFile.sha256, skillsCli: skillsCli.receipt, nativeVersion: rpc.version, declarations: expected, admitted })).digest("hex");
107840
108186
  const baseReceipt = { planDigest, skillsCli: skillsCli.receipt, nativeVersion: rpc.version, ownedNativeProcessId: rpc.processId, agent: "codex", applied: false, planned, nativeEligible: planned.length === 0, transport: "owned-stdio-process", existingSessionsReloaded: false, nativeExecutionVerified: false };
107841
108187
  if (options.apply)
107842
- need3(options.reviewedPlanDigest === planDigest, "PLAN_CHANGED: run the dry-run again and pass its reviewed --plan-digest with --apply");
108188
+ need4(options.reviewedPlanDigest === planDigest, "PLAN_CHANGED: run the dry-run again and pass its reviewed --plan-digest with --apply");
107843
108189
  const parent = join56(dataDir3, "native-hook-trust");
107844
- const st = lstatSync27(parent, { throwIfNoEntry: false });
108190
+ const st = lstatSync28(parent, { throwIfNoEntry: false });
107845
108191
  if (st) {
107846
- need3(st.isDirectory() && !st.isSymbolicLink() && st.uid === process.getuid() && (st.mode & 511) === 448, "UNSAFE_JOURNAL");
108192
+ need4(st.isDirectory() && !st.isSymbolicLink() && st.uid === process.getuid() && (st.mode & 511) === 448, "UNSAFE_JOURNAL");
107847
108193
  const priorJournals = readdirSync20(parent);
107848
- need3(priorJournals.length < 1000, "JOURNAL_BOUND");
108194
+ need4(priorJournals.length < 1000, "JOURNAL_BOUND");
107849
108195
  for (const name of priorJournals) {
107850
- need3(/^[a-f0-9-]{36}$/.test(name), "UNSAFE_JOURNAL");
107851
- need3(lstatSync27(join56(parent, name, "receipt.json"), { throwIfNoEntry: false })?.isFile(), "RECONCILE_REQUIRED: inspect the incomplete private journal before applying again");
108196
+ need4(/^[a-f0-9-]{36}$/.test(name), "UNSAFE_JOURNAL");
108197
+ need4(lstatSync28(join56(parent, name, "receipt.json"), { throwIfNoEntry: false })?.isFile(), "RECONCILE_REQUIRED: inspect the incomplete private journal before applying again");
107852
108198
  }
107853
108199
  }
107854
108200
  if (!options.apply || !planned.length)
@@ -107861,7 +108207,7 @@ async function enrollCodexNativeHooks(options = {}, connect = connectCodexHookRp
107861
108207
  save2(join56(journal, "hooks.before.json"), hooksFile.bytes);
107862
108208
  save2(join56(journal, "policy.before.json"), policyFile.bytes);
107863
108209
  save2(join56(journal, "intent.json"), json2({ version: 1, planDigest, skillsCli: skillsCli.receipt, nativeVersion: rpc.version, configPath, beforeSha256: configFile.sha256, hooksSha256: hooksFile.sha256, policySha256: policyFile.sha256, expectedVersion: layers[0].version, hooks: planned }));
107864
- need3(isDeepStrictEqual6(admit(await list2()), admitted), "NATIVE_DISCOVERY_CHANGED");
108210
+ need4(isDeepStrictEqual6(admit(await list2()), admitted), "NATIVE_DISCOVERY_CHANGED");
107865
108211
  checkInputs();
107866
108212
  let result2;
107867
108213
  try {
@@ -107869,19 +108215,19 @@ async function enrollCodexNativeHooks(options = {}, connect = connectCodexHookRp
107869
108215
  } catch {
107870
108216
  throw new Error("CODEX_HOOK_TRUST_NATIVE_WRITE_FAILED: reconcile the private journal before retrying");
107871
108217
  }
107872
- need3(result2?.status === "ok" && result2.filePath === configPath && /^sha256:[a-f0-9]{64}$/.test(result2.version), "NATIVE_WRITE_OVERRIDDEN");
108218
+ need4(result2?.status === "ok" && result2.filePath === configPath && /^sha256:[a-f0-9]{64}$/.test(result2.version), "NATIVE_WRITE_OVERRIDDEN");
107873
108219
  const after2 = snapshot(configPath, true), expectedConfig = structuredClone(original);
107874
108220
  expectedConfig.hooks ??= {};
107875
108221
  expectedConfig.hooks.state ??= {};
107876
108222
  for (const h of planned)
107877
108223
  expectedConfig.hooks.state[h.key] = { ...expectedConfig.hooks.state[h.key], enabled: true, trusted_hash: h.currentHash };
107878
- need3(isDeepStrictEqual6(structure(after2.text), expectedConfig) && codexTrustTextWitness(after2.text, keys3) === preservationText, "PRESERVATION_FAILED");
108224
+ need4(isDeepStrictEqual6(structure(after2.text), expectedConfig) && codexTrustTextWitness(after2.text, keys3) === preservationText, "PRESERVATION_FAILED");
107879
108225
  unchanged2(policyFile);
107880
108226
  unchanged2(hooksFile);
107881
108227
  assertManagedAgentBridge("codex", { home, dataDir: dataDir3, projectDir: home });
107882
108228
  const current = await list2(), confirmed = admit(current);
107883
- need3(confirmed.every((h) => h.enabled && h.trustStatus === "trusted") && isDeepStrictEqual6(confirmed.map((h) => [h.key, h.currentHash]), admitted.map((h) => [h.key, h.currentHash])), "NATIVE_NOT_ELIGIBLE");
107884
- need3(isDeepStrictEqual6(current.filter((h) => !keys3.includes(h.key)), discovered.filter((h) => !keys3.includes(h.key))), "UNRELATED_HOOK_CHANGED");
108229
+ need4(confirmed.every((h) => h.enabled && h.trustStatus === "trusted") && isDeepStrictEqual6(confirmed.map((h) => [h.key, h.currentHash]), admitted.map((h) => [h.key, h.currentHash])), "NATIVE_NOT_ELIGIBLE");
108230
+ need4(isDeepStrictEqual6(current.filter((h) => !keys3.includes(h.key)), discovered.filter((h) => !keys3.includes(h.key))), "UNRELATED_HOOK_CHANGED");
107885
108231
  unchanged2(after2);
107886
108232
  unchanged2(hooksFile);
107887
108233
  unchanged2(policyFile);
@@ -107996,7 +108342,7 @@ __export(exports_agent_integration, {
107996
108342
  registerAgentIntegration: () => registerAgentIntegration
107997
108343
  });
107998
108344
  import { readFileSync as readFileSync37 } from "fs";
107999
- import { isAbsolute as isAbsolute24 } from "path";
108345
+ import { isAbsolute as isAbsolute25 } from "path";
108000
108346
  function pinnedHookProfile(input3, configuredProfile) {
108001
108347
  try {
108002
108348
  const parsed = parseSkillContextInput(JSON.stringify(input3));
@@ -108114,12 +108460,12 @@ function registerAgentIntegration(parent) {
108114
108460
  input3.hook_event_name = event;
108115
108461
  const projects = [process.cwd()];
108116
108462
  if (input3.cwd !== undefined) {
108117
- if (typeof input3.cwd !== "string" || !isAbsolute24(input3.cwd) || input3.cwd.includes("\x00"))
108463
+ if (typeof input3.cwd !== "string" || !isAbsolute25(input3.cwd) || input3.cwd.includes("\x00"))
108118
108464
  throw new Error("Invalid native hook working directory");
108119
108465
  projects.push(input3.cwd);
108120
108466
  }
108121
108467
  if (options.agent === "cursor") {
108122
- if (!Array.isArray(input3.workspace_roots) || input3.workspace_roots.length > 32 || input3.workspace_roots.some((path) => typeof path !== "string" || !isAbsolute24(path) || path.includes("\x00")))
108468
+ if (!Array.isArray(input3.workspace_roots) || input3.workspace_roots.length > 32 || input3.workspace_roots.some((path) => typeof path !== "string" || !isAbsolute25(path) || path.includes("\x00")))
108123
108469
  throw new Error("Invalid Cursor workspace roots");
108124
108470
  projects.push(...input3.workspace_roots);
108125
108471
  input3.cwd ??= input3.workspace_roots[0] ?? process.cwd();
@@ -108357,17 +108703,17 @@ var exports_profiles = {};
108357
108703
  __export(exports_profiles, {
108358
108704
  registerProfiles: () => registerProfiles
108359
108705
  });
108360
- import { closeSync as closeSync20, constants as constants19, fstatSync as fstatSync20, openSync as openSync20, readSync as readSync16, writeFileSync as writeFileSync24 } from "fs";
108706
+ import { closeSync as closeSync21, constants as constants20, fstatSync as fstatSync21, openSync as openSync21, readSync as readSync17, writeFileSync as writeFileSync24 } from "fs";
108361
108707
  function readProfileInput(path) {
108362
- const fd = openSync20(path, constants19.O_RDONLY | constants19.O_NONBLOCK);
108708
+ const fd = openSync21(path, constants20.O_RDONLY | constants20.O_NONBLOCK);
108363
108709
  try {
108364
- const stat3 = fstatSync20(fd);
108710
+ const stat3 = fstatSync21(fd);
108365
108711
  if (!stat3.isFile() || stat3.size > MAX_PROFILE_DOCUMENT_BYTES)
108366
108712
  throw new Error("Profile input exceeds the size limit or is not a regular file");
108367
108713
  const bytes = Buffer.alloc(MAX_PROFILE_DOCUMENT_BYTES + 1);
108368
108714
  let size2 = 0;
108369
108715
  while (size2 < bytes.length) {
108370
- const read3 = readSync16(fd, bytes, size2, bytes.length - size2, null);
108716
+ const read3 = readSync17(fd, bytes, size2, bytes.length - size2, null);
108371
108717
  if (!read3)
108372
108718
  break;
108373
108719
  size2 += read3;
@@ -108376,7 +108722,7 @@ function readProfileInput(path) {
108376
108722
  throw new Error("Profile input exceeds the size limit");
108377
108723
  return new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(0, size2));
108378
108724
  } finally {
108379
- closeSync20(fd);
108725
+ closeSync21(fd);
108380
108726
  }
108381
108727
  }
108382
108728
  function registerProfiles(parent) {
@@ -108427,23 +108773,23 @@ __export(exports_grants, {
108427
108773
  registerGrants: () => registerGrants
108428
108774
  });
108429
108775
  import {
108430
- constants as constants20,
108431
- closeSync as closeSync21,
108432
- fstatSync as fstatSync21,
108433
- openSync as openSync21,
108434
- readSync as readSync17,
108776
+ constants as constants21,
108777
+ closeSync as closeSync23,
108778
+ fstatSync as fstatSync23,
108779
+ openSync as openSync23,
108780
+ readSync as readSync18,
108435
108781
  writeFileSync as writeFileSync25
108436
108782
  } from "fs";
108437
108783
  function readInput(path) {
108438
- const fd = openSync21(path, constants20.O_RDONLY | constants20.O_NONBLOCK);
108784
+ const fd = openSync23(path, constants21.O_RDONLY | constants21.O_NONBLOCK);
108439
108785
  try {
108440
- const stat3 = fstatSync21(fd);
108786
+ const stat3 = fstatSync23(fd);
108441
108787
  if (!stat3.isFile() || stat3.size > MAX_EXECUTION_GRANT_BYTES)
108442
108788
  throw new Error("Grant input must be a regular file within the policy size limit.");
108443
108789
  const bytes = Buffer.alloc(MAX_EXECUTION_GRANT_BYTES + 1);
108444
108790
  let size2 = 0;
108445
108791
  while (size2 < bytes.length) {
108446
- const count = readSync17(fd, bytes, size2, bytes.length - size2, null);
108792
+ const count = readSync18(fd, bytes, size2, bytes.length - size2, null);
108447
108793
  if (!count)
108448
108794
  break;
108449
108795
  size2 += count;
@@ -108456,7 +108802,7 @@ function readInput(path) {
108456
108802
  throw new Error("Grant input must be a JSON document containing a grants array.");
108457
108803
  }
108458
108804
  } finally {
108459
- closeSync21(fd);
108805
+ closeSync23(fd);
108460
108806
  }
108461
108807
  }
108462
108808
  function registerGrants(parent) {
@@ -108492,7 +108838,7 @@ var init_grants = __esm(() => {
108492
108838
  });
108493
108839
 
108494
108840
  // src/lib/station-hydrate.ts
108495
- import { createHash as createHash26 } from "crypto";
108841
+ import { createHash as createHash27 } from "crypto";
108496
108842
  import {
108497
108843
  copyFileSync as copyFileSync2,
108498
108844
  mkdirSync as mkdirSync26,
@@ -108501,7 +108847,7 @@ import {
108501
108847
  statSync as statSync21,
108502
108848
  writeFileSync as writeFileSync26
108503
108849
  } from "fs";
108504
- import { dirname as dirname29, join as join57, resolve as resolve22, sep as sep10 } from "path";
108850
+ import { dirname as dirname30, join as join57, resolve as resolve23, sep as sep10 } from "path";
108505
108851
  function fail5(code2, message, detail = []) {
108506
108852
  throw new StationSnapshotError(code2, message, detail);
108507
108853
  }
@@ -108695,12 +109041,12 @@ function skillSha256(skill) {
108695
109041
  return sha256File(skill.files[0].winner.fullPath);
108696
109042
  }
108697
109043
  const joined = skill.files.map((file2) => sha256File(file2.winner.fullPath));
108698
- return createHash26("sha256").update(joined.sort().join(`
109044
+ return createHash27("sha256").update(joined.sort().join(`
108699
109045
  `)).digest("hex");
108700
109046
  }
108701
109047
  function writeStationHydration(options) {
108702
- const repoRoot = resolve22(options.repoRoot ?? process.cwd());
108703
- const cacheRoot = resolve22(options.cacheRoot ?? resolveCorpusRoot());
109048
+ const repoRoot = resolve23(options.repoRoot ?? process.cwd());
109049
+ const cacheRoot = resolve23(options.cacheRoot ?? resolveCorpusRoot());
108704
109050
  const plan = planStationHydration(options.stationId, repoRoot);
108705
109051
  const resultSkills = plan.winners.map((skill) => ({
108706
109052
  ident: skill.ident,
@@ -108754,7 +109100,7 @@ function writeStationHydration(options) {
108754
109100
  }
108755
109101
  let written = 0;
108756
109102
  for (const entry of toWrite) {
108757
- mkdirSync26(dirname29(entry.destination), { recursive: true });
109103
+ mkdirSync26(dirname30(entry.destination), { recursive: true });
108758
109104
  copyFileSync2(entry.fullPath, entry.destination);
108759
109105
  written += 1;
108760
109106
  }
@@ -108775,8 +109121,8 @@ function writeStationHydration(options) {
108775
109121
  },
108776
109122
  skills: resultSkills
108777
109123
  };
108778
- const hydrationManifestPath = join57(dirname29(cacheRoot), `hydration-${options.stationId}.json`);
108779
- mkdirSync26(dirname29(hydrationManifestPath), { recursive: true });
109124
+ const hydrationManifestPath = join57(dirname30(cacheRoot), `hydration-${options.stationId}.json`);
109125
+ mkdirSync26(dirname30(hydrationManifestPath), { recursive: true });
108780
109126
  writeFileSync26(hydrationManifestPath, `${JSON.stringify(hydration, null, 2)}
108781
109127
  `);
108782
109128
  return {
@@ -108852,10 +109198,10 @@ var init_hydrate = __esm(() => {
108852
109198
  });
108853
109199
 
108854
109200
  // src/lib/prepare-skill.ts
108855
- import { createHash as createHash27, randomUUID as randomUUID11 } from "crypto";
108856
- import { chmodSync as chmodSync3, existsSync as existsSync34, lstatSync as lstatSync28, mkdirSync as mkdirSync27, mkdtempSync as mkdtempSync6, readFileSync as readFileSync39, readdirSync as readdirSync22, renameSync as renameSync12, rmSync as rmSync9, writeFileSync as writeFileSync27 } from "fs";
109201
+ import { createHash as createHash28, randomUUID as randomUUID11 } from "crypto";
109202
+ import { chmodSync as chmodSync3, existsSync as existsSync34, lstatSync as lstatSync29, mkdirSync as mkdirSync27, mkdtempSync as mkdtempSync6, readFileSync as readFileSync39, readdirSync as readdirSync22, renameSync as renameSync12, rmSync as rmSync9, writeFileSync as writeFileSync27 } from "fs";
108857
109203
  import { tmpdir as tmpdir2 } from "os";
108858
- import { dirname as dirname30, isAbsolute as isAbsolute25, join as join58, relative as relative9, resolve as resolve23, sep as sep11 } from "path";
109204
+ import { dirname as dirname31, isAbsolute as isAbsolute26, join as join58, relative as relative9, resolve as resolve24, sep as sep11 } from "path";
108859
109205
  function prepareSkill(name, options) {
108860
109206
  const normalized = normalizePortableSkillName(name);
108861
109207
  if (!new RegExp(SEMVER_PATTERN).test(options.version))
@@ -108900,7 +109246,7 @@ function prepareSkill(name, options) {
108900
109246
  mkdirSync27(join58(staging, directory2), { recursive: true });
108901
109247
  for (const file2 of before2.files) {
108902
109248
  const destination = join58(staging, file2.path);
108903
- mkdirSync27(dirname30(destination), { recursive: true });
109249
+ mkdirSync27(dirname31(destination), { recursive: true });
108904
109250
  writeFileSync27(destination, file2.bytes, { mode: file2.mode });
108905
109251
  }
108906
109252
  const stagedManifest = join58(staging, "skill.json");
@@ -108960,8 +109306,8 @@ function validateRuntimeEntrypoint(candidate2, root2) {
108960
109306
  const entry = candidate2.runtime.entrypoint;
108961
109307
  if (typeof entry !== "string")
108962
109308
  return;
108963
- const target = resolve23(root2, entry), rel = relative9(root2, target);
108964
- if (isAbsolute25(entry) || /^[a-zA-Z]:/.test(entry) || entry.includes("\\") || !rel || rel === ".." || rel.startsWith(`..${sep11}`) || isAbsolute25(rel) || !existsSync34(target) || !lstatSync28(target).isFile()) {
109309
+ const target = resolve24(root2, entry), rel = relative9(root2, target);
109310
+ if (isAbsolute26(entry) || /^[a-zA-Z]:/.test(entry) || entry.includes("\\") || !rel || rel === ".." || rel.startsWith(`..${sep11}`) || isAbsolute26(rel) || !existsSync34(target) || !lstatSync29(target).isFile()) {
108965
109311
  throw new Error("Executable runtime.entrypoint must name an existing regular file inside the skill directory.");
108966
109312
  }
108967
109313
  }
@@ -108982,6 +109328,7 @@ function validateRawCandidate(candidate2) {
108982
109328
  const issues = validatePortableManifestContract(candidate2, { strict: true });
108983
109329
  if (issues.length)
108984
109330
  throw new Error(`Invalid skill.json: ${issues.map((issue2) => issue2.code).join(", ")}`);
109331
+ validateRuntimeEntrypointCompatibility(candidate2);
108985
109332
  for (const field2 of ["inputs", "commands"]) {
108986
109333
  const items = candidate2[field2];
108987
109334
  if (items === undefined)
@@ -109007,6 +109354,18 @@ function validateRawCandidate(candidate2) {
109007
109354
  }
109008
109355
  }
109009
109356
  }
109357
+ function validateRuntimeEntrypointCompatibility(candidate2) {
109358
+ if (candidate2.kind !== "executable" || !isRecord6(candidate2.runtime))
109359
+ return;
109360
+ const runtime = candidate2.runtime.runtime;
109361
+ const entrypoint = candidate2.runtime.entrypoint;
109362
+ if (typeof runtime !== "string" || typeof entrypoint !== "string")
109363
+ return;
109364
+ const extension = entrypoint.toLowerCase().split(".").pop();
109365
+ if (extension === "py" && runtime !== "python3") {
109366
+ throw new Error("Invalid skill.json: runtime.entrypoint with .py extension requires runtime python3.");
109367
+ }
109368
+ }
109010
109369
  function compareVersions(left, right) {
109011
109370
  const parts = (value) => value.split("+")[0].split(/-(.*)/s).slice(0, 2);
109012
109371
  const [a, ap] = parts(left), [b, bp] = parts(right);
@@ -109033,11 +109392,11 @@ function compareVersions(left, right) {
109033
109392
  return 0;
109034
109393
  }
109035
109394
  function snapshot2(root2) {
109036
- const rootStat = lstatSync28(root2);
109395
+ const rootStat = lstatSync29(root2);
109037
109396
  if (rootStat.isSymbolicLink() || !rootStat.isDirectory())
109038
109397
  throw new Error("Skill root must be a real directory, not a symlink.");
109039
109398
  const files = [], directories = [];
109040
- const hash4 = createHash27("sha256").update(`${rootStat.dev}:${rootStat.ino}\x00`);
109399
+ const hash4 = createHash28("sha256").update(`${rootStat.dev}:${rootStat.ino}\x00`);
109041
109400
  let count = 0, bytes = 0;
109042
109401
  const walk2 = (relative10) => {
109043
109402
  for (const name of readdirSync22(join58(root2, relative10)).sort()) {
@@ -109046,7 +109405,7 @@ function snapshot2(root2) {
109046
109405
  const path = relative10 ? `${relative10}/${name}` : name;
109047
109406
  if (++count > 20000)
109048
109407
  throw new Error("Skill exceeds the preparation entry limit (20000).");
109049
- const absolute = join58(root2, path), stat3 = lstatSync28(absolute);
109408
+ const absolute = join58(root2, path), stat3 = lstatSync29(absolute);
109050
109409
  if (stat3.isSymbolicLink())
109051
109410
  throw new Error(`Skill contains a symlink: ${path}. No files were changed.`);
109052
109411
  if (stat3.isDirectory() && name === "node_modules")
@@ -109461,7 +109820,7 @@ var init_schedule = __esm(() => {
109461
109820
 
109462
109821
  // src/lib/registry-sync.ts
109463
109822
  import { mkdirSync as mkdirSync28, writeFileSync as writeFileSync28 } from "fs";
109464
- import { dirname as dirname31, relative as relative10 } from "path";
109823
+ import { dirname as dirname32, relative as relative10 } from "path";
109465
109824
  function createRegistrySyncArtifact(options = {}) {
109466
109825
  const profile = options.profile ?? "all";
109467
109826
  const includeDocs = options.includeDocs ?? true;
@@ -109518,7 +109877,7 @@ function createRegistrySyncArtifact(options = {}) {
109518
109877
  };
109519
109878
  }
109520
109879
  function writeRegistrySyncArtifact(path, artifact) {
109521
- mkdirSync28(dirname31(path), { recursive: true });
109880
+ mkdirSync28(dirname32(path), { recursive: true });
109522
109881
  writeFileSync28(path, `${JSON.stringify(artifact, null, 2)}
109523
109882
  `);
109524
109883
  }
@@ -109542,7 +109901,8 @@ var exports_registry2 = {};
109542
109901
  __export(exports_registry2, {
109543
109902
  registerVersions: () => registerVersions,
109544
109903
  registerRegistry: () => registerRegistry,
109545
- registerPull: () => registerPull
109904
+ registerPull: () => registerPull,
109905
+ registerLifecycle: () => registerLifecycle
109546
109906
  });
109547
109907
  function registerRegistry(parent) {
109548
109908
  const registry2 = parent.command("registry").description("Generate registry artifacts for hosted skills services");
@@ -109551,12 +109911,12 @@ function registerRegistry(parent) {
109551
109911
  async function writeJson2(value, space) {
109552
109912
  const text3 = `${JSON.stringify(value, null, space)}
109553
109913
  `;
109554
- await new Promise((resolve24, reject2) => {
109914
+ await new Promise((resolve25, reject2) => {
109555
109915
  process.stdout.write(text3, (error61) => {
109556
109916
  if (error61)
109557
109917
  reject2(error61);
109558
109918
  else
109559
- resolve24();
109919
+ resolve25();
109560
109920
  });
109561
109921
  });
109562
109922
  }
@@ -109698,6 +110058,25 @@ Versions of ${name}
109698
110058
  }
109699
110059
  });
109700
110060
  }
110061
+ function registerLifecycle(parent) {
110062
+ parent.command("lifecycle").argument("<name>", "Skill name on the configured instance").requiredOption("--state <state>", "Lifecycle state: active or archived").requiredOption("--revision <revision>", "Exact revision id from skills info/get").option("--reason <reason>", "Bounded archive reason").option("--replacement <slug>", "Optional successor slug").option("--json", "Output as JSON", false).description("Change a hosted skill's active/archive lifecycle with an exact revision guard").action(async (name, options) => {
110063
+ if (options.state !== "active" && options.state !== "archived")
110064
+ throw new Error("--state must be active or archived");
110065
+ const client2 = await createRemoteSkillsClient();
110066
+ if (!client2)
110067
+ throw new Error("No API key configured, so there is no instance to update.");
110068
+ try {
110069
+ const result2 = await client2.setSkillLifecycle(name.trim(), options.state, { expectedRevisionId: options.revision, ...options.reason ? { reason: options.reason } : {}, ...options.replacement ? { replacementSlug: options.replacement } : {} });
110070
+ console.log(options.json ? JSON.stringify(result2, null, 2) : `Updated ${name} to ${options.state}.`);
110071
+ } catch (error61) {
110072
+ if (options.json)
110073
+ console.log(JSON.stringify({ error: error61.message }, null, 2));
110074
+ else
110075
+ console.error(source_default.red(error61.message));
110076
+ process.exitCode = 1;
110077
+ }
110078
+ });
110079
+ }
109701
110080
  var init_registry2 = __esm(() => {
109702
110081
  init_source();
109703
110082
  init_registry_sync();
@@ -110013,7 +110392,7 @@ var exports_private_publications = {};
110013
110392
  __export(exports_private_publications, {
110014
110393
  registerPrivatePublications: () => registerPrivatePublications
110015
110394
  });
110016
- import { resolve as resolve24 } from "path";
110395
+ import { resolve as resolve25 } from "path";
110017
110396
  function verifyOptions(options, action) {
110018
110397
  if (options.userId === undefined !== (options.membershipId === undefined) || options.userId !== undefined && (!publicationUuid(options.userId) || !publicationUuid(options.membershipId)))
110019
110398
  throw new PrivatePublicationError("PUBLICATION_CONTEXT_REQUIRED", "Provide both observed --user-id and --membership-id UUIDs.");
@@ -110058,9 +110437,9 @@ function registerPrivatePublications(parent) {
110058
110437
  if (code2 === null)
110059
110438
  return;
110060
110439
  const context2 = options.userId ? { userId: options.userId, membershipId: options.membershipId } : undefined;
110061
- const client2 = await privatePublicationSession(options.email, code2, context2), directory2 = resolve24(options.recoveryDir);
110440
+ const client2 = await privatePublicationSession(options.email, code2, context2), directory2 = resolve25(options.recoveryDir);
110062
110441
  if (action === "publish")
110063
- await preparePrivatePublication(client2, resolve24(args2[0]), directory2, { skillId: options.skillId, expectedCurrentVersionId: options.expectedCurrentVersion ?? null, idempotencyKey: options.idempotencyKey });
110442
+ await preparePrivatePublication(client2, resolve25(args2[0]), directory2, { skillId: options.skillId, expectedCurrentVersionId: options.expectedCurrentVersion ?? null, idempotencyKey: options.idempotencyKey });
110064
110443
  const result2 = action === "publish" || action === "resume" ? await continuePrivatePublication(client2, directory2, { confirm: true, waitMs: Number(options.waitSeconds) * 1000 }) : await inspectPrivatePublication(client2, directory2, action === "cancel");
110065
110444
  print2(result2, options.json);
110066
110445
  } catch (error61) {
@@ -110161,7 +110540,7 @@ __export(exports_auth, {
110161
110540
  import { createInterface as createInterface3 } from "readline";
110162
110541
  function prompt(question) {
110163
110542
  const rl = createInterface3({ input: process.stdin, output: process.stdout });
110164
- return new Promise((resolve25) => {
110543
+ return new Promise((resolve26) => {
110165
110544
  let settled = false;
110166
110545
  const finish = (answer) => {
110167
110546
  if (settled)
@@ -110170,7 +110549,7 @@ function prompt(question) {
110170
110549
  rl.close();
110171
110550
  if (answer === null)
110172
110551
  process.exitCode = 130;
110173
- resolve25(answer);
110552
+ resolve26(answer);
110174
110553
  };
110175
110554
  rl.once("SIGINT", () => finish(null));
110176
110555
  rl.once("close", () => finish(null));
@@ -110245,6 +110624,11 @@ function authIdentityPayload(authSource, live, cached2, offline = false) {
110245
110624
  const userId = stringField2(user?.id) ?? cached2?.userId;
110246
110625
  const orgId = stringField2(organization2?.id) ?? cached2?.orgId;
110247
110626
  const role3 = stringField2(user?.role);
110627
+ const apiKey = recordField(root2.apiKey) ?? recordField(data?.apiKey);
110628
+ const apiKeyId = stringField2(apiKey?.id);
110629
+ const apiKeyScopes = apiKey?.scopes;
110630
+ const safeApiKeyId = apiKeyId && /^[A-Za-z0-9_-]{1,256}$/.test(apiKeyId) ? apiKeyId : undefined;
110631
+ const safeApiKeyScopes = Array.isArray(apiKeyScopes) && apiKeyScopes.length <= 32 && apiKeyScopes.every((scope) => typeof scope === "string" && scope.length <= 128 && /^(?:\*|[a-z][a-z0-9_-]*:(?:\*|[a-z][a-z0-9_-]*))$/.test(scope)) ? [...new Set(apiKeyScopes)] : undefined;
110248
110632
  return {
110249
110633
  status: "authenticated",
110250
110634
  authSource,
@@ -110254,7 +110638,8 @@ function authIdentityPayload(authSource, live, cached2, offline = false) {
110254
110638
  ...orgName ? { organizationName: orgName } : {},
110255
110639
  ...userId ? { userId } : {},
110256
110640
  ...orgId ? { orgId } : {},
110257
- ...role3 ? { role: role3 } : {}
110641
+ ...role3 ? { role: role3 } : {},
110642
+ ...safeApiKeyId && safeApiKeyScopes ? { apiKeyId: safeApiKeyId, scopes: safeApiKeyScopes } : {}
110258
110643
  };
110259
110644
  }
110260
110645
  function printWhoami(payload) {
@@ -110264,6 +110649,8 @@ function printWhoami(payload) {
110264
110649
  console.log(source_default.bold("Org: ") + payload.organization);
110265
110650
  if (payload.role)
110266
110651
  console.log(source_default.bold("Role: ") + payload.role);
110652
+ if (payload.apiKeyId)
110653
+ console.log(source_default.bold("Key: ") + payload.apiKeyId);
110267
110654
  if (payload.organizationName)
110268
110655
  console.log(source_default.bold("Name: ") + payload.organizationName);
110269
110656
  if (payload.authSource)
@@ -110278,7 +110665,7 @@ function printWhoami(payload) {
110278
110665
  console.log(source_default.dim("(offline \u2014 showing cached info)"));
110279
110666
  }
110280
110667
  function sleep(ms) {
110281
- return new Promise((resolve25) => setTimeout(resolve25, ms));
110668
+ return new Promise((resolve26) => setTimeout(resolve26, ms));
110282
110669
  }
110283
110670
  function browserCommand(url2) {
110284
110671
  if (process.platform === "darwin")
@@ -110585,6 +110972,25 @@ function registerAuth(parent) {
110585
110972
  writeCommandError(error61, "Failed to revoke API key", options.json);
110586
110973
  }
110587
110974
  });
110975
+ keys3.command("add-publish-scope").argument("<key-id>").requiredOption("--expected-scopes <csv>", "Current comma-separated scopes; stale values are refused").option("--json", "Output as JSON", false).description("Add skills:publish to one existing key without minting or rotating it").action(async (id3, options) => {
110976
+ try {
110977
+ const connection = await resolveSkillsConnection();
110978
+ if (!connection)
110979
+ throw new Error("A hosted Skills credential is required for key scope administration");
110980
+ const identity4 = await apiRequest("/api/auth/whoami", { headers: { Authorization: `Bearer ${connection.apiKey}` } }, connection.apiOrigin);
110981
+ const identityOrg = recordField(identity4.organization);
110982
+ const orgId = stringField2(identityOrg?.id);
110983
+ if (!orgId)
110984
+ throw new Error("The Skills authority did not return a tenant identity; refusing key scope administration");
110985
+ const result2 = await new RemoteSkillsClient(connection.apiKey, connection.apiOrigin).addSkillPublishScope(id3, options.expectedScopes.split(",").map((scope) => scope.trim()).filter(Boolean), orgId);
110986
+ if (options.json || !isTTY)
110987
+ console.log(JSON.stringify(result2, null, 2));
110988
+ else
110989
+ console.log(source_default.green(`Added skills:publish to ${id3}; scopes read back from the server.`));
110990
+ } catch (error61) {
110991
+ writeCommandError(error61, "Failed to add Skills publication scope", options.json);
110992
+ }
110993
+ });
110588
110994
  auth.command("login").description("Sign in with browser/device code or email code").option("--email <email>", "Email address (non-interactive)").option("--code <code>", "Verification code (non-interactive)").option("--membership-id <id>", "Enroll an exact workspace membership into an explicit HASNA_PROFILE").option("--code-stdin", "Read a fresh six-digit code for workspace enrollment from stdin").option("--api-key <key>", "Verify and store an API key").option("--device", "Use browser/device-code login", false).option("--no-open", "Do not open a browser for device-code login").option("--poll", "Poll until browser authentication completes in non-interactive mode", false).option("--poll-timeout-ms <ms>", "Maximum time to wait for device-code login").option("--json", "Output result as JSON", false).action(async (options) => {
110589
110995
  if (options.membershipId !== undefined) {
110590
110996
  if (options.apiKey || options.device || options.code || options.poll) {
@@ -110780,7 +111186,7 @@ function promptInvitationProof(kind) {
110780
111186
  const label = kind === "token" ? "invitation token" : "recovery code";
110781
111187
  const character = kind === "token" ? /^[A-Za-z0-9_-]$/ : /^\d$/;
110782
111188
  const { stdin, stderr: output2 } = process, wasRaw = stdin.isRaw, wasFlowing = stdin.readableFlowing;
110783
- return new Promise((resolve25) => {
111189
+ return new Promise((resolve26) => {
110784
111190
  let value = "", settled = false, overflow = false;
110785
111191
  const finish = (answer) => {
110786
111192
  if (settled)
@@ -110797,7 +111203,7 @@ function promptInvitationProof(kind) {
110797
111203
  `);
110798
111204
  if (answer === null)
110799
111205
  process.exitCode = 130;
110800
- resolve25(answer);
111206
+ resolve26(answer);
110801
111207
  };
110802
111208
  const cancel = () => finish(null);
110803
111209
  const keypress = (text3, key) => {
@@ -119648,10 +120054,11 @@ var { registerPortableSkillCommands: registerPortableSkillCommands2 } = await Pr
119648
120054
  registerPortableSkillCommands2(program2);
119649
120055
  var { registerSchedule: registerSchedule2 } = await Promise.resolve().then(() => (init_schedule(), exports_schedule));
119650
120056
  registerSchedule2(program2);
119651
- var { registerRegistry: registerRegistry2, registerPull: registerPull2, registerVersions: registerVersions2 } = await Promise.resolve().then(() => (init_registry2(), exports_registry2));
120057
+ var { registerRegistry: registerRegistry2, registerPull: registerPull2, registerVersions: registerVersions2, registerLifecycle: registerLifecycle2 } = await Promise.resolve().then(() => (init_registry2(), exports_registry2));
119652
120058
  registerRegistry2(program2);
119653
120059
  registerPull2(program2);
119654
120060
  registerVersions2(program2);
120061
+ registerLifecycle2(program2);
119655
120062
  var { registerPublish: registerPublish2 } = await Promise.resolve().then(() => (init_publish(), exports_publish));
119656
120063
  registerPublish2(program2);
119657
120064
  var { registerPrivatePublications: registerPrivatePublications2 } = await Promise.resolve().then(() => (init_private_publications(), exports_private_publications));