@hasna/skills 0.10.92 → 0.10.93

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/mcp.js CHANGED
@@ -38,7 +38,7 @@ var package_default;
38
38
  var init_package = __esm(() => {
39
39
  package_default = {
40
40
  name: "@hasna/skills",
41
- version: "0.10.92",
41
+ version: "0.10.93",
42
42
  description: "Skills library for AI coding agents",
43
43
  type: "module",
44
44
  bin: {
@@ -36403,6 +36403,17 @@ var init_runtime_launcher = __esm(() => {
36403
36403
  PINNED_LAUNCHER_MAX_BYTES = 16 * 1024;
36404
36404
  });
36405
36405
 
36406
+ // src/lib/linux-access-acl.ts
36407
+ var LINUX_ACL_FREE_WHEN_UNSUPPORTED;
36408
+ var init_linux_access_acl = __esm(() => {
36409
+ LINUX_ACL_FREE_WHEN_UNSUPPORTED = new Set([
36410
+ 0xef53n,
36411
+ 0x58465342n,
36412
+ 0x9123683en,
36413
+ 0x01021994n
36414
+ ]);
36415
+ });
36416
+
36406
36417
  // src/lib/retained-review-artifacts.ts
36407
36418
  import { createHash as createHash23 } from "crypto";
36408
36419
  import { constants as constants15, closeSync as closeSync17, fstatSync as fstatSync17, fsyncSync as fsyncSync4, lstatSync as lstatSync22, mkdirSync as mkdirSync6, openSync as openSync17, readSync as readSync11, writeSync as writeSync3 } from "fs";
@@ -36524,6 +36535,7 @@ var init_agent_integration = __esm(() => {
36524
36535
  init_claude_settings_witness();
36525
36536
  init_codex_hook_trust_files();
36526
36537
  init_runtime_launcher();
36538
+ init_linux_access_acl();
36527
36539
  init_retained_review_artifacts();
36528
36540
  });
36529
36541
 
@@ -38806,8 +38818,8 @@ function resolveDiscovery(options, exclusion) {
38806
38818
  const configPath = exclusion?.nativeHome === undefined ? agentDiscoveryConfigPath(home, agent) : join33(nativeHome, agent === "codex" ? "config.toml" : "settings.json");
38807
38819
  const configText = witness(configPath, agent === "hermes" ? "yaml" : agent === "codex" ? "toml" : "json", agent === "hermes" ? ["skills", "plugins", "hooks"] : agent === "claude" ? ["enabledPlugins", "extraKnownMarketplaces"] : agent === "codex" ? [...CODEX_DISCOVERY_PROJECTION_FIELDS] : agent === "gemini" ? ["skills", "extensions", "security"] : agent === "opencode" ? ["plugin", "skills"] : agent === "sumi" ? [...SUMI_DISCOVERY_PROJECTION_FIELDS] : ["version"]);
38808
38820
  const config2 = configText === null ? {} : agent === "hermes" ? parseHermesConfig(configText) : parseConfig(configText, configPath, agent === "codex");
38809
- const unresolved = (detail) => {
38810
- throw new Error(`Native discovery is unresolved (${agent}: ${detail}); provide a reviewed --discovery-inputs file`);
38821
+ const unresolved = (detail, source) => {
38822
+ throw new NativeDiscoveryUnresolved(agent, detail, source);
38811
38823
  };
38812
38824
  let opaqueClosureVerified = false;
38813
38825
  const verifyOpaqueClosure = (declarations) => {
@@ -38821,6 +38833,17 @@ function resolveDiscovery(options, exclusion) {
38821
38833
  verifyDiscovery(retained, undefined, undefined, undefined, exclusion?.narrowed, canonical9(configPath));
38822
38834
  opaqueClosureVerified = true;
38823
38835
  };
38836
+ const reviewRemedy = (source, check2) => {
38837
+ try {
38838
+ check2();
38839
+ } catch (error61) {
38840
+ if (error61 instanceof NativeDiscoveryUnresolved) {
38841
+ error61.reviewable = true;
38842
+ error61.source ??= source;
38843
+ }
38844
+ throw error61;
38845
+ }
38846
+ };
38824
38847
  if (exclusion) {
38825
38848
  if (configText !== null && agent !== "codex" && agent !== "hermes")
38826
38849
  parseNativeJsonObject(configText);
@@ -38892,7 +38915,7 @@ function resolveDiscovery(options, exclusion) {
38892
38915
  unresolved(`non-enumerable ${label} require a current settings review`);
38893
38916
  };
38894
38917
  if (hasHooks)
38895
- verifyCurrentOpaqueSettings("hooks");
38918
+ reviewRemedy(canonical9(configPath), () => verifyCurrentOpaqueSettings("hooks"));
38896
38919
  if (agent === "claude") {
38897
38920
  if (config2.env !== undefined) {
38898
38921
  if (!object6(config2.env) || Object.keys(config2.env).length > 512)
@@ -38905,7 +38928,7 @@ function resolveDiscovery(options, exclusion) {
38905
38928
  if (hasFunctionHookEnvironment) {
38906
38929
  if (!["0", "1"].includes(config2.env.CLAUDE_CODE_ENABLE_FUNCTION_HOOKS))
38907
38930
  unresolved("malformed Claude env.CLAUDE_CODE_ENABLE_FUNCTION_HOOKS flag");
38908
- verifyCurrentOpaqueSettings("function-hook environment controls");
38931
+ reviewRemedy(canonical9(configPath), () => verifyCurrentOpaqueSettings("function-hook environment controls"));
38909
38932
  }
38910
38933
  }
38911
38934
  if (config2.pluginConfigs !== undefined) {
@@ -38932,7 +38955,7 @@ function resolveDiscovery(options, exclusion) {
38932
38955
  }
38933
38956
  hasPluginConfigs = Object.keys(config2.pluginConfigs).length > 0;
38934
38957
  if (hasPluginConfigs)
38935
- verifyCurrentOpaqueSettings("plugin configurations");
38958
+ reviewRemedy(canonical9(configPath), () => verifyCurrentOpaqueSettings("plugin configurations"));
38936
38959
  }
38937
38960
  if (config2.enabledPlugins !== undefined && !object6(config2.enabledPlugins))
38938
38961
  unresolved("enabledPlugins must be an object");
@@ -39044,7 +39067,7 @@ function resolveDiscovery(options, exclusion) {
39044
39067
  if (Object.keys(config2.enabledPlugins ?? config2.plugins ?? config2.extensions ?? {}).length > 512)
39045
39068
  unresolved("unbounded native registrations");
39046
39069
  if (hasHooks || hasPluginConfigs || hasFunctionHookEnvironment)
39047
- verifyOpaqueClosure([]);
39070
+ reviewRemedy(canonical9(configPath), () => verifyOpaqueClosure([]));
39048
39071
  }
39049
39072
  if (options.reviewed && (options.reviewed.version !== 1 || !Array.isArray(options.reviewed.agents) || options.reviewed.agents.some((item) => !item || typeof item !== "object") || new Set(options.reviewed.agents.map((item) => item.agent)).size !== options.reviewed.agents.length))
39050
39073
  throw new Error("Invalid --discovery-inputs version or agents");
@@ -39297,40 +39320,41 @@ function resolveDiscovery(options, exclusion) {
39297
39320
  if (exclusion && Object.keys(manifest).some((key2) => /skill|plugin|hook|marketplace|extension|instruction/i.test(key2) && !["skills", "hooks"].includes(key2)))
39298
39321
  unresolved("unknown plugin discovery controls");
39299
39322
  const hooks = witness(join33(root, "hooks/hooks.json"));
39300
- if (manifest.hooks !== undefined || hooks !== null) {
39301
- if (!exclusion || exclusion.retained?.method !== "reviewed")
39302
- unresolved("plugin hooks require a separate no-skill-injection review");
39303
- const required2 = [manifestPath, ...hooks !== null ? [join33(root, "hooks/hooks.json")] : []];
39304
- const scoped = agent === "codex" && codex !== undefined ? [] : undefined;
39305
- if (manifest.hooks !== undefined) {
39306
- if (scoped && manifest.hooks && typeof manifest.hooks === "object" && !Array.isArray(manifest.hooks)) {
39307
- const inline = codexPluginHookHandlers(manifest.hooks);
39308
- if (!inline)
39309
- unresolved("unsupported inline plugin hooks");
39310
- scoped.push(inline);
39311
- } else {
39312
- if (typeof manifest.hooks !== "string")
39313
- unresolved("unsupported plugin hooks target");
39314
- const hook = resolve23(root, manifest.hooks);
39315
- if (!hook.startsWith(root + sep11))
39316
- unresolved("plugin hooks target escapes its root");
39317
- required2.push(hook);
39318
- if (scoped)
39319
- scoped.push(readCodexHookDeclaration(witness(hook), hook));
39320
- }
39321
- }
39322
- if (scoped && hooks !== null)
39323
- scoped.push(readCodexHookDeclaration(hooks, join33(root, "hooks/hooks.json")));
39324
- for (const path of required2) {
39325
- const saved = exclusion.retained.sources.filter((source) => source.path === canonical9(path) && source.sha256 !== null && source.format === undefined && source.fields === undefined);
39326
- if (saved.length ? saved.some((source) => projected(source, undefined, budget3) !== source.sha256) : !(scoped && reviewedInstalledCopy(root, path, codex)))
39327
- unresolved("plugin hooks require current independently reviewed sources");
39328
- }
39329
- if (scoped && scoped.every((item) => item !== null && item.commands === 0)) {
39330
- verifyCodexPluginHookClosure(root, codex, codex.source, new Set(scoped.flatMap((item) => [...item.servers])), required2.map((path) => canonical9(path)));
39331
- } else
39332
- verifyOpaqueClosure(required2.map((path) => canonical9(path)));
39333
- }
39323
+ if (manifest.hooks !== undefined || hooks !== null)
39324
+ reviewRemedy(canonical9(hooks !== null ? join33(root, "hooks/hooks.json") : manifestPath), () => {
39325
+ if (!exclusion || exclusion.retained?.method !== "reviewed")
39326
+ unresolved("plugin hooks require a separate no-skill-injection review");
39327
+ const required2 = [manifestPath, ...hooks !== null ? [join33(root, "hooks/hooks.json")] : []];
39328
+ const scoped = agent === "codex" && codex !== undefined ? [] : undefined;
39329
+ if (manifest.hooks !== undefined) {
39330
+ if (scoped && manifest.hooks && typeof manifest.hooks === "object" && !Array.isArray(manifest.hooks)) {
39331
+ const inline = codexPluginHookHandlers(manifest.hooks);
39332
+ if (!inline)
39333
+ unresolved("unsupported inline plugin hooks");
39334
+ scoped.push(inline);
39335
+ } else {
39336
+ if (typeof manifest.hooks !== "string")
39337
+ unresolved("unsupported plugin hooks target");
39338
+ const hook = resolve23(root, manifest.hooks);
39339
+ if (!hook.startsWith(root + sep11))
39340
+ unresolved("plugin hooks target escapes its root");
39341
+ required2.push(hook);
39342
+ if (scoped)
39343
+ scoped.push(readCodexHookDeclaration(witness(hook), hook));
39344
+ }
39345
+ }
39346
+ if (scoped && hooks !== null)
39347
+ scoped.push(readCodexHookDeclaration(hooks, join33(root, "hooks/hooks.json")));
39348
+ for (const path of required2) {
39349
+ const saved = exclusion.retained.sources.filter((source) => source.path === canonical9(path) && source.sha256 !== null && source.format === undefined && source.fields === undefined);
39350
+ if (saved.length ? saved.some((source) => projected(source, undefined, budget3) !== source.sha256) : !(scoped && reviewedInstalledCopy(root, path, codex)))
39351
+ unresolved("plugin hooks require current independently reviewed sources", canonical9(path));
39352
+ }
39353
+ if (scoped && scoped.every((item) => item !== null && item.commands === 0)) {
39354
+ verifyCodexPluginHookClosure(root, codex, codex.source, new Set(scoped.flatMap((item) => [...item.servers])), required2.map((path) => canonical9(path)));
39355
+ } else
39356
+ verifyOpaqueClosure(required2.map((path) => canonical9(path)));
39357
+ });
39334
39358
  const commands = join33(root, "commands");
39335
39359
  safe6(commands);
39336
39360
  if (agent === "claude" && (manifest.commands !== undefined || lstatSync25(commands, { throwIfNoEntry: false })?.isDirectory() && entries(commands).length))
@@ -39440,7 +39464,7 @@ function resolveDiscovery(options, exclusion) {
39440
39464
  unresolved("native discovery roots exceed their bound");
39441
39465
  return { agent, roots: [...roots].sort(), sources, method: "automatic", ...agent === "gemini" ? { builtinNames } : {}, ...agent === "hermes" ? { directories: captureDiscoveryDirectories([join33(home, ".hermes/plugins"), join33(home, ".hermes/hermes-agent")].map((path) => canonical9(path))) } : {} };
39442
39466
  }
39443
- var DISCOVERY_RUNTIME_COMMANDS, quotedPath = (path) => JSON.stringify(path).replace(/[^\x20-\x7e]/g, (character) => `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`), realpathOrNull = (path) => {
39467
+ var DISCOVERY_RUNTIME_COMMANDS, NativeDiscoveryUnresolved, quotedPath = (path) => JSON.stringify(path).replace(/[^\x20-\x7e]/g, (character) => `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`), realpathOrNull = (path) => {
39444
39468
  try {
39445
39469
  return realpathSync8(path);
39446
39470
  } catch {
@@ -39477,6 +39501,18 @@ var init_agent_discovery = __esm(() => {
39477
39501
  init_codex_semantic_cache_witness();
39478
39502
  init_agent_discovery_directories();
39479
39503
  DISCOVERY_RUNTIME_COMMANDS = Object.freeze({ gemini: "gemini" });
39504
+ NativeDiscoveryUnresolved = class NativeDiscoveryUnresolved extends Error {
39505
+ agent;
39506
+ detail;
39507
+ source;
39508
+ reviewable = false;
39509
+ constructor(agent, detail, source) {
39510
+ super(`Native discovery is unresolved (${agent}: ${detail}); provide a reviewed --discovery-inputs file`);
39511
+ this.agent = agent;
39512
+ this.detail = detail;
39513
+ this.source = source;
39514
+ }
39515
+ };
39480
39516
  CLAUDE_CONTROL_WITNESS_MODES = new Set(["claude-settings-v1", "claude-settings-v2", "claude-settings-v3", "claude-settings-v4", "claude-settings-v5", "claude-marketplace-registry", "claude-marketplace-registry-v2", "claude-marketplace-entry-v1", "claude-plugin-registry"]);
39481
39517
  CLAUDE_CONTROL_FILES = new Set(["settings.json", "settings.local.json", "installed_plugins.json", "known_marketplaces.json"]);
39482
39518
  ADOPTABLE_SETTINGS_MATCHES = Object.freeze(["exact", "screen-reader-receipt"]);
@@ -39515,6 +39551,11 @@ function physicalPath(path) {
39515
39551
  }
39516
39552
  return resolve24(realpathSync9(cursor), ...suffix);
39517
39553
  }
39554
+ function portableAuthoringDiscoveryRefusal(error61, destination) {
39555
+ const head = `Native discovery is unresolved (${error61.agent}: ${error61.detail}).${error61.source ? ` Checked source: ${error61.source}.` : ""}`;
39556
+ const review = `skills hook install --agent ${error61.agent} --discovery-inputs <reviewed-file> --apply`;
39557
+ return error61.reviewable ? `${head} Portable Skills authoring stays refused: an unreviewed ${error61.agent} hook or plugin option could load skills written to ${destination}. This command takes no --discovery-inputs option; review the current ${error61.agent} configuration with ${review}, then retry.` : `${head} Portable Skills authoring stays refused: Skills cannot list every skill root this ${error61.agent} configuration registers, so it cannot rule out ${destination}. This command takes no --discovery-inputs option; correct that ${error61.agent} configuration entry, then retry. Where a reviewed discovery binding covers it, record one with ${review}.`;
39558
+ }
39518
39559
  function contains(root, path) {
39519
39560
  const boundary = root.endsWith(sep12) ? root : root + sep12;
39520
39561
  return path === root || path.startsWith(boundary);
@@ -39615,11 +39656,18 @@ function assertPortableAuthoringPath(path, options = {}) {
39615
39656
  if (native) {
39616
39657
  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.`);
39617
39658
  }
39618
- const roots = configuredRoots(home, options.homeDir !== undefined);
39619
- for (const value of selected) {
39620
- if (physicalPath(value.path) === physicalPath(join34(home, `.${value.agent}`)))
39621
- continue;
39622
- roots.push(...resolveAgentDiscoveryExclusionRoots({ home, agent: value.agent, nativeHome: value.path, canonical: physicalPath, executable: null }));
39659
+ const roots = [];
39660
+ try {
39661
+ roots.push(...configuredRoots(home, options.homeDir !== undefined));
39662
+ for (const value of selected) {
39663
+ if (physicalPath(value.path) === physicalPath(join34(home, `.${value.agent}`)))
39664
+ continue;
39665
+ roots.push(...resolveAgentDiscoveryExclusionRoots({ home, agent: value.agent, nativeHome: value.path, canonical: physicalPath, executable: null }));
39666
+ }
39667
+ } catch (error61) {
39668
+ if (error61 instanceof NativeDiscoveryUnresolved)
39669
+ throw new Error(portableAuthoringDiscoveryRefusal(error61, lexical));
39670
+ throw error61;
39623
39671
  }
39624
39672
  for (const root of roots) {
39625
39673
  if (candidates.some((candidate) => [resolve24(root), physicalPath(root)].some((nativeRoot) => contains(nativeRoot, candidate) || contains(candidate, nativeRoot)))) {
package/bin/migrate.js CHANGED
@@ -25,7 +25,7 @@ import { join as join5 } from "path";
25
25
  // package.json
26
26
  var package_default = {
27
27
  name: "@hasna/skills",
28
- version: "0.10.92",
28
+ version: "0.10.93",
29
29
  description: "Skills library for AI coding agents",
30
30
  type: "module",
31
31
  bin: {
package/bin/server.js CHANGED
@@ -83767,7 +83767,7 @@ restoreLaunchCwd();
83767
83767
  // package.json
83768
83768
  var package_default = {
83769
83769
  name: "@hasna/skills",
83770
- version: "0.10.92",
83770
+ version: "0.10.93",
83771
83771
  description: "Skills library for AI coding agents",
83772
83772
  type: "module",
83773
83773
  bin: {
package/bin/worker.js CHANGED
@@ -76186,7 +76186,7 @@ import { randomUUID as randomUUID6 } from "crypto";
76186
76186
  // package.json
76187
76187
  var package_default = {
76188
76188
  name: "@hasna/skills",
76189
- version: "0.10.92",
76189
+ version: "0.10.93",
76190
76190
  description: "Skills library for AI coding agents",
76191
76191
  type: "module",
76192
76192
  bin: {
@@ -1,2 +1,3 @@
1
1
  import type { Command } from "commander";
2
+ export declare const AUTHORING_NATIVE_HOOKS_HELP = "\nNative hooks:\n Authoring refuses while another agent's native hooks, plugin hooks or plugin\n options are not covered by a current discovery review, because they could\n load skills from the authoring corpus. The refusal names the agent and the\n file it checked; review that agent's configuration with\n skills hook install --agent <agent> --discovery-inputs <reviewed-file> --apply\n and retry. Authoring commands themselves take no --discovery-inputs option.\n";
2
3
  export declare function registerPortableSkillCommands(parent: Command): void;
package/dist/index.js CHANGED
@@ -16369,7 +16369,7 @@ import { basename as basename15, dirname as dirname27, isAbsolute as isAbsolute2
16369
16369
  import { homedir as homedir5 } from "os";
16370
16370
  import { isAbsolute as isAbsolute25, join as join39, resolve as resolve25 } from "path";
16371
16371
  // package.json
16372
- var version = "0.10.92";
16372
+ var version = "0.10.93";
16373
16373
  var package_default = {
16374
16374
  name: "@hasna/skills",
16375
16375
  version,
@@ -20802,6 +20802,82 @@ function assertPinnedLauncherRuntimeSafe(runtime) {
20802
20802
  }
20803
20803
  }
20804
20804
 
20805
+ // src/lib/linux-access-acl.ts
20806
+ var LINUX_ENODATA = 61;
20807
+ var LINUX_EOPNOTSUPP = 95;
20808
+ var LINUX_ACL_QUERY_ATTEMPTS = 4;
20809
+ var LINUX_ACL_FREE_WHEN_UNSUPPORTED = new Set([
20810
+ 0xef53n,
20811
+ 0x58465342n,
20812
+ 0x9123683en,
20813
+ 0x01021994n
20814
+ ]);
20815
+ function queryAttribute(probe2, errno, fd, attribute) {
20816
+ for (let attempt = 0;attempt < LINUX_ACL_QUERY_ATTEMPTS; attempt++) {
20817
+ errno.set?.(0);
20818
+ const result = probe2.fgetxattr(fd, attribute);
20819
+ const code = errno.get();
20820
+ if (result !== -1 && result !== -1n)
20821
+ return "present";
20822
+ if (code === LINUX_ENODATA)
20823
+ return "absent";
20824
+ if (code === LINUX_EOPNOTSUPP)
20825
+ return "unsupported";
20826
+ }
20827
+ return "unverified";
20828
+ }
20829
+ function linuxAccessAclAbsent(probe2, fd, creationParent) {
20830
+ if (probe2.arch !== "x64" && probe2.arch !== "arm64")
20831
+ return false;
20832
+ const errno = probe2.errno;
20833
+ if (!errno)
20834
+ return false;
20835
+ let unsupported = false;
20836
+ for (const attribute of ["system.posix_acl_access", ...creationParent ? ["system.posix_acl_default"] : []]) {
20837
+ const state = queryAttribute(probe2, errno, fd, attribute);
20838
+ if (state === "present" || state === "unverified")
20839
+ return false;
20840
+ if (state === "unsupported")
20841
+ unsupported = true;
20842
+ }
20843
+ if (!unsupported)
20844
+ return true;
20845
+ const type = probe2.filesystemType(fd);
20846
+ return type !== null && LINUX_ACL_FREE_WHEN_UNSUPPORTED.has(type);
20847
+ }
20848
+ function withGlibcAclProbe(use) {
20849
+ try {
20850
+ const { dlopen, ptr, read: read2, FFIType } = __require("bun:ffi");
20851
+ const library = dlopen("libc.so.6", {
20852
+ fgetxattr: { args: ["i32", "ptr", "ptr", "u64"], returns: FFIType.i64_fast },
20853
+ fstatfs: { args: ["i32", "ptr"], returns: "i32" },
20854
+ __errno_location: { args: [], returns: "ptr" }
20855
+ });
20856
+ try {
20857
+ const location = library.symbols.__errno_location();
20858
+ const names = new Map;
20859
+ return use({
20860
+ arch: process.arch,
20861
+ errno: location ? { get: () => read2.i32(location) } : null,
20862
+ fgetxattr: (fd, attribute) => {
20863
+ let name = names.get(attribute);
20864
+ if (!name)
20865
+ names.set(attribute, name = Buffer.from(attribute + "\x00"));
20866
+ return library.symbols.fgetxattr(fd, ptr(name), null, 0);
20867
+ },
20868
+ filesystemType: (fd) => {
20869
+ const statfs = new BigUint64Array(32);
20870
+ return library.symbols.fstatfs(fd, ptr(statfs)) === 0 ? statfs[0] : null;
20871
+ }
20872
+ });
20873
+ } finally {
20874
+ library.close();
20875
+ }
20876
+ } catch {
20877
+ return false;
20878
+ }
20879
+ }
20880
+
20805
20881
  // src/lib/retained-review-artifacts.ts
20806
20882
  import { createHash as createHash29 } from "crypto";
20807
20883
  import { constants as constants18, closeSync as closeSync17, fstatSync as fstatSync17, fsyncSync as fsyncSync6, lstatSync as lstatSync29, mkdirSync as mkdirSync8, openSync as openSync17, readSync as readSync12, writeSync as writeSync4 } from "fs";
@@ -21796,28 +21872,7 @@ function hookProjectionRefusal(reason2) {
21796
21872
  throw new Error(`CLAUDE_MANAGED_HOOK_${reason2}`);
21797
21873
  }
21798
21874
  function hasNoLinuxAccessAcl(fd, creationParent) {
21799
- try {
21800
- const { dlopen, read: read2, ptr } = __require("bun:ffi");
21801
- const library = dlopen("libc.so.6", {
21802
- fgetxattr: { args: ["i32", "ptr", "ptr", "u64"], returns: "i64" },
21803
- __errno_location: { args: [], returns: "ptr" }
21804
- });
21805
- try {
21806
- const errno = library.symbols.__errno_location();
21807
- if (!errno)
21808
- return false;
21809
- for (const attribute of ["system.posix_acl_access", ...creationParent ? ["system.posix_acl_default"] : []]) {
21810
- const name = Buffer.from(attribute + "\x00");
21811
- if (Number(library.symbols.fgetxattr(fd, ptr(name), null, 0)) !== -1 || read2.i32(errno) !== 61)
21812
- return false;
21813
- }
21814
- return true;
21815
- } finally {
21816
- library.close();
21817
- }
21818
- } catch {
21819
- return false;
21820
- }
21875
+ return withGlibcAclProbe((probe2) => linuxAccessAclAbsent(probe2, fd, creationParent));
21821
21876
  }
21822
21877
  function assertNativePathAcl(path, observed, options = {}) {
21823
21878
  if (process.platform !== "darwin" && process.platform !== "linux")
@@ -22758,7 +22813,7 @@ function planCodexPluginNameReconcile(request) {
22758
22813
  pathDenies: [...pathDenies].sort(),
22759
22814
  ...discovery ? { discovery } : {}
22760
22815
  };
22761
- const plan = planAgentIntegration({ home, dataDir: dataDir2, projectDir, agents: ["codex"], codexNativeCatalog: catalog, codexReconcile: input });
22816
+ const plan = planAgentIntegration({ home, dataDir: dataDir2, projectDir, agents: ["codex"], codexNativeCatalog: catalog, codexReconcile: input, allowRootAliases: aliases.length > 0 });
22762
22817
  assertCodexReconcileScope(plan, { configPath, policyPath, prior, names, remoteIdentities, discovery: discovery ?? savedDiscovery });
22763
22818
  const configChange = plan.changes.find((change) => resolve24(change.path) === configPath);
22764
22819
  const plannedRules = configChange ? Bun.TOML.parse(configChange.after).skills?.config ?? [] : [];
@@ -25764,6 +25819,19 @@ function discoveryRootUnresolved(agent, command, detail) {
25764
25819
  function isDiscoveryRootUnresolved(error) {
25765
25820
  return error instanceof Error && error.message.startsWith(`${DISCOVERY_ROOT_UNRESOLVED}: `);
25766
25821
  }
25822
+
25823
+ class NativeDiscoveryUnresolved extends Error {
25824
+ agent;
25825
+ detail;
25826
+ source;
25827
+ reviewable = false;
25828
+ constructor(agent, detail, source) {
25829
+ super(`Native discovery is unresolved (${agent}: ${detail}); provide a reviewed --discovery-inputs file`);
25830
+ this.agent = agent;
25831
+ this.detail = detail;
25832
+ this.source = source;
25833
+ }
25834
+ }
25767
25835
  var quotedPath = (path) => JSON.stringify(path).replace(/[^\x20-\x7e]/g, (character) => `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`);
25768
25836
  var realpathOrNull = (path) => {
25769
25837
  try {
@@ -26859,8 +26927,8 @@ function resolveDiscovery(options, exclusion) {
26859
26927
  const configPath = exclusion?.nativeHome === undefined ? agentDiscoveryConfigPath(home, agent) : join41(nativeHome, agent === "codex" ? "config.toml" : "settings.json");
26860
26928
  const configText = witness(configPath, agent === "hermes" ? "yaml" : agent === "codex" ? "toml" : "json", agent === "hermes" ? ["skills", "plugins", "hooks"] : agent === "claude" ? ["enabledPlugins", "extraKnownMarketplaces"] : agent === "codex" ? [...CODEX_DISCOVERY_PROJECTION_FIELDS] : agent === "gemini" ? ["skills", "extensions", "security"] : agent === "opencode" ? ["plugin", "skills"] : agent === "sumi" ? [...SUMI_DISCOVERY_PROJECTION_FIELDS] : ["version"]);
26861
26929
  const config = configText === null ? {} : agent === "hermes" ? parseHermesConfig(configText) : parseConfig(configText, configPath, agent === "codex");
26862
- const unresolved = (detail) => {
26863
- throw new Error(`Native discovery is unresolved (${agent}: ${detail}); provide a reviewed --discovery-inputs file`);
26930
+ const unresolved = (detail, source) => {
26931
+ throw new NativeDiscoveryUnresolved(agent, detail, source);
26864
26932
  };
26865
26933
  let opaqueClosureVerified = false;
26866
26934
  const verifyOpaqueClosure = (declarations) => {
@@ -26874,6 +26942,17 @@ function resolveDiscovery(options, exclusion) {
26874
26942
  verifyDiscovery(retained, undefined, undefined, undefined, exclusion?.narrowed, canonical9(configPath));
26875
26943
  opaqueClosureVerified = true;
26876
26944
  };
26945
+ const reviewRemedy = (source, check) => {
26946
+ try {
26947
+ check();
26948
+ } catch (error) {
26949
+ if (error instanceof NativeDiscoveryUnresolved) {
26950
+ error.reviewable = true;
26951
+ error.source ??= source;
26952
+ }
26953
+ throw error;
26954
+ }
26955
+ };
26877
26956
  if (exclusion) {
26878
26957
  if (configText !== null && agent !== "codex" && agent !== "hermes")
26879
26958
  parseNativeJsonObject(configText);
@@ -26945,7 +27024,7 @@ function resolveDiscovery(options, exclusion) {
26945
27024
  unresolved(`non-enumerable ${label} require a current settings review`);
26946
27025
  };
26947
27026
  if (hasHooks)
26948
- verifyCurrentOpaqueSettings("hooks");
27027
+ reviewRemedy(canonical9(configPath), () => verifyCurrentOpaqueSettings("hooks"));
26949
27028
  if (agent === "claude") {
26950
27029
  if (config.env !== undefined) {
26951
27030
  if (!object6(config.env) || Object.keys(config.env).length > 512)
@@ -26958,7 +27037,7 @@ function resolveDiscovery(options, exclusion) {
26958
27037
  if (hasFunctionHookEnvironment) {
26959
27038
  if (!["0", "1"].includes(config.env.CLAUDE_CODE_ENABLE_FUNCTION_HOOKS))
26960
27039
  unresolved("malformed Claude env.CLAUDE_CODE_ENABLE_FUNCTION_HOOKS flag");
26961
- verifyCurrentOpaqueSettings("function-hook environment controls");
27040
+ reviewRemedy(canonical9(configPath), () => verifyCurrentOpaqueSettings("function-hook environment controls"));
26962
27041
  }
26963
27042
  }
26964
27043
  if (config.pluginConfigs !== undefined) {
@@ -26985,7 +27064,7 @@ function resolveDiscovery(options, exclusion) {
26985
27064
  }
26986
27065
  hasPluginConfigs = Object.keys(config.pluginConfigs).length > 0;
26987
27066
  if (hasPluginConfigs)
26988
- verifyCurrentOpaqueSettings("plugin configurations");
27067
+ reviewRemedy(canonical9(configPath), () => verifyCurrentOpaqueSettings("plugin configurations"));
26989
27068
  }
26990
27069
  if (config.enabledPlugins !== undefined && !object6(config.enabledPlugins))
26991
27070
  unresolved("enabledPlugins must be an object");
@@ -27097,7 +27176,7 @@ function resolveDiscovery(options, exclusion) {
27097
27176
  if (Object.keys(config.enabledPlugins ?? config.plugins ?? config.extensions ?? {}).length > 512)
27098
27177
  unresolved("unbounded native registrations");
27099
27178
  if (hasHooks || hasPluginConfigs || hasFunctionHookEnvironment)
27100
- verifyOpaqueClosure([]);
27179
+ reviewRemedy(canonical9(configPath), () => verifyOpaqueClosure([]));
27101
27180
  }
27102
27181
  if (options.reviewed && (options.reviewed.version !== 1 || !Array.isArray(options.reviewed.agents) || options.reviewed.agents.some((item) => !item || typeof item !== "object") || new Set(options.reviewed.agents.map((item) => item.agent)).size !== options.reviewed.agents.length))
27103
27182
  throw new Error("Invalid --discovery-inputs version or agents");
@@ -27350,40 +27429,41 @@ function resolveDiscovery(options, exclusion) {
27350
27429
  if (exclusion && Object.keys(manifest).some((key2) => /skill|plugin|hook|marketplace|extension|instruction/i.test(key2) && !["skills", "hooks"].includes(key2)))
27351
27430
  unresolved("unknown plugin discovery controls");
27352
27431
  const hooks = witness(join41(root2, "hooks/hooks.json"));
27353
- if (manifest.hooks !== undefined || hooks !== null) {
27354
- if (!exclusion || exclusion.retained?.method !== "reviewed")
27355
- unresolved("plugin hooks require a separate no-skill-injection review");
27356
- const required = [manifestPath, ...hooks !== null ? [join41(root2, "hooks/hooks.json")] : []];
27357
- const scoped2 = agent === "codex" && codex !== undefined ? [] : undefined;
27358
- if (manifest.hooks !== undefined) {
27359
- if (scoped2 && manifest.hooks && typeof manifest.hooks === "object" && !Array.isArray(manifest.hooks)) {
27360
- const inline = codexPluginHookHandlers(manifest.hooks);
27361
- if (!inline)
27362
- unresolved("unsupported inline plugin hooks");
27363
- scoped2.push(inline);
27364
- } else {
27365
- if (typeof manifest.hooks !== "string")
27366
- unresolved("unsupported plugin hooks target");
27367
- const hook = resolve28(root2, manifest.hooks);
27368
- if (!hook.startsWith(root2 + sep15))
27369
- unresolved("plugin hooks target escapes its root");
27370
- required.push(hook);
27371
- if (scoped2)
27372
- scoped2.push(readCodexHookDeclaration(witness(hook), hook));
27373
- }
27374
- }
27375
- if (scoped2 && hooks !== null)
27376
- scoped2.push(readCodexHookDeclaration(hooks, join41(root2, "hooks/hooks.json")));
27377
- for (const path of required) {
27378
- const saved = exclusion.retained.sources.filter((source) => source.path === canonical9(path) && source.sha256 !== null && source.format === undefined && source.fields === undefined);
27379
- if (saved.length ? saved.some((source) => projected(source, undefined, budget3) !== source.sha256) : !(scoped2 && reviewedInstalledCopy(root2, path, codex)))
27380
- unresolved("plugin hooks require current independently reviewed sources");
27381
- }
27382
- if (scoped2 && scoped2.every((item) => item !== null && item.commands === 0)) {
27383
- verifyCodexPluginHookClosure(root2, codex, codex.source, new Set(scoped2.flatMap((item) => [...item.servers])), required.map((path) => canonical9(path)));
27384
- } else
27385
- verifyOpaqueClosure(required.map((path) => canonical9(path)));
27386
- }
27432
+ if (manifest.hooks !== undefined || hooks !== null)
27433
+ reviewRemedy(canonical9(hooks !== null ? join41(root2, "hooks/hooks.json") : manifestPath), () => {
27434
+ if (!exclusion || exclusion.retained?.method !== "reviewed")
27435
+ unresolved("plugin hooks require a separate no-skill-injection review");
27436
+ const required = [manifestPath, ...hooks !== null ? [join41(root2, "hooks/hooks.json")] : []];
27437
+ const scoped2 = agent === "codex" && codex !== undefined ? [] : undefined;
27438
+ if (manifest.hooks !== undefined) {
27439
+ if (scoped2 && manifest.hooks && typeof manifest.hooks === "object" && !Array.isArray(manifest.hooks)) {
27440
+ const inline = codexPluginHookHandlers(manifest.hooks);
27441
+ if (!inline)
27442
+ unresolved("unsupported inline plugin hooks");
27443
+ scoped2.push(inline);
27444
+ } else {
27445
+ if (typeof manifest.hooks !== "string")
27446
+ unresolved("unsupported plugin hooks target");
27447
+ const hook = resolve28(root2, manifest.hooks);
27448
+ if (!hook.startsWith(root2 + sep15))
27449
+ unresolved("plugin hooks target escapes its root");
27450
+ required.push(hook);
27451
+ if (scoped2)
27452
+ scoped2.push(readCodexHookDeclaration(witness(hook), hook));
27453
+ }
27454
+ }
27455
+ if (scoped2 && hooks !== null)
27456
+ scoped2.push(readCodexHookDeclaration(hooks, join41(root2, "hooks/hooks.json")));
27457
+ for (const path of required) {
27458
+ const saved = exclusion.retained.sources.filter((source) => source.path === canonical9(path) && source.sha256 !== null && source.format === undefined && source.fields === undefined);
27459
+ if (saved.length ? saved.some((source) => projected(source, undefined, budget3) !== source.sha256) : !(scoped2 && reviewedInstalledCopy(root2, path, codex)))
27460
+ unresolved("plugin hooks require current independently reviewed sources", canonical9(path));
27461
+ }
27462
+ if (scoped2 && scoped2.every((item) => item !== null && item.commands === 0)) {
27463
+ verifyCodexPluginHookClosure(root2, codex, codex.source, new Set(scoped2.flatMap((item) => [...item.servers])), required.map((path) => canonical9(path)));
27464
+ } else
27465
+ verifyOpaqueClosure(required.map((path) => canonical9(path)));
27466
+ });
27387
27467
  const commands = join41(root2, "commands");
27388
27468
  safe6(commands);
27389
27469
  if (agent === "claude" && (manifest.commands !== undefined || lstatSync34(commands, { throwIfNoEntry: false })?.isDirectory() && entries(commands).length))
@@ -27522,6 +27602,11 @@ function physicalPath(path) {
27522
27602
  }
27523
27603
  return resolve29(realpathSync14(cursor), ...suffix);
27524
27604
  }
27605
+ function portableAuthoringDiscoveryRefusal(error, destination) {
27606
+ const head = `Native discovery is unresolved (${error.agent}: ${error.detail}).${error.source ? ` Checked source: ${error.source}.` : ""}`;
27607
+ const review = `skills hook install --agent ${error.agent} --discovery-inputs <reviewed-file> --apply`;
27608
+ return error.reviewable ? `${head} Portable Skills authoring stays refused: an unreviewed ${error.agent} hook or plugin option could load skills written to ${destination}. This command takes no --discovery-inputs option; review the current ${error.agent} configuration with ${review}, then retry.` : `${head} Portable Skills authoring stays refused: Skills cannot list every skill root this ${error.agent} configuration registers, so it cannot rule out ${destination}. This command takes no --discovery-inputs option; correct that ${error.agent} configuration entry, then retry. Where a reviewed discovery binding covers it, record one with ${review}.`;
27609
+ }
27525
27610
  function contains2(root2, path) {
27526
27611
  const boundary = root2.endsWith(sep16) ? root2 : root2 + sep16;
27527
27612
  return path === root2 || path.startsWith(boundary);
@@ -27622,11 +27707,18 @@ function assertPortableAuthoringPath(path, options = {}) {
27622
27707
  if (native) {
27623
27708
  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.`);
27624
27709
  }
27625
- const roots = configuredRoots(home, options.homeDir !== undefined);
27626
- for (const value of selected) {
27627
- if (physicalPath(value.path) === physicalPath(join42(home, `.${value.agent}`)))
27628
- continue;
27629
- roots.push(...resolveAgentDiscoveryExclusionRoots({ home, agent: value.agent, nativeHome: value.path, canonical: physicalPath, executable: null }));
27710
+ const roots = [];
27711
+ try {
27712
+ roots.push(...configuredRoots(home, options.homeDir !== undefined));
27713
+ for (const value of selected) {
27714
+ if (physicalPath(value.path) === physicalPath(join42(home, `.${value.agent}`)))
27715
+ continue;
27716
+ roots.push(...resolveAgentDiscoveryExclusionRoots({ home, agent: value.agent, nativeHome: value.path, canonical: physicalPath, executable: null }));
27717
+ }
27718
+ } catch (error) {
27719
+ if (error instanceof NativeDiscoveryUnresolved)
27720
+ throw new Error(portableAuthoringDiscoveryRefusal(error, lexical));
27721
+ throw error;
27630
27722
  }
27631
27723
  for (const root2 of roots) {
27632
27724
  if (candidates.some((candidate2) => [resolve29(root2), physicalPath(root2)].some((nativeRoot) => contains2(nativeRoot, candidate2) || contains2(candidate2, nativeRoot)))) {
@@ -65,6 +65,19 @@ export interface AgentDiscoveryBinding {
65
65
  export declare const DISCOVERY_ROOT_UNRESOLVED = "DISCOVERY_ROOT_UNRESOLVED";
66
66
  export declare function discoveryRootUnresolved(agent: IntegrationAgent, command: string, detail: string): Error;
67
67
  export declare function isDiscoveryRootUnresolved(error: unknown): error is Error;
68
+ /** A native configuration Skills cannot resolve. The message names the
69
+ * --discovery-inputs option of the native commands that accept it (hook
70
+ * install, migrate native). Portable authoring takes no such option and
71
+ * rewrites the remedy from these fields: `reviewable` marks a hook, plugin hook
72
+ * or plugin option check that a current discovery review satisfies, and
73
+ * `source` names the configuration or hook file it checked (a path only). */
74
+ export declare class NativeDiscoveryUnresolved extends Error {
75
+ readonly agent: IntegrationAgent;
76
+ readonly detail: string;
77
+ source?: string | undefined;
78
+ reviewable: boolean;
79
+ constructor(agent: IntegrationAgent, detail: string, source?: string | undefined);
80
+ }
68
81
  /** The runtime executable a discovery review resolved through PATH, with the
69
82
  * realpath its launcher led to. The policy stores it beside the binding
70
83
  * (bridge.discoveryExecutables), not inside it, so a consumer that compares