@hasna/skills 0.10.65 → 0.10.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/index.js CHANGED
@@ -36888,7 +36888,7 @@ var package_default;
36888
36888
  var init_package = __esm(() => {
36889
36889
  package_default = {
36890
36890
  name: "@hasna/skills",
36891
- version: "0.10.65",
36891
+ version: "0.10.66",
36892
36892
  description: "Skills library for AI coding agents",
36893
36893
  type: "module",
36894
36894
  bin: {
@@ -40633,8 +40633,8 @@ function assertAgentPolicyCollections(policy) {
40633
40633
  }
40634
40634
  }
40635
40635
  if (value.codexSemanticCache !== undefined) {
40636
- const proof = record(value.codexSemanticCache, 8), witness = record(proof.witness, 6);
40637
- requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && Object.keys(proof).length === 8 && proof.schema === "hasna.codex-semantic-cache-discovery.v1" && typeof proof.previousPolicySha256 === "string" && /^[a-f0-9]{64}$/.test(proof.previousPolicySha256) && Object.keys(witness).length === 6 && witness.schema === "hasna.codex-semantic-cache-witness.v1" && typeof witness.sha256 === "string" && /^[a-f0-9]{64}$/.test(witness.sha256));
40636
+ const proof = record(value.codexSemanticCache, 9), witness = record(proof.witness, 7);
40637
+ requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && [8, 9].includes(Object.keys(proof).length) && Object.keys(proof).every((key) => ["schema", "configPath", "hookRootAlias", "witness", "appOnlyParents", "previousPolicySha256", "supersededSources", "supersededDirectories", "reviewedHookParents"].includes(key)) && proof.schema === "hasna.codex-semantic-cache-discovery.v1" && typeof proof.previousPolicySha256 === "string" && /^[a-f0-9]{64}$/.test(proof.previousPolicySha256) && [6, 7].includes(Object.keys(witness).length) && Object.keys(witness).every((key) => ["schema", "cacheRoot", "controls", "appOnlyParents", "skills", "sha256", "hookParents"].includes(key)) && witness.schema === "hasna.codex-semantic-cache-witness.v1" && typeof witness.sha256 === "string" && /^[a-f0-9]{64}$/.test(witness.sha256));
40638
40638
  text(proof.configPath);
40639
40639
  requireBound(isAbsolute4(proof.configPath) && resolve5(proof.configPath) === proof.configPath && basename4(proof.configPath) === "config.toml");
40640
40640
  text(witness.cacheRoot);
@@ -40653,6 +40653,20 @@ function assertAgentPolicyCollections(policy) {
40653
40653
  text(parent[key]);
40654
40654
  requireBound(isAbsolute4(parent.pluginParent) && resolve5(parent.pluginParent) === parent.pluginParent);
40655
40655
  }
40656
+ if (proof.reviewedHookParents !== undefined)
40657
+ for (const parent of array(proof.reviewedHookParents, 4096)) {
40658
+ requireBound(object(parent) && parent.role === "reviewed-hook" && (parent.installation === "remote-receipt" && Object.keys(parent).length === 6 || parent.installation === "local-marketplace" && Object.keys(parent).length === 7));
40659
+ requireBound(parent.installation === "remote-receipt" ? Object.keys(parent).sort().join(",") === "installation,namespace,pluginId,pluginParent,remotePluginId,role" : Object.keys(parent).sort().join(",") === "installation,marketplaceSha256,marketplaceSourcePath,namespace,pluginId,pluginParent,role");
40660
+ for (const key of ["pluginId", "namespace", "pluginParent", "installation"])
40661
+ text(parent[key]);
40662
+ if (parent.installation === "remote-receipt")
40663
+ text(parent.remotePluginId);
40664
+ else {
40665
+ text(parent.marketplaceSourcePath);
40666
+ requireBound(typeof parent.marketplaceSha256 === "string" && /^[a-f0-9]{64}$/.test(parent.marketplaceSha256) && isAbsolute4(parent.marketplaceSourcePath) && resolve5(parent.marketplaceSourcePath) === parent.marketplaceSourcePath && basename4(parent.marketplaceSourcePath) === "marketplace.json");
40667
+ }
40668
+ requireBound(isAbsolute4(parent.pluginParent) && resolve5(parent.pluginParent) === parent.pluginParent);
40669
+ }
40656
40670
  for (const row of [...array(witness.controls, 4096), ...array(witness.appOnlyParents, 4096)]) {
40657
40671
  requireBound(object(row));
40658
40672
  for (const key of ["pluginId", "namespace", "pluginParent"])
@@ -40661,6 +40675,26 @@ function assertAgentPolicyCollections(policy) {
40661
40675
  if (row[key] !== undefined)
40662
40676
  requireBound(typeof row[key] === "string" && /^[a-f0-9]{64}$/.test(row[key]));
40663
40677
  }
40678
+ if (witness.hookParents !== undefined)
40679
+ for (const row of array(witness.hookParents, 4096)) {
40680
+ requireBound(object(row) && row.role === "reviewed-hook" && (row.installation === "remote-receipt" && Object.keys(row).length === 9 || row.installation === "local-marketplace" && Object.keys(row).length === 9));
40681
+ requireBound(row.installation === "remote-receipt" ? Object.keys(row).sort().join(",") === "hooksSha256,installation,manifestSha256,namespace,pluginId,pluginParent,receiptSha256,remotePluginId,role" : Object.keys(row).sort().join(",") === "hooksSha256,installation,manifestSha256,marketplaceSha256,marketplaceSourcePath,namespace,pluginId,pluginParent,role");
40682
+ for (const key of ["pluginId", "namespace", "pluginParent", "installation"])
40683
+ text(row[key]);
40684
+ if (row.installation === "remote-receipt")
40685
+ text(row.remotePluginId);
40686
+ else {
40687
+ text(row.marketplaceSourcePath);
40688
+ requireBound(typeof row.marketplaceSha256 === "string" && /^[a-f0-9]{64}$/.test(row.marketplaceSha256) && isAbsolute4(row.marketplaceSourcePath) && resolve5(row.marketplaceSourcePath) === row.marketplaceSourcePath && basename4(row.marketplaceSourcePath) === "marketplace.json");
40689
+ }
40690
+ requireBound(isAbsolute4(row.pluginParent) && resolve5(row.pluginParent) === row.pluginParent);
40691
+ for (const key of ["manifestSha256", "hooksSha256"])
40692
+ requireBound(typeof row[key] === "string" && /^[a-f0-9]{64}$/.test(row[key]));
40693
+ if (row.installation === "remote-receipt")
40694
+ requireBound(typeof row.receiptSha256 === "string" && /^[a-f0-9]{64}$/.test(row.receiptSha256));
40695
+ else
40696
+ requireBound(row.receiptSha256 === undefined);
40697
+ }
40664
40698
  for (const skill of array(witness.skills, 4096)) {
40665
40699
  requireBound(object(skill));
40666
40700
  for (const key of ["name", "pluginId", "namespace", "pluginParent"])
@@ -53789,7 +53823,25 @@ var init_codex_settings_witness = __esm(() => {
53789
53823
  // src/lib/codex-semantic-cache-witness.ts
53790
53824
  import { createHash as createHash17 } from "crypto";
53791
53825
  import { constants as constants10, closeSync as closeSync9, fstatSync as fstatSync9, lstatSync as lstatSync16, openSync as openSync9, readSync as readSync7, readdirSync as readdirSync7, realpathSync as realpathSync8 } from "fs";
53792
- import { dirname as dirname15, isAbsolute as isAbsolute15, join as join25, relative as relative6, resolve as resolve15, sep as sep7 } from "path";
53826
+ import { basename as basename9, dirname as dirname15, isAbsolute as isAbsolute15, join as join25, relative as relative6, resolve as resolve15, sep as sep7 } from "path";
53827
+ function codexLocalMarketplaceMapsPlugin(text2, marketplace, plugin) {
53828
+ try {
53829
+ hashNativeJsonControls(text2);
53830
+ const value = JSON.parse(text2);
53831
+ if (!plainObject(value) || !exactKeys(value, ["interface", "name", "plugins"]) || value.name !== marketplace || !(typeof value.interface === "string" || Number.isSafeInteger(value.interface)) || !Array.isArray(value.plugins) || value.plugins.length < 1 || value.plugins.length > 4096)
53832
+ return false;
53833
+ const rows = value.plugins.filter((row2) => plainObject(row2) && row2.name === plugin);
53834
+ if (rows.length !== 1)
53835
+ return false;
53836
+ const row = rows[0];
53837
+ if (!exactKeys(row, ["name", "source"]) || !plainObject(row.source) || !exactKeys(row.source, ["source", "path"]) || row.source.source !== "local" || typeof row.source.path !== "string" || !row.source.path.startsWith("./") || row.source.path.includes("\\"))
53838
+ return false;
53839
+ const parts = row.source.path.split("/");
53840
+ return parts[0] === "." && parts.length > 1 && parts.slice(1).every((part) => /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(part)) && parts.at(-1) === plugin;
53841
+ } catch {
53842
+ return false;
53843
+ }
53844
+ }
53793
53845
  function defaultRead(path) {
53794
53846
  const before2 = lstatSync16(path, { throwIfNoEntry: false, bigint: true });
53795
53847
  if (before2 === undefined)
@@ -53851,7 +53903,7 @@ function validPluginParent(cacheRoot, pluginParent, namespace, pluginId) {
53851
53903
  return parts.length === 2 && parts.every(identifier3) && parts[1] === namespace && pluginId === `${namespace}@${parts[0]}`;
53852
53904
  }
53853
53905
  function assertWitnessShape(value) {
53854
- if (!plainObject(value) || !exactKeys(value, ["schema", "cacheRoot", "controls", "appOnlyParents", "skills", "sha256"]) || value.schema !== CODEX_SEMANTIC_CACHE_WITNESS_SCHEMA || typeof value.cacheRoot !== "string" || !isAbsolute15(value.cacheRoot) || resolve15(value.cacheRoot) !== value.cacheRoot || !digest(value.sha256) || !Array.isArray(value.controls) || value.controls.length === 0 || value.controls.length > 4096 || !Array.isArray(value.appOnlyParents) || value.appOnlyParents.length > 4096 || !Array.isArray(value.skills) || value.skills.length === 0 || value.skills.length > 4096)
53906
+ if (!plainObject(value) || !exactKeys(value, ["schema", "cacheRoot", "controls", "appOnlyParents", "skills", "sha256"], ["hookParents"]) || value.schema !== CODEX_SEMANTIC_CACHE_WITNESS_SCHEMA || typeof value.cacheRoot !== "string" || !isAbsolute15(value.cacheRoot) || resolve15(value.cacheRoot) !== value.cacheRoot || !digest(value.sha256) || !Array.isArray(value.controls) || value.controls.length === 0 || value.controls.length > 4096 || !Array.isArray(value.appOnlyParents) || value.appOnlyParents.length > 4096 || !Array.isArray(value.skills) || value.skills.length === 0 || value.skills.length > 4096)
53855
53907
  refuse4();
53856
53908
  const witness = value;
53857
53909
  const controlParents = new Set;
@@ -53872,6 +53924,20 @@ function assertWitnessShape(value) {
53872
53924
  refuse4();
53873
53925
  appOnlyParentPaths.add(row.pluginParent);
53874
53926
  }
53927
+ const hookParentPaths = new Set;
53928
+ const hookParents = witness.hookParents === undefined ? [] : witness.hookParents;
53929
+ if (!Array.isArray(hookParents) || hookParents.length > 4096)
53930
+ refuse4();
53931
+ for (const candidate of hookParents) {
53932
+ if (!plainObject(candidate))
53933
+ refuse4();
53934
+ const row = candidate;
53935
+ const remote = row.installation === "remote-receipt";
53936
+ const local = row.installation === "local-marketplace";
53937
+ if (!exactKeys(row, ["role", "pluginId", "namespace", "pluginParent", "installation", "manifestSha256", "hooksSha256"], remote ? ["remotePluginId", "receiptSha256"] : local ? ["marketplaceSourcePath", "marketplaceSha256"] : []) || row.role !== "reviewed-hook" || !identifier3(row.namespace) || typeof row.pluginId !== "string" || !/^[A-Za-z0-9_-]{1,64}@[A-Za-z0-9_-]{1,64}$/.test(row.pluginId) || typeof row.pluginParent !== "string" || !validPluginParent(String(witness.cacheRoot), row.pluginParent, row.namespace, row.pluginId) || remote && (typeof row.remotePluginId !== "string" || !/^[A-Za-z0-9_~-]{1,1024}$/.test(row.remotePluginId) || !digest(row.receiptSha256)) || local && (typeof row.marketplaceSourcePath !== "string" || !isAbsolute15(row.marketplaceSourcePath) || resolve15(row.marketplaceSourcePath) !== row.marketplaceSourcePath || basename9(row.marketplaceSourcePath) !== "marketplace.json" || !digest(row.marketplaceSha256)) || !remote && !local || !digest(row.manifestSha256) || !digest(row.hooksSha256) || hookParentPaths.has(row.pluginParent) || controlParents.has(row.pluginParent) || appOnlyParentPaths.has(row.pluginParent))
53938
+ refuse4();
53939
+ hookParentPaths.add(row.pluginParent);
53940
+ }
53875
53941
  const skillNames = new Set;
53876
53942
  const qualifiedNames = new Set;
53877
53943
  for (const candidate of witness.skills) {
@@ -53891,6 +53957,7 @@ function assertWitnessShape(value) {
53891
53957
  cacheRoot: witness.cacheRoot,
53892
53958
  controls: witness.controls,
53893
53959
  appOnlyParents: witness.appOnlyParents,
53960
+ ...witness.hookParents === undefined ? {} : { hookParents: witness.hookParents },
53894
53961
  skills: witness.skills
53895
53962
  };
53896
53963
  if (hash2(projection) !== witness.sha256)
@@ -54081,10 +54148,128 @@ function appOnlyParentProjection(cacheRoot, parents2, read2) {
54081
54148
  }
54082
54149
  return rows.sort((a, b) => a.pluginId.localeCompare(b.pluginId) || a.pluginParent.localeCompare(b.pluginParent));
54083
54150
  }
54084
- function assertParents(cacheRoot, controls, appOnlyParents, files, members) {
54151
+ function assertJsonValue(value, depth = 0, budget2 = { members: 0 }) {
54152
+ if (depth > 32 || ++budget2.members > 4096)
54153
+ refuse4();
54154
+ if (value === null || typeof value === "string" || typeof value === "boolean")
54155
+ return;
54156
+ if (typeof value === "number" && Number.isFinite(value))
54157
+ return;
54158
+ if (Array.isArray(value)) {
54159
+ for (const item of value)
54160
+ assertJsonValue(item, depth + 1, budget2);
54161
+ return;
54162
+ }
54163
+ if (!plainObject(value))
54164
+ refuse4();
54165
+ for (const [key, item] of Object.entries(value)) {
54166
+ if (!key || /[\x00-\x1f\x7f]/.test(key))
54167
+ refuse4();
54168
+ assertJsonValue(item, depth + 1, budget2);
54169
+ }
54170
+ }
54171
+ function reviewedHookControls(root, read2) {
54172
+ const manifestPath = join25(root, ".codex-plugin/plugin.json"), hooksPath = join25(root, "hooks/hooks.json");
54173
+ let manifest, manifestSha256, hooks, hooksSha256;
54174
+ try {
54175
+ const manifestText = read2(manifestPath);
54176
+ manifestSha256 = hashNativeJsonControls(manifestText, "version");
54177
+ manifest = JSON.parse(manifestText);
54178
+ const hooksText = read2(hooksPath);
54179
+ hashNativeJsonControls(hooksText);
54180
+ hooksSha256 = createHash17("sha256").update(hooksText).digest("hex");
54181
+ hooks = JSON.parse(hooksText);
54182
+ } catch {
54183
+ return refuse4();
54184
+ }
54185
+ if (!plainObject(manifest) || !exactKeys(manifest, ["name", "version", "hooks"], ["description"]) || !identifier3(manifest.name) || typeof manifest.version !== "string" || manifest.version !== basename9(root) || manifest.hooks !== "./hooks/hooks.json" || manifest.description !== undefined && (typeof manifest.description !== "string" || !manifest.description.trim() || manifest.description.length > 1024))
54186
+ refuse4();
54187
+ const manifestRecord = manifest;
54188
+ if (!plainObject(hooks) || !exactKeys(hooks, ["hooks"]) || !plainObject(hooks.hooks))
54189
+ refuse4();
54190
+ const hookTable = hooks.hooks;
54191
+ const events = Object.entries(hookTable);
54192
+ if (!events.length || events.length > 32)
54193
+ refuse4();
54194
+ for (const [event, groups] of events) {
54195
+ if (!codexHookEvents.has(event) || !Array.isArray(groups) || !groups.length || groups.length > 32)
54196
+ refuse4();
54197
+ for (const group of groups) {
54198
+ if (!plainObject(group) || !exactKeys(group, ["hooks"]) || !Array.isArray(group.hooks) || !group.hooks.length || group.hooks.length > 32)
54199
+ refuse4();
54200
+ const handlers = group.hooks;
54201
+ for (const handler of handlers) {
54202
+ if (!plainObject(handler) || !exactKeys(handler, ["type", "server", "tool", "input"], ["timeout"]) || handler.type !== "mcp_tool" || !identifier3(handler.server) || !identifier3(handler.tool) || !plainObject(handler.input) || handler.timeout !== undefined && (!Number.isSafeInteger(handler.timeout) || Number(handler.timeout) < 1 || Number(handler.timeout) > 300))
54203
+ refuse4();
54204
+ assertJsonValue(handler.input);
54205
+ }
54206
+ }
54207
+ }
54208
+ return { namespace: manifestRecord.name, manifestSha256, hooksSha256 };
54209
+ }
54210
+ function reviewedHookParentProjection(cacheRoot, parents2, read2) {
54211
+ if (!Array.isArray(parents2) || parents2.length > 4096)
54212
+ refuse4();
54213
+ const seen = new Set, rows = [];
54214
+ for (const parent of parents2) {
54215
+ const remote = parent?.installation === "remote-receipt", local = parent?.installation === "local-marketplace";
54216
+ if (!parent || !exactKeys(parent, ["installation", "namespace", "pluginId", "pluginParent", "role"], remote ? ["remotePluginId"] : local ? ["marketplaceSourcePath", "marketplaceSha256"] : []) || parent.role !== "reviewed-hook" || !identifier3(parent.namespace) || !/^[A-Za-z0-9_-]{1,64}@[A-Za-z0-9_-]{1,64}$/.test(parent.pluginId) || typeof parent.pluginParent !== "string" || remote && (typeof parent.remotePluginId !== "string" || !/^[A-Za-z0-9_~-]{1,1024}$/.test(parent.remotePluginId)) || local && (typeof parent.marketplaceSourcePath !== "string" || !isAbsolute15(parent.marketplaceSourcePath) || resolve15(parent.marketplaceSourcePath) !== parent.marketplaceSourcePath || basename9(parent.marketplaceSourcePath) !== "marketplace.json" || !digest(parent.marketplaceSha256)) || !remote && !local)
54217
+ refuse4();
54218
+ const parts = relative6(cacheRoot, parent.pluginParent).split(sep7);
54219
+ if (!isAbsolute15(parent.pluginParent) || resolve15(parent.pluginParent) !== parent.pluginParent || parts.length !== 2 || parts.some((part) => !identifier3(part)) || parts[1] !== parent.namespace || parent.pluginId !== `${parent.namespace}@${parts[0]}` || seen.has(parent.pluginParent))
54220
+ refuse4();
54221
+ seen.add(parent.pluginParent);
54222
+ const parentStat = lstatSync16(parent.pluginParent, { throwIfNoEntry: false });
54223
+ if (!parentStat?.isDirectory() || parentStat.isSymbolicLink() || realpathSync8(parent.pluginParent) !== parent.pluginParent)
54224
+ refuse4();
54225
+ const receiptPath = join25(parent.pluginParent, ".codex-remote-plugin-install.json"), receiptStat = lstatSync16(receiptPath, { throwIfNoEntry: false });
54226
+ let receiptText;
54227
+ if (remote) {
54228
+ if (!receiptStat?.isFile() || receiptStat.isSymbolicLink() || receiptStat.size > MAX_RECEIPT_BYTES)
54229
+ refuse4();
54230
+ try {
54231
+ receiptText = read2(receiptPath);
54232
+ hashNativeJsonControls(receiptText);
54233
+ const receipt = JSON.parse(receiptText);
54234
+ if (!plainObject(receipt) || !exactKeys(receipt, ["schema_version", "remote_plugin_id"]) || receipt.schema_version !== 1 || receipt.remote_plugin_id !== parent.remotePluginId)
54235
+ refuse4();
54236
+ } catch {
54237
+ refuse4();
54238
+ }
54239
+ } else {
54240
+ const marketplaceSourcePath = parent.marketplaceSourcePath ?? refuse4();
54241
+ if (receiptStat !== undefined || !parent.marketplaceSha256)
54242
+ refuse4();
54243
+ let marketplaceText;
54244
+ try {
54245
+ marketplaceText = read2(marketplaceSourcePath);
54246
+ } catch {
54247
+ return refuse4();
54248
+ }
54249
+ if (createHash17("sha256").update(marketplaceText).digest("hex") !== parent.marketplaceSha256 || !codexLocalMarketplaceMapsPlugin(marketplaceText, parts[0], parent.namespace))
54250
+ refuse4();
54251
+ }
54252
+ const materializations = readdirSync7(parent.pluginParent).filter((name) => name !== ".codex-remote-plugin-install.json").map((version) => {
54253
+ if (!/^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/.test(version))
54254
+ refuse4();
54255
+ const root = join25(parent.pluginParent, version), stat = lstatSync16(root, { throwIfNoEntry: false });
54256
+ if (!stat?.isDirectory() || stat.isSymbolicLink() || realpathSync8(root) !== root)
54257
+ refuse4();
54258
+ const controls = reviewedHookControls(root, read2);
54259
+ if (controls.namespace !== parent.namespace)
54260
+ refuse4();
54261
+ return { manifestSha256: controls.manifestSha256, hooksSha256: controls.hooksSha256 };
54262
+ });
54263
+ if (!materializations.length || materializations.some((item) => canonical7(item) !== canonical7(materializations[0])))
54264
+ refuse4();
54265
+ rows.push({ ...parent, ...receiptText === undefined ? {} : { receiptSha256: createHash17("sha256").update(receiptText).digest("hex") }, ...materializations[0] });
54266
+ }
54267
+ return rows.sort((a, b) => a.pluginId.localeCompare(b.pluginId) || a.pluginParent.localeCompare(b.pluginParent));
54268
+ }
54269
+ function assertParents(cacheRoot, controls, appOnlyParents, hookParents, files, members) {
54085
54270
  const expected = new Set;
54086
54271
  const expectedMarkets = new Set;
54087
- for (const control of [...controls, ...appOnlyParents]) {
54272
+ for (const control of [...controls, ...appOnlyParents, ...hookParents]) {
54088
54273
  const rel = relative6(cacheRoot, control.pluginParent), parts = rel.split(sep7);
54089
54274
  if (resolve15(control.pluginParent) !== control.pluginParent || parts.length !== 2 || parts.some((part) => !identifier3(part)) || control.pluginId !== `${control.namespace}@${parts[0]}` || parts[1] !== control.namespace)
54090
54275
  refuse4();
@@ -54125,7 +54310,9 @@ function assertParents(cacheRoot, controls, appOnlyParents, files, members) {
54125
54310
  refuse4();
54126
54311
  if ([".app.json", ".mcp.json"].includes(base2) && (parts.length !== 4 || dirname15(member) !== root))
54127
54312
  refuse4();
54128
- if (parts.includes("hooks"))
54313
+ if ([".app.json", ".mcp.json"].includes(base2) && hookParents.some((reviewed) => reviewed.pluginParent === parent))
54314
+ refuse4();
54315
+ if (parts.includes("hooks") && (![4, 5].includes(parts.length) || parts[3] !== "hooks" || (parts.length === 4 ? base2 !== "hooks" : base2 !== "hooks.json") || !hookParents.some((reviewed) => reviewed.pluginParent === join25(cacheRoot, parts[0], parts[1]))))
54129
54316
  refuse4();
54130
54317
  }
54131
54318
  }
@@ -54235,13 +54422,14 @@ function captureCodexSemanticCacheWitness(options) {
54235
54422
  const initialTree = treeSnapshot(options.cacheRoot);
54236
54423
  const controls = controlProjection(options.controls, read2);
54237
54424
  const appOnlyParents = appOnlyParentProjection(options.cacheRoot, options.appOnlyParents ?? [], read2);
54425
+ const hookParents = reviewedHookParentProjection(options.cacheRoot, options.reviewedHookParents ?? [], read2);
54238
54426
  const skillParents = new Set(controls.map((control) => control.pluginParent));
54239
- if (appOnlyParents.some((parent) => skillParents.has(parent.pluginParent)))
54427
+ if (appOnlyParents.some((parent) => skillParents.has(parent.pluginParent)) || hookParents.some((parent) => skillParents.has(parent.pluginParent) || appOnlyParents.some((app) => app.pluginParent === parent.pluginParent)))
54240
54428
  refuse4();
54241
54429
  if (!reviewedCodexPluginCapabilitiesUnchanged(options.cacheRoot, options.controls, read2, options.rules))
54242
54430
  refuse4();
54243
54431
  const files = initialTree.files;
54244
- assertParents(options.cacheRoot, controls, appOnlyParents, files, initialTree.state.members);
54432
+ assertParents(options.cacheRoot, controls, appOnlyParents, hookParents, files, initialTree.state.members);
54245
54433
  const expectedNamesByRoot = assertSkillMaterializations(options.cacheRoot, options.controls, files, read2);
54246
54434
  const docs = files.filter((path) => path.endsWith(`${sep7}SKILL.md`));
54247
54435
  const skillRows = [];
@@ -54250,6 +54438,8 @@ function captureCodexSemanticCacheWitness(options) {
54250
54438
  const rel = relative6(options.cacheRoot, document3).split(sep7);
54251
54439
  if (appOnlyParents.some((parent) => parent.pluginParent === join25(options.cacheRoot, rel[0], rel[1])))
54252
54440
  refuse4();
54441
+ if (hookParents.some((parent) => parent.pluginParent === join25(options.cacheRoot, rel[0], rel[1])))
54442
+ refuse4();
54253
54443
  const documentStat = lstatSync16(document3, { throwIfNoEntry: false });
54254
54444
  if (!documentStat?.isFile() || documentStat.isSymbolicLink() || documentStat.size > MAX_DOCUMENT_BYTES)
54255
54445
  refuse4();
@@ -54313,7 +54503,7 @@ function captureCodexSemanticCacheWitness(options) {
54313
54503
  tracked.verify();
54314
54504
  const finalTree = treeSnapshot(options.cacheRoot);
54315
54505
  assertSameTree(initialTree.state, finalTree.state, tracked.paths());
54316
- const completeProjection = { schema: CODEX_SEMANTIC_CACHE_WITNESS_SCHEMA, cacheRoot: options.cacheRoot, controls, appOnlyParents, skills: uniqueSkills };
54506
+ const completeProjection = { schema: CODEX_SEMANTIC_CACHE_WITNESS_SCHEMA, cacheRoot: options.cacheRoot, controls, appOnlyParents, hookParents, skills: uniqueSkills };
54317
54507
  return { ...completeProjection, sha256: hash2(completeProjection) };
54318
54508
  } catch (error) {
54319
54509
  if (error instanceof Error && error.message.startsWith("CODEX_SEMANTIC_CACHE_WITNESS_UNSUPPORTED"))
@@ -54329,6 +54519,7 @@ function assertCodexSemanticCacheWitnessUnchanged(previous, current) {
54329
54519
  cacheRoot: previous.cacheRoot,
54330
54520
  controls: previous.controls,
54331
54521
  appOnlyParents: previous.appOnlyParents,
54522
+ ...previous.hookParents === undefined ? {} : { hookParents: previous.hookParents },
54332
54523
  skills: previous.skills
54333
54524
  };
54334
54525
  const currentProjection = {
@@ -54336,20 +54527,41 @@ function assertCodexSemanticCacheWitnessUnchanged(previous, current) {
54336
54527
  cacheRoot: current.cacheRoot,
54337
54528
  controls: current.controls,
54338
54529
  appOnlyParents: current.appOnlyParents,
54530
+ ...current.hookParents === undefined ? {} : { hookParents: current.hookParents },
54339
54531
  skills: current.skills
54340
54532
  };
54341
- if (hash2(priorProjection) !== previous.sha256 || hash2(currentProjection) !== current.sha256 || canonical7(priorProjection) !== canonical7(currentProjection))
54533
+ const comparable = (projection) => ({ ...projection, hookParents: projection.hookParents ?? [] });
54534
+ if (hash2(priorProjection) !== previous.sha256 || hash2(currentProjection) !== current.sha256 || canonical7(comparable(priorProjection)) !== canonical7(comparable(currentProjection)))
54342
54535
  refuse4();
54343
54536
  }
54344
54537
  var CODEX_SEMANTIC_CACHE_WITNESS_SCHEMA = "hasna.codex-semantic-cache-witness.v1", identifier3 = (value) => typeof value === "string" && /^[A-Za-z0-9_-]{1,64}$/.test(value), digest = (value) => typeof value === "string" && /^[a-f0-9]{64}$/.test(value), refuse4 = () => {
54345
54538
  throw new Error("CODEX_SEMANTIC_CACHE_WITNESS_UNSUPPORTED: review Codex plugin cache identity and controls");
54346
- }, MAX_DOCUMENT_BYTES, MAX_RECEIPT_BYTES;
54539
+ }, MAX_DOCUMENT_BYTES, MAX_RECEIPT_BYTES, codexHookEvents;
54347
54540
  var init_codex_semantic_cache_witness = __esm(() => {
54348
54541
  init_claude_settings_witness();
54349
54542
  init_codex_plugin_skill_controls();
54350
54543
  init_codex_native_skill_catalog();
54351
54544
  MAX_DOCUMENT_BYTES = 1024 * 1024;
54352
54545
  MAX_RECEIPT_BYTES = 16 * 1024;
54546
+ codexHookEvents = new Set([
54547
+ "SessionStart",
54548
+ "UserPromptSubmit",
54549
+ "PreToolUse",
54550
+ "PostToolUse",
54551
+ "PostToolUseFailure",
54552
+ "Stop",
54553
+ "SubagentStart",
54554
+ "SubagentStop",
54555
+ "PreCompact",
54556
+ "Notification",
54557
+ "PermissionRequest",
54558
+ "SessionEnd",
54559
+ "ConfigChange",
54560
+ "WorktreeCreate",
54561
+ "WorktreeRemove",
54562
+ "TeammateIdle",
54563
+ "TaskComplete"
54564
+ ]);
54353
54565
  });
54354
54566
 
54355
54567
  // src/lib/managed-policy.ts
@@ -55745,7 +55957,7 @@ var init_retained_review_artifacts = __esm(() => {
55745
55957
  import { createHash as createHash22, randomUUID as randomUUID6 } from "crypto";
55746
55958
  import { isDeepStrictEqual as isDeepStrictEqual7 } from "util";
55747
55959
  import { existsSync as existsSync13, lstatSync as lstatSync23, statSync as statSync10, mkdirSync as mkdirSync7, readFileSync as readFileSync16, readdirSync as readdirSync9, opendirSync as opendirSync3, readlinkSync as readlinkSync7, realpathSync as realpathSync11, renameSync as renameSync3, rmdirSync as rmdirSync2, writeFileSync as writeFileSync6, unlinkSync as unlinkSync4, chmodSync, openSync as openSync14, closeSync as closeSync14, fsyncSync as fsyncSync6, fstatSync as fstatSync14, readSync as readSync11, constants as constants16, linkSync as linkSync2 } from "fs";
55748
- import { dirname as dirname18, join as join30, resolve as resolve19, relative as relative7, isAbsolute as isAbsolute20, sep as sep9 } from "path";
55960
+ import { basename as basename10, dirname as dirname18, join as join30, resolve as resolve19, relative as relative7, isAbsolute as isAbsolute20, sep as sep9 } from "path";
55749
55961
  import { homedir as homedir3 } from "os";
55750
55962
  function nativeAgentRoot(home, agent, cwd2 = process.cwd()) {
55751
55963
  if (agent === "sumi")
@@ -56896,7 +57108,7 @@ function planAgentSettingsWitnessUpgrade(options) {
56896
57108
  return { dataDir: dataDir3, profileId: policy.profileId, changes: [{ path: join30(dataDir3, "agent-policy.json"), before: snapshot2.text, after: after2 }], nativeSkills: [], observedPolicy: { path: join30(dataDir3, "agent-policy.json"), before: snapshot2.text }, observedSettings: { path: configPath, before: settings }, discoveryBefore: [replacement], discoveryAfter: [replacement], ...policy.bridge.discoveryExecutables ? { discoveryExecutables: policy.bridge.discoveryExecutables } : {}, rootAliases: aliases, managedAgentChecks: { home, agents: [options.agent] }, settingsWitnessUpgrade: { agent: options.agent, path: configPath, fromHashMode: previous.hashMode ?? "bytes", fromSha256: previous.sha256, toHashMode: next.hashMode, toSha256: next.sha256, reviewedPreimage: options.reviewedPreimage, currentSettingsSha256: options.expectedSettingsSha256, replacedWitnesses: replaced.map((source) => ({ hashMode: source.hashMode ?? "bytes", sha256: source.sha256 })) } };
56897
57109
  }
56898
57110
  function planCodexSemanticCacheWitnessUpgrade(options) {
56899
- if (options.agent !== "codex" || !/^[a-f0-9]{64}$/.test(options.expectedPolicySha256) || !/^[a-f0-9]{64}$/.test(options.expectedSettingsSha256) || options.expectedCacheWitnessSha256 !== undefined && !/^[a-f0-9]{64}$/.test(options.expectedCacheWitnessSha256) || !Array.isArray(options.appOnlyParents) || options.appOnlyParents.length > 4096 || new Set(options.appOnlyParents).size !== options.appOnlyParents.length)
57111
+ if (options.agent !== "codex" || !/^[a-f0-9]{64}$/.test(options.expectedPolicySha256) || !/^[a-f0-9]{64}$/.test(options.expectedSettingsSha256) || options.expectedCacheWitnessSha256 !== undefined && !/^[a-f0-9]{64}$/.test(options.expectedCacheWitnessSha256) || !Array.isArray(options.appOnlyParents) || options.appOnlyParents.length > 4096 || new Set(options.appOnlyParents).size !== options.appOnlyParents.length || options.reviewedHookParents !== undefined && (!Array.isArray(options.reviewedHookParents) || options.reviewedHookParents.length > 4096 || new Set(options.reviewedHookParents).size !== options.reviewedHookParents.length))
56900
57112
  throw new Error("Invalid Codex semantic cache upgrade request");
56901
57113
  const home = resolve19(options.home ?? homedir3()), dataDir3 = options.dataDir ?? getDataDirReadOnly();
56902
57114
  const snapshot2 = readManagedSkillPolicySnapshot(dataDir3);
@@ -56920,14 +57132,23 @@ function planCodexSemanticCacheWitnessUpgrade(options) {
56920
57132
  throw new Error("Native settings preimage changed");
56921
57133
  const boundedRead = (path) => new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(readNativeBytes(path, 1024 * 1024));
56922
57134
  const unchangedFullSource = (path) => {
56923
- const source = binding.sources.find((source2) => source2.path === path && source2.sha256 !== null && source2.format === undefined && source2.fields === undefined && source2.reviewArtifact === undefined && (source2.hashMode === undefined || source2.hashMode === "bytes"));
56924
- if (!source)
56925
- throw new Error("Cache upgrade lacks prior full identity source");
57135
+ const sources = binding.sources.filter((source2) => source2.path === path && source2.sha256 !== null && source2.format === undefined && source2.fields === undefined && source2.reviewArtifact === undefined && (source2.hashMode === undefined || source2.hashMode === "bytes"));
57136
+ if (sources.length !== 1)
57137
+ throw new Error("Cache upgrade requires one unambiguous prior full identity source");
57138
+ const source = sources[0];
56926
57139
  const text2 = boundedRead(path);
56927
57140
  if (sha4(text2) !== source.sha256)
56928
57141
  throw new Error("Reviewed cache identity source changed");
56929
57142
  return text2;
56930
57143
  };
57144
+ const unchangedReviewedHookSource = (path) => {
57145
+ const sources = binding.sources.filter((source) => source.path === path);
57146
+ if (!sources.length)
57147
+ throw new Error("Cache upgrade lacks prior full identity source");
57148
+ if (sources.length !== 1)
57149
+ throw new Error("Reviewed hook identity source is ambiguous");
57150
+ return unchangedFullSource(path);
57151
+ };
56931
57152
  const appOnlyParents = options.appOnlyParents.map((parent) => {
56932
57153
  const parts = relative7(cacheRoot, parent).split(sep9);
56933
57154
  if (!isAbsolute20(parent) || resolve19(parent) !== parent || parts.length !== 2 || parts.some((part) => !/^[A-Za-z0-9_-]{1,64}$/.test(part)) || controls.some((control) => control.pluginParent === parent))
@@ -56942,11 +57163,60 @@ function planCodexSemanticCacheWitnessUpgrade(options) {
56942
57163
  unchangedFullSource(source.path);
56943
57164
  return { role: "app-only", pluginId: `${parts[1]}@${parts[0]}`, namespace: parts[1], pluginParent: parent, remotePluginId: receipt.remote_plugin_id };
56944
57165
  }).sort((a, b) => a.pluginParent.localeCompare(b.pluginParent));
56945
- const parents2 = [...new Set([...controls.map((control) => control.pluginParent), ...appOnlyParents.map((parent) => parent.pluginParent)])];
57166
+ const reviewedHookParents = (options.reviewedHookParents ?? []).map((parent) => {
57167
+ const parts = relative7(cacheRoot, parent).split(sep9);
57168
+ if (!isAbsolute20(parent) || resolve19(parent) !== parent || parts.length !== 2 || parts.some((part) => !/^[A-Za-z0-9_-]{1,64}$/.test(part)) || controls.some((control) => control.pluginParent === parent) || appOnlyParents.some((role) => role.pluginParent === parent))
57169
+ throw new Error("Unsupported reviewed native-hook parent role");
57170
+ const receiptPath = join30(parent, ".codex-remote-plugin-install.json"), receiptStat = lstatSync23(receiptPath, { throwIfNoEntry: false });
57171
+ let identity6;
57172
+ if (receiptStat) {
57173
+ if (!receiptStat.isFile() || receiptStat.isSymbolicLink() || receiptStat.size > 16 * 1024)
57174
+ throw new Error("Invalid reviewed native-hook install receipt");
57175
+ const receiptText = unchangedReviewedHookSource(receiptPath);
57176
+ let receipt;
57177
+ try {
57178
+ hashNativeJsonControls(receiptText);
57179
+ receipt = JSON.parse(receiptText);
57180
+ } catch {
57181
+ throw new Error("Invalid reviewed native-hook install receipt");
57182
+ }
57183
+ if (!receipt || Array.isArray(receipt) || Object.keys(receipt).length !== 2 || receipt.schema_version !== 1 || typeof receipt.remote_plugin_id !== "string" || !/^[A-Za-z0-9_~-]{1,1024}$/.test(receipt.remote_plugin_id))
57184
+ throw new Error("Invalid reviewed native-hook install receipt");
57185
+ identity6 = { role: "reviewed-hook", pluginId: `${parts[1]}@${parts[0]}`, namespace: parts[1], pluginParent: parent, installation: "remote-receipt", remotePluginId: receipt.remote_plugin_id };
57186
+ } else {
57187
+ const pluginId = `${parts[1]}@${parts[0]}`;
57188
+ const marketplaceSources = binding.sources.filter((source2) => basename10(source2.path) === "marketplace.json" && source2.sha256 !== null && source2.format === undefined && source2.fields === undefined && source2.reviewArtifact === undefined && (source2.hashMode === undefined || source2.hashMode === "bytes"));
57189
+ const matches2 = marketplaceSources.flatMap((source2) => {
57190
+ const text2 = unchangedFullSource(source2.path);
57191
+ return codexLocalMarketplaceMapsPlugin(text2, parts[0], parts[1]) ? [{ source: source2, text: text2 }] : [];
57192
+ });
57193
+ if (matches2.length !== 1)
57194
+ throw new Error("Local marketplace hook parent lacks one exact enrolled marketplace source");
57195
+ const { source } = matches2[0];
57196
+ const config = Bun.TOML.parse(settings);
57197
+ if (config.plugins?.[pluginId]?.enabled !== true)
57198
+ throw new Error("Local marketplace hook parent is not enabled in the unchanged Codex settings");
57199
+ identity6 = { role: "reviewed-hook", pluginId, namespace: parts[1], pluginParent: parent, installation: "local-marketplace", marketplaceSourcePath: source.path, marketplaceSha256: source.sha256 };
57200
+ }
57201
+ const versions = readdirSync9(parent).filter((name) => name !== ".codex-remote-plugin-install.json");
57202
+ if (!versions.length || versions.length > 4096)
57203
+ throw new Error("Reviewed native-hook parent has no bounded materializations");
57204
+ for (const version of versions) {
57205
+ if (!/^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/.test(version))
57206
+ throw new Error("Invalid reviewed native-hook version identity");
57207
+ const root = join30(parent, version), stat = lstatSync23(root, { throwIfNoEntry: false });
57208
+ if (!stat?.isDirectory() || stat.isSymbolicLink() || realpathSync11(root) !== root)
57209
+ throw new Error("Invalid reviewed native-hook materialization");
57210
+ unchangedReviewedHookSource(join30(root, ".codex-plugin/plugin.json"));
57211
+ unchangedReviewedHookSource(join30(root, "hooks/hooks.json"));
57212
+ }
57213
+ return identity6;
57214
+ }).sort((a, b) => a.pluginParent.localeCompare(b.pluginParent));
57215
+ const parents2 = [...new Set([...controls.map((control) => control.pluginParent), ...appOnlyParents.map((parent) => parent.pluginParent), ...reviewedHookParents.map((parent) => parent.pluginParent)])];
56946
57216
  const reviewedAlias = aliases.find((alias) => alias.agent === "codex");
56947
57217
  const hookRootAlias = reviewedAlias ? { alias: reviewedAlias.alias, target: reviewedAlias.target } : null;
56948
57218
  assertCodexSemanticCacheHookSafety(cacheRoot, parents2, configPath, hookRootAlias);
56949
- const supersededSources = binding.sources.filter((source) => codexSemanticCacheSourceRole(source, cacheRoot, parents2));
57219
+ const supersededSources = binding.sources.filter((source) => codexSemanticCacheSourceRole(source, cacheRoot, parents2, reviewedHookParents.map((parent) => parent.pluginParent)));
56950
57220
  for (const source of supersededSources)
56951
57221
  if ([".app.json", ".mcp.json"].includes(source.path.split(sep9).at(-1)))
56952
57222
  unchangedFullSource(source.path);
@@ -56954,7 +57224,7 @@ function planCodexSemanticCacheWitnessUpgrade(options) {
56954
57224
  if (!supersededDirectories.some((directory) => directory.path === cacheRoot) || (binding.directories ?? []).some((directory) => cacheRoot.startsWith(directory.path + sep9)))
56955
57225
  throw new Error("Cache upgrade requires exact cache directory coverage without an unproved ancestor projection");
56956
57226
  const rules = Bun.TOML.parse(settings).skills?.config ?? [];
56957
- const witness = captureCodexSemanticCacheWitness({ cacheRoot, controls, appOnlyParents, rules, read: boundedRead });
57227
+ const witness = captureCodexSemanticCacheWitness({ cacheRoot, controls, appOnlyParents, reviewedHookParents, rules, read: boundedRead });
56958
57228
  if (options.expectedCacheWitnessSha256 !== undefined && witness.sha256 !== options.expectedCacheWitnessSha256)
56959
57229
  throw new Error("Reviewed semantic cache preimage changed");
56960
57230
  const replacement = { ...binding, codexDisabledPluginSkills: controls, codexSemanticCache: {
@@ -56963,6 +57233,7 @@ function planCodexSemanticCacheWitnessUpgrade(options) {
56963
57233
  hookRootAlias,
56964
57234
  witness,
56965
57235
  appOnlyParents,
57236
+ reviewedHookParents,
56966
57237
  previousPolicySha256: options.expectedPolicySha256,
56967
57238
  supersededSources,
56968
57239
  supersededDirectories
@@ -56981,7 +57252,7 @@ function planCodexSemanticCacheWitnessUpgrade(options) {
56981
57252
  rootAliases: aliases,
56982
57253
  managedAgentChecks: { home, agents: ["codex"] },
56983
57254
  ...policy.bridge.discoveryExecutables ? { discoveryExecutables: policy.bridge.discoveryExecutables } : {},
56984
- cacheWitnessUpgrade: { ...options, home, dataDir: dataDir3, appOnlyParents: appOnlyParents.map((parent) => parent.pluginParent) }
57255
+ cacheWitnessUpgrade: { ...options, home, dataDir: dataDir3, appOnlyParents: appOnlyParents.map((parent) => parent.pluginParent), reviewedHookParents: reviewedHookParents.map((parent) => parent.pluginParent) }
56985
57256
  };
56986
57257
  }
56987
57258
  function planReviewedArtifactMigration(options) {
@@ -57716,7 +57987,7 @@ import {
57716
57987
  writeFileSync as writeFileSync8
57717
57988
  } from "fs";
57718
57989
  import { homedir as homedir4 } from "os";
57719
- import { basename as basename9, dirname as dirname19, join as join32 } from "path";
57990
+ import { basename as basename11, dirname as dirname19, join as join32 } from "path";
57720
57991
  function isSkillsOwnershipMarker(marker) {
57721
57992
  return typeof marker === "object" && marker !== null && Object.hasOwn(marker, "managedBy") && marker.managedBy === SYNC_MARKER_MANAGED_BY;
57722
57993
  }
@@ -57958,7 +58229,7 @@ function writeManagedSkillDirUnlocked(dir, skillMd, options, assertCurrent) {
57958
58229
  return { action, path: skillMdPath };
57959
58230
  const parentDir = dirname19(dir);
57960
58231
  mkdirSync9(parentDir, { recursive: true });
57961
- const transactionDir = mkdtempSync(join32(parentDir, `.hasna-skills-write-${basename9(dir)}-`));
58232
+ const transactionDir = mkdtempSync(join32(parentDir, `.hasna-skills-write-${basename11(dir)}-`));
57962
58233
  const candidateDir = join32(transactionDir, "candidate");
57963
58234
  const backupDir = join32(transactionDir, "backup");
57964
58235
  const candidateSkillMdPath = join32(candidateDir, "SKILL.md");
@@ -60132,7 +60403,7 @@ var init_plugin_admission = __esm(() => {
60132
60403
 
60133
60404
  // src/lib/plugin-discovery.ts
60134
60405
  import { closeSync as closeSync16, constants as constants18, fstatSync as fstatSync16, lstatSync as lstatSync26, openSync as openSync16, opendirSync as opendirSync5, readSync as readSync13 } from "fs";
60135
- import { basename as basename10, dirname as dirname21, isAbsolute as isAbsolute23, join as join38, resolve as resolve22 } from "path";
60406
+ import { basename as basename12, dirname as dirname21, isAbsolute as isAbsolute23, join as join38, resolve as resolve22 } from "path";
60136
60407
  function validateManagedPluginWitnesses(value) {
60137
60408
  pluginNeed(Array.isArray(value) && value.length > 0 && value.length <= PLUGIN_PROJECTION_LIMITS.registrations, "Invalid managed plugin witness collection");
60138
60409
  const seen = new Set;
@@ -60215,7 +60486,7 @@ function hashManagedPluginRegistry(path, managed) {
60215
60486
  pluginNeed(/^(?:[A-Za-z0-9][A-Za-z0-9._+-]*-)?[a-f0-9]{12}$/.test(row.version) && row.installPath === join38(cacheRoot, row.version), "Managed plugin cache path or version is outside its registration");
60216
60487
  const approval = (producer) => {
60217
60488
  pluginText(producer);
60218
- const digest2 = `sha256:${basename10(producer)}`;
60489
+ const digest2 = `sha256:${basename12(producer)}`;
60219
60490
  const receipt2 = readPluginAdmissionReceipt(witness.storeRoot, witness.bindingId, digest2);
60220
60491
  pluginNeed(receipt2.materializedPath === producer, "Managed producer path is not an approved immutable projection");
60221
60492
  if (!verified.has(producer)) {
@@ -60284,7 +60555,7 @@ var init_plugin_discovery = __esm(() => {
60284
60555
  // src/lib/claude-marketplace-registry.ts
60285
60556
  import { createHash as createHash25 } from "crypto";
60286
60557
  import { closeSync as closeSync17, constants as constants19, fstatSync as fstatSync17, lstatSync as lstatSync27, openSync as openSync17, readSync as readSync14 } from "fs";
60287
- import { basename as basename11, dirname as dirname22, isAbsolute as isAbsolute24, resolve as resolve23 } from "path";
60558
+ import { basename as basename13, dirname as dirname22, isAbsolute as isAbsolute24, resolve as resolve23 } from "path";
60288
60559
  function need8(value, reason2) {
60289
60560
  if (!value)
60290
60561
  throw new Error(`Claude marketplace registry ${reason2}`);
@@ -60304,7 +60575,7 @@ function parents2(path) {
60304
60575
  }
60305
60576
  function readRegistry2(path, budget2) {
60306
60577
  absolutePath4(path);
60307
- need8(basename11(path) === "known_marketplaces.json", "requires known_marketplaces.json");
60578
+ need8(basename13(path) === "known_marketplaces.json", "requires known_marketplaces.json");
60308
60579
  need8(Number.isSafeInteger(budget2.remaining) && budget2.remaining >= 0, "has an invalid byte budget");
60309
60580
  const ancestors2 = parents2(path), initial2 = lstatSync27(path, { bigint: true });
60310
60581
  need8(initial2.isFile() && !initial2.isSymbolicLink() && initial2.size <= BigInt(CLAUDE_MARKETPLACE_REGISTRY_LIMITS.bytes), "is not a bounded regular file");
@@ -60751,7 +61022,7 @@ var init_codex_hook_discovery_recovery = __esm(() => {
60751
61022
  // src/lib/agent-discovery.ts
60752
61023
  import { createHash as createHash27 } from "crypto";
60753
61024
  import { lstatSync as lstatSync28, readFileSync as readFileSync21, readdirSync as readdirSync12, realpathSync as realpathSync12 } from "fs";
60754
- import { basename as basename12, dirname as dirname23, isAbsolute as isAbsolute26, join as join39, relative as relative8, resolve as resolve24, sep as sep10 } from "path";
61025
+ import { basename as basename14, dirname as dirname23, isAbsolute as isAbsolute26, join as join39, relative as relative8, resolve as resolve24, sep as sep10 } from "path";
60755
61026
  import { isDeepStrictEqual as isDeepStrictEqual11 } from "util";
60756
61027
  function discoveryRootUnresolved(agent, command, detail) {
60757
61028
  return new Error(`${DISCOVERY_ROOT_UNRESOLVED}: ${agent} discovery cannot resolve its "${command}" executable: ${detail}. The reviewed discovery is unchanged; this is an environment gap, not drift.`);
@@ -60831,7 +61102,7 @@ function assertReviewedClaudeCacheClosures(home, config, review, canonical9) {
60831
61102
  throw new Error("Reviewed Claude enabled plugin registration requires an object with an installPath string");
60832
61103
  }
60833
61104
  if ([cacheAliasRoot, cacheRoot].some((root2) => row.installPath === root2 || row.installPath.startsWith(root2 + sep10))) {
60834
- if (!cachePath(row.installPath) || row.installPath.length > AGENT_POLICY_LIMITS.pathCharacters || row.version !== undefined && (typeof row.version !== "string" || basename12(row.installPath) !== row.version)) {
61105
+ if (!cachePath(row.installPath) || row.installPath.length > AGENT_POLICY_LIMITS.pathCharacters || row.version !== undefined && (typeof row.version !== "string" || basename14(row.installPath) !== row.version)) {
60835
61106
  throw new Error("Reviewed Claude discovery has a malformed active cache registration");
60836
61107
  }
60837
61108
  if (row.scope === "user" && (row.projectPath === undefined || row.projectPath === null)) {} else if (row.scope === "project" && typeof row.projectPath === "string" && isAbsolute26(row.projectPath) && resolve24(row.projectPath) === row.projectPath && row.projectPath.length <= AGENT_POLICY_LIMITS.pathCharacters) {} else
@@ -61109,7 +61380,7 @@ function absentRetiredClaudeRoots(binding) {
61109
61380
  if (!targetValid || !targetScopes.has("user\x00"))
61110
61381
  continue;
61111
61382
  const active = rows[0]?.installPath;
61112
- if (typeof active !== "string" || rows[0]?.version !== basename12(active) || dirname23(active) !== dirname23(root2) || active === root2 || !lstatSync28(active, { throwIfNoEntry: false })?.isDirectory() || realpathSync12(active) !== active)
61383
+ if (typeof active !== "string" || rows[0]?.version !== basename14(active) || dirname23(active) !== dirname23(root2) || active === root2 || !lstatSync28(active, { throwIfNoEntry: false })?.isDirectory() || realpathSync12(active) !== active)
61113
61384
  continue;
61114
61385
  const activeManifest = full(join39(active, ".claude-plugin/plugin.json"));
61115
61386
  if (!activeManifest || projected(activeManifest) !== activeManifest.sha256)
@@ -61118,14 +61389,15 @@ function absentRetiredClaudeRoots(binding) {
61118
61389
  }
61119
61390
  return [...result2];
61120
61391
  }
61121
- function codexSemanticCacheSourceRole(source, cacheRoot, parents3) {
61392
+ function codexSemanticCacheSourceRole(source, cacheRoot, parents3, hookParents = []) {
61122
61393
  if (!isAbsolute26(source.path) || resolve24(source.path) !== source.path || /[\x00-\x1f\x7f]/.test(source.path) || source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || source.reviewArtifact !== undefined || source.hashMode !== undefined && source.hashMode !== "bytes")
61123
61394
  return false;
61124
61395
  const parts = relative8(cacheRoot, source.path).split(sep10);
61125
61396
  if (parts.length < 3 || !parents3.includes(join39(cacheRoot, parts[0], parts[1])))
61126
61397
  return false;
61127
61398
  const tail2 = parts.slice(3).join("/");
61128
- return parts.length === 5 && tail2 === ".codex-plugin/plugin.json" && source.sha256 !== null || parts.length === 4 && [".app.json", ".mcp.json"].includes(tail2) && source.sha256 !== null || source.sha256 === null && (parts.length === 4 && tail2 === "SKILL.md" || parts.length === 5 && tail2 === "hooks/hooks.json");
61399
+ const parent = join39(cacheRoot, parts[0], parts[1]);
61400
+ return parts.length === 5 && tail2 === ".codex-plugin/plugin.json" && source.sha256 !== null || parts.length === 4 && [".app.json", ".mcp.json"].includes(tail2) && source.sha256 !== null || parts.length === 5 && tail2 === "hooks/hooks.json" && hookParents.includes(parent) && source.sha256 !== null || source.sha256 === null && (parts.length === 4 && tail2 === "SKILL.md" || parts.length === 5 && tail2 === "hooks/hooks.json");
61129
61401
  }
61130
61402
  function codexSemanticCacheDirectoryRole(path, cacheRoot) {
61131
61403
  return isAbsolute26(path) && resolve24(path) === path && !/[\x00-\x1f\x7f]/.test(path) && (path === cacheRoot || path.startsWith(cacheRoot + sep10));
@@ -61157,20 +61429,28 @@ function verifyCodexSemanticCacheDiscovery(binding, reviewedRootAliases) {
61157
61429
  const cacheRoot = proof.witness.cacheRoot;
61158
61430
  if (controls.some((control) => dirname23(dirname23(control.pluginParent)) !== cacheRoot))
61159
61431
  throw new Error("Codex semantic cache names another enrolled cache");
61160
- const parents3 = [...new Set([...controls.map((control) => control.pluginParent), ...proof.appOnlyParents.map((parent) => parent.pluginParent)])];
61161
- const sources = binding.sources.filter((source) => codexSemanticCacheSourceRole(source, cacheRoot, parents3));
61432
+ const reviewedHookParents = proof.reviewedHookParents ?? [];
61433
+ if (!Array.isArray(reviewedHookParents) || reviewedHookParents.length > 4096 || reviewedHookParents.some((parent) => !parent || !(parent.installation === "remote-receipt" && Object.keys(parent).sort().join(",") === "installation,namespace,pluginId,pluginParent,remotePluginId,role" && typeof parent.remotePluginId === "string" || parent.installation === "local-marketplace" && Object.keys(parent).sort().join(",") === "installation,marketplaceSha256,marketplaceSourcePath,namespace,pluginId,pluginParent,role" && typeof parent.marketplaceSourcePath === "string" && /^[a-f0-9]{64}$/.test(parent.marketplaceSha256 ?? "")) || parent.role !== "reviewed-hook" || typeof parent.pluginId !== "string" || typeof parent.namespace !== "string" || typeof parent.pluginParent !== "string") || new Set(reviewedHookParents.map((parent) => parent.pluginParent)).size !== reviewedHookParents.length || !isDeepStrictEqual11((proof.witness.hookParents ?? []).map(({ manifestSha256: _manifest, hooksSha256: _hooks, receiptSha256: _receipt, ...parent }) => parent), reviewedHookParents)) {
61434
+ throw new Error("Invalid reviewed native-hook cache role");
61435
+ }
61436
+ for (const parent of reviewedHookParents)
61437
+ if (parent.installation === "local-marketplace" && !binding.sources.some((source) => source.path === parent.marketplaceSourcePath && source.sha256 === parent.marketplaceSha256 && source.sha256 !== null && source.format === undefined && source.fields === undefined && source.reviewArtifact === undefined && (source.hashMode === undefined || source.hashMode === "bytes")))
61438
+ throw new Error("Local marketplace hook parent lost its enrolled source witness");
61439
+ const parents3 = [...new Set([...controls.map((control) => control.pluginParent), ...proof.appOnlyParents.map((parent) => parent.pluginParent), ...reviewedHookParents.map((parent) => parent.pluginParent)])];
61440
+ const hookParentPaths = reviewedHookParents.map((parent) => parent.pluginParent);
61441
+ const sources = binding.sources.filter((source) => codexSemanticCacheSourceRole(source, cacheRoot, parents3, hookParentPaths));
61162
61442
  const directories = (binding.directories ?? []).filter((directory) => codexSemanticCacheDirectoryRole(directory.path, cacheRoot));
61163
61443
  if (!directories.length || !isDeepStrictEqual11(sources, proof.supersededSources) || !isDeepStrictEqual11(directories, proof.supersededDirectories))
61164
61444
  throw new Error("Codex semantic cache provenance changed");
61165
61445
  const configPath = proof.configPath;
61166
- if (!isAbsolute26(configPath) || resolve24(configPath) !== configPath || basename12(configPath) !== "config.toml" || /[\x00-\x1f\x7f]/.test(configPath))
61446
+ if (!isAbsolute26(configPath) || resolve24(configPath) !== configPath || basename14(configPath) !== "config.toml" || /[\x00-\x1f\x7f]/.test(configPath))
61167
61447
  throw new Error("Invalid semantic cache configuration source");
61168
61448
  const configSource = binding.sources.find((source) => source.path === configPath && source.sha256 !== null && source.format === undefined && source.fields === undefined);
61169
61449
  if (!configSource || projected(configSource) !== configSource.sha256)
61170
61450
  throw new Error("Codex semantic cache requires unchanged reviewed configuration");
61171
61451
  assertCodexSemanticCacheHookSafety(cacheRoot, parents3, configPath, proof.hookRootAlias);
61172
61452
  const rules = parseConfig(read2(configPath), configPath, true).skills?.config ?? [];
61173
- const current = captureCodexSemanticCacheWitness({ cacheRoot, controls, appOnlyParents: proof.appOnlyParents, rules });
61453
+ const current = captureCodexSemanticCacheWitness({ cacheRoot, controls, appOnlyParents: proof.appOnlyParents, reviewedHookParents, rules });
61174
61454
  assertCodexSemanticCacheWitnessUnchanged(proof.witness, current);
61175
61455
  return proof;
61176
61456
  }
@@ -61254,7 +61534,7 @@ function codexInstallationRoots(binding) {
61254
61534
  const config = join39(dirname23(dirname23(cache3)), "config.toml"), home = dirname23(dirname23(dirname23(cache3)));
61255
61535
  const configSource = binding.sources.find((source) => source.path === config && source.sha256 !== null && (!source.format || source.format === "toml" && source.fields?.includes("plugins")));
61256
61536
  const nativeRoots = NATIVE_SKILL_ROOTS.filter(([agent]) => agent === "codex").map(([, path]) => join39(home, path));
61257
- if (!configSource || proof.plugins.some((input) => nativeRoots.some((root2) => root2 === input.sourceRoot || root2.startsWith(input.sourceRoot + sep10) || input.sourceRoot.startsWith(root2 + sep10)) || binding.sources.some((source) => basename12(source.path) === "config.toml" && (source.path === input.sourceRoot || source.path.startsWith(input.sourceRoot + sep10)))))
61537
+ if (!configSource || proof.plugins.some((input) => nativeRoots.some((root2) => root2 === input.sourceRoot || root2.startsWith(input.sourceRoot + sep10) || input.sourceRoot.startsWith(root2 + sep10)) || binding.sources.some((source) => basename14(source.path) === "config.toml" && (source.path === input.sourceRoot || source.path.startsWith(input.sourceRoot + sep10)))))
61258
61538
  throw new Error("Native installation input overlaps configuration or loading roots");
61259
61539
  if (proof.plugins.some((input) => dirname23(dirname23(input.pluginParent)) !== cache3 || !binding.sources.some((source) => source.path === join39(input.sourceRoot, ".codex-plugin/plugin.json") && source.sha256 !== null && source.format === undefined && source.fields === undefined)))
61260
61540
  throw new Error("Missing native installation input source witness");
@@ -61266,13 +61546,13 @@ function codexInstallationRoots(binding) {
61266
61546
  });
61267
61547
  }
61268
61548
  function assertMarketplaceBinding(binding, source) {
61269
- if (source.hashMode === "claude-plugin-manifest-v1" && (binding.agent !== "claude" || basename12(source.path) !== "plugin.json" || !source.path.endsWith(join39(sep10, ".claude-plugin", "plugin.json"))))
61549
+ if (source.hashMode === "claude-plugin-manifest-v1" && (binding.agent !== "claude" || basename14(source.path) !== "plugin.json" || !source.path.endsWith(join39(sep10, ".claude-plugin", "plugin.json"))))
61270
61550
  throw new Error("Claude plugin manifest witnesses require Claude plugin discovery");
61271
- if (source.hashMode === "sumi-settings-v1" && (binding.agent !== "sumi" || binding.method !== "reviewed" || basename12(source.path) !== "sumi.json"))
61551
+ if (source.hashMode === "sumi-settings-v1" && (binding.agent !== "sumi" || binding.method !== "reviewed" || basename14(source.path) !== "sumi.json"))
61272
61552
  throw new Error("Sumi settings witnesses require explicit reviewed Sumi configuration");
61273
- if ((source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4" || source.hashMode === "codex-settings-v5")) && (binding.agent !== "codex" || binding.method !== "reviewed" || basename12(source.path) !== "config.toml"))
61553
+ if ((source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4" || source.hashMode === "codex-settings-v5")) && (binding.agent !== "codex" || binding.method !== "reviewed" || basename14(source.path) !== "config.toml"))
61274
61554
  throw new Error("Codex settings witnesses require explicit reviewed Codex configuration");
61275
- if ((source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "claude-settings-v4")) && (binding.agent !== "claude" || binding.method !== "reviewed" || basename12(source.path) !== "settings.json"))
61555
+ if ((source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "claude-settings-v4")) && (binding.agent !== "claude" || binding.method !== "reviewed" || basename14(source.path) !== "settings.json"))
61276
61556
  throw new Error("Claude settings witnesses require explicit reviewed Claude configuration");
61277
61557
  if ((source.hashMode === "claude-marketplace-registry" || source.hashMode === "claude-marketplace-registry-v2") && (binding.agent !== "claude" || binding.method !== "reviewed"))
61278
61558
  throw new Error("Claude marketplace witnesses require explicit reviewed Claude discovery");
@@ -61384,7 +61664,7 @@ function verifyAutomaticDiscoveryClosure(binding, options) {
61384
61664
  const current = resolveAgentDiscovery({ home: options.home, agent: binding.agent, canonical: options.canonical, executable: runtime });
61385
61665
  if (JSON.stringify(current) === JSON.stringify(binding))
61386
61666
  return;
61387
- const reviewedWithRuntime = (binding.builtinNames?.length ?? 0) > 0 || binding.sources.some((source) => basename12(source.path) === "package.json");
61667
+ const reviewedWithRuntime = (binding.builtinNames?.length ?? 0) > 0 || binding.sources.some((source) => basename14(source.path) === "package.json");
61388
61668
  const otherwiseCurrent = current.method === binding.method && JSON.stringify(current.roots) === JSON.stringify(binding.roots) && JSON.stringify(current.directories) === JSON.stringify(binding.directories) && current.sources.every((source) => binding.sources.some((saved) => isDeepStrictEqual11(saved, source)));
61389
61669
  if (command && gap && runtime === null && reviewedWithRuntime && otherwiseCurrent)
61390
61670
  throw discoveryRootUnresolved(binding.agent, command, gap);
@@ -61527,7 +61807,7 @@ function resolveAgentDiscovery(options) {
61527
61807
  throw new Error("Discovery review must include the agent configuration source");
61528
61808
  const reviewedSources = supersedesSettingsProjection(agent, review.sources, canonical9(configPath)) ? sources.filter((source) => !isSupersededSettingsProjection(agent, canonical9(configPath), source)) : sources;
61529
61809
  const reviewedSourcesWithManifestProjection = review.sources.map((source) => {
61530
- if (agent !== "claude" || source.sha256 === null || source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || source.hashMode !== undefined && source.hashMode !== "bytes" || basename12(source.path) !== "plugin.json" || !source.path.endsWith(join39(sep10, ".claude-plugin", "plugin.json")))
61810
+ if (agent !== "claude" || source.sha256 === null || source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || source.hashMode !== undefined && source.hashMode !== "bytes" || basename14(source.path) !== "plugin.json" || !source.path.endsWith(join39(sep10, ".claude-plugin", "plugin.json")))
61531
61811
  return source;
61532
61812
  const pluginRoot = dirname23(dirname23(source.path)), hooksPath = join39(pluginRoot, "hooks/hooks.json");
61533
61813
  const hookStat = lstatSync28(hooksPath, { throwIfNoEntry: false });
@@ -61707,7 +61987,7 @@ var init_agent_discovery = __esm(() => {
61707
61987
  // src/lib/authoring-path.ts
61708
61988
  import { lstatSync as lstatSync29, realpathSync as realpathSync13 } from "fs";
61709
61989
  import { homedir as homedir7 } from "os";
61710
- import { basename as basename13, dirname as dirname24, join as join40, resolve as resolve25, sep as sep11 } from "path";
61990
+ import { basename as basename15, dirname as dirname24, join as join40, resolve as resolve25, sep as sep11 } from "path";
61711
61991
  function pathParts(path) {
61712
61992
  return resolve25(path).split(sep11).filter(Boolean);
61713
61993
  }
@@ -61726,7 +62006,7 @@ function physicalPath(path) {
61726
62006
  let cursor = resolve25(path);
61727
62007
  const suffix = [];
61728
62008
  while (!lstatSync29(cursor, { throwIfNoEntry: false })) {
61729
- suffix.unshift(basename13(cursor));
62009
+ suffix.unshift(basename15(cursor));
61730
62010
  const parent = dirname24(cursor);
61731
62011
  if (parent === cursor)
61732
62012
  return resolve25(path);
@@ -61821,7 +62101,7 @@ import {
61821
62101
  statSync as statSync13,
61822
62102
  writeFileSync as writeFileSync10
61823
62103
  } from "fs";
61824
- import { basename as basename14, dirname as dirname25, isAbsolute as isAbsolute27, join as join41, normalize as normalize4, relative as relative9, resolve as resolve26, sep as sep12 } from "path";
62104
+ import { basename as basename16, dirname as dirname25, isAbsolute as isAbsolute27, join as join41, normalize as normalize4, relative as relative9, resolve as resolve26, sep as sep12 } from "path";
61825
62105
  function getPortableSkillsRoot(options = {}) {
61826
62106
  return resolvePortableSkillsRoot(options, true);
61827
62107
  }
@@ -61969,7 +62249,7 @@ function physicalImportPath(path) {
61969
62249
  let ancestor = resolve26(path);
61970
62250
  const suffix = [];
61971
62251
  while (!existsSync19(ancestor)) {
61972
- suffix.unshift(basename14(ancestor));
62252
+ suffix.unshift(basename16(ancestor));
61973
62253
  ancestor = dirname25(ancestor);
61974
62254
  }
61975
62255
  return join41(realpathSync14(ancestor), ...suffix);
@@ -61994,8 +62274,8 @@ function portPortableSkill(sourcePath, options = {}) {
61994
62274
  const explicitName = options.name != null;
61995
62275
  const skillName = normalizeNewPortableSkillName(options.name ?? inferred.name);
61996
62276
  if (isOfficialSkillName(skillName) && !options.allowShadow) {
61997
- const sourceSlug = safeNormalizeName(basename14(absoluteSource));
61998
- const via = explicitName ? `Name '${skillName}' matches a bundled official skill.` : `Inferred name '${skillName}'${sourceSlug && sourceSlug !== skillName ? ` (from source folder '${basename14(absoluteSource)}')` : ""} matches a bundled official skill.`;
62277
+ const sourceSlug = safeNormalizeName(basename16(absoluteSource));
62278
+ const via = explicitName ? `Name '${skillName}' matches a bundled official skill.` : `Inferred name '${skillName}'${sourceSlug && sourceSlug !== skillName ? ` (from source folder '${basename16(absoluteSource)}')` : ""} matches a bundled official skill.`;
61999
62279
  throw new Error(`${via} Importing it would shadow the official '${skillName}'. ` + `Pass --name to choose a different name, or --allow-shadow to override deliberately.`);
62000
62280
  }
62001
62281
  const readOnlyDestination = join41(resolvePortableSkillsRoot(options, false), skillName);
@@ -64204,13 +64484,13 @@ var require_cli_spinners = __commonJS((exports, module) => {
64204
64484
 
64205
64485
  // src/lib/auth-store.ts
64206
64486
  import { chmodSync as chmodSync2, existsSync as existsSync21, mkdirSync as mkdirSync13, readFileSync as readFileSync25, renameSync as renameSync8, statSync as statSync14, unlinkSync as unlinkSync6, writeFileSync as writeFileSync11 } from "fs";
64207
- import { basename as basename15, dirname as dirname26, join as join43 } from "path";
64487
+ import { basename as basename17, dirname as dirname26, join as join43 } from "path";
64208
64488
  function getAuthFilePath(env3 = process.env) {
64209
64489
  return skillsCredentialFilePath(env3);
64210
64490
  }
64211
64491
  function getIdentityFilePath(env3 = process.env) {
64212
64492
  const file = skillsCredentialFilePath(env3);
64213
- return join43(dirname26(file), basename15(file).replace(/^credentials/, "identity") + ".json");
64493
+ return join43(dirname26(file), basename17(file).replace(/^credentials/, "identity") + ".json");
64214
64494
  }
64215
64495
  function getAuthIdentity(env3 = process.env) {
64216
64496
  return readIdentity(env3);
@@ -86234,7 +86514,7 @@ var init_remote_auth = __esm(() => {
86234
86514
  // src/lib/sign-in.ts
86235
86515
  import { createHash as createHash30 } from "crypto";
86236
86516
  import { chmodSync as chmodSync3, mkdirSync as mkdirSync14, readFileSync as readFileSync26, readdirSync as readdirSync15, renameSync as renameSync9, unlinkSync as unlinkSync7, writeFileSync as writeFileSync12 } from "fs";
86237
- import { basename as basename16, dirname as dirname27, join as join44 } from "path";
86517
+ import { basename as basename18, dirname as dirname27, join as join44 } from "path";
86238
86518
  function isRecord7(value) {
86239
86519
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
86240
86520
  }
@@ -86379,7 +86659,7 @@ async function pollDeviceAuthorization(input2) {
86379
86659
  }
86380
86660
  function pendingDeviceSignInStem(env3) {
86381
86661
  const file2 = skillsCredentialFilePath(env3);
86382
- return { dir: dirname27(file2), stem: basename16(file2).replace(/^credentials/, "device-login") };
86662
+ return { dir: dirname27(file2), stem: basename18(file2).replace(/^credentials/, "device-login") };
86383
86663
  }
86384
86664
  function pendingDeviceSignInPath(origin, env3 = process.env) {
86385
86665
  const { dir, stem } = pendingDeviceSignInStem(env3);
@@ -113773,7 +114053,7 @@ import {
113773
114053
  renameSync as renameSync14,
113774
114054
  writeFileSync as writeFileSync24
113775
114055
  } from "fs";
113776
- import { basename as basename17, delimiter as delimiter3, dirname as dirname36, isAbsolute as isAbsolute33, join as join63, relative as relative12, resolve as resolve31, sep as sep14 } from "path";
114056
+ import { basename as basename19, delimiter as delimiter3, dirname as dirname36, isAbsolute as isAbsolute33, join as join63, relative as relative12, resolve as resolve31, sep as sep14 } from "path";
113777
114057
  function oldLauncherState(item) {
113778
114058
  if (item.oldShape === "pinned")
113779
114059
  return { shape: "pinned", runtime: item.oldRuntime, cwd: item.oldCwd, target: item.oldTarget, sha256: item.oldSha256, format: item.oldFormat, profile: item.oldProfile };
@@ -114605,7 +114885,7 @@ function inspectAliasPackageChain(home, aliasPath, oldLinkTarget, oldTarget, bin
114605
114885
  function validateAliasSource(home, name, actual) {
114606
114886
  const packageRoot = dirname36(dirname36(actual));
114607
114887
  const roots = [join63(home, ".hasna", "skills", "runtime"), join63(home, ".bun", "install"), join63(home, ".local", "lib", "node_modules")];
114608
- if (basename17(packageRoot) !== "skills" || basename17(dirname36(packageRoot)) !== "@hasna" || !roots.some((root2) => isWithin(root2, packageRoot))) {
114888
+ if (basename19(packageRoot) !== "skills" || basename19(dirname36(packageRoot)) !== "@hasna" || !roots.some((root2) => isWithin(root2, packageRoot))) {
114609
114889
  throw new Error("ALIAS_SOURCE_ROOT_UNSUPPORTED");
114610
114890
  }
114611
114891
  assertOwnedSafePath(packageRoot, home);
@@ -114700,8 +114980,8 @@ function adoptCopyfileAliases(options = {}) {
114700
114980
  for (const item of aliases) {
114701
114981
  if (!launcherIs(item.path, oldLauncherState(item)))
114702
114982
  throw new Error("ALIAS_CHANGED_BEFORE_SWITCH");
114703
- inspectAliasPackageChain(home, item.path, item.oldLinkTarget, item.oldTarget, layout.bin[basename17(item.path)], item.chain, true);
114704
- const source = validateAliasSource(home, basename17(item.path), item.oldTarget);
114983
+ inspectAliasPackageChain(home, item.path, item.oldLinkTarget, item.oldTarget, layout.bin[basename19(item.path)], item.chain, true);
114984
+ const source = validateAliasSource(home, basename19(item.path), item.oldTarget);
114705
114985
  if (source.version !== item.oldVersion || source.binarySha256 !== item.oldBinarySha256)
114706
114986
  throw new Error("ALIAS_SOURCE_DRIFT");
114707
114987
  receipt.state = "switching";
@@ -114710,11 +114990,11 @@ function adoptCopyfileAliases(options = {}) {
114710
114990
  replaceLauncher(item);
114711
114991
  if (!launcherIs(item.path, newLauncherState(item)) || !launcherIs(item.backupPath, oldLauncherState(item)))
114712
114992
  throw new Error("ALIAS_SWITCH_READBACK_MISMATCH");
114713
- inspectAliasPackageChain(home, item.path, item.oldLinkTarget, item.oldTarget, layout.bin[basename17(item.path)], item.chain, true);
114993
+ inspectAliasPackageChain(home, item.path, item.oldLinkTarget, item.oldTarget, layout.bin[basename19(item.path)], item.chain, true);
114714
114994
  options.onAliasSwitched?.(item.path);
114715
114995
  }
114716
114996
  for (const item of aliases) {
114717
- inspectAliasPackageChain(home, item.path, item.oldLinkTarget, item.oldTarget, layout.bin[basename17(item.path)], item.chain, true);
114997
+ inspectAliasPackageChain(home, item.path, item.oldLinkTarget, item.oldTarget, layout.bin[basename19(item.path)], item.chain, true);
114718
114998
  if (!launcherIs(item.backupPath, oldLauncherState(item)))
114719
114999
  throw new Error("ALIAS_BACKUP_DRIFT");
114720
115000
  }
@@ -114727,16 +115007,16 @@ function adoptCopyfileAliases(options = {}) {
114727
115007
  for (const item of [...aliases].reverse()) {
114728
115008
  try {
114729
115009
  if (!entryExists(item.backupPath)) {
114730
- inspectAliasPackageChain(home, item.path, item.oldLinkTarget, item.oldTarget, layout.bin[basename17(item.path)], item.chain, true);
114731
- const source2 = validateAliasSource(home, basename17(item.path), item.oldTarget);
115010
+ inspectAliasPackageChain(home, item.path, item.oldLinkTarget, item.oldTarget, layout.bin[basename19(item.path)], item.chain, true);
115011
+ const source2 = validateAliasSource(home, basename19(item.path), item.oldTarget);
114732
115012
  if (!entryExists(item.path) || !launcherIs(item.path, oldLauncherState(item)) || source2.version !== item.oldVersion || source2.binarySha256 !== item.oldBinarySha256)
114733
115013
  failed = true;
114734
115014
  continue;
114735
115015
  }
114736
115016
  if (!launcherIs(item.backupPath, oldLauncherState(item)))
114737
115017
  throw new Error("ALIAS_BACKUP_DRIFT");
114738
- inspectAliasPackageChain(home, item.path, item.oldLinkTarget, item.oldTarget, layout.bin[basename17(item.path)], item.chain, true);
114739
- const source = validateAliasSource(home, basename17(item.path), item.oldTarget);
115018
+ inspectAliasPackageChain(home, item.path, item.oldLinkTarget, item.oldTarget, layout.bin[basename19(item.path)], item.chain, true);
115019
+ const source = validateAliasSource(home, basename19(item.path), item.oldTarget);
114740
115020
  if (source.version !== item.oldVersion || source.binarySha256 !== item.oldBinarySha256)
114741
115021
  throw new Error("ALIAS_SOURCE_DRIFT");
114742
115022
  if (launcherIs(item.path, oldLauncherState(item)))
@@ -114789,7 +115069,7 @@ function rollbackCopyfileAliases(receiptId, options = {}) {
114789
115069
  throw new Error("ALIAS_RECEIPT_BINDING_INVALID");
114790
115070
  const seen = new Set;
114791
115071
  for (const item of receipt.aliases) {
114792
- const name = basename17(item.path), target = layout.bin[name];
115072
+ const name = basename19(item.path), target = layout.bin[name];
114793
115073
  if (!target || seen.has(item.path) || !aliasDirs(home).includes(dirname36(item.path)) || item.newTarget !== join63(layout.currentPackageRoot, target) || item.backupPath !== `${item.path}.skills-alias-prev-${receiptId}` || item.chain !== undefined && (!item.chain || typeof item.chain !== "object" || typeof item.chain.packageLinkPath !== "string" || typeof item.chain.packageLinkTarget !== "string")) {
114794
115074
  throw new Error("ALIAS_RECEIPT_LAUNCHER_INVALID");
114795
115075
  }
@@ -114845,7 +115125,7 @@ function rollbackCopyfileAliases(receiptId, options = {}) {
114845
115125
  restored++;
114846
115126
  }
114847
115127
  for (const item of receipt.aliases) {
114848
- inspectAliasPackageChain(home, item.path, item.oldLinkTarget, item.oldTarget, layout.bin[basename17(item.path)], item.chain, true);
115128
+ inspectAliasPackageChain(home, item.path, item.oldLinkTarget, item.oldTarget, layout.bin[basename19(item.path)], item.chain, true);
114849
115129
  }
114850
115130
  receipt.state = "rolled-back";
114851
115131
  persistAliasReceipt(receiptPath, receipt);
@@ -114898,8 +115178,8 @@ async function updateCopyfileRuntime(version2, options = {}) {
114898
115178
  const finalPath = join63(layout.runtimeRoot, `${version2}-copyfile`);
114899
115179
  const launcherRuntime = pinnedLauncherRuntime();
114900
115180
  const launchers = layout.launchers.map((item) => {
114901
- const newTarget = join63(finalPath, "node_modules", "@hasna", "skills", layout.bin[basename17(item.path)]);
114902
- return { ...item, newTarget, ...pinnedRecordFields(launcherRuntime, finalPath, newTarget, launcherProfileForBin(basename17(item.path), layout.bin[basename17(item.path)])) };
115181
+ const newTarget = join63(finalPath, "node_modules", "@hasna", "skills", layout.bin[basename19(item.path)]);
115182
+ return { ...item, newTarget, ...pinnedRecordFields(launcherRuntime, finalPath, newTarget, launcherProfileForBin(basename19(item.path), layout.bin[basename19(item.path)])) };
114903
115183
  });
114904
115184
  const releaseLock = acquireRuntimeLock(layout.runtimeRoot);
114905
115185
  let switched = [];
@@ -115121,11 +115401,11 @@ function rollbackCopyfileRuntime(receiptId, options = {}) {
115121
115401
  const switched = [];
115122
115402
  const seen = new Set;
115123
115403
  for (const item of receipt.launchers) {
115124
- const bin = oldBins[basename17(item.path)];
115404
+ const bin = oldBins[basename19(item.path)];
115125
115405
  if (!bin || !isAbsolute33(item.path) || seen.has(item.path) || item.oldTarget !== join63(receipt.currentPackageRoot, bin) || item.newTarget !== join63(receipt.targetPackageRoot, bin) || !/^.+\.skills-prev-[0-9a-f-]{36}$/.test(item.backupPath) || !item.backupPath.startsWith(`${item.path}.skills-prev-`) || typeof item.oldLinkTarget !== "string" || resolve31(dirname36(item.path), item.oldLinkTarget) !== item.oldTarget)
115126
115406
  throw new Error("RECEIPT_LAUNCHER_BINDING_INVALID");
115127
115407
  assertNoSymlinkAncestors(dirname36(item.path));
115128
- assertLauncherRecordShapes(item, launcherProfileForBin(basename17(item.path), bin));
115408
+ assertLauncherRecordShapes(item, launcherProfileForBin(basename19(item.path), bin));
115129
115409
  seen.add(item.path);
115130
115410
  const oldState = oldLauncherState(item), newState = newLauncherState(item);
115131
115411
  let activeTarget;
@@ -115191,7 +115471,7 @@ __export(exports_runtime, {
115191
115471
  });
115192
115472
  import { createHash as createHash39, randomUUID as randomUUID11 } from "crypto";
115193
115473
  import { lstatSync as lstatSync36, mkdirSync as mkdirSync27, readFileSync as readFileSync41, writeFileSync as writeFileSync25 } from "fs";
115194
- import { basename as basename18, isAbsolute as isAbsolute34, join as join64 } from "path";
115474
+ import { basename as basename20, isAbsolute as isAbsolute34, join as join64 } from "path";
115195
115475
  import { createInterface } from "readline";
115196
115476
  function registerRuntime(parent) {
115197
115477
  parent.command("run").argument("<skill>", "Skill name").argument("[args...]", "Arguments to pass to the skill; use -- to end Skills options").allowUnknownOption(true).passThroughOptions(true).option("--json", "Output result as JSON", false).option("--remote", "Run on the configured server, using its catalog and quote", false).option("--target <target>", "Execution target: local or cloud").option("--secret-bindings <path>", "Reviewed, exact-selection local execution vault bindings (JSON file)").option("--secret-bindings-template", "Print a scoped bindings template without resolving secrets or running the skill", false).option("--input <json>", "Structured cloud execution input").option("--skill-version <version>", "Exact selected skill version").option("--selection-profile <id>", "Selected Skills profile").option("--session <id>", "Pinned Skills session").option("--cached", "Use the explicit verified selected cache", false).option("--yes", "Approve the server's quoted credit cost for this run", false).option("--idempotency-key <key>", "Reuse this key when retrying the same remote submission").option("--file <path>", "Attach a local input file to a remote run (repeatable)", (value, prior) => [...prior, value], []).option("--wait", "Poll remote runs until a terminal status", false).option("--poll-interval-ms <ms>", "Remote polling interval in milliseconds", "1000").option("--poll-timeout-ms <ms>", "Maximum time to wait for a remote run", "300000").description("Run a skill directly").action(async (name, args2, options, command) => {
@@ -115724,7 +116004,7 @@ async function handleRun(name, args2, options, separatorBeforeSkill) {
115724
116004
  const info = lstatSync36(path);
115725
116005
  if (!info.isFile() || info.size > 20 * 1024 * 1024)
115726
116006
  throw new Error("Input must be a regular file no larger than 20 MiB");
115727
- return { name: basename18(path), bytes: new Uint8Array(readFileSync41(path)) };
116007
+ return { name: basename20(path), bytes: new Uint8Array(readFileSync41(path)) };
115728
116008
  });
115729
116009
  describeRemoteFiles(inputFiles);
115730
116010
  client2 = new RemoteSkillsClient(routing.apiKey, routing.apiOrigin);
@@ -118175,7 +118455,7 @@ var init_codex_native_trust = __esm(() => {
118175
118455
  // src/lib/claude-prospective-review.ts
118176
118456
  import { createHash as createHash43 } from "crypto";
118177
118457
  import { lstatSync as lstatSync41, readFileSync as readFileSync45, readdirSync as readdirSync25, realpathSync as realpathSync22 } from "fs";
118178
- import { basename as basename19, dirname as dirname42, isAbsolute as isAbsolute38, join as join71, relative as relative14, resolve as resolve37, sep as sep17 } from "path";
118458
+ import { basename as basename21, dirname as dirname42, isAbsolute as isAbsolute38, join as join71, relative as relative14, resolve as resolve37, sep as sep17 } from "path";
118179
118459
  import { isDeepStrictEqual as isDeepStrictEqual18 } from "util";
118180
118460
  function hashClaudeDiscoveryBinding(binding) {
118181
118461
  return sha8(JSON.stringify(binding));
@@ -118192,7 +118472,7 @@ function object11(value) {
118192
118472
  function hasOwn2(value, key) {
118193
118473
  return object11(value) && Object.hasOwn(value, key);
118194
118474
  }
118195
- function assertJsonValue(value, name, depth = 0) {
118475
+ function assertJsonValue2(value, name, depth = 0) {
118196
118476
  if (depth > 32)
118197
118477
  refuse8(`${name} exceeds the JSON nesting bound`);
118198
118478
  if (value === null || typeof value === "string" || typeof value === "boolean")
@@ -118204,12 +118484,12 @@ function assertJsonValue(value, name, depth = 0) {
118204
118484
  }
118205
118485
  if (Array.isArray(value)) {
118206
118486
  for (const item of value)
118207
- assertJsonValue(item, name, depth + 1);
118487
+ assertJsonValue2(item, name, depth + 1);
118208
118488
  return;
118209
118489
  }
118210
118490
  if (object11(value)) {
118211
118491
  for (const item of Object.values(value))
118212
- assertJsonValue(item, name, depth + 1);
118492
+ assertJsonValue2(item, name, depth + 1);
118213
118493
  return;
118214
118494
  }
118215
118495
  refuse8(`${name} contains a non-JSON value`);
@@ -118500,13 +118780,13 @@ function reviewClaudeProspectiveCandidate(request2, requestFileSha256) {
118500
118780
  pluginNames.add(selected.plugin);
118501
118781
  if (!object11(selected.optionsPatch))
118502
118782
  refuse8("selected plugin optionsPatch must be a JSON object");
118503
- assertJsonValue(selected.optionsPatch, "selected plugin optionsPatch");
118783
+ assertJsonValue2(selected.optionsPatch, "selected plugin optionsPatch");
118504
118784
  if (selected.optionsPatch.enabled !== true)
118505
118785
  refuse8("selected plugin optionsPatch must explicitly declare enabled: true");
118506
118786
  if (Buffer.byteLength(canonicalJson3(selected.optionsPatch), "utf8") > 16 * 1024)
118507
118787
  refuse8("selected plugin optionsPatch exceeds its byte bound");
118508
118788
  abs(selected.manifestPath, "manifest path");
118509
- if (!selected.manifestPath.startsWith(candidate2.root + sep17) || basename19(dirname42(selected.manifestPath)) !== ".claude-plugin" || selected.manifestPath !== join71(dirname42(dirname42(selected.manifestPath)), ".claude-plugin", "plugin.json"))
118789
+ if (!selected.manifestPath.startsWith(candidate2.root + sep17) || basename21(dirname42(selected.manifestPath)) !== ".claude-plugin" || selected.manifestPath !== join71(dirname42(dirname42(selected.manifestPath)), ".claude-plugin", "plugin.json"))
118510
118790
  refuse8("plugin manifest must be under a plugin root inside the frozen marketplace closure");
118511
118791
  const pluginRoot2 = dirname42(dirname42(selected.manifestPath));
118512
118792
  const relativePluginRoot = relative14(candidate2.root, pluginRoot2);
@@ -119249,13 +119529,13 @@ function registerAgentIntegration(parent) {
119249
119529
  process.exitCode = 1;
119250
119530
  }
119251
119531
  });
119252
- hook.command("rebind-cache").requiredOption("--agent <agent>", "codex").requiredOption("--expected-policy-sha256 <sha256>", "Exact current managed policy bytes").requiredOption("--expected-settings-sha256 <sha256>", "Exact current Codex configuration bytes").option("--app-only-parent <path>", "Explicit canonical remote cache parent with app capabilities and no Skill docs", (value, previous) => [...previous, value], []).option("--expected-cache-witness-sha256 <sha256>", "Exact semantic cache digest from the reviewed preview; required with --apply").option("--apply", "Apply the reviewed policy-only cache witness migration", false).option("--json", "Return metadata-only preview or receipt", false).description("Explicitly migrate an enrolled Codex cache to semantic skill and capability identity").action(async (options) => {
119532
+ hook.command("rebind-cache").requiredOption("--agent <agent>", "codex").requiredOption("--expected-policy-sha256 <sha256>", "Exact current managed policy bytes").requiredOption("--expected-settings-sha256 <sha256>", "Exact current Codex configuration bytes").option("--app-only-parent <path>", "Explicit canonical remote cache parent with app capabilities and no Skill docs", (value, previous) => [...previous, value], []).option("--reviewed-hook-parent <path>", "Explicit canonical cache parent with already-reviewed native mcp_tool hooks", (value, previous) => [...previous, value], []).option("--expected-cache-witness-sha256 <sha256>", "Exact semantic cache digest from the reviewed preview; required with --apply").option("--apply", "Apply the reviewed policy-only cache witness migration", false).option("--json", "Return metadata-only preview or receipt", false).description("Explicitly migrate an enrolled Codex cache to semantic skill and capability identity").action(async (options) => {
119253
119533
  try {
119254
119534
  if (options.agent !== "codex")
119255
119535
  throw new Error("Cache witness rebind accepts codex only");
119256
119536
  if (options.apply && options.expectedCacheWitnessSha256 === undefined)
119257
119537
  throw new Error("Cache witness apply requires --expected-cache-witness-sha256 from an exact reviewed preview");
119258
- const plan = planCodexSemanticCacheWitnessUpgrade({ agent: "codex", appOnlyParents: options.appOnlyParent, expectedPolicySha256: options.expectedPolicySha256, expectedSettingsSha256: options.expectedSettingsSha256, ...options.expectedCacheWitnessSha256 !== undefined ? { expectedCacheWitnessSha256: options.expectedCacheWitnessSha256 } : {} });
119538
+ const plan = planCodexSemanticCacheWitnessUpgrade({ agent: "codex", appOnlyParents: options.appOnlyParent, reviewedHookParents: options.reviewedHookParent, expectedPolicySha256: options.expectedPolicySha256, expectedSettingsSha256: options.expectedSettingsSha256, ...options.expectedCacheWitnessSha256 !== undefined ? { expectedCacheWitnessSha256: options.expectedCacheWitnessSha256 } : {} });
119259
119539
  const result2 = options.apply ? applyAgentIntegration(plan) : { changed: [], backups: [] };
119260
119540
  const proof = plan.discoveryAfter[0].codexSemanticCache;
119261
119541
  await writeCliOutput(options.json ? JSON.stringify({ applied: options.apply, cacheWitnessUpgrade: plan.cacheWitnessUpgrade, witness: proof.witness, previousDirectories: proof.supersededDirectories, previousSources: proof.supersededSources, ...result2 }) : `Codex semantic cache witness ${options.apply ? "upgraded" : "planned"}; native configuration and cache were not changed.`);
@@ -120853,7 +121133,7 @@ var init_registry_sync = __esm(() => {
120853
121133
 
120854
121134
  // src/lib/review-export.ts
120855
121135
  import { constants as constants30, closeSync as closeSync31, existsSync as existsSync38, fstatSync as fstatSync31, fsyncSync as fsyncSync10, lstatSync as lstatSync45, openSync as openSync31, realpathSync as realpathSync24, statSync as statSync25, writeFileSync as writeFileSync33 } from "fs";
120856
- import { basename as basename20, dirname as dirname47, isAbsolute as isAbsolute43, join as join74, parse as parse13, resolve as resolve41, sep as sep21 } from "path";
121136
+ import { basename as basename22, dirname as dirname47, isAbsolute as isAbsolute43, join as join74, parse as parse13, resolve as resolve41, sep as sep21 } from "path";
120857
121137
  function exactVersion(spec) {
120858
121138
  const at2 = spec.indexOf("@");
120859
121139
  const slug2 = spec.slice(0, at2);
@@ -120864,7 +121144,7 @@ function exactVersion(spec) {
120864
121144
  return { slug: slug2, version: version2 };
120865
121145
  }
120866
121146
  function assertPrivateDestination(output2) {
120867
- if (!isAbsolute43(output2) || resolve41(output2) !== output2 || !basename20(output2).endsWith(".tar.gz")) {
121147
+ if (!isAbsolute43(output2) || resolve41(output2) !== output2 || !basename22(output2).endsWith(".tar.gz")) {
120868
121148
  throw new Error("Review output must be an absolute, normalized .tar.gz path.");
120869
121149
  }
120870
121150
  const parent = dirname47(output2);