@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/THIRD_PARTY_NOTICES +1 -1
- package/bin/index.js +829 -726
- package/bin/mcp.js +95 -47
- package/bin/migrate.js +1 -1
- package/bin/server.js +1 -1
- package/bin/worker.js +1 -1
- package/dist/cli/commands/portable-skills.d.ts +1 -0
- package/dist/index.js +161 -69
- package/dist/lib/agent-discovery.d.ts +13 -0
- package/dist/lib/authoring-path.d.ts +5 -0
- package/dist/lib/linux-access-acl.d.ts +55 -0
- package/dist/runtime-prerequisites.js +1 -1
- package/dist/sdk/index.js +161 -69
- package/package.json +1 -1
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
import { NativeDiscoveryUnresolved } from "./agent-discovery.js";
|
|
1
2
|
export interface PortableAuthoringPathOptions {
|
|
2
3
|
/** The account whose native discovery must remain free of authored payloads. */
|
|
3
4
|
homeDir?: string;
|
|
4
5
|
}
|
|
6
|
+
/** The authoring form of a native discovery refusal. Authoring commands take
|
|
7
|
+
* no --discovery-inputs option, so name the command that does, or say that a
|
|
8
|
+
* review does not resolve it. Names and paths only, never file content. */
|
|
9
|
+
export declare function portableAuthoringDiscoveryRefusal(error: NativeDiscoveryUnresolved, destination: string): string;
|
|
5
10
|
/**
|
|
6
11
|
* Refuse a write target that is, or physically aliases, an agent discovery
|
|
7
12
|
* root. Read-only inventory and archive operations deliberately do not call
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Linux POSIX ACL absence check (SH-00084).
|
|
3
|
+
*
|
|
4
|
+
* Access ACLs change effective permissions independently of mode and group.
|
|
5
|
+
* The guarded writers do not copy ACLs, so they require verified absence on
|
|
6
|
+
* supported Linux/glibc. A default ACL initializes direct children at
|
|
7
|
+
* creation, not existing descendants: query it only for directories where the
|
|
8
|
+
* caller will create an object.
|
|
9
|
+
*
|
|
10
|
+
* Presence is queried only (size 0); no attribute value is read or copied.
|
|
11
|
+
*
|
|
12
|
+
* errno is thread-local and any later libc call on this thread, or a signal
|
|
13
|
+
* handler that does not preserve it, can overwrite it. The probe therefore:
|
|
14
|
+
* - resets errno before each query where the layer can write it,
|
|
15
|
+
* - reads it as the very next step after the call, with nothing allocated in
|
|
16
|
+
* between (the call returns an immediate number, not a BigInt, and errno is
|
|
17
|
+
* read with bun:ffi's read.i32, which allocates nothing),
|
|
18
|
+
* - re-queries a bounded number of times when the result is -1 with an errno
|
|
19
|
+
* other than the two "absent" answers, since a stray overwrite does not
|
|
20
|
+
* repeat while a genuine failure does. A persistent failure refuses.
|
|
21
|
+
* A result other than -1 (the attribute exists, or an anomalous value) always
|
|
22
|
+
* refuses at once and never depends on errno.
|
|
23
|
+
*/
|
|
24
|
+
/** ENODATA on the asm-generic errno table (Linux x86_64 and aarch64). */
|
|
25
|
+
export declare const LINUX_ENODATA = 61;
|
|
26
|
+
/** EOPNOTSUPP, which glibc also names ENOTSUP, on the asm-generic table. */
|
|
27
|
+
export declare const LINUX_EOPNOTSUPP = 95;
|
|
28
|
+
/** Queries per attribute before an unexplained failure refuses. */
|
|
29
|
+
export declare const LINUX_ACL_QUERY_ATTEMPTS = 4;
|
|
30
|
+
/**
|
|
31
|
+
* Filesystems where an unsupported POSIX ACL attribute means the kernel
|
|
32
|
+
* enforces no ACL at all (support compiled out, or mounted with noacl), so
|
|
33
|
+
* mode and ownership are the whole access model. Network and FUSE filesystems
|
|
34
|
+
* (NFSv4, SMB, 9p, FUSE and others) also answer EOPNOTSUPP while enforcing
|
|
35
|
+
* their own ACLs or server-side access, so they stay unverified.
|
|
36
|
+
*/
|
|
37
|
+
export declare const LINUX_ACL_FREE_WHEN_UNSUPPORTED: ReadonlySet<bigint>;
|
|
38
|
+
/** The raw operations, separable so tests can drive every errno path. */
|
|
39
|
+
export interface LinuxAclProbe {
|
|
40
|
+
/** process.arch of the running binary; only asm-generic errno tables are admitted. */
|
|
41
|
+
readonly arch: string;
|
|
42
|
+
/** Thread-local errno of the calling thread, or null when it cannot be located. */
|
|
43
|
+
readonly errno: {
|
|
44
|
+
get(): number;
|
|
45
|
+
set?(value: number): void;
|
|
46
|
+
} | null;
|
|
47
|
+
/** fgetxattr(fd, name, NULL, 0): the attribute size, or -1. */
|
|
48
|
+
fgetxattr(fd: number, attribute: string): number | bigint;
|
|
49
|
+
/** fstatfs(fd).f_type, or null when fstatfs fails. */
|
|
50
|
+
filesystemType(fd: number): bigint | null;
|
|
51
|
+
}
|
|
52
|
+
/** True only when every queried POSIX ACL attribute is verifiably absent. */
|
|
53
|
+
export declare function linuxAccessAclAbsent(probe: LinuxAclProbe, fd: number, creationParent: boolean): boolean;
|
|
54
|
+
/** Run with the glibc probe; any loading or ABI failure refuses (false). */
|
|
55
|
+
export declare function withGlibcAclProbe(use: (probe: LinuxAclProbe) => boolean): boolean;
|
|
@@ -49,7 +49,7 @@ var __require = import.meta.require;
|
|
|
49
49
|
// src/runtime-prerequisites.ts
|
|
50
50
|
import { isAbsolute as isAbsolute7 } from "path";
|
|
51
51
|
// package.json
|
|
52
|
-
var version = "0.10.
|
|
52
|
+
var version = "0.10.93";
|
|
53
53
|
var package_default = {
|
|
54
54
|
name: "@hasna/skills",
|
|
55
55
|
version,
|
package/dist/sdk/index.js
CHANGED
|
@@ -91998,7 +91998,7 @@ var init_event_sink = __esm(() => {
|
|
|
91998
91998
|
init_dist();
|
|
91999
91999
|
});
|
|
92000
92000
|
// package.json
|
|
92001
|
-
var version = "0.10.
|
|
92001
|
+
var version = "0.10.93";
|
|
92002
92002
|
var package_default = {
|
|
92003
92003
|
name: "@hasna/skills",
|
|
92004
92004
|
version,
|
|
@@ -105659,6 +105659,19 @@ function discoveryRootUnresolved(agent, command, detail) {
|
|
|
105659
105659
|
function isDiscoveryRootUnresolved(error) {
|
|
105660
105660
|
return error instanceof Error && error.message.startsWith(`${DISCOVERY_ROOT_UNRESOLVED}: `);
|
|
105661
105661
|
}
|
|
105662
|
+
|
|
105663
|
+
class NativeDiscoveryUnresolved extends Error {
|
|
105664
|
+
agent;
|
|
105665
|
+
detail;
|
|
105666
|
+
source;
|
|
105667
|
+
reviewable = false;
|
|
105668
|
+
constructor(agent, detail, source) {
|
|
105669
|
+
super(`Native discovery is unresolved (${agent}: ${detail}); provide a reviewed --discovery-inputs file`);
|
|
105670
|
+
this.agent = agent;
|
|
105671
|
+
this.detail = detail;
|
|
105672
|
+
this.source = source;
|
|
105673
|
+
}
|
|
105674
|
+
}
|
|
105662
105675
|
var quotedPath = (path) => JSON.stringify(path).replace(/[^\x20-\x7e]/g, (character) => `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`);
|
|
105663
105676
|
var realpathOrNull = (path) => {
|
|
105664
105677
|
try {
|
|
@@ -106754,8 +106767,8 @@ function resolveDiscovery(options, exclusion) {
|
|
|
106754
106767
|
const configPath = exclusion?.nativeHome === undefined ? agentDiscoveryConfigPath(home, agent) : join34(nativeHome, agent === "codex" ? "config.toml" : "settings.json");
|
|
106755
106768
|
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"]);
|
|
106756
106769
|
const config = configText === null ? {} : agent === "hermes" ? parseHermesConfig(configText) : parseConfig(configText, configPath, agent === "codex");
|
|
106757
|
-
const unresolved = (detail) => {
|
|
106758
|
-
throw new
|
|
106770
|
+
const unresolved = (detail, source) => {
|
|
106771
|
+
throw new NativeDiscoveryUnresolved(agent, detail, source);
|
|
106759
106772
|
};
|
|
106760
106773
|
let opaqueClosureVerified = false;
|
|
106761
106774
|
const verifyOpaqueClosure = (declarations) => {
|
|
@@ -106769,6 +106782,17 @@ function resolveDiscovery(options, exclusion) {
|
|
|
106769
106782
|
verifyDiscovery(retained, undefined, undefined, undefined, exclusion?.narrowed, canonical9(configPath));
|
|
106770
106783
|
opaqueClosureVerified = true;
|
|
106771
106784
|
};
|
|
106785
|
+
const reviewRemedy = (source, check) => {
|
|
106786
|
+
try {
|
|
106787
|
+
check();
|
|
106788
|
+
} catch (error) {
|
|
106789
|
+
if (error instanceof NativeDiscoveryUnresolved) {
|
|
106790
|
+
error.reviewable = true;
|
|
106791
|
+
error.source ??= source;
|
|
106792
|
+
}
|
|
106793
|
+
throw error;
|
|
106794
|
+
}
|
|
106795
|
+
};
|
|
106772
106796
|
if (exclusion) {
|
|
106773
106797
|
if (configText !== null && agent !== "codex" && agent !== "hermes")
|
|
106774
106798
|
parseNativeJsonObject(configText);
|
|
@@ -106840,7 +106864,7 @@ function resolveDiscovery(options, exclusion) {
|
|
|
106840
106864
|
unresolved(`non-enumerable ${label} require a current settings review`);
|
|
106841
106865
|
};
|
|
106842
106866
|
if (hasHooks)
|
|
106843
|
-
verifyCurrentOpaqueSettings("hooks");
|
|
106867
|
+
reviewRemedy(canonical9(configPath), () => verifyCurrentOpaqueSettings("hooks"));
|
|
106844
106868
|
if (agent === "claude") {
|
|
106845
106869
|
if (config.env !== undefined) {
|
|
106846
106870
|
if (!object6(config.env) || Object.keys(config.env).length > 512)
|
|
@@ -106853,7 +106877,7 @@ function resolveDiscovery(options, exclusion) {
|
|
|
106853
106877
|
if (hasFunctionHookEnvironment) {
|
|
106854
106878
|
if (!["0", "1"].includes(config.env.CLAUDE_CODE_ENABLE_FUNCTION_HOOKS))
|
|
106855
106879
|
unresolved("malformed Claude env.CLAUDE_CODE_ENABLE_FUNCTION_HOOKS flag");
|
|
106856
|
-
verifyCurrentOpaqueSettings("function-hook environment controls");
|
|
106880
|
+
reviewRemedy(canonical9(configPath), () => verifyCurrentOpaqueSettings("function-hook environment controls"));
|
|
106857
106881
|
}
|
|
106858
106882
|
}
|
|
106859
106883
|
if (config.pluginConfigs !== undefined) {
|
|
@@ -106880,7 +106904,7 @@ function resolveDiscovery(options, exclusion) {
|
|
|
106880
106904
|
}
|
|
106881
106905
|
hasPluginConfigs = Object.keys(config.pluginConfigs).length > 0;
|
|
106882
106906
|
if (hasPluginConfigs)
|
|
106883
|
-
verifyCurrentOpaqueSettings("plugin configurations");
|
|
106907
|
+
reviewRemedy(canonical9(configPath), () => verifyCurrentOpaqueSettings("plugin configurations"));
|
|
106884
106908
|
}
|
|
106885
106909
|
if (config.enabledPlugins !== undefined && !object6(config.enabledPlugins))
|
|
106886
106910
|
unresolved("enabledPlugins must be an object");
|
|
@@ -106992,7 +107016,7 @@ function resolveDiscovery(options, exclusion) {
|
|
|
106992
107016
|
if (Object.keys(config.enabledPlugins ?? config.plugins ?? config.extensions ?? {}).length > 512)
|
|
106993
107017
|
unresolved("unbounded native registrations");
|
|
106994
107018
|
if (hasHooks || hasPluginConfigs || hasFunctionHookEnvironment)
|
|
106995
|
-
verifyOpaqueClosure([]);
|
|
107019
|
+
reviewRemedy(canonical9(configPath), () => verifyOpaqueClosure([]));
|
|
106996
107020
|
}
|
|
106997
107021
|
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))
|
|
106998
107022
|
throw new Error("Invalid --discovery-inputs version or agents");
|
|
@@ -107245,40 +107269,41 @@ function resolveDiscovery(options, exclusion) {
|
|
|
107245
107269
|
if (exclusion && Object.keys(manifest).some((key2) => /skill|plugin|hook|marketplace|extension|instruction/i.test(key2) && !["skills", "hooks"].includes(key2)))
|
|
107246
107270
|
unresolved("unknown plugin discovery controls");
|
|
107247
107271
|
const hooks = witness(join34(root2, "hooks/hooks.json"));
|
|
107248
|
-
if (manifest.hooks !== undefined || hooks !== null)
|
|
107249
|
-
|
|
107250
|
-
|
|
107251
|
-
|
|
107252
|
-
|
|
107253
|
-
|
|
107254
|
-
if (
|
|
107255
|
-
|
|
107256
|
-
|
|
107257
|
-
|
|
107258
|
-
|
|
107259
|
-
|
|
107260
|
-
|
|
107261
|
-
|
|
107262
|
-
|
|
107263
|
-
|
|
107264
|
-
|
|
107265
|
-
|
|
107266
|
-
|
|
107267
|
-
scoped2
|
|
107268
|
-
|
|
107269
|
-
|
|
107270
|
-
|
|
107271
|
-
scoped2
|
|
107272
|
-
|
|
107273
|
-
|
|
107274
|
-
|
|
107275
|
-
|
|
107276
|
-
|
|
107277
|
-
|
|
107278
|
-
|
|
107279
|
-
|
|
107280
|
-
|
|
107281
|
-
|
|
107272
|
+
if (manifest.hooks !== undefined || hooks !== null)
|
|
107273
|
+
reviewRemedy(canonical9(hooks !== null ? join34(root2, "hooks/hooks.json") : manifestPath), () => {
|
|
107274
|
+
if (!exclusion || exclusion.retained?.method !== "reviewed")
|
|
107275
|
+
unresolved("plugin hooks require a separate no-skill-injection review");
|
|
107276
|
+
const required = [manifestPath, ...hooks !== null ? [join34(root2, "hooks/hooks.json")] : []];
|
|
107277
|
+
const scoped2 = agent === "codex" && codex !== undefined ? [] : undefined;
|
|
107278
|
+
if (manifest.hooks !== undefined) {
|
|
107279
|
+
if (scoped2 && manifest.hooks && typeof manifest.hooks === "object" && !Array.isArray(manifest.hooks)) {
|
|
107280
|
+
const inline = codexPluginHookHandlers(manifest.hooks);
|
|
107281
|
+
if (!inline)
|
|
107282
|
+
unresolved("unsupported inline plugin hooks");
|
|
107283
|
+
scoped2.push(inline);
|
|
107284
|
+
} else {
|
|
107285
|
+
if (typeof manifest.hooks !== "string")
|
|
107286
|
+
unresolved("unsupported plugin hooks target");
|
|
107287
|
+
const hook = resolve27(root2, manifest.hooks);
|
|
107288
|
+
if (!hook.startsWith(root2 + sep13))
|
|
107289
|
+
unresolved("plugin hooks target escapes its root");
|
|
107290
|
+
required.push(hook);
|
|
107291
|
+
if (scoped2)
|
|
107292
|
+
scoped2.push(readCodexHookDeclaration(witness(hook), hook));
|
|
107293
|
+
}
|
|
107294
|
+
}
|
|
107295
|
+
if (scoped2 && hooks !== null)
|
|
107296
|
+
scoped2.push(readCodexHookDeclaration(hooks, join34(root2, "hooks/hooks.json")));
|
|
107297
|
+
for (const path of required) {
|
|
107298
|
+
const saved = exclusion.retained.sources.filter((source) => source.path === canonical9(path) && source.sha256 !== null && source.format === undefined && source.fields === undefined);
|
|
107299
|
+
if (saved.length ? saved.some((source) => projected(source, undefined, budget3) !== source.sha256) : !(scoped2 && reviewedInstalledCopy(root2, path, codex)))
|
|
107300
|
+
unresolved("plugin hooks require current independently reviewed sources", canonical9(path));
|
|
107301
|
+
}
|
|
107302
|
+
if (scoped2 && scoped2.every((item) => item !== null && item.commands === 0)) {
|
|
107303
|
+
verifyCodexPluginHookClosure(root2, codex, codex.source, new Set(scoped2.flatMap((item) => [...item.servers])), required.map((path) => canonical9(path)));
|
|
107304
|
+
} else
|
|
107305
|
+
verifyOpaqueClosure(required.map((path) => canonical9(path)));
|
|
107306
|
+
});
|
|
107282
107307
|
const commands = join34(root2, "commands");
|
|
107283
107308
|
safe6(commands);
|
|
107284
107309
|
if (agent === "claude" && (manifest.commands !== undefined || lstatSync30(commands, { throwIfNoEntry: false })?.isDirectory() && entries(commands).length))
|
|
@@ -107902,6 +107927,82 @@ function assertPinnedLauncherRuntimeSafe(runtime) {
|
|
|
107902
107927
|
}
|
|
107903
107928
|
}
|
|
107904
107929
|
|
|
107930
|
+
// src/lib/linux-access-acl.ts
|
|
107931
|
+
var LINUX_ENODATA = 61;
|
|
107932
|
+
var LINUX_EOPNOTSUPP = 95;
|
|
107933
|
+
var LINUX_ACL_QUERY_ATTEMPTS = 4;
|
|
107934
|
+
var LINUX_ACL_FREE_WHEN_UNSUPPORTED = new Set([
|
|
107935
|
+
0xef53n,
|
|
107936
|
+
0x58465342n,
|
|
107937
|
+
0x9123683en,
|
|
107938
|
+
0x01021994n
|
|
107939
|
+
]);
|
|
107940
|
+
function queryAttribute(probe2, errno, fd, attribute) {
|
|
107941
|
+
for (let attempt = 0;attempt < LINUX_ACL_QUERY_ATTEMPTS; attempt++) {
|
|
107942
|
+
errno.set?.(0);
|
|
107943
|
+
const result = probe2.fgetxattr(fd, attribute);
|
|
107944
|
+
const code = errno.get();
|
|
107945
|
+
if (result !== -1 && result !== -1n)
|
|
107946
|
+
return "present";
|
|
107947
|
+
if (code === LINUX_ENODATA)
|
|
107948
|
+
return "absent";
|
|
107949
|
+
if (code === LINUX_EOPNOTSUPP)
|
|
107950
|
+
return "unsupported";
|
|
107951
|
+
}
|
|
107952
|
+
return "unverified";
|
|
107953
|
+
}
|
|
107954
|
+
function linuxAccessAclAbsent(probe2, fd, creationParent) {
|
|
107955
|
+
if (probe2.arch !== "x64" && probe2.arch !== "arm64")
|
|
107956
|
+
return false;
|
|
107957
|
+
const errno = probe2.errno;
|
|
107958
|
+
if (!errno)
|
|
107959
|
+
return false;
|
|
107960
|
+
let unsupported = false;
|
|
107961
|
+
for (const attribute of ["system.posix_acl_access", ...creationParent ? ["system.posix_acl_default"] : []]) {
|
|
107962
|
+
const state = queryAttribute(probe2, errno, fd, attribute);
|
|
107963
|
+
if (state === "present" || state === "unverified")
|
|
107964
|
+
return false;
|
|
107965
|
+
if (state === "unsupported")
|
|
107966
|
+
unsupported = true;
|
|
107967
|
+
}
|
|
107968
|
+
if (!unsupported)
|
|
107969
|
+
return true;
|
|
107970
|
+
const type = probe2.filesystemType(fd);
|
|
107971
|
+
return type !== null && LINUX_ACL_FREE_WHEN_UNSUPPORTED.has(type);
|
|
107972
|
+
}
|
|
107973
|
+
function withGlibcAclProbe(use) {
|
|
107974
|
+
try {
|
|
107975
|
+
const { dlopen, ptr, read: read3, FFIType } = __require("bun:ffi");
|
|
107976
|
+
const library = dlopen("libc.so.6", {
|
|
107977
|
+
fgetxattr: { args: ["i32", "ptr", "ptr", "u64"], returns: FFIType.i64_fast },
|
|
107978
|
+
fstatfs: { args: ["i32", "ptr"], returns: "i32" },
|
|
107979
|
+
__errno_location: { args: [], returns: "ptr" }
|
|
107980
|
+
});
|
|
107981
|
+
try {
|
|
107982
|
+
const location = library.symbols.__errno_location();
|
|
107983
|
+
const names = new Map;
|
|
107984
|
+
return use({
|
|
107985
|
+
arch: process.arch,
|
|
107986
|
+
errno: location ? { get: () => read3.i32(location) } : null,
|
|
107987
|
+
fgetxattr: (fd, attribute) => {
|
|
107988
|
+
let name = names.get(attribute);
|
|
107989
|
+
if (!name)
|
|
107990
|
+
names.set(attribute, name = Buffer.from(attribute + "\x00"));
|
|
107991
|
+
return library.symbols.fgetxattr(fd, ptr(name), null, 0);
|
|
107992
|
+
},
|
|
107993
|
+
filesystemType: (fd) => {
|
|
107994
|
+
const statfs = new BigUint64Array(32);
|
|
107995
|
+
return library.symbols.fstatfs(fd, ptr(statfs)) === 0 ? statfs[0] : null;
|
|
107996
|
+
}
|
|
107997
|
+
});
|
|
107998
|
+
} finally {
|
|
107999
|
+
library.close();
|
|
108000
|
+
}
|
|
108001
|
+
} catch {
|
|
108002
|
+
return false;
|
|
108003
|
+
}
|
|
108004
|
+
}
|
|
108005
|
+
|
|
107905
108006
|
// src/lib/agent-integration.ts
|
|
107906
108007
|
var sha5 = (data) => createHash33("sha256").update(data).digest("hex");
|
|
107907
108008
|
var ROOTS = NATIVE_SKILL_ROOTS;
|
|
@@ -108735,28 +108836,7 @@ function hookProjectionRefusal(reason2) {
|
|
|
108735
108836
|
throw new Error(`CLAUDE_MANAGED_HOOK_${reason2}`);
|
|
108736
108837
|
}
|
|
108737
108838
|
function hasNoLinuxAccessAcl(fd, creationParent) {
|
|
108738
|
-
|
|
108739
|
-
const { dlopen, read: read3, ptr } = __require("bun:ffi");
|
|
108740
|
-
const library = dlopen("libc.so.6", {
|
|
108741
|
-
fgetxattr: { args: ["i32", "ptr", "ptr", "u64"], returns: "i64" },
|
|
108742
|
-
__errno_location: { args: [], returns: "ptr" }
|
|
108743
|
-
});
|
|
108744
|
-
try {
|
|
108745
|
-
const errno = library.symbols.__errno_location();
|
|
108746
|
-
if (!errno)
|
|
108747
|
-
return false;
|
|
108748
|
-
for (const attribute of ["system.posix_acl_access", ...creationParent ? ["system.posix_acl_default"] : []]) {
|
|
108749
|
-
const name = Buffer.from(attribute + "\x00");
|
|
108750
|
-
if (Number(library.symbols.fgetxattr(fd, ptr(name), null, 0)) !== -1 || read3.i32(errno) !== 61)
|
|
108751
|
-
return false;
|
|
108752
|
-
}
|
|
108753
|
-
return true;
|
|
108754
|
-
} finally {
|
|
108755
|
-
library.close();
|
|
108756
|
-
}
|
|
108757
|
-
} catch {
|
|
108758
|
-
return false;
|
|
108759
|
-
}
|
|
108839
|
+
return withGlibcAclProbe((probe2) => linuxAccessAclAbsent(probe2, fd, creationParent));
|
|
108760
108840
|
}
|
|
108761
108841
|
function assertNativePathAcl(path, observed, options = {}) {
|
|
108762
108842
|
if (process.platform !== "darwin" && process.platform !== "linux")
|
|
@@ -109697,7 +109777,7 @@ function planCodexPluginNameReconcile(request2) {
|
|
|
109697
109777
|
pathDenies: [...pathDenies].sort(),
|
|
109698
109778
|
...discovery ? { discovery } : {}
|
|
109699
109779
|
};
|
|
109700
|
-
const plan = planAgentIntegration({ home, dataDir: dataDir2, projectDir, agents: ["codex"], codexNativeCatalog: catalog, codexReconcile: input });
|
|
109780
|
+
const plan = planAgentIntegration({ home, dataDir: dataDir2, projectDir, agents: ["codex"], codexNativeCatalog: catalog, codexReconcile: input, allowRootAliases: aliases.length > 0 });
|
|
109701
109781
|
assertCodexReconcileScope(plan, { configPath, policyPath, prior, names, remoteIdentities, discovery: discovery ?? savedDiscovery });
|
|
109702
109782
|
const configChange = plan.changes.find((change) => resolve28(change.path) === configPath);
|
|
109703
109783
|
const plannedRules = configChange ? Bun.TOML.parse(configChange.after).skills?.config ?? [] : [];
|
|
@@ -111768,6 +111848,11 @@ function physicalPath(path) {
|
|
|
111768
111848
|
}
|
|
111769
111849
|
return resolve29(realpathSync15(cursor), ...suffix);
|
|
111770
111850
|
}
|
|
111851
|
+
function portableAuthoringDiscoveryRefusal(error, destination) {
|
|
111852
|
+
const head = `Native discovery is unresolved (${error.agent}: ${error.detail}).${error.source ? ` Checked source: ${error.source}.` : ""}`;
|
|
111853
|
+
const review = `skills hook install --agent ${error.agent} --discovery-inputs <reviewed-file> --apply`;
|
|
111854
|
+
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}.`;
|
|
111855
|
+
}
|
|
111771
111856
|
function contains2(root2, path) {
|
|
111772
111857
|
const boundary = root2.endsWith(sep16) ? root2 : root2 + sep16;
|
|
111773
111858
|
return path === root2 || path.startsWith(boundary);
|
|
@@ -111868,11 +111953,18 @@ function assertPortableAuthoringPath(path, options = {}) {
|
|
|
111868
111953
|
if (native) {
|
|
111869
111954
|
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.`);
|
|
111870
111955
|
}
|
|
111871
|
-
const roots =
|
|
111872
|
-
|
|
111873
|
-
|
|
111874
|
-
|
|
111875
|
-
|
|
111956
|
+
const roots = [];
|
|
111957
|
+
try {
|
|
111958
|
+
roots.push(...configuredRoots(home, options.homeDir !== undefined));
|
|
111959
|
+
for (const value of selected) {
|
|
111960
|
+
if (physicalPath(value.path) === physicalPath(join38(home, `.${value.agent}`)))
|
|
111961
|
+
continue;
|
|
111962
|
+
roots.push(...resolveAgentDiscoveryExclusionRoots({ home, agent: value.agent, nativeHome: value.path, canonical: physicalPath, executable: null }));
|
|
111963
|
+
}
|
|
111964
|
+
} catch (error) {
|
|
111965
|
+
if (error instanceof NativeDiscoveryUnresolved)
|
|
111966
|
+
throw new Error(portableAuthoringDiscoveryRefusal(error, lexical));
|
|
111967
|
+
throw error;
|
|
111876
111968
|
}
|
|
111877
111969
|
for (const root2 of roots) {
|
|
111878
111970
|
if (candidates.some((candidate2) => [resolve29(root2), physicalPath(root2)].some((nativeRoot) => contains2(nativeRoot, candidate2) || contains2(candidate2, nativeRoot)))) {
|