@hasna/skills 0.10.75 → 0.10.77

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -6988,7 +6988,7 @@ var require_public_api = __commonJS((exports) => {
6988
6988
  });
6989
6989
 
6990
6990
  // src/lib/registry.ts
6991
- import { existsSync as existsSync15, readFileSync as readFileSync27, readdirSync as readdirSync14 } from "fs";
6991
+ import { existsSync as existsSync15, readFileSync as readFileSync27, readdirSync as readdirSync15 } from "fs";
6992
6992
  import { join as join41 } from "path";
6993
6993
 
6994
6994
  // src/lib/config.ts
@@ -7257,12 +7257,12 @@ function unsetConfig(key, scope = "project") {
7257
7257
  // src/lib/portable-skills.ts
7258
7258
  import {
7259
7259
  existsSync as existsSync14,
7260
- mkdirSync as mkdirSync11,
7261
- mkdtempSync as mkdtempSync2,
7262
- readdirSync as readdirSync13,
7260
+ mkdirSync as mkdirSync12,
7261
+ mkdtempSync as mkdtempSync3,
7262
+ readdirSync as readdirSync14,
7263
7263
  realpathSync as realpathSync15,
7264
7264
  renameSync as renameSync6,
7265
- rmSync as rmSync4,
7265
+ rmSync as rmSync5,
7266
7266
  statSync as statSync13,
7267
7267
  writeFileSync as writeFileSync9
7268
7268
  } from "fs";
@@ -9973,7 +9973,7 @@ function assertAgentPolicyCollections(policy) {
9973
9973
 
9974
9974
  // src/lib/agent-discovery.ts
9975
9975
  import { createHash as createHash30 } from "crypto";
9976
- import { lstatSync as lstatSync32, readFileSync as readFileSync26, readdirSync as readdirSync12, realpathSync as realpathSync13 } from "fs";
9976
+ import { lstatSync as lstatSync32, readFileSync as readFileSync26, readdirSync as readdirSync13, realpathSync as realpathSync13 } from "fs";
9977
9977
  import { basename as basename15, dirname as dirname26, isAbsolute as isAbsolute28, join as join38, relative as relative10, resolve as resolve27, sep as sep15 } from "path";
9978
9978
  import { isDeepStrictEqual as isDeepStrictEqual9 } from "util";
9979
9979
 
@@ -12462,6 +12462,39 @@ function captureCodexSettings(path, budget2 = { remaining: 256 * 1024 * 1024 })
12462
12462
  // src/lib/codex-hook-mcp-dependencies.ts
12463
12463
  import { createHash as createHash13 } from "crypto";
12464
12464
  import { basename as basename6, dirname as dirname11, isAbsolute as isAbsolute11, join as join13, resolve as resolve11, sep as sep4 } from "path";
12465
+
12466
+ // src/lib/codex-plugin-capability-paths.ts
12467
+ var CODEX_PLUGIN_MANIFEST_LOCATIONS = Object.freeze([
12468
+ "plugin.json",
12469
+ ".codex-plugin/plugin.json",
12470
+ ".claude-plugin/plugin.json",
12471
+ ".cursor-plugin/plugin.json"
12472
+ ]);
12473
+ var CODEX_PLUGIN_MANIFEST_DIRECTORIES = Object.freeze([".codex-plugin", ".claude-plugin", ".cursor-plugin"]);
12474
+ var CODEX_PLUGIN_ROOT_CAPABILITY_ENTRIES = Object.freeze([
12475
+ "plugin.json",
12476
+ ".codex-plugin",
12477
+ ".claude-plugin",
12478
+ ".cursor-plugin",
12479
+ "hooks",
12480
+ "hooks.json",
12481
+ ".mcp.json",
12482
+ ".app.json",
12483
+ "commands",
12484
+ "agents"
12485
+ ]);
12486
+ function foldCodexPluginEntryName(name) {
12487
+ return name.toUpperCase().toLowerCase();
12488
+ }
12489
+ function codexPluginRootCapabilityEntry(name) {
12490
+ const folded = foldCodexPluginEntryName(name);
12491
+ return CODEX_PLUGIN_ROOT_CAPABILITY_ENTRIES.includes(folded) ? folded : null;
12492
+ }
12493
+ function isCodexSkillDocumentName(name) {
12494
+ return foldCodexPluginEntryName(name) === "skill.md";
12495
+ }
12496
+
12497
+ // src/lib/codex-hook-mcp-dependencies.ts
12465
12498
  var need5 = (value) => {
12466
12499
  if (!value)
12467
12500
  throw new Error("Incomplete or unsupported reviewed Codex hook dependency");
@@ -12610,15 +12643,13 @@ function captureCodexHookMcpDependencies(configPath, reviewed, configText, chang
12610
12643
  }
12611
12644
  };
12612
12645
  const root = join13(cacheRoot, identity2, selectCodexPluginVersion(versions, selectionBudget));
12613
- const agent = read2(join13(root, "plugin.json"));
12646
+ const [agentPluginManifest, ...legacyManifests] = CODEX_PLUGIN_MANIFEST_LOCATIONS;
12647
+ const agent = read2(join13(root, agentPluginManifest));
12614
12648
  if (agent !== null) {
12615
12649
  const schema = JSON.parse(agent).$schema;
12616
12650
  need5(typeof schema !== "string" || !schema.startsWith("https://agent-plugins.org/schemas/"));
12617
12651
  }
12618
- const codex = read2(join13(root, ".codex-plugin/plugin.json"));
12619
- const claude = read2(join13(root, ".claude-plugin/plugin.json"));
12620
- const cursor = read2(join13(root, ".cursor-plugin/plugin.json"));
12621
- const text2 = codex ?? claude ?? cursor;
12652
+ const text2 = legacyManifests.map((location) => read2(join13(root, location))).find((value) => value !== null) ?? null;
12622
12653
  if (text2 === null)
12623
12654
  continue;
12624
12655
  const manifest = JSON.parse(text2);
@@ -13491,14 +13522,14 @@ function hashDiscoveryPathFile(path, budget2, changes) {
13491
13522
  }
13492
13523
 
13493
13524
  // src/lib/codex-vendor-refresh.ts
13494
- import { lstatSync as lstatSync15, readdirSync as readdirSync6, readFileSync as readFileSync12 } from "fs";
13525
+ import { lstatSync as lstatSync15, readdirSync as readdirSync7, readFileSync as readFileSync12 } from "fs";
13495
13526
  import { isAbsolute as isAbsolute16, join as join19, relative as relative6, resolve as resolve16, sep as sep9 } from "path";
13496
13527
  import { isDeepStrictEqual as isDeepStrictEqual5 } from "util";
13497
13528
 
13498
13529
  // src/lib/codex-plugin-skill-controls.ts
13499
13530
  import { createHash as createHash18 } from "crypto";
13500
13531
  import { basename as basename8, dirname as dirname15, join as join18, relative as relative5, resolve as resolve15, sep as sep8 } from "path";
13501
- import { lstatSync as lstatSync14, readdirSync as readdirSync5, readFileSync as readFileSync11, readlinkSync as readlinkSync3, realpathSync as realpathSync6 } from "fs";
13532
+ import { lstatSync as lstatSync14, readdirSync as readdirSync6, readFileSync as readFileSync11, readlinkSync as readlinkSync3, realpathSync as realpathSync6 } from "fs";
13502
13533
 
13503
13534
  // src/lib/codex-native-skill-catalog.ts
13504
13535
  import { realpathSync as realpathSync5 } from "fs";
@@ -13836,14 +13867,35 @@ class KernelLock {
13836
13867
  }
13837
13868
 
13838
13869
  // src/lib/codex-corpus-write.ts
13839
- import { execFileSync } from "child_process";
13870
+ import { AsyncLocalStorage } from "async_hooks";
13871
+ import { execFileSync, spawnSync as spawnSync3 } from "child_process";
13840
13872
  import { createHash as createHash17 } from "crypto";
13841
- import { accessSync, constants as constants8, lstatSync as lstatSync13, readFileSync as readFileSync10, realpathSync as realpathSync3, statSync as statSync7 } from "fs";
13873
+ import { accessSync, constants as constants8, lstatSync as lstatSync13, mkdirSync as mkdirSync5, mkdtempSync, readdirSync as readdirSync5, readFileSync as readFileSync10, realpathSync as realpathSync3, rmSync as rmSync2, statSync as statSync7 } from "fs";
13842
13874
  import { basename as basename7, delimiter, dirname as dirname14, isAbsolute as isAbsolute13, join as join16, relative as relative4, resolve as resolve14, sep as sep7 } from "path";
13843
13875
  var KEY = ".native-corpus-admission";
13844
- var fail = () => {
13845
- throw new Error("CODEX_CORPUS_ADMISSION_REQUIRED: verified native admission and its existing shared lock are required");
13876
+ var fail = (reason2) => {
13877
+ throw new Error(`CODEX_CORPUS_ADMISSION_REQUIRED: verified native admission and its existing shared lock are required${reason2 ? ` (${reason2})` : ""}`);
13846
13878
  };
13879
+ function codexAdmissionRecord(options) {
13880
+ const record4 = options.onCodexAdmission;
13881
+ const invalid = () => {
13882
+ throw new Error("CODEX_CORPUS_ADMISSION_RECORD_INVALID: onCodexAdmission must be a synchronous function");
13883
+ };
13884
+ if (record4 !== undefined && typeof record4 !== "function")
13885
+ invalid();
13886
+ return { policy: { fallback: typeof record4 === "function" }, deliver(admission) {
13887
+ if (!admission || typeof record4 !== "function")
13888
+ return;
13889
+ const result = record4(admission);
13890
+ if (result !== null && (typeof result === "object" || typeof result === "function") && typeof result.then === "function") {
13891
+ Promise.resolve(result).catch(() => {});
13892
+ invalid();
13893
+ }
13894
+ } };
13895
+ }
13896
+ function codexAdmissionReceipt(admission) {
13897
+ return admission?.nativeAdmission === "unavailable" && admission.probe ? { nativeAdmission: "unavailable", nativeAdmissionProbe: { ...admission.probe } } : {};
13898
+ }
13847
13899
  function physicalTarget(path) {
13848
13900
  const suffix = [];
13849
13901
  for (let cursor = path;; cursor = dirname14(cursor)) {
@@ -13925,13 +13977,246 @@ function executable(options) {
13925
13977
  const digest = hash2();
13926
13978
  if (options.codexSha256 && digest !== options.codexSha256)
13927
13979
  return fail();
13928
- return { path, assertCurrent() {
13980
+ return { path, sha256: digest, size: Number(initial.size), assertCurrent() {
13929
13981
  const current = statSync7(path, { bigint: true });
13930
13982
  if (realpathSync3(found) !== path || ["dev", "ino", "size", "mtimeNs", "ctimeNs", "mode"].some((key2) => initial[key2] !== current[key2]) || hash2() !== digest)
13931
13983
  fail();
13932
13984
  } };
13933
13985
  }
13934
- function acquireCodexCorpusWrite(roots, options) {
13986
+ var PROBE = { timeout: 5000, maxBuffer: 4096, killSignal: "SIGKILL", encoding: "utf8" };
13987
+ var UNRECOGNIZED = /^error: unrecognized subcommand 'corpus-admission-inspect'(?:\r?\n|$)/;
13988
+ var VERSION = /^codex-cli (?:0|[1-9][0-9]{0,5})\.(?:0|[1-9][0-9]{0,5})\.(?:0|[1-9][0-9]{0,5})(?:-[0-9A-Za-z-]{1,32}(?:\.[0-9A-Za-z-]{1,32}){0,7})?$/;
13989
+ var LOCK_DIRECTORY = "codex-corpus-locks";
13990
+ var PROBE_PARENT = "codex-probe-homes";
13991
+ var retain = (hold) => {
13992
+ hold.refs++;
13993
+ return { hold, released: false };
13994
+ };
13995
+ var release = (ref) => {
13996
+ if (ref.released)
13997
+ return;
13998
+ ref.released = true;
13999
+ if (--ref.hold.refs === 0)
14000
+ ref.hold.lock.close();
14001
+ };
14002
+ var enclosing = new AsyncLocalStorage;
14003
+ var leaseHolds = new WeakMap;
14004
+ var contains = (base, path) => {
14005
+ const distance = relative4(base, path);
14006
+ return distance === "" || !distance.startsWith(`..${sep7}`) && distance !== ".." && !isAbsolute13(distance);
14007
+ };
14008
+ function nativeLockAbsent(root) {
14009
+ for (const name of [`${KEY}.flock-v1`, `${KEY}.lock`]) {
14010
+ try {
14011
+ lstatSync13(join16(root, name));
14012
+ return false;
14013
+ } catch (error) {
14014
+ if (error.code !== "ENOENT")
14015
+ throw error;
14016
+ }
14017
+ }
14018
+ return true;
14019
+ }
14020
+ function skillsState(root, leaf, roots) {
14021
+ const chain = [realpathSync3(dirname14(root))];
14022
+ for (const part of [".hasna", "skills", leaf])
14023
+ chain.push(join16(chain.at(-1), part));
14024
+ const path = chain.at(-1);
14025
+ const uid2 = process.getuid();
14026
+ const verify = () => {
14027
+ if (roots.some((item) => contains(item, path)) || codexCorpusRootForPath(path) !== undefined)
14028
+ fail();
14029
+ for (let ancestor = dirname14(chain[0]);; ancestor = dirname14(ancestor)) {
14030
+ const stat2 = lstatSync13(ancestor), sticky = stat2.uid === 0 && (stat2.mode & 512) !== 0;
14031
+ if (!stat2.isDirectory() || stat2.uid !== uid2 && stat2.uid !== 0 || (stat2.mode & 18) !== 0 && !sticky)
14032
+ fail();
14033
+ if (dirname14(ancestor) === ancestor)
14034
+ break;
14035
+ }
14036
+ for (const component of chain) {
14037
+ const stat2 = lstatSync13(component, { throwIfNoEntry: false });
14038
+ if (!stat2)
14039
+ return;
14040
+ if (!stat2.isDirectory() || stat2.uid !== uid2 && stat2.uid !== 0 || (stat2.mode & 18) !== 0 || component === path && stat2.uid !== uid2)
14041
+ fail();
14042
+ }
14043
+ };
14044
+ verify();
14045
+ return { path, ensure() {
14046
+ verify();
14047
+ for (const component of chain.slice(1)) {
14048
+ try {
14049
+ mkdirSync5(component, { mode: 448 });
14050
+ } catch (error) {
14051
+ if (error.code !== "EEXIST")
14052
+ throw error;
14053
+ }
14054
+ }
14055
+ verify();
14056
+ if (realpathSync3(path) !== path)
14057
+ fail();
14058
+ return path;
14059
+ } };
14060
+ }
14061
+ function probeParent(roots) {
14062
+ const dataRoot = resolve14(getDataDirReadOnly()), path = join16(dataRoot, PROBE_PARENT), uid2 = process.getuid();
14063
+ const chain = [];
14064
+ for (let component = path;; component = dirname14(component)) {
14065
+ chain.unshift(component);
14066
+ if (dirname14(component) === component)
14067
+ break;
14068
+ }
14069
+ const verify = () => {
14070
+ if (roots.some((item) => contains(item, path)) || codexCorpusRootForPath(path) !== undefined)
14071
+ fail();
14072
+ for (const component of chain) {
14073
+ const stat2 = lstatSync13(component, { throwIfNoEntry: false });
14074
+ if (!stat2)
14075
+ return;
14076
+ const skills = contains(dataRoot, component), sticky = !skills && stat2.uid === 0 && (stat2.mode & 512) !== 0;
14077
+ if (!stat2.isDirectory() || stat2.uid !== uid2 && (skills || stat2.uid !== 0) || (stat2.mode & 18) !== 0 && !sticky)
14078
+ fail();
14079
+ }
14080
+ };
14081
+ verify();
14082
+ for (const component of chain) {
14083
+ if (lstatSync13(component, { throwIfNoEntry: false }))
14084
+ continue;
14085
+ try {
14086
+ mkdirSync5(component, { mode: 448 });
14087
+ } catch (error) {
14088
+ if (error.code !== "EEXIST")
14089
+ throw error;
14090
+ }
14091
+ }
14092
+ verify();
14093
+ if (realpathSync3(path) !== path)
14094
+ fail();
14095
+ return path;
14096
+ }
14097
+ function probeHomeIntact(home, empty) {
14098
+ const stat2 = lstatSync13(home.path, { bigint: true, throwIfNoEntry: false });
14099
+ return !!stat2 && stat2.isDirectory() && stat2.dev === home.dev && stat2.ino === home.ino && stat2.uid === BigInt(process.getuid()) && (stat2.mode & 0o777n) === 0o700n && realpathSync3(home.path) === home.path && (!empty || readdirSync5(home.path).length === 0);
14100
+ }
14101
+ function removeProbeHome(home) {
14102
+ try {
14103
+ const stat2 = lstatSync13(home.path, { bigint: true });
14104
+ if (stat2.isDirectory() && stat2.dev === home.dev && stat2.ino === home.ino)
14105
+ rmSync2(home.path, { recursive: true, force: true });
14106
+ } catch {}
14107
+ }
14108
+ function probe(path, args, parent, stdio) {
14109
+ const created = mkdtempSync(join16(parent, "probe-")), stat2 = lstatSync13(created, { bigint: true });
14110
+ const home = { path: created, dev: stat2.dev, ino: stat2.ino };
14111
+ try {
14112
+ if (!probeHomeIntact(home, true))
14113
+ return;
14114
+ const env = { CODEX_HOME: home.path };
14115
+ for (const key2 of ["PATH", "HOME"])
14116
+ if (process.env[key2] !== undefined)
14117
+ env[key2] = process.env[key2];
14118
+ const result = spawnSync3(path, args, { ...PROBE, cwd: home.path, env, stdio: ["ignore", stdio, stdio] });
14119
+ return probeHomeIntact(home, false) ? result : undefined;
14120
+ } finally {
14121
+ removeProbeHome(home);
14122
+ }
14123
+ }
14124
+ function probeAdmissionCommand(path, parent) {
14125
+ const help = probe(path, ["help", "corpus-admission-inspect"], parent, "pipe");
14126
+ if (!help || help.error || help.signal !== null)
14127
+ return "inconclusive";
14128
+ if (help.status === 0)
14129
+ return "present";
14130
+ if (help.status !== 2 || help.stdout !== "" || typeof help.stderr !== "string" || !UNRECOGNIZED.test(help.stderr))
14131
+ return "inconclusive";
14132
+ const control = probe(path, ["help", "exec"], parent, "ignore");
14133
+ return control && !control.error && control.signal === null && control.status === 0 ? "absent" : "inconclusive";
14134
+ }
14135
+ function strictVersion(path, parent) {
14136
+ const result = probe(path, ["--version"], parent, "pipe");
14137
+ if (!result || result.error || result.signal !== null || result.status !== 0 || typeof result.stdout !== "string")
14138
+ return;
14139
+ const line = result.stdout.replace(/\r?\n$/, "");
14140
+ return VERSION.test(line) ? line : undefined;
14141
+ }
14142
+ function rootLockKey(root, id) {
14143
+ return `codex-corpus-${createHash17("sha256").update(`${root}\x00${id.device}\x00${id.inode}`).digest("hex")}`;
14144
+ }
14145
+ function acquireFallback(inputs, options) {
14146
+ let reason2 = "executable-unverified";
14147
+ const refs = new Map, held = [];
14148
+ const close = () => {
14149
+ for (const ref of [...refs.values()].reverse())
14150
+ release(ref);
14151
+ };
14152
+ try {
14153
+ const native = executable(options);
14154
+ reason2 = "skills-lock-unavailable";
14155
+ const roots = inputs.map((item) => item.root);
14156
+ const locks = new Map(roots.map((root) => [root, skillsState(root, LOCK_DIRECTORY, roots)]));
14157
+ const parent = probeParent(roots);
14158
+ reason2 = "probe-inconclusive";
14159
+ const state = probeAdmissionCommand(native.path, parent);
14160
+ if (state === "present")
14161
+ reason2 = "command-present";
14162
+ if (state !== "absent")
14163
+ fail();
14164
+ const version = strictVersion(native.path, parent);
14165
+ if (version === undefined)
14166
+ fail();
14167
+ reason2 = "executable-unverified";
14168
+ native.assertCurrent();
14169
+ reason2 = "skills-lock-unavailable";
14170
+ for (const { input, root } of inputs) {
14171
+ const id = identity3(root), key2 = rootLockKey(root, id);
14172
+ if (!refs.has(key2)) {
14173
+ const owner2 = enclosing.getStore()?.get(key2);
14174
+ if (owner2 && !owner2.released)
14175
+ refs.set(key2, retain(owner2.hold));
14176
+ else {
14177
+ const lock = new KernelLock(locks.get(root).ensure(), key2, { mode: "exclusive" });
14178
+ refs.set(key2, retain({ lock, refs: 0 }));
14179
+ if (!lock.trySync(1000)) {
14180
+ reason2 = "writer-busy";
14181
+ fail();
14182
+ }
14183
+ }
14184
+ }
14185
+ held.push({ input, root, id, ref: refs.get(key2) });
14186
+ }
14187
+ const assertCurrent = () => {
14188
+ try {
14189
+ for (const item of held) {
14190
+ if (item.ref.released)
14191
+ fail();
14192
+ item.ref.hold.lock.assertUnchanged();
14193
+ if (realpathSync3(item.input) !== item.root || !sameIdentity(identity3(item.root), item.id) || !nativeLockAbsent(item.root))
14194
+ fail();
14195
+ }
14196
+ native.assertCurrent();
14197
+ } catch {
14198
+ fail("lease-changed");
14199
+ }
14200
+ };
14201
+ reason2 = "lease-changed";
14202
+ assertCurrent();
14203
+ const lease = { assertCurrent, close, admission: { nativeAdmission: "unavailable", probe: {
14204
+ kind: "help-unrecognized-subcommand",
14205
+ executable: native.path,
14206
+ sha256: native.sha256,
14207
+ size: native.size,
14208
+ version,
14209
+ probeExitCode: 2,
14210
+ controlExitCode: 0
14211
+ } } };
14212
+ leaseHolds.set(lease, refs);
14213
+ return lease;
14214
+ } catch {
14215
+ close();
14216
+ return fail(reason2);
14217
+ }
14218
+ }
14219
+ function acquireCodexCorpusWrite(roots, options, policy = {}) {
13935
14220
  const held = [];
13936
14221
  const close = () => {
13937
14222
  for (const item of held.reverse())
@@ -13944,10 +14229,20 @@ function acquireCodexCorpusWrite(roots, options) {
13944
14229
  fail();
13945
14230
  }
13946
14231
  };
14232
+ let fallback = false, refusal;
13947
14233
  try {
13948
14234
  if (roots.some((root) => typeof root !== "string" || !isAbsolute13(root) || root.includes("\x00")))
13949
14235
  fail();
13950
14236
  const inputs = [...new Set(roots)].map((input) => ({ input, root: realpathSync3(input) })).sort((a, b) => a.root.localeCompare(b.root));
14237
+ const absent = inputs.filter(({ root }) => nativeLockAbsent(root));
14238
+ if (absent.length && absent.length !== inputs.length) {
14239
+ refusal = "native-lock-present";
14240
+ fail();
14241
+ }
14242
+ if (absent.length && policy.fallback !== false) {
14243
+ fallback = true;
14244
+ return acquireFallback(inputs, options);
14245
+ }
13951
14246
  for (const { input, root } of inputs) {
13952
14247
  const lock = new KernelLock(root, KEY, { mode: "shared", existingOnly: true });
13953
14248
  held.push({ input, root, lock });
@@ -13975,19 +14270,25 @@ function acquireCodexCorpusWrite(roots, options) {
13975
14270
  if (Object.keys(row).sort().join(",") !== "lock,root,schema,state" || row.schema !== "codex-corpus-admission-status/v1" || row.state !== "committed-v1" && row.state !== "committed-v2" || !sameIdentity(row.root, rootIdentity) || !sameIdentity(row.lock, lockIdentity))
13976
14271
  fail();
13977
14272
  }
13978
- return { assertCurrent, close };
13979
- } catch {
14273
+ return { assertCurrent, close, admission: { nativeAdmission: "verified" } };
14274
+ } catch (error) {
14275
+ if (fallback)
14276
+ throw error;
13980
14277
  close();
13981
- return fail();
14278
+ return fail(refusal);
13982
14279
  }
13983
14280
  }
13984
- function withCodexCorpusWrite(roots, run, options = {}) {
14281
+ function scoped(lease, run) {
14282
+ const holds = leaseHolds.get(lease);
14283
+ return holds?.size ? enclosing.run(new Map([...enclosing.getStore() ?? [], ...holds]), run) : run();
14284
+ }
14285
+ function withCodexCorpusWrite(roots, run, options = {}, policy = {}) {
13985
14286
  if (!roots.length)
13986
14287
  return run(() => {});
13987
- const lease = acquireCodexCorpusWrite(roots, options);
14288
+ const lease = acquireCodexCorpusWrite(roots, options, policy);
13988
14289
  try {
13989
14290
  lease.assertCurrent();
13990
- const result = run(lease.assertCurrent);
14291
+ const result = scoped(lease, () => run(lease.assertCurrent, lease.admission));
13991
14292
  lease.assertCurrent();
13992
14293
  return result;
13993
14294
  } finally {
@@ -14108,6 +14409,7 @@ async function connectCodexHookRpc(options) {
14108
14409
  const rpc = {
14109
14410
  version,
14110
14411
  processId: child2.pid,
14412
+ admission: corpusLease.admission,
14111
14413
  request(method, params) {
14112
14414
  if (stopped)
14113
14415
  return Promise.reject(new Error(configInvalid ? CODEX_CONFIG_INVALID : "CODEX_HOOK_TRUST_NATIVE_RPC_CLOSED"));
@@ -14561,7 +14863,7 @@ function reviewedRetiredCodexRoot(cache, root, controls, rules, read2, allowAbse
14561
14863
  if (!enrolled.some((control) => control.namespace === parsed.namespace && control.manifestSha256 === parsed.manifestSha256 && !parsed.appSha256 && !parsed.mcpSha256))
14562
14864
  return false;
14563
14865
  let entries = 0;
14564
- const emptySkills = (directory, depth) => depth <= 64 && readdirSync5(directory).every((name) => {
14866
+ const emptySkills = (directory, depth) => depth <= 64 && readdirSync6(directory).every((name) => {
14565
14867
  if (++entries > 4096 || name === "SKILL.md")
14566
14868
  return false;
14567
14869
  const path = join18(directory, name), stat2 = lstatSync14(path);
@@ -14586,7 +14888,7 @@ function reviewedCodexPluginCapabilitiesUnchanged(cache, controls, read2, rules)
14586
14888
  if (control.remotePluginId !== undefined && !remoteInstallationMatches(parent, control.remotePluginId, read2))
14587
14889
  return false;
14588
14890
  }
14589
- const names = readdirSync5(parent);
14891
+ const names = readdirSync6(parent);
14590
14892
  entries += names.length;
14591
14893
  if (entries > 4096)
14592
14894
  return false;
@@ -14794,20 +15096,20 @@ function codexVendorMarketplace(cache, path) {
14794
15096
  return null;
14795
15097
  return CODEX_VENDOR_MARKETPLACES.includes(parts[0]) ? parts[0] : null;
14796
15098
  }
14797
- var OTHER_PLUGIN_CONTROLS = Object.freeze(["plugin.json", ".claude-plugin", ".cursor-plugin", "hooks", "hooks.json", ".mcp.json", "commands", "agents"]);
15099
+ var OTHER_PLUGIN_CONTROLS = Object.freeze(CODEX_PLUGIN_ROOT_CAPABILITY_ENTRIES.filter((entry) => entry !== ".codex-plugin" && entry !== ".app.json"));
14798
15100
  var VENDOR_MANIFEST_KEYS = Object.freeze(["name", "version", "description", "author", "homepage", "repository", "license", "keywords", "interface", "skills", "apps"]);
14799
15101
  var DEFAULT_SKILLS_PATHS = Object.freeze(["./skills", "./skills/"]);
14800
15102
  var VENDOR_APP_DECLARATION = "./.app.json";
14801
15103
  var MAX_SUBTREE_ENTRIES = 20000;
14802
15104
  var MAX_SUBTREE_DEPTH = 32;
14803
15105
  var hiddenName = (name) => name.startsWith(".") || name === "node_modules";
14804
- var isSkillDocument = (name) => name.toLowerCase() === "skill.md";
15106
+ var isSkillDocument = isCodexSkillDocumentName;
14805
15107
  var present = (path) => lstatSync15(path, { throwIfNoEntry: false }) !== undefined;
14806
- var holdsOtherControl = (path) => readdirSync6(path).some((name) => OTHER_PLUGIN_CONTROLS.includes(name.toLowerCase()));
15108
+ var holdsOtherControl = (path) => readdirSync7(path).some((name) => OTHER_PLUGIN_CONTROLS.includes(codexPluginRootCapabilityEntry(name) ?? ""));
14807
15109
  function pluginTreeVisible(path, hidden, insideSkill, depth, budget2) {
14808
15110
  if (depth > MAX_SUBTREE_DEPTH)
14809
15111
  return false;
14810
- const names = readdirSync6(path);
15112
+ const names = readdirSync7(path);
14811
15113
  const skill = names.some(isSkillDocument);
14812
15114
  if (skill && (hidden || insideSkill))
14813
15115
  return false;
@@ -14831,7 +15133,7 @@ function codexVendorPluginRootRefreshSafe(root, budget2 = { remaining: MAX_SUBTR
14831
15133
  return false;
14832
15134
  if (!directory(join19(root, ".codex-plugin")))
14833
15135
  return false;
14834
- const controls = readdirSync6(join19(root, ".codex-plugin"));
15136
+ const controls = readdirSync7(join19(root, ".codex-plugin"));
14835
15137
  if (controls.length !== 1 || controls[0] !== "plugin.json")
14836
15138
  return false;
14837
15139
  const manifest = join19(root, ".codex-plugin", "plugin.json"), stat2 = lstatSync15(manifest, { throwIfNoEntry: false });
@@ -14854,7 +15156,7 @@ function codexVendorPluginRootRefreshSafe(root, budget2 = { remaining: MAX_SUBTR
14854
15156
  }
14855
15157
  function vendorMembers(path, budget2) {
14856
15158
  const directories = [];
14857
- for (const name of readdirSync6(path)) {
15159
+ for (const name of readdirSync7(path)) {
14858
15160
  if (--budget2.remaining < 0)
14859
15161
  return null;
14860
15162
  const stat2 = lstatSync15(join19(path, name));
@@ -15144,7 +15446,7 @@ import { basename as basename13, dirname as dirname24, isAbsolute as isAbsolute2
15144
15446
  import { homedir as homedir5 } from "os";
15145
15447
  import { isAbsolute as isAbsolute25, join as join36, resolve as resolve24 } from "path";
15146
15448
  // package.json
15147
- var version = "0.10.75";
15449
+ var version = "0.10.77";
15148
15450
  var package_default = {
15149
15451
  name: "@hasna/skills",
15150
15452
  version,
@@ -15287,7 +15589,7 @@ var package_default = {
15287
15589
 
15288
15590
  // node_modules/@hasna/contracts/dist/client/transport.js
15289
15591
  import { isIP } from "net";
15290
- import { spawnSync as spawnSync3 } from "child_process";
15592
+ import { spawnSync as spawnSync4 } from "child_process";
15291
15593
  import { closeSync as closeSync22, fstatSync as fstatSync22, openSync as openSync22, readFileSync as readFileSync22 } from "fs";
15292
15594
  import { O_NOFOLLOW as O_NOFOLLOW2, O_NONBLOCK as O_NONBLOCK2, O_RDONLY as O_RDONLY2 } from "constants";
15293
15595
  import { hostname as osHostname } from "os";
@@ -15687,7 +15989,7 @@ function isAmbientEnvironment(env) {
15687
15989
  return env === process.env || env[AMBIENT_ENVIRONMENT] === true;
15688
15990
  }
15689
15991
  function defaultKeychainRunner(argv) {
15690
- const result = spawnSync3(KEYCHAIN_SECURITY_BIN, [...argv], {
15992
+ const result = spawnSync4(KEYCHAIN_SECURITY_BIN, [...argv], {
15691
15993
  encoding: "utf8",
15692
15994
  stdio: ["ignore", "pipe", "pipe"],
15693
15995
  timeout: KEYCHAIN_SPAWN_TIMEOUT_MS
@@ -16232,6 +16534,9 @@ function selectsSkillsLocalMode(env = process.env) {
16232
16534
  return !hasSkillsEnvAuthorityIntent(env) && isSkillsLocalOptIn(env);
16233
16535
  }
16234
16536
 
16537
+ // src/lib/credential-profile-command.ts
16538
+ var urlKeys = clientTransportEnvKeys("skills").apiUrlKeys;
16539
+
16235
16540
  // src/lib/fleet-credentials.ts
16236
16541
  var SKILLS_APP = "skills";
16237
16542
  var ENV_KEYS = clientTransportEnvKeys(SKILLS_APP);
@@ -16782,7 +17087,7 @@ async function createProfileClient(signal) {
16782
17087
  }
16783
17088
 
16784
17089
  // src/lib/dependency-preparation.ts
16785
- import { constants as constants10, closeSync as closeSync10, fstatSync as fstatSync10, lstatSync as lstatSync18, mkdirSync as mkdirSync5, openSync as openSync10, readFileSync as readFileSync14, readdirSync as readdirSync7, rmdirSync as rmdirSync2, unlinkSync as unlinkSync3, ftruncateSync, writeSync as writeSync2 } from "fs";
17090
+ import { constants as constants10, closeSync as closeSync10, fstatSync as fstatSync10, lstatSync as lstatSync18, mkdirSync as mkdirSync6, openSync as openSync10, readFileSync as readFileSync14, readdirSync as readdirSync8, rmdirSync as rmdirSync2, unlinkSync as unlinkSync3, ftruncateSync, writeSync as writeSync2 } from "fs";
16786
17091
  import { join as join21 } from "path";
16787
17092
 
16788
17093
  // src/lib/preparation-process.ts
@@ -16841,7 +17146,7 @@ function claimPreparation(skillPath) {
16841
17146
  const state = join21(marker, "state.json"), active = join21(marker, "active");
16842
17147
  let created = false;
16843
17148
  try {
16844
- mkdirSync5(marker, { mode: 448 });
17149
+ mkdirSync6(marker, { mode: 448 });
16845
17150
  created = true;
16846
17151
  } catch (error) {
16847
17152
  if (error.code !== "EEXIST")
@@ -16852,7 +17157,7 @@ function claimPreparation(skillPath) {
16852
17157
  if (!lstatSync18(marker).isDirectory() || lstatSync18(marker).isSymbolicLink())
16853
17158
  return;
16854
17159
  if (!created) {
16855
- if (readdirSync7(marker).some((name) => name !== "state.json"))
17160
+ if (readdirSync8(marker).some((name) => name !== "state.json"))
16856
17161
  return;
16857
17162
  if (!lstatSync18(state).isFile() || lstatSync18(state).isSymbolicLink() || lstatSync18(state).size > 1024)
16858
17163
  return;
@@ -16860,7 +17165,7 @@ function claimPreparation(skillPath) {
16860
17165
  if (previous.version !== 1 || previous.status !== "failed" || Object.keys(previous).length !== 2)
16861
17166
  return;
16862
17167
  }
16863
- mkdirSync5(active, { mode: 448 });
17168
+ mkdirSync6(active, { mode: 448 });
16864
17169
  fd = openSync10(state, constants10.O_RDWR | constants10.O_NOFOLLOW | (created ? constants10.O_CREAT | constants10.O_EXCL : 0), 384);
16865
17170
  if (!fstatSync10(fd).isFile()) {
16866
17171
  closeSync10(fd);
@@ -16993,7 +17298,7 @@ import { existsSync as existsSync13, readFileSync as readFileSync25 } from "fs";
16993
17298
  import { join as join35 } from "path";
16994
17299
 
16995
17300
  // src/lib/installer.ts
16996
- import { existsSync as existsSync12, readFileSync as readFileSync23, rmSync as rmSync3 } from "fs";
17301
+ import { existsSync as existsSync12, readFileSync as readFileSync23, rmSync as rmSync4 } from "fs";
16997
17302
  import { join as join34 } from "path";
16998
17303
  import { homedir as homedir4 } from "os";
16999
17304
 
@@ -17002,12 +17307,12 @@ import {
17002
17307
  cpSync as cpSync2,
17003
17308
  existsSync as existsSync10,
17004
17309
  lstatSync as lstatSync29,
17005
- mkdirSync as mkdirSync9,
17006
- mkdtempSync,
17310
+ mkdirSync as mkdirSync10,
17311
+ mkdtempSync as mkdtempSync2,
17007
17312
  readFileSync as readFileSync20,
17008
- readdirSync as readdirSync11,
17313
+ readdirSync as readdirSync12,
17009
17314
  renameSync as renameSync5,
17010
- rmSync as rmSync2,
17315
+ rmSync as rmSync3,
17011
17316
  statSync as statSync12,
17012
17317
  writeFileSync as writeFileSync7
17013
17318
  } from "fs";
@@ -17016,7 +17321,7 @@ import { basename as basename12, dirname as dirname23, join as join32 } from "pa
17016
17321
 
17017
17322
  // src/lib/codex-native-skill-policy.ts
17018
17323
  import { createHash as createHash21, randomUUID as randomUUID3 } from "crypto";
17019
- import { closeSync as closeSync11, constants as constants11, fstatSync as fstatSync11, fsyncSync as fsyncSync3, lstatSync as lstatSync19, mkdirSync as mkdirSync6, openSync as openSync11, readFileSync as readFileSync15, readSync as readSync7, readlinkSync as readlinkSync4, realpathSync as realpathSync8, renameSync as renameSync3, unlinkSync as unlinkSync4, writeFileSync as writeFileSync4 } from "fs";
17324
+ import { closeSync as closeSync11, constants as constants11, fstatSync as fstatSync11, fsyncSync as fsyncSync3, lstatSync as lstatSync19, mkdirSync as mkdirSync7, openSync as openSync11, readFileSync as readFileSync15, readSync as readSync7, readlinkSync as readlinkSync4, realpathSync as realpathSync8, renameSync as renameSync3, unlinkSync as unlinkSync4, writeFileSync as writeFileSync4 } from "fs";
17020
17325
  import { dirname as dirname17, isAbsolute as isAbsolute18, join as join23, resolve as resolve17 } from "path";
17021
17326
  import { isDeepStrictEqual as isDeepStrictEqual6 } from "util";
17022
17327
  var CODEX_NATIVE_POLICY_CAPABILITY = "host-path-allowlist-v1";
@@ -17285,7 +17590,7 @@ function writeExecutableCache(dataDir2, entries) {
17285
17590
  return;
17286
17591
  const existing = lstatSync19(directory2, { throwIfNoEntry: false });
17287
17592
  if (!existing)
17288
- mkdirSync6(directory2, { mode: 448 });
17593
+ mkdirSync7(directory2, { mode: 448 });
17289
17594
  else if (existing.isSymbolicLink() || !existing.isDirectory())
17290
17595
  return;
17291
17596
  const holder = lstatSync19(directory2, { throwIfNoEntry: false, bigint: true });
@@ -17580,7 +17885,7 @@ function recordCodexNativePolicyAcceptance(dataDir2, verification, accepted) {
17580
17885
  ...verification.attestation ? { attestation: { schema: verification.attestation.schema, peerProcessId: verification.attestation.peerProcessId } } : {}
17581
17886
  };
17582
17887
  try {
17583
- mkdirSync6(directory2, { recursive: true, mode: 448 });
17888
+ mkdirSync7(directory2, { recursive: true, mode: 448 });
17584
17889
  const stat2 = lstatSync19(directory2);
17585
17890
  if (stat2.isSymbolicLink() || !stat2.isDirectory())
17586
17891
  throw new Error(`the receipt directory is not a real directory: ${directory2}`);
@@ -17612,9 +17917,10 @@ function recordCodexNativePolicyAcceptance(dataDir2, verification, accepted) {
17612
17917
 
17613
17918
  // src/lib/codex-semantic-cache-witness.ts
17614
17919
  import { createHash as createHash22 } from "crypto";
17615
- import { constants as constants12, closeSync as closeSync12, fstatSync as fstatSync12, lstatSync as lstatSync20, openSync as openSync12, readSync as readSync8, readdirSync as readdirSync8, realpathSync as realpathSync9 } from "fs";
17920
+ import { constants as constants12, closeSync as closeSync12, fstatSync as fstatSync12, lstatSync as lstatSync20, openSync as openSync12, readSync as readSync8, readdirSync as readdirSync9, realpathSync as realpathSync9 } from "fs";
17616
17921
  import { basename as basename10, dirname as dirname18, isAbsolute as isAbsolute19, join as join25, relative as relative8, resolve as resolve18, sep as sep11 } from "path";
17617
17922
  var CODEX_SEMANTIC_CACHE_WITNESS_SCHEMA = "hasna.codex-semantic-cache-witness.v1";
17923
+ var SEMANTIC_BOUND_ROOT_ENTRIES = Object.freeze([".codex-plugin", ".app.json", ".mcp.json", "hooks"]);
17618
17924
  var identifier5 = (value) => typeof value === "string" && /^[A-Za-z0-9_-]{1,64}$/.test(value);
17619
17925
  var digest = (value) => typeof value === "string" && /^[a-f0-9]{64}$/.test(value);
17620
17926
  var refuse4 = () => {
@@ -17777,7 +18083,7 @@ function assertCanonicalDirectory(path) {
17777
18083
  function walkSafeTree(path, state, depth = 0, root = path) {
17778
18084
  if (depth > 64 || ++state.entries > 16384)
17779
18085
  refuse4();
17780
- const names = readdirSync8(path).sort();
18086
+ const names = readdirSync9(path).sort();
17781
18087
  const files = [];
17782
18088
  for (const name of names) {
17783
18089
  if (!name || name === "." || name === ".." || name.includes(sep11) || ++state.entries > 16384)
@@ -17923,7 +18229,7 @@ function appOnlyParentProjection(cacheRoot, parents2, read2) {
17923
18229
  } catch {
17924
18230
  refuse4();
17925
18231
  }
17926
- const versions = readdirSync8(parent.pluginParent).filter((name) => name !== ".codex-remote-plugin-install.json");
18232
+ const versions = readdirSync9(parent.pluginParent).filter((name) => name !== ".codex-remote-plugin-install.json");
17927
18233
  if (!versions.length || versions.length > 4096)
17928
18234
  refuse4();
17929
18235
  const materializations = versions.map((version2) => {
@@ -18068,7 +18374,7 @@ function reviewedHookParentProjection(cacheRoot, parents2, read2) {
18068
18374
  if (createHash22("sha256").update(marketplaceText).digest("hex") !== parent.marketplaceSha256 || !codexLocalMarketplaceMapsPlugin(marketplaceText, parts[0], parent.namespace))
18069
18375
  refuse4();
18070
18376
  }
18071
- const materializations = readdirSync8(parent.pluginParent).filter((name) => name !== ".codex-remote-plugin-install.json").map((version2) => {
18377
+ const materializations = readdirSync9(parent.pluginParent).filter((name) => name !== ".codex-remote-plugin-install.json").map((version2) => {
18072
18378
  if (!/^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/.test(version2))
18073
18379
  refuse4();
18074
18380
  const root = join25(parent.pluginParent, version2), stat2 = lstatSync20(root, { throwIfNoEntry: false });
@@ -18102,14 +18408,14 @@ function assertParents(cacheRoot, controls, appOnlyParents, hookParents, files,
18102
18408
  refuse4();
18103
18409
  actual.add(join25(cacheRoot, parts[0], parts[1]));
18104
18410
  }
18105
- const actualMarkets = readdirSync8(cacheRoot);
18411
+ const actualMarkets = readdirSync9(cacheRoot);
18106
18412
  if (actualMarkets.length !== expectedMarkets.size || actualMarkets.some((market) => !expectedMarkets.has(market)))
18107
18413
  refuse4();
18108
18414
  for (const market of actualMarkets) {
18109
18415
  const marketPath = join25(cacheRoot, market), marketStat = lstatSync20(marketPath);
18110
18416
  if (!identifier5(market) || !marketStat.isDirectory() || marketStat.isSymbolicLink())
18111
18417
  refuse4();
18112
- for (const plugin of readdirSync8(marketPath)) {
18418
+ for (const plugin of readdirSync9(marketPath)) {
18113
18419
  const parent = join25(marketPath, plugin), stat2 = lstatSync20(parent);
18114
18420
  if (!identifier5(plugin) || !stat2.isDirectory() || stat2.isSymbolicLink())
18115
18421
  refuse4();
@@ -18124,14 +18430,23 @@ function assertParents(cacheRoot, controls, appOnlyParents, hookParents, files,
18124
18430
  continue;
18125
18431
  const parent = join25(cacheRoot, parts[0], parts[1]);
18126
18432
  const root = join25(parent, parts[2]);
18127
- const base = parts[parts.length - 1];
18128
- if (parts.includes(".codex-plugin") && (parts.length < 4 || parts[3] !== ".codex-plugin" || (parts.length === 4 ? base !== ".codex-plugin" : parts.length !== 5 || base !== "plugin.json")))
18433
+ const base = parts[parts.length - 1], folded = foldCodexPluginEntryName(base);
18434
+ if (parts.length === 3 && (codexPluginRootCapabilityEntry(base) !== null || isCodexSkillDocumentName(base)))
18435
+ refuse4();
18436
+ const rootEntry = parts.length >= 4 ? codexPluginRootCapabilityEntry(parts[3]) : null;
18437
+ if (rootEntry !== null && rootEntry !== parts[3])
18438
+ refuse4();
18439
+ if (rootEntry !== null && !SEMANTIC_BOUND_ROOT_ENTRIES.includes(rootEntry))
18129
18440
  refuse4();
18130
- if ([".app.json", ".mcp.json"].includes(base) && (parts.length !== 4 || dirname18(member) !== root))
18441
+ if (isCodexSkillDocumentName(base) && base !== "SKILL.md")
18131
18442
  refuse4();
18132
- if ([".app.json", ".mcp.json"].includes(base) && hookParents.some((reviewed) => reviewed.pluginParent === parent))
18443
+ if (parts.some((part) => CODEX_PLUGIN_MANIFEST_DIRECTORIES.includes(foldCodexPluginEntryName(part))) && (parts.length < 4 || parts[3] !== ".codex-plugin" || (parts.length === 4 ? base !== ".codex-plugin" : parts.length !== 5 || base !== "plugin.json")))
18133
18444
  refuse4();
18134
- if ((parts[3] === "hooks" || base === "hooks.json") && (![4, 5].includes(parts.length) || parts[3] !== "hooks" || (parts.length === 4 ? base !== "hooks" : base !== "hooks.json") || !hookParents.some((reviewed) => reviewed.pluginParent === join25(cacheRoot, parts[0], parts[1]))))
18445
+ if ([".app.json", ".mcp.json"].includes(folded) && (parts.length !== 4 || dirname18(member) !== root))
18446
+ refuse4();
18447
+ if ([".app.json", ".mcp.json"].includes(folded) && hookParents.some((reviewed) => reviewed.pluginParent === parent))
18448
+ refuse4();
18449
+ if ((rootEntry === "hooks" || folded === "hooks.json") && (![4, 5].includes(parts.length) || parts[3] !== "hooks" || (parts.length === 4 ? base !== "hooks" : base !== "hooks.json") || !hookParents.some((reviewed) => reviewed.pluginParent === join25(cacheRoot, parts[0], parts[1]))))
18135
18450
  refuse4();
18136
18451
  }
18137
18452
  }
@@ -18161,7 +18476,7 @@ function assertSkillMaterializations(cacheRoot, controls, files, read2) {
18161
18476
  const expectedNames = new Set(rows.map((row) => row.name));
18162
18477
  if (expectedNames.size !== rows.length)
18163
18478
  refuse4();
18164
- const entries = readdirSync8(parent);
18479
+ const entries = readdirSync9(parent);
18165
18480
  let roots = 0;
18166
18481
  for (const entry of entries) {
18167
18482
  if (entry === ".codex-remote-plugin-install.json")
@@ -18400,7 +18715,7 @@ function codexPluginCacheSkillTree(path, depth) {
18400
18715
  // src/lib/agent-integration.ts
18401
18716
  import { createHash as createHash27, randomUUID as randomUUID4 } from "crypto";
18402
18717
  import { isDeepStrictEqual as isDeepStrictEqual8 } from "util";
18403
- import { existsSync as existsSync9, lstatSync as lstatSync28, statSync as statSync11, mkdirSync as mkdirSync8, readFileSync as readFileSync19, readdirSync as readdirSync10, opendirSync as opendirSync4, readlinkSync as readlinkSync7, realpathSync as realpathSync12, renameSync as renameSync4, rmdirSync as rmdirSync3, writeFileSync as writeFileSync6, unlinkSync as unlinkSync5, chmodSync, openSync as openSync17, closeSync as closeSync17, fsyncSync as fsyncSync7, fstatSync as fstatSync17, readSync as readSync12, constants as constants18, linkSync as linkSync3 } from "fs";
18718
+ import { existsSync as existsSync9, lstatSync as lstatSync28, statSync as statSync11, mkdirSync as mkdirSync9, readFileSync as readFileSync19, readdirSync as readdirSync11, opendirSync as opendirSync4, readlinkSync as readlinkSync7, realpathSync as realpathSync12, renameSync as renameSync4, rmdirSync as rmdirSync3, writeFileSync as writeFileSync6, unlinkSync as unlinkSync5, chmodSync, openSync as openSync17, closeSync as closeSync17, fsyncSync as fsyncSync7, fstatSync as fstatSync17, readSync as readSync12, constants as constants18, linkSync as linkSync3 } from "fs";
18404
18719
  import { basename as basename11, dirname as dirname22, join as join31, resolve as resolve23, relative as relative9, isAbsolute as isAbsolute24, sep as sep14 } from "path";
18405
18720
  import { homedir as homedir2 } from "os";
18406
18721
 
@@ -18486,7 +18801,7 @@ function requiresCliSkillLoading(dataDir2 = getDataDirReadOnly()) {
18486
18801
 
18487
18802
  // src/lib/agent-bridge.ts
18488
18803
  import { createHash as createHash23 } from "crypto";
18489
- import { lstatSync as lstatSync23, readFileSync as readFileSync17, readdirSync as readdirSync9 } from "fs";
18804
+ import { lstatSync as lstatSync23, readFileSync as readFileSync17, readdirSync as readdirSync10 } from "fs";
18490
18805
  import { join as join28 } from "path";
18491
18806
  var CLI_BRIDGE_NAME = "skills-cli";
18492
18807
  var CLI_BRIDGE_VERSION = 1;
@@ -18516,7 +18831,7 @@ function isOwnedCliBridge(path, expectedPaths) {
18516
18831
  try {
18517
18832
  if (!lstatSync23(path).isDirectory())
18518
18833
  return false;
18519
- if (JSON.stringify(readdirSync9(path).sort()) !== JSON.stringify(Object.keys(CLI_BRIDGE_FILES).sort()))
18834
+ if (JSON.stringify(readdirSync10(path).sort()) !== JSON.stringify(Object.keys(CLI_BRIDGE_FILES).sort()))
18520
18835
  return false;
18521
18836
  return Object.entries(CLI_BRIDGE_FILES).every(([name, content]) => {
18522
18837
  const file = join28(path, name), stat2 = lstatSync23(file);
@@ -18796,7 +19111,7 @@ function disableCodexBundledSkills(text2) {
18796
19111
  }
18797
19112
 
18798
19113
  // src/lib/agent-sumi.ts
18799
- import { spawnSync as spawnSync4 } from "child_process";
19114
+ import { spawnSync as spawnSync5 } from "child_process";
18800
19115
  import { accessSync as accessSync2, constants as constants14, existsSync as existsSync8, lstatSync as lstatSync24, realpathSync as realpathSync10, statSync as statSync10 } from "fs";
18801
19116
  import { delimiter as delimiter2, isAbsolute as isAbsolute20, join as join29, resolve as resolve20 } from "path";
18802
19117
 
@@ -18954,7 +19269,7 @@ function sumiPathPlan(home, cwd = process.cwd(), env = process.env) {
18954
19269
  childEnv[key2] = env[key2];
18955
19270
  let child2;
18956
19271
  try {
18957
- child2 = spawnSync4(executable2, ["--json", "--home", resolve20(home), "--cwd", resolve20(cwd)], {
19272
+ child2 = spawnSync5(executable2, ["--json", "--home", resolve20(home), "--cwd", resolve20(cwd)], {
18958
19273
  cwd: resolve20(cwd),
18959
19274
  env: childEnv,
18960
19275
  encoding: "buffer",
@@ -19420,7 +19735,7 @@ function assertPinnedLauncherRuntimeSafe(runtime) {
19420
19735
 
19421
19736
  // src/lib/retained-review-artifacts.ts
19422
19737
  import { createHash as createHash26 } from "crypto";
19423
- import { constants as constants17, closeSync as closeSync16, fstatSync as fstatSync16, fsyncSync as fsyncSync6, lstatSync as lstatSync27, mkdirSync as mkdirSync7, openSync as openSync16, readSync as readSync11, writeSync as writeSync4 } from "fs";
19738
+ import { constants as constants17, closeSync as closeSync16, fstatSync as fstatSync16, fsyncSync as fsyncSync6, lstatSync as lstatSync27, mkdirSync as mkdirSync8, openSync as openSync16, readSync as readSync11, writeSync as writeSync4 } from "fs";
19424
19739
  import { dirname as dirname21, isAbsolute as isAbsolute23, join as join30, resolve as resolve22, sep as sep13 } from "path";
19425
19740
  var sha3 = (bytes) => createHash26("sha256").update(bytes).digest("hex");
19426
19741
  var hex = (value) => typeof value === "string" && /^[a-f0-9]{64}$/.test(value);
@@ -19550,7 +19865,7 @@ function writeReviewArtifactExclusive(change) {
19550
19865
  for (let parent = dirname21(change.path);!lstatSync27(parent, { throwIfNoEntry: false }); parent = dirname21(parent))
19551
19866
  missing2.push(parent);
19552
19867
  for (const parent of missing2.reverse())
19553
- mkdirSync7(parent, { mode: 448 });
19868
+ mkdirSync8(parent, { mode: 448 });
19554
19869
  safe4(change.path);
19555
19870
  privateStore(change.artifact.storeRoot);
19556
19871
  for (let parent = dirname21(change.path);parent !== change.artifact.storeRoot; parent = dirname21(parent)) {
@@ -19800,7 +20115,7 @@ function treeHash(root) {
19800
20115
  const rel = relative9(root, path);
19801
20116
  if (stat2.isDirectory()) {
19802
20117
  hash3.update(`d\x00${rel}\x00`);
19803
- for (const name of readdirSync10(path).sort())
20118
+ for (const name of readdirSync11(path).sort())
19804
20119
  visit2(join31(path, name));
19805
20120
  return;
19806
20121
  }
@@ -20695,7 +21010,7 @@ function planClaudeHookEventsUpdate(options) {
20695
21010
  }
20696
21011
  function atomicWrite2(path, content) {
20697
21012
  assertSafePath(path);
20698
- mkdirSync8(dirname22(path), { recursive: true, mode: 448 });
21013
+ mkdirSync9(dirname22(path), { recursive: true, mode: 448 });
20699
21014
  const temporary = `${path}.skills-${randomUUID4()}`;
20700
21015
  try {
20701
21016
  writeFileSync6(temporary, content, { mode: 384, flag: "wx" });
@@ -20863,7 +21178,7 @@ function planCodexSemanticCacheWitnessUpgrade(options) {
20863
21178
  throw new Error("Local marketplace hook parent is not enabled in the unchanged Codex settings");
20864
21179
  identity5 = { role: "reviewed-hook", pluginId: pluginId2, namespace: parts[1], pluginParent: parent, installation: "local-marketplace", marketplaceSourcePath: source.path, marketplaceSha256: source.sha256 };
20865
21180
  }
20866
- const versions = readdirSync10(parent).filter((name) => name !== ".codex-remote-plugin-install.json");
21181
+ const versions = readdirSync11(parent).filter((name) => name !== ".codex-remote-plugin-install.json");
20867
21182
  if (!versions.length || versions.length > 4096)
20868
21183
  throw new Error("Reviewed native-hook parent has no bounded materializations");
20869
21184
  for (const version2 of versions) {
@@ -20957,9 +21272,10 @@ function applyAgentIntegration(plan, options = {}) {
20957
21272
  const alias = plan.rootAliases?.find((item) => item.agent === "codex" && (change.path === item.target || change.path.startsWith(item.target + "/")));
20958
21273
  return lexical ? [lexical] : alias ? [alias.alias] : [];
20959
21274
  });
20960
- return withCodexCorpusWrite(roots, (assertCurrent) => applyAgentIntegrationUnlocked(plan, options, assertCurrent), options);
21275
+ return withCodexCorpusWrite(roots, (assertCurrent, admission) => applyAgentIntegrationUnlocked(plan, options, assertCurrent, admission), options);
20961
21276
  }
20962
- function applyAgentIntegrationUnlocked(plan, options = {}, assertCurrent) {
21277
+ function applyAgentIntegrationUnlocked(plan, options = {}, assertCurrent, admission) {
21278
+ const fallback = codexAdmissionReceipt(admission);
20963
21279
  for (const source of plan.reviewArtifactSources ?? [])
20964
21280
  verifyReviewArtifactOriginal(source.path, source.sha256);
20965
21281
  for (const source of plan.observedNativeSources ?? [])
@@ -21023,10 +21339,10 @@ function applyAgentIntegrationUnlocked(plan, options = {}, assertCurrent) {
21023
21339
  recheckRootAliases(aliases);
21024
21340
  for (const agent of plan.retainedReviewChecks?.agents ?? [])
21025
21341
  assertManagedAgentBridge(agent, { ...plan.retainedReviewChecks, dataDir: plan.dataDir });
21026
- return { changed: [], backups, ...aliases.length ? { rootAliases: aliases } : {} };
21342
+ return { changed: [], backups, ...aliases.length ? { rootAliases: aliases } : {}, ...fallback };
21027
21343
  }
21028
21344
  assertSafePath(backupRoot);
21029
- mkdirSync8(backupRoot, { recursive: true, mode: 448 });
21345
+ mkdirSync9(backupRoot, { recursive: true, mode: 448 });
21030
21346
  chmodSync(backupRoot, 448);
21031
21347
  for (const [index, change] of plan.changes.entries())
21032
21348
  if (change.before !== null) {
@@ -21074,7 +21390,7 @@ function applyAgentIntegrationUnlocked(plan, options = {}, assertCurrent) {
21074
21390
  assertManagedAgentBridge(agent, { home: plan.managedAgentChecks.home, dataDir: plan.dataDir, projectDir: plan.managedAgentChecks.projectDir ?? plan.managedAgentChecks.home });
21075
21391
  for (const agent of plan.retainedReviewChecks?.agents ?? [])
21076
21392
  assertManagedAgentBridge(agent, { ...plan.retainedReviewChecks, dataDir: plan.dataDir });
21077
- atomicWrite2(join31(backupRoot, "receipt.json"), JSON.stringify({ version: 1, changes: written.map((change) => ({ path: change.path, beforeHash: change.before === null ? null : sha4(change.before), afterHash: sha4(change.after) })), backups, ...plan.cacheWitnessUpgrade ? { cacheWitnessUpgrade: plan.cacheWitnessUpgrade } : {}, ...plan.retainedReviewArtifacts?.length ? { retainedReviewArtifacts: plan.retainedReviewArtifacts.map((item) => ({ path: item.path, ...item.artifact })) } : {}, ...aliases.length ? { rootAliases: aliases } : {} }) + `
21393
+ atomicWrite2(join31(backupRoot, "receipt.json"), JSON.stringify({ version: 1, changes: written.map((change) => ({ path: change.path, beforeHash: change.before === null ? null : sha4(change.before), afterHash: sha4(change.after) })), backups, ...plan.cacheWitnessUpgrade ? { cacheWitnessUpgrade: plan.cacheWitnessUpgrade } : {}, ...plan.retainedReviewArtifacts?.length ? { retainedReviewArtifacts: plan.retainedReviewArtifacts.map((item) => ({ path: item.path, ...item.artifact })) } : {}, ...aliases.length ? { rootAliases: aliases } : {}, ...fallback }) + `
21078
21394
  `);
21079
21395
  } catch (error) {
21080
21396
  assertCurrent();
@@ -21102,7 +21418,7 @@ function applyAgentIntegrationUnlocked(plan, options = {}, assertCurrent) {
21102
21418
  }
21103
21419
  throw error;
21104
21420
  }
21105
- return { changed: plan.changes.map((change) => change.path), backups, ...aliases.length ? { rootAliases: aliases } : {} };
21421
+ return { changed: plan.changes.map((change) => change.path), backups, ...aliases.length ? { rootAliases: aliases } : {}, ...fallback };
21106
21422
  }
21107
21423
  function syncArchiveDirectory(path) {
21108
21424
  assertSafePath(path);
@@ -21142,9 +21458,10 @@ function archiveNativeSkills(inventory, options) {
21142
21458
  throw new Error("CODEX_CORPUS_ROOT_UNVERIFIED");
21143
21459
  return [...new Set([root, owner2].filter((value) => value !== undefined))];
21144
21460
  });
21145
- return withCodexCorpusWrite(roots, (assertCurrent) => archiveNativeSkillsUnlocked(inventory, options, assertCurrent), options);
21461
+ return withCodexCorpusWrite(roots, (assertCurrent, admission) => archiveNativeSkillsUnlocked(inventory, options, assertCurrent, admission), options);
21146
21462
  }
21147
- function archiveNativeSkillsUnlocked(inventory, options, assertCurrent) {
21463
+ function archiveNativeSkillsUnlocked(inventory, options, assertCurrent, admission) {
21464
+ const fallback = codexAdmissionReceipt(admission);
21148
21465
  const aliases = [...new Map(inventory.filter((entry) => entry.rootAlias).map((entry) => [entry.rootAlias.alias, entry.rootAlias])).values()];
21149
21466
  if (aliases.length && !options.allowRootAliases)
21150
21467
  throw new Error("Native migration requires explicit allowRootAliases for agent root aliases");
@@ -21162,7 +21479,7 @@ function archiveNativeSkillsUnlocked(inventory, options, assertCurrent) {
21162
21479
  throw new Error(`Native skill changed after planning: ${entry.path}`);
21163
21480
  const targetManifest = options.targetManifest ? { schema: options.targetManifest.schema, digest: options.targetManifest.digest, targetCount: options.targetManifest.targets.length } : undefined;
21164
21481
  if (!selected.length)
21165
- return { entries: [], ...targetManifest ? { targetManifest } : {}, ...aliases.length ? { rootAliases: aliases } : {} };
21482
+ return { entries: [], ...targetManifest ? { targetManifest } : {}, ...aliases.length ? { rootAliases: aliases } : {}, ...fallback };
21166
21483
  const operationId = randomUUID4(), archiveRoot = join31(options.dataDir ?? getDataDir(), "migration", operationId, "native"), receiptPath = join31(archiveRoot, "receipt.json");
21167
21484
  const entries = selected.map((entry, index) => ({
21168
21485
  source: entry.vendor ? join31(entry.path, "SKILL.md") : entry.path,
@@ -21171,7 +21488,7 @@ function archiveNativeSkillsUnlocked(inventory, options, assertCurrent) {
21171
21488
  ...entry.vendor ? { discoveryOnly: true } : {},
21172
21489
  status: "planned"
21173
21490
  }));
21174
- const journal = { version: 2, operationId, status: "planned", entries, ...targetManifest ? { targetManifest } : {}, ...aliases.length ? { rootAliases: aliases } : {} };
21491
+ const journal = { version: 2, operationId, status: "planned", entries, ...targetManifest ? { targetManifest } : {}, ...aliases.length ? { rootAliases: aliases } : {}, ...fallback };
21175
21492
  const moved = [];
21176
21493
  const verifyArchive = (entry) => {
21177
21494
  assertSafePath(entry.archive);
@@ -21185,7 +21502,7 @@ function archiveNativeSkillsUnlocked(inventory, options, assertCurrent) {
21185
21502
  const created = [];
21186
21503
  for (let path = archiveRoot;!existsSync9(path); path = dirname22(path))
21187
21504
  created.push(path);
21188
- mkdirSync8(archiveRoot, { recursive: true, mode: 448 });
21505
+ mkdirSync9(archiveRoot, { recursive: true, mode: 448 });
21189
21506
  try {
21190
21507
  for (const directory2 of created)
21191
21508
  syncArchiveDirectory(directory2);
@@ -21268,7 +21585,7 @@ function archiveNativeSkillsUnlocked(inventory, options, assertCurrent) {
21268
21585
  } catch {}
21269
21586
  throw new Error(`Native archive failed; inspect the recovery journal at ${receiptPath} before retrying.`, { cause: error });
21270
21587
  }
21271
- return { entries: entries.map(({ status, conflict, ...entry }) => entry), receiptPath, ...targetManifest ? { targetManifest } : {}, ...aliases.length ? { rootAliases: aliases } : {} };
21588
+ return { entries: entries.map(({ status, conflict, ...entry }) => entry), receiptPath, ...targetManifest ? { targetManifest } : {}, ...aliases.length ? { rootAliases: aliases } : {}, ...fallback };
21272
21589
  }
21273
21590
  function classifiedCodexPluginCacheCopy(entry, cache, read2, admit) {
21274
21591
  try {
@@ -21716,7 +22033,7 @@ function packageSourceRoots(source) {
21716
22033
  function containsSkillDirectories(path) {
21717
22034
  let entries;
21718
22035
  try {
21719
- entries = readdirSync11(path);
22036
+ entries = readdirSync12(path);
21720
22037
  } catch {
21721
22038
  return false;
21722
22039
  }
@@ -21811,12 +22128,16 @@ function writeManagedAgentSkill(params) {
21811
22128
  agent: params.agent,
21812
22129
  path: result.path,
21813
22130
  action: result.action,
21814
- ...result.reason ? { reason: result.reason } : {}
22131
+ ...result.reason ? { reason: result.reason } : {},
22132
+ ...result.nativeAdmission ? { nativeAdmission: result.nativeAdmission, nativeAdmissionProbe: result.nativeAdmissionProbe } : {}
21815
22133
  };
21816
22134
  }
21817
22135
  function writeManagedSkillDir(dir, skillMd, options) {
21818
22136
  const root = options.dryRun ? undefined : codexCorpusRootForPath(dir);
21819
- return withCodexCorpusWrite(root ? [root] : [], (assertCurrent) => writeManagedSkillDirUnlocked(dir, skillMd, options, assertCurrent), options);
22137
+ return withCodexCorpusWrite(root ? [root] : [], (assertCurrent, admission) => {
22138
+ const result = writeManagedSkillDirUnlocked(dir, skillMd, options, assertCurrent);
22139
+ return { ...result, ...codexAdmissionReceipt(admission) };
22140
+ }, options);
21820
22141
  }
21821
22142
  function writeManagedSkillDirUnlocked(dir, skillMd, options, assertCurrent) {
21822
22143
  const skillMdPath = join32(dir, "SKILL.md");
@@ -21857,8 +22178,8 @@ function writeManagedSkillDirUnlocked(dir, skillMd, options, assertCurrent) {
21857
22178
  if (options.dryRun)
21858
22179
  return { action, path: skillMdPath };
21859
22180
  const parentDir = dirname23(dir);
21860
- mkdirSync9(parentDir, { recursive: true });
21861
- const transactionDir = mkdtempSync(join32(parentDir, `.hasna-skills-write-${basename12(dir)}-`));
22181
+ mkdirSync10(parentDir, { recursive: true });
22182
+ const transactionDir = mkdtempSync2(join32(parentDir, `.hasna-skills-write-${basename12(dir)}-`));
21862
22183
  const candidateDir = join32(transactionDir, "candidate");
21863
22184
  const backupDir = join32(transactionDir, "backup");
21864
22185
  const candidateSkillMdPath = join32(candidateDir, "SKILL.md");
@@ -21876,7 +22197,7 @@ function writeManagedSkillDirUnlocked(dir, skillMd, options, assertCurrent) {
21876
22197
  if (options.resourceDir) {
21877
22198
  cpSync2(options.resourceDir, candidateDir, { recursive: true, force: true });
21878
22199
  } else {
21879
- mkdirSync9(candidateDir, { recursive: true });
22200
+ mkdirSync10(candidateDir, { recursive: true });
21880
22201
  }
21881
22202
  writeFileSync7(candidateSkillMdPath, skillMd.endsWith(`
21882
22203
  `) ? skillMd : `${skillMd}
@@ -21900,7 +22221,7 @@ function writeManagedSkillDirUnlocked(dir, skillMd, options, assertCurrent) {
21900
22221
  try {
21901
22222
  assertCurrent();
21902
22223
  if (existsSync10(dir))
21903
- rmSync2(dir, { recursive: true, force: true });
22224
+ rmSync3(dir, { recursive: true, force: true });
21904
22225
  renameDirectory(backupDir, dir);
21905
22226
  originalMoved = false;
21906
22227
  } catch (rollbackError) {
@@ -21913,22 +22234,26 @@ function writeManagedSkillDirUnlocked(dir, skillMd, options, assertCurrent) {
21913
22234
  if (!preserveTransaction) {
21914
22235
  try {
21915
22236
  assertCurrent();
21916
- rmSync2(transactionDir, { recursive: true, force: true });
22237
+ rmSync3(transactionDir, { recursive: true, force: true });
21917
22238
  } catch {}
21918
22239
  }
21919
22240
  }
21920
22241
  return { action, path: skillMdPath };
21921
22242
  }
21922
22243
  function removeManagedAgentSkill(skill, agent, homeDir2 = homedir3(), options = {}) {
22244
+ const record5 = codexAdmissionRecord(options);
21923
22245
  const dir = join32(agentGlobalSkillsDir(agent, homeDir2), skill);
21924
22246
  const root = codexCorpusRootForPath(dir);
21925
- return withCodexCorpusWrite(root ? [root] : [], () => removeManagedAgentSkillUnlocked(skill, agent, homeDir2, options), options);
22247
+ return withCodexCorpusWrite(root ? [root] : [], (_assertCurrent, admission) => {
22248
+ record5.deliver(admission);
22249
+ return removeManagedAgentSkillUnlocked(skill, agent, homeDir2, options);
22250
+ }, options, record5.policy);
21926
22251
  }
21927
22252
  function removeManagedAgentSkillUnlocked(skill, agent, homeDir2 = homedir3(), options = {}) {
21928
22253
  const dir = join32(agentGlobalSkillsDir(agent, homeDir2), skill);
21929
22254
  if (!hasSkillsOwnershipMarker(dir))
21930
22255
  return false;
21931
- rmSync2(dir, { recursive: true, force: true });
22256
+ rmSync3(dir, { recursive: true, force: true });
21932
22257
  return true;
21933
22258
  }
21934
22259
  function sourceSkillMd(skillPath, name, description, kind, preferBundledDocs = false) {
@@ -21975,7 +22300,7 @@ function resolveSkillAlias(name) {
21975
22300
  }
21976
22301
 
21977
22302
  // src/lib/project-state.ts
21978
- import { existsSync as existsSync11, mkdirSync as mkdirSync10, readFileSync as readFileSync21, writeFileSync as writeFileSync8 } from "fs";
22303
+ import { existsSync as existsSync11, mkdirSync as mkdirSync11, readFileSync as readFileSync21, writeFileSync as writeFileSync8 } from "fs";
21979
22304
  import { join as join33 } from "path";
21980
22305
  var VALID_PIN_SOURCES = [
21981
22306
  "official",
@@ -22022,7 +22347,7 @@ function ensureProjectConfig(targetDir = process.cwd()) {
22022
22347
  }
22023
22348
  function saveProjectConfig(config, targetDir = process.cwd()) {
22024
22349
  const dir = getProjectStateDir(targetDir);
22025
- mkdirSync10(dir, { recursive: true });
22350
+ mkdirSync11(dir, { recursive: true });
22026
22351
  const normalized2 = normalizeProjectConfig({ ...config, updatedAt: new Date().toISOString() });
22027
22352
  writeFileSync8(getProjectConfigPath(targetDir), JSON.stringify(normalized2, null, 2) + `
22028
22353
  `);
@@ -22291,15 +22616,20 @@ function installSkillForAgent(name, options, generateSkillMd) {
22291
22616
  codexCommand: options.codexCommand,
22292
22617
  codexSha256: options.codexSha256
22293
22618
  });
22619
+ const fallback = result.nativeAdmission ? { nativeAdmission: result.nativeAdmission, nativeAdmissionProbe: result.nativeAdmissionProbe } : {};
22294
22620
  if (result.action === "skip") {
22295
- return { skill: canonicalName, success: false, error: result.reason ?? "skipped", path: result.path };
22621
+ return { skill: canonicalName, success: false, error: result.reason ?? "skipped", path: result.path, ...fallback };
22296
22622
  }
22297
- return { skill: canonicalName, success: true, path: result.path };
22623
+ return { skill: canonicalName, success: true, path: result.path, ...fallback };
22298
22624
  }
22299
22625
  function removeSkillForAgent(name, options) {
22626
+ const record5 = codexAdmissionRecord(options);
22300
22627
  const dir = getAgentSkillPath(name, options.agent, options.scope ?? "global", options.projectDir);
22301
22628
  const root = codexCorpusRootForPath(dir);
22302
- return withCodexCorpusWrite(root ? [root] : [], () => removeSkillForAgentUnlocked(name, options), options);
22629
+ return withCodexCorpusWrite(root ? [root] : [], (_assertCurrent, admission) => {
22630
+ record5.deliver(admission);
22631
+ return removeSkillForAgentUnlocked(name, options);
22632
+ }, options, record5.policy);
22303
22633
  }
22304
22634
  function removeSkillForAgentUnlocked(name, options) {
22305
22635
  const canonicalName = getCanonicalSkillName(name);
@@ -22307,7 +22637,7 @@ function removeSkillForAgentUnlocked(name, options) {
22307
22637
  const dir = getAgentSkillPath(canonicalName, options.agent, scope, options.projectDir);
22308
22638
  if (!hasSkillsOwnershipMarker(dir))
22309
22639
  return false;
22310
- rmSync3(dir, { recursive: true, force: true });
22640
+ rmSync4(dir, { recursive: true, force: true });
22311
22641
  return true;
22312
22642
  }
22313
22643
  function resolveAgentSkillMd(name, generateSkillMd) {
@@ -24465,13 +24795,13 @@ function assertProjectDiscovery(agent, directories, home, canonical9 = resolve27
24465
24795
  for (const name of ["plugin", "plugins"]) {
24466
24796
  const path = canonical9(join38(directory2, ".sumi", name));
24467
24797
  safe6(path);
24468
- if (lstatSync32(path, { throwIfNoEntry: false })?.isDirectory() && readdirSync12(path).length)
24798
+ if (lstatSync32(path, { throwIfNoEntry: false })?.isDirectory() && readdirSync13(path).length)
24469
24799
  throw new Error(`NATIVE_SKILL_DRIFT: project Sumi plugins require a dedicated discovery review: ${path}`);
24470
24800
  }
24471
24801
  if (agent === "claude") {
24472
24802
  const commands = canonical9(join38(directory2, ".claude/commands"));
24473
24803
  safe6(commands);
24474
- if (lstatSync32(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync12(commands).length)
24804
+ if (lstatSync32(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync13(commands).length)
24475
24805
  throw new Error("NATIVE_SKILL_DRIFT: legacy project command discovery requires a dedicated format adapter");
24476
24806
  }
24477
24807
  }
@@ -24620,7 +24950,7 @@ function resolveAgentDiscovery(options) {
24620
24950
  for (const path of plugins) {
24621
24951
  safe6(path);
24622
24952
  if (lstatSync32(path, { throwIfNoEntry: false })?.isDirectory())
24623
- for (const name of readdirSync12(path).sort()) {
24953
+ for (const name of readdirSync13(path).sort()) {
24624
24954
  if (name === "skills-cli.js" && path === plugins[1])
24625
24955
  continue;
24626
24956
  const target = join38(path, name);
@@ -24631,7 +24961,7 @@ function resolveAgentDiscovery(options) {
24631
24961
  }
24632
24962
  for (const root2 of roots) {
24633
24963
  safe6(root2);
24634
- if (lstatSync32(root2, { throwIfNoEntry: false })?.isDirectory() && readdirSync12(root2).some((name) => name.endsWith(".md")))
24964
+ if (lstatSync32(root2, { throwIfNoEntry: false })?.isDirectory() && readdirSync13(root2).some((name) => name.endsWith(".md")))
24635
24965
  unresolved("flat markdown skills require a dedicated native migration adapter");
24636
24966
  }
24637
24967
  }
@@ -24675,7 +25005,7 @@ function resolveAgentDiscovery(options) {
24675
25005
  safe6(builtinRoot);
24676
25006
  if (!lstatSync32(builtinRoot, { throwIfNoEntry: false })?.isDirectory())
24677
25007
  unresolved("installed Gemini builtin root is missing");
24678
- for (const name of readdirSync12(builtinRoot).sort()) {
25008
+ for (const name of readdirSync13(builtinRoot).sort()) {
24679
25009
  const text2 = witness(join38(builtinRoot, name, "SKILL.md"));
24680
25010
  const match = text2?.match(/^---\r?\n[\s\S]*?^name:\s*([a-z0-9][a-z0-9-]*)\s*$/m);
24681
25011
  if (!match?.[1] || builtinNames.includes(match[1]))
@@ -24773,7 +25103,7 @@ function resolveAgentDiscovery(options) {
24773
25103
  unresolved("plugin hooks require a separate no-skill-injection review");
24774
25104
  const commands = join38(root2, "commands");
24775
25105
  safe6(commands);
24776
- if (agent === "claude" && (manifest.commands !== undefined || lstatSync32(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync12(commands).length))
25106
+ if (agent === "claude" && (manifest.commands !== undefined || lstatSync32(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync13(commands).length))
24777
25107
  unresolved("legacy command discovery requires retirement or a dedicated format adapter");
24778
25108
  const rootSkill = witness(join38(root2, "SKILL.md"));
24779
25109
  if (rootSkill !== null)
@@ -24795,7 +25125,7 @@ function resolveAgentDiscovery(options) {
24795
25125
  const installed = registrations === null ? {} : parseConfig(registrations, join38(home, ".claude/plugins/installed_plugins.json")).plugins;
24796
25126
  const commands = canonical9(join38(home, ".claude/commands"));
24797
25127
  safe6(commands);
24798
- if (lstatSync32(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync12(commands).length)
25128
+ if (lstatSync32(commands, { throwIfNoEntry: false })?.isDirectory() && readdirSync13(commands).length)
24799
25129
  unresolved("legacy home command discovery requires a dedicated format adapter");
24800
25130
  for (const [id, enabled] of Object.entries(config.enabledPlugins ?? {})) {
24801
25131
  if (enabled === false)
@@ -24837,7 +25167,7 @@ function resolveAgentDiscovery(options) {
24837
25167
  }
24838
25168
  const localPlugins = join38(home, ".config/opencode/plugins");
24839
25169
  safe6(localPlugins);
24840
- if (lstatSync32(localPlugins, { throwIfNoEntry: false }) && readdirSync12(localPlugins).some((name) => name !== "skills-cli.js"))
25170
+ if (lstatSync32(localPlugins, { throwIfNoEntry: false }) && readdirSync13(localPlugins).some((name) => name !== "skills-cli.js"))
24841
25171
  unresolved("additional local plugin hooks require review");
24842
25172
  } else if (agent === "sumi") {
24843
25173
  if ((config.plugin?.length ?? 0) > 0 || (config.plugins?.length ?? 0) > 0 || sources.some((source) => source.path !== canonical9(configPath) && source.path !== canonical9(join38(sumiConfigDirectory(home), "sumi.jsonc")) && source.sha256 !== null))
@@ -24856,7 +25186,7 @@ function resolveAgentDiscovery(options) {
24856
25186
  const directory2 = join38(home, ".gemini/extensions");
24857
25187
  safe6(directory2);
24858
25188
  if (lstatSync32(directory2, { throwIfNoEntry: false }))
24859
- for (const name of readdirSync12(directory2)) {
25189
+ for (const name of readdirSync13(directory2)) {
24860
25190
  const root2 = join38(directory2, name);
24861
25191
  safe6(root2);
24862
25192
  if (!lstatSync32(root2)?.isDirectory())
@@ -24901,7 +25231,7 @@ function physicalPath(path) {
24901
25231
  }
24902
25232
  return resolve28(realpathSync14(cursor), ...suffix);
24903
25233
  }
24904
- function contains(root2, path) {
25234
+ function contains2(root2, path) {
24905
25235
  return path === root2 || path.startsWith(root2 + sep16);
24906
25236
  }
24907
25237
  function configuredRoots(home, explicitHome) {
@@ -24954,14 +25284,14 @@ function assertPortableAuthoringPath(path, options = {}) {
24954
25284
  const defaults = NATIVE_DISCOVERY_ROOTS.map((parts) => join39(home, ...parts));
24955
25285
  defaults.push(join39(home, ".codex/plugins/cache"), join39(home, ".claude/plugins/cache"), join39(home, ".claude/plugins/synced"), join39(home, ".gemini/extensions"));
24956
25286
  for (const root2 of defaults) {
24957
- if (candidates.some((candidate2) => contains(resolve28(root2), candidate2) || contains(physicalPath(root2), candidate2)))
25287
+ if (candidates.some((candidate2) => contains2(resolve28(root2), candidate2) || contains2(physicalPath(root2), candidate2)))
24958
25288
  native ??= root2;
24959
25289
  }
24960
25290
  if (native) {
24961
25291
  throw new Error(`Refusing portable Skills authoring below native discovery root '${native}': ${lexical}. Set HASNA_SKILLS_DIR to a private authoring corpus outside native roots.`);
24962
25292
  }
24963
25293
  for (const root2 of configuredRoots(home, options.homeDir !== undefined)) {
24964
- if (candidates.some((candidate2) => contains(resolve28(root2), candidate2) || contains(physicalPath(root2), candidate2))) {
25294
+ if (candidates.some((candidate2) => contains2(resolve28(root2), candidate2) || contains2(physicalPath(root2), candidate2))) {
24965
25295
  throw new Error(`Refusing portable Skills authoring below configured native discovery root: ${lexical}`);
24966
25296
  }
24967
25297
  }
@@ -25004,7 +25334,7 @@ function listPortableSkills(options = {}) {
25004
25334
  if (!safeIsDirectory(root2))
25005
25335
  return [];
25006
25336
  const skills = [];
25007
- for (const entry of readdirSync13(root2).sort()) {
25337
+ for (const entry of readdirSync14(root2).sort()) {
25008
25338
  if (entry.startsWith("."))
25009
25339
  continue;
25010
25340
  const path = join40(root2, entry);
@@ -25048,7 +25378,7 @@ function scaffoldPortableSkill(name, options = {}) {
25048
25378
  if (existsSync14(skillPath)) {
25049
25379
  if (!options.overwrite)
25050
25380
  throw new Error(`Skill '${skillName}' already exists at ${skillPath}`);
25051
- rmSync4(skillPath, { recursive: true, force: true });
25381
+ rmSync5(skillPath, { recursive: true, force: true });
25052
25382
  }
25053
25383
  const kind = options.kind ?? "executable";
25054
25384
  const description = options.description ?? `${displayName(skillName)} skill`;
@@ -25075,7 +25405,7 @@ function portPortableSkillDirectory(sourceDir, options = {}) {
25075
25405
  };
25076
25406
  const imported = [];
25077
25407
  const skipped = [];
25078
- const entries = readdirSync13(absoluteSource, { withFileTypes: true }).map((entry) => entry.name).filter((entryName) => !entryName.startsWith(".")).sort();
25408
+ const entries = readdirSync14(absoluteSource, { withFileTypes: true }).map((entry) => entry.name).filter((entryName) => !entryName.startsWith(".")).sort();
25079
25409
  for (const entryName of entries) {
25080
25410
  const childPath = join40(absoluteSource, entryName);
25081
25411
  if (!safeIsDirectory(childPath))
@@ -25120,11 +25450,11 @@ function physicalImportPath(path) {
25120
25450
  function assertDisjointImportPaths(source, destination) {
25121
25451
  const sourcePath = realpathSync15(source);
25122
25452
  const destinationPath = physicalImportPath(destination);
25123
- const contains2 = (parent, child2) => {
25453
+ const contains3 = (parent, child2) => {
25124
25454
  const path = relative11(parent, child2);
25125
25455
  return path === "" || !isAbsolute29(path) && path !== ".." && !path.startsWith(`..${sep17}`);
25126
25456
  };
25127
- if (contains2(sourcePath, destinationPath) || contains2(destinationPath, sourcePath)) {
25457
+ if (contains3(sourcePath, destinationPath) || contains3(destinationPath, sourcePath)) {
25128
25458
  throw new Error("Source and destination skill directories must not overlap");
25129
25459
  }
25130
25460
  }
@@ -25151,9 +25481,9 @@ function portPortableSkill(sourcePath, options = {}) {
25151
25481
  if (existsSync14(destination)) {
25152
25482
  if (!options.overwrite)
25153
25483
  throw new Error(`Skill '${skillName}' already exists at ${destination}`);
25154
- rmSync4(destination, { recursive: true, force: true });
25484
+ rmSync5(destination, { recursive: true, force: true });
25155
25485
  }
25156
- mkdirSync11(dirname28(destination), { recursive: true });
25486
+ mkdirSync12(dirname28(destination), { recursive: true });
25157
25487
  copySkillDirectory(absoluteSource, destination);
25158
25488
  const base = {
25159
25489
  ...inferred,
@@ -25195,7 +25525,7 @@ function writeCorpusSkill(input, options = {}) {
25195
25525
  const skillPath = join40(root2, name);
25196
25526
  assertPortableAuthoringPath(skillPath, options);
25197
25527
  const created = !existsSync14(skillPath);
25198
- mkdirSync11(skillPath, { recursive: true });
25528
+ mkdirSync12(skillPath, { recursive: true });
25199
25529
  writeFileSync9(join40(skillPath, "SKILL.md"), input.skillMd);
25200
25530
  const manifest = buildCorpusManifest(input, name);
25201
25531
  writeSkillJsonWithHash(skillPath, manifest);
@@ -25209,8 +25539,8 @@ function installCorpusSkillAtomically(input, options = {}) {
25209
25539
  const target = join40(root2, name);
25210
25540
  assertPortableAuthoringPath(target, options);
25211
25541
  const created = !existsSync14(target);
25212
- mkdirSync11(root2, { recursive: true });
25213
- const staging = mkdtempSync2(join40(root2, `.pull-${name}-`));
25542
+ mkdirSync12(root2, { recursive: true });
25543
+ const staging = mkdtempSync3(join40(root2, `.pull-${name}-`));
25214
25544
  let moved = false;
25215
25545
  let backup = null;
25216
25546
  try {
@@ -25218,16 +25548,16 @@ function installCorpusSkillAtomically(input, options = {}) {
25218
25548
  const manifest = buildCorpusManifest(input, name);
25219
25549
  writeSkillJsonWithHash(staging, manifest);
25220
25550
  if (existsSync14(target)) {
25221
- backup = mkdtempSync2(join40(root2, `.pull-backup-${name}-`));
25551
+ backup = mkdtempSync3(join40(root2, `.pull-backup-${name}-`));
25222
25552
  renameSync6(target, join40(backup, name));
25223
25553
  moved = true;
25224
25554
  }
25225
25555
  renameSync6(staging, target);
25226
25556
  if (moved && backup)
25227
- rmSync4(backup, { recursive: true, force: true });
25557
+ rmSync5(backup, { recursive: true, force: true });
25228
25558
  return { name, path: target, manifest, created };
25229
25559
  } catch (error) {
25230
- rmSync4(staging, { recursive: true, force: true });
25560
+ rmSync5(staging, { recursive: true, force: true });
25231
25561
  if (moved && backup && existsSync14(join40(backup, name))) {
25232
25562
  try {
25233
25563
  renameSync6(join40(backup, name), target);
@@ -25523,7 +25853,7 @@ function discoverSkillsInDir(dir, source = "custom") {
25523
25853
  return [];
25524
25854
  const result = [];
25525
25855
  try {
25526
- const entries = readdirSync14(dir, { withFileTypes: true });
25856
+ const entries = readdirSync15(dir, { withFileTypes: true });
25527
25857
  for (const entry of entries) {
25528
25858
  if (!entry.isDirectory())
25529
25859
  continue;
@@ -25559,7 +25889,7 @@ function findExtensionSkillPath(name) {
25559
25889
  if (!config.extensionsDir || !existsSync15(config.extensionsDir))
25560
25890
  return null;
25561
25891
  try {
25562
- const entries = readdirSync14(config.extensionsDir, { withFileTypes: true });
25892
+ const entries = readdirSync15(config.extensionsDir, { withFileTypes: true });
25563
25893
  for (const entry of entries) {
25564
25894
  if (!entry.isDirectory())
25565
25895
  continue;
@@ -25634,7 +25964,7 @@ function getAllTags(catalog) {
25634
25964
  }
25635
25965
  // src/lib/run-state.ts
25636
25966
  import { createHash as createHash31, randomBytes } from "crypto";
25637
- import { existsSync as existsSync16, mkdirSync as mkdirSync12, readFileSync as readFileSync28, readdirSync as readdirSync15, statSync as statSync14, writeFileSync as writeFileSync10 } from "fs";
25967
+ import { existsSync as existsSync16, mkdirSync as mkdirSync13, readFileSync as readFileSync28, readdirSync as readdirSync16, statSync as statSync14, writeFileSync as writeFileSync10 } from "fs";
25638
25968
  import { extname, join as join42, relative as relative12 } from "path";
25639
25969
  function createSkillRun(params, targetDir = process.cwd()) {
25640
25970
  const now = new Date;
@@ -25645,9 +25975,9 @@ function createSkillRun(params, targetDir = process.cwd()) {
25645
25975
  const runDir = join42(root2, "runs", day, id);
25646
25976
  const logsDir = join42(runDir, "logs");
25647
25977
  const exportDir = join42(root2, "exports", skillName, id);
25648
- mkdirSync12(logsDir, { recursive: true });
25649
- mkdirSync12(exportDir, { recursive: true });
25650
- mkdirSync12(join42(root2, "tmp"), { recursive: true });
25978
+ mkdirSync13(logsDir, { recursive: true });
25979
+ mkdirSync13(exportDir, { recursive: true });
25980
+ mkdirSync13(join42(root2, "tmp"), { recursive: true });
25651
25981
  const record5 = {
25652
25982
  id,
25653
25983
  skill: skillName,
@@ -25714,11 +26044,11 @@ function listSkillRuns(targetDir = process.cwd(), limit = 50) {
25714
26044
  if (!existsSync16(runsRoot))
25715
26045
  return [];
25716
26046
  const records = [];
25717
- for (const day of readdirSync15(runsRoot).sort().reverse()) {
26047
+ for (const day of readdirSync16(runsRoot).sort().reverse()) {
25718
26048
  const dayDir = join42(runsRoot, day);
25719
26049
  if (!statSync14(dayDir).isDirectory())
25720
26050
  continue;
25721
- for (const runId of readdirSync15(dayDir).sort().reverse()) {
26051
+ for (const runId of readdirSync16(dayDir).sort().reverse()) {
25722
26052
  const record5 = readRunRecord(join42(dayDir, runId));
25723
26053
  if (record5)
25724
26054
  records.push(record5);
@@ -25732,7 +26062,7 @@ function findSkillRun(runId, targetDir = process.cwd()) {
25732
26062
  const runsRoot = join42(getProjectStateDir(targetDir), "runs");
25733
26063
  if (!existsSync16(runsRoot))
25734
26064
  return null;
25735
- for (const day of readdirSync15(runsRoot)) {
26065
+ for (const day of readdirSync16(runsRoot)) {
25736
26066
  const record5 = readRunRecord(join42(runsRoot, day, runId));
25737
26067
  if (record5)
25738
26068
  return record5;
@@ -25778,7 +26108,7 @@ function readRunRecord(runDir) {
25778
26108
  }
25779
26109
  function walkFiles(dir) {
25780
26110
  const files = [];
25781
- for (const entry of readdirSync15(dir)) {
26111
+ for (const entry of readdirSync16(dir)) {
25782
26112
  const full = join42(dir, entry);
25783
26113
  if (statSync14(full).isDirectory())
25784
26114
  files.push(...walkFiles(full));
@@ -47286,7 +47616,7 @@ async function createRemoteSkillsClient(env = process.env) {
47286
47616
  return connection ? new RemoteSkillsClient(connection.apiKey, connection.apiOrigin) : null;
47287
47617
  }
47288
47618
  // src/lib/scheduler.ts
47289
- import { existsSync as existsSync17, readFileSync as readFileSync29, writeFileSync as writeFileSync11, mkdirSync as mkdirSync13 } from "fs";
47619
+ import { existsSync as existsSync17, readFileSync as readFileSync29, writeFileSync as writeFileSync11, mkdirSync as mkdirSync14 } from "fs";
47290
47620
  import { join as join43 } from "path";
47291
47621
  function getSchedulesPath(targetDir = process.cwd()) {
47292
47622
  return join43(targetDir, ".skills", "schedules.json");
@@ -47304,7 +47634,7 @@ function saveSchedules(data, targetDir = process.cwd()) {
47304
47634
  const path = getSchedulesPath(targetDir);
47305
47635
  const dir = join43(targetDir, ".skills");
47306
47636
  if (!existsSync17(dir))
47307
- mkdirSync13(dir, { recursive: true });
47637
+ mkdirSync14(dir, { recursive: true });
47308
47638
  writeFileSync11(path, JSON.stringify(data, null, 2));
47309
47639
  }
47310
47640
  function validateCronField(expr, min, max, label) {
@@ -47518,7 +47848,7 @@ function revisionIdOfRecord(record10) {
47518
47848
  return revisionIdOf(record10);
47519
47849
  }
47520
47850
  // src/lib/pull.ts
47521
- import { existsSync as existsSync18, mkdirSync as mkdirSync14, mkdtempSync as mkdtempSync3, readFileSync as readFileSync30, renameSync as renameSync7, rmSync as rmSync5, writeFileSync as writeFileSync12 } from "fs";
47851
+ import { existsSync as existsSync18, mkdirSync as mkdirSync15, mkdtempSync as mkdtempSync4, readFileSync as readFileSync30, renameSync as renameSync7, rmSync as rmSync6, writeFileSync as writeFileSync12 } from "fs";
47522
47852
  import { dirname as dirname29, join as join44 } from "path";
47523
47853
 
47524
47854
  // src/lib/skill-bundles.ts
@@ -47713,7 +48043,7 @@ function reconcileTombstone(slug2, corpusOptions) {
47713
48043
  if (!hasSkillsOwnershipMarker(target)) {
47714
48044
  return { name: slug2, success: true, tombstoned: true, removed: false, leftInPlace: true };
47715
48045
  }
47716
- rmSync5(target, { recursive: true, force: true });
48046
+ rmSync6(target, { recursive: true, force: true });
47717
48047
  return { name: slug2, success: true, tombstoned: true, removed: true };
47718
48048
  }
47719
48049
  function readPullMarker(dir) {
@@ -47852,16 +48182,16 @@ function verifyBundleResponseBytes(buffer, response, verify = {}) {
47852
48182
  }
47853
48183
  function installBundleAtomically(name, entries, options = {}, marker = {}) {
47854
48184
  const root2 = getPortableSkillsRoot(options);
47855
- mkdirSync14(root2, { recursive: true });
48185
+ mkdirSync15(root2, { recursive: true });
47856
48186
  const target = join44(root2, name);
47857
48187
  const created = !existsSync18(target);
47858
- const staging = mkdtempSync3(join44(root2, `.pull-${name}-`));
48188
+ const staging = mkdtempSync4(join44(root2, `.pull-${name}-`));
47859
48189
  let moved = false;
47860
48190
  let backup = null;
47861
48191
  try {
47862
48192
  for (const entry of entries) {
47863
48193
  const destination = join44(staging, entry.path);
47864
- mkdirSync14(dirname29(destination), { recursive: true });
48194
+ mkdirSync15(dirname29(destination), { recursive: true });
47865
48195
  writeFileSync12(destination, entry.bytes, { mode: entry.mode });
47866
48196
  }
47867
48197
  writePullMarker(staging, {
@@ -47873,15 +48203,15 @@ function installBundleAtomically(name, entries, options = {}, marker = {}) {
47873
48203
  ...marker.revisionId ? { revisionId: marker.revisionId } : {}
47874
48204
  });
47875
48205
  if (existsSync18(target)) {
47876
- backup = mkdtempSync3(join44(root2, `.pull-backup-${name}-`));
48206
+ backup = mkdtempSync4(join44(root2, `.pull-backup-${name}-`));
47877
48207
  renameSync7(target, join44(backup, name));
47878
48208
  moved = true;
47879
48209
  }
47880
48210
  renameSync7(staging, target);
47881
48211
  if (moved && backup)
47882
- rmSync5(backup, { recursive: true, force: true });
48212
+ rmSync6(backup, { recursive: true, force: true });
47883
48213
  } catch (error61) {
47884
- rmSync5(staging, { recursive: true, force: true });
48214
+ rmSync6(staging, { recursive: true, force: true });
47885
48215
  if (moved && backup && existsSync18(join44(backup, name))) {
47886
48216
  try {
47887
48217
  renameSync7(join44(backup, name), target);
@@ -48764,7 +49094,7 @@ function findSkillsParityForMcpTool(tool) {
48764
49094
  return SKILLS_CLI_MCP_PARITY.find((entry) => entry.mcpTools.includes(tool));
48765
49095
  }
48766
49096
  // src/lib/registry-sync.ts
48767
- import { mkdirSync as mkdirSync15, writeFileSync as writeFileSync13 } from "fs";
49097
+ import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync13 } from "fs";
48768
49098
  import { dirname as dirname30, relative as relative13 } from "path";
48769
49099
  function createRegistrySyncArtifact(options = {}) {
48770
49100
  const profile = options.profile ?? "all";
@@ -48822,7 +49152,7 @@ function createRegistrySyncArtifact(options = {}) {
48822
49152
  };
48823
49153
  }
48824
49154
  function writeRegistrySyncArtifact(path, artifact) {
48825
- mkdirSync15(dirname30(path), { recursive: true });
49155
+ mkdirSync16(dirname30(path), { recursive: true });
48826
49156
  writeFileSync13(path, `${JSON.stringify(artifact, null, 2)}
48827
49157
  `);
48828
49158
  }
@@ -49906,7 +50236,7 @@ function clone3(value) {
49906
50236
  return JSON.parse(JSON.stringify(value));
49907
50237
  }
49908
50238
  // src/lib/feedback.ts
49909
- import { appendFileSync, existsSync as existsSync19, mkdirSync as mkdirSync16 } from "fs";
50239
+ import { appendFileSync, existsSync as existsSync19, mkdirSync as mkdirSync17 } from "fs";
49910
50240
  import { dirname as dirname31, join as join45 } from "path";
49911
50241
  import { Database } from "bun:sqlite";
49912
50242
  function getFeedbackDbPath() {
@@ -49916,7 +50246,7 @@ function getFeedbackDb() {
49916
50246
  const dbPath = getFeedbackDbPath();
49917
50247
  const dir = dirname31(dbPath);
49918
50248
  if (!existsSync19(dir))
49919
- mkdirSync16(dir, { recursive: true });
50249
+ mkdirSync17(dir, { recursive: true });
49920
50250
  const db = new Database(dbPath);
49921
50251
  db.exec("PRAGMA journal_mode = WAL");
49922
50252
  db.exec([
@@ -49945,7 +50275,7 @@ function saveFeedback(input2) {
49945
50275
  const path = join45(getDataDir(), "feedback.jsonl");
49946
50276
  const dir = dirname31(path);
49947
50277
  if (!existsSync19(dir))
49948
- mkdirSync16(dir, { recursive: true });
50278
+ mkdirSync17(dir, { recursive: true });
49949
50279
  appendFileSync(path, JSON.stringify({ message, category, email: input2.email ?? null, agent: input2.agent ?? null, version: input2.version ?? null, createdAt: new Date().toISOString() }) + `
49950
50280
  `);
49951
50281
  return { saved: true, category, path };
@@ -49969,9 +50299,9 @@ function isApiMode(env = process.env) {
49969
50299
  import { createHash as createHash35, createHmac as createHmac2 } from "crypto";
49970
50300
  import {
49971
50301
  existsSync as existsSync20,
49972
- mkdirSync as mkdirSync17,
50302
+ mkdirSync as mkdirSync18,
49973
50303
  readFileSync as readFileSync31,
49974
- readdirSync as readdirSync16,
50304
+ readdirSync as readdirSync17,
49975
50305
  statSync as statSync15,
49976
50306
  writeFileSync as writeFileSync14
49977
50307
  } from "fs";
@@ -50171,7 +50501,7 @@ function importSkillsLocalSnapshot(snapshot2, targetDir = process.cwd(), options
50171
50501
  if (hash5 !== file2.sha256) {
50172
50502
  throw new Error(`Snapshot file checksum mismatch: ${file2.path}`);
50173
50503
  }
50174
- mkdirSync17(dirname32(absolutePath5), { recursive: true });
50504
+ mkdirSync18(dirname32(absolutePath5), { recursive: true });
50175
50505
  writeFileSync14(absolutePath5, bytes);
50176
50506
  written += 1;
50177
50507
  }
@@ -50468,7 +50798,7 @@ function parsePositiveInteger(value) {
50468
50798
  }
50469
50799
  function walkFiles2(dir) {
50470
50800
  const files = [];
50471
- for (const entry of readdirSync16(dir)) {
50801
+ for (const entry of readdirSync17(dir)) {
50472
50802
  const full = join46(dir, entry);
50473
50803
  const stats = statSync15(full);
50474
50804
  if (stats.isDirectory())
@@ -50554,7 +50884,7 @@ function toArrayBuffer(bytes) {
50554
50884
  import { createHash as createHash36 } from "crypto";
50555
50885
  import {
50556
50886
  copyFileSync,
50557
- mkdirSync as mkdirSync18,
50887
+ mkdirSync as mkdirSync19,
50558
50888
  readFileSync as readFileSync32,
50559
50889
  statSync as statSync17,
50560
50890
  writeFileSync as writeFileSync15
@@ -50562,7 +50892,7 @@ import {
50562
50892
  import { dirname as dirname33, isAbsolute as isAbsolute31, relative as relative15, resolve as resolve30, sep as sep20 } from "path";
50563
50893
 
50564
50894
  // src/lib/portable-snapshot-filter.ts
50565
- import { readdirSync as readdirSync17, statSync as statSync16 } from "fs";
50895
+ import { readdirSync as readdirSync18, statSync as statSync16 } from "fs";
50566
50896
  import { homedir as homedir7 } from "os";
50567
50897
  import { join as join47, sep as sep19 } from "path";
50568
50898
  var SYNC_HOMES = [
@@ -50671,7 +51001,7 @@ function destinationFor(definition, stationId, relativePath) {
50671
51001
  function walkEntries(absoluteRoot) {
50672
51002
  let entries;
50673
51003
  try {
50674
- entries = readdirSync17(absoluteRoot, { withFileTypes: true });
51004
+ entries = readdirSync18(absoluteRoot, { withFileTypes: true });
50675
51005
  } catch {
50676
51006
  return [];
50677
51007
  }
@@ -50847,7 +51177,7 @@ function writeStationSnapshot(options) {
50847
51177
  let written = 0;
50848
51178
  for (const plan of untouched) {
50849
51179
  const destination = resolve30(repoRoot, plan.destination);
50850
- mkdirSync18(dirname33(destination), { recursive: true });
51180
+ mkdirSync19(dirname33(destination), { recursive: true });
50851
51181
  copyFileSync(plan.source.fullPath, destination);
50852
51182
  written += 1;
50853
51183
  }
@@ -50866,7 +51196,7 @@ function writeStationSnapshot(options) {
50866
51196
  files: manifestFiles
50867
51197
  };
50868
51198
  const manifestPath = resolve30(repoRoot, "resources", options.stationId, "skills", "sync-manifest.json");
50869
- mkdirSync18(dirname33(manifestPath), { recursive: true });
51199
+ mkdirSync19(dirname33(manifestPath), { recursive: true });
50870
51200
  writeFileSync15(manifestPath, `${JSON.stringify(manifest, null, 2)}
50871
51201
  `);
50872
51202
  return {
@@ -50880,8 +51210,8 @@ function writeStationSnapshot(options) {
50880
51210
  import { createHash as createHash37 } from "crypto";
50881
51211
  import {
50882
51212
  copyFileSync as copyFileSync2,
50883
- mkdirSync as mkdirSync19,
50884
- readdirSync as readdirSync18,
51213
+ mkdirSync as mkdirSync20,
51214
+ readdirSync as readdirSync19,
50885
51215
  readFileSync as readFileSync33,
50886
51216
  statSync as statSync18,
50887
51217
  writeFileSync as writeFileSync16
@@ -50928,7 +51258,7 @@ function planStationHydration(stationId, repoRoot) {
50928
51258
  const agentRoot = join48(snapshotRoot, "agent-homes", agent);
50929
51259
  let identEntries;
50930
51260
  try {
50931
- identEntries = readdirSync18(agentRoot, { withFileTypes: true });
51261
+ identEntries = readdirSync19(agentRoot, { withFileTypes: true });
50932
51262
  } catch {
50933
51263
  continue;
50934
51264
  }
@@ -51142,7 +51472,7 @@ function writeStationHydration(options) {
51142
51472
  }
51143
51473
  let written = 0;
51144
51474
  for (const entry of toWrite) {
51145
- mkdirSync19(dirname34(entry.destination), { recursive: true });
51475
+ mkdirSync20(dirname34(entry.destination), { recursive: true });
51146
51476
  copyFileSync2(entry.fullPath, entry.destination);
51147
51477
  written += 1;
51148
51478
  }
@@ -51164,7 +51494,7 @@ function writeStationHydration(options) {
51164
51494
  skills: resultSkills
51165
51495
  };
51166
51496
  const hydrationManifestPath = join48(dirname34(cacheRoot), `hydration-${options.stationId}.json`);
51167
- mkdirSync19(dirname34(hydrationManifestPath), { recursive: true });
51497
+ mkdirSync20(dirname34(hydrationManifestPath), { recursive: true });
51168
51498
  writeFileSync16(hydrationManifestPath, `${JSON.stringify(hydration, null, 2)}
51169
51499
  `);
51170
51500
  return {
@@ -51175,7 +51505,7 @@ function writeStationHydration(options) {
51175
51505
  };
51176
51506
  }
51177
51507
  // src/lib/private-publication-recovery.ts
51178
- import { constants as constants21, closeSync as closeSync20, fsyncSync as fsyncSync8, fstatSync as fstatSync20, lstatSync as lstatSync34, mkdirSync as mkdirSync20, openSync as openSync20, readSync as readSync15, realpathSync as realpathSync16, renameSync as renameSync8, unlinkSync as unlinkSync6, writeFileSync as writeFileSync17 } from "fs";
51508
+ import { constants as constants21, closeSync as closeSync20, fsyncSync as fsyncSync8, fstatSync as fstatSync20, lstatSync as lstatSync34, mkdirSync as mkdirSync21, openSync as openSync20, readSync as readSync15, realpathSync as realpathSync16, renameSync as renameSync8, unlinkSync as unlinkSync6, writeFileSync as writeFileSync17 } from "fs";
51179
51509
  import { dirname as dirname35, isAbsolute as isAbsolute32, join as join49, resolve as resolve32 } from "path";
51180
51510
  import { randomUUID as randomUUID5 } from "crypto";
51181
51511
  var fail3 = () => {
@@ -51322,7 +51652,7 @@ async function preparePrivatePublication(client2, sourceDirectory, recoveryDirec
51322
51652
  };
51323
51653
  if (!isAbsolute32(recoveryDirectory) || resolve32(recoveryDirectory) !== recoveryDirectory || realpathSync16(dirname35(recoveryDirectory)) !== dirname35(recoveryDirectory))
51324
51654
  return fail3();
51325
- mkdirSync20(recoveryDirectory, { mode: 448 });
51655
+ mkdirSync21(recoveryDirectory, { mode: 448 });
51326
51656
  safeDirectory(recoveryDirectory);
51327
51657
  const parent = openSync20(dirname35(recoveryDirectory), constants21.O_RDONLY | constants21.O_NOFOLLOW);
51328
51658
  try {
@@ -51646,7 +51976,7 @@ function applySessionReconciliation(snapshot2, target, planned, record12, verifi
51646
51976
  }
51647
51977
  // src/lib/claude-prospective-review.ts
51648
51978
  import { createHash as createHash40 } from "crypto";
51649
- import { lstatSync as lstatSync35, readFileSync as readFileSync34, readdirSync as readdirSync19, realpathSync as realpathSync17 } from "fs";
51979
+ import { lstatSync as lstatSync35, readFileSync as readFileSync34, readdirSync as readdirSync20, realpathSync as realpathSync17 } from "fs";
51650
51980
  import { basename as basename18, dirname as dirname36, isAbsolute as isAbsolute33, join as join50, relative as relative16, resolve as resolve34, sep as sep22 } from "path";
51651
51981
  var MAX_CANDIDATE_FILES = 16384;
51652
51982
  var MAX_CANDIDATE_BYTES = 256 * 1024 * 1024;
@@ -51693,7 +52023,7 @@ function captureClaudeProspectiveCandidateClosure(root2) {
51693
52023
  let bytes = 0;
51694
52024
  const walk2 = (directory3) => {
51695
52025
  const beforeDirectory = lstatSync35(directory3);
51696
- const names = readdirSync19(directory3).sort();
52026
+ const names = readdirSync20(directory3).sort();
51697
52027
  if (new Set(names).size !== names.length)
51698
52028
  refuse6("candidate contains ambiguous directory entries");
51699
52029
  for (const name of names) {