@hasna/skills 0.10.65 → 0.10.67
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/README.md +23 -1
- package/bin/index.js +365 -85
- package/bin/mcp.js +264 -43
- package/bin/migrate.js +1 -1
- package/bin/server.js +1 -1
- package/bin/worker.js +1 -1
- package/dist/index.js +333 -53
- package/dist/lib/agent-discovery.d.ts +3 -2
- package/dist/lib/agent-integration.d.ts +2 -0
- package/dist/lib/codex-semantic-cache-witness.d.ts +23 -0
- package/dist/lib/skillinfo.d.ts +12 -2
- package/dist/runtime-prerequisites.js +37 -3
- package/dist/sdk/index.d.ts +1 -0
- package/dist/sdk/index.js +345 -64
- package/package.json +1 -1
package/bin/mcp.js
CHANGED
|
@@ -23,7 +23,7 @@ var package_default;
|
|
|
23
23
|
var init_package = __esm(() => {
|
|
24
24
|
package_default = {
|
|
25
25
|
name: "@hasna/skills",
|
|
26
|
-
version: "0.10.
|
|
26
|
+
version: "0.10.67",
|
|
27
27
|
description: "Skills library for AI coding agents",
|
|
28
28
|
type: "module",
|
|
29
29
|
bin: {
|
|
@@ -23089,8 +23089,8 @@ function assertAgentPolicyCollections(policy) {
|
|
|
23089
23089
|
}
|
|
23090
23090
|
}
|
|
23091
23091
|
if (value.codexSemanticCache !== undefined) {
|
|
23092
|
-
const proof = record2(value.codexSemanticCache,
|
|
23093
|
-
requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && Object.keys(proof).length
|
|
23092
|
+
const proof = record2(value.codexSemanticCache, 9), witness = record2(proof.witness, 7);
|
|
23093
|
+
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));
|
|
23094
23094
|
text(proof.configPath);
|
|
23095
23095
|
requireBound(isAbsolute5(proof.configPath) && resolve4(proof.configPath) === proof.configPath && basename5(proof.configPath) === "config.toml");
|
|
23096
23096
|
text(witness.cacheRoot);
|
|
@@ -23109,6 +23109,20 @@ function assertAgentPolicyCollections(policy) {
|
|
|
23109
23109
|
text(parent[key]);
|
|
23110
23110
|
requireBound(isAbsolute5(parent.pluginParent) && resolve4(parent.pluginParent) === parent.pluginParent);
|
|
23111
23111
|
}
|
|
23112
|
+
if (proof.reviewedHookParents !== undefined)
|
|
23113
|
+
for (const parent of array2(proof.reviewedHookParents, 4096)) {
|
|
23114
|
+
requireBound(object2(parent) && parent.role === "reviewed-hook" && (parent.installation === "remote-receipt" && Object.keys(parent).length === 6 || parent.installation === "local-marketplace" && Object.keys(parent).length === 7));
|
|
23115
|
+
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");
|
|
23116
|
+
for (const key of ["pluginId", "namespace", "pluginParent", "installation"])
|
|
23117
|
+
text(parent[key]);
|
|
23118
|
+
if (parent.installation === "remote-receipt")
|
|
23119
|
+
text(parent.remotePluginId);
|
|
23120
|
+
else {
|
|
23121
|
+
text(parent.marketplaceSourcePath);
|
|
23122
|
+
requireBound(typeof parent.marketplaceSha256 === "string" && /^[a-f0-9]{64}$/.test(parent.marketplaceSha256) && isAbsolute5(parent.marketplaceSourcePath) && resolve4(parent.marketplaceSourcePath) === parent.marketplaceSourcePath && basename5(parent.marketplaceSourcePath) === "marketplace.json");
|
|
23123
|
+
}
|
|
23124
|
+
requireBound(isAbsolute5(parent.pluginParent) && resolve4(parent.pluginParent) === parent.pluginParent);
|
|
23125
|
+
}
|
|
23112
23126
|
for (const row of [...array2(witness.controls, 4096), ...array2(witness.appOnlyParents, 4096)]) {
|
|
23113
23127
|
requireBound(object2(row));
|
|
23114
23128
|
for (const key of ["pluginId", "namespace", "pluginParent"])
|
|
@@ -23117,6 +23131,26 @@ function assertAgentPolicyCollections(policy) {
|
|
|
23117
23131
|
if (row[key] !== undefined)
|
|
23118
23132
|
requireBound(typeof row[key] === "string" && /^[a-f0-9]{64}$/.test(row[key]));
|
|
23119
23133
|
}
|
|
23134
|
+
if (witness.hookParents !== undefined)
|
|
23135
|
+
for (const row of array2(witness.hookParents, 4096)) {
|
|
23136
|
+
requireBound(object2(row) && row.role === "reviewed-hook" && (row.installation === "remote-receipt" && Object.keys(row).length === 9 || row.installation === "local-marketplace" && Object.keys(row).length === 9));
|
|
23137
|
+
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");
|
|
23138
|
+
for (const key of ["pluginId", "namespace", "pluginParent", "installation"])
|
|
23139
|
+
text(row[key]);
|
|
23140
|
+
if (row.installation === "remote-receipt")
|
|
23141
|
+
text(row.remotePluginId);
|
|
23142
|
+
else {
|
|
23143
|
+
text(row.marketplaceSourcePath);
|
|
23144
|
+
requireBound(typeof row.marketplaceSha256 === "string" && /^[a-f0-9]{64}$/.test(row.marketplaceSha256) && isAbsolute5(row.marketplaceSourcePath) && resolve4(row.marketplaceSourcePath) === row.marketplaceSourcePath && basename5(row.marketplaceSourcePath) === "marketplace.json");
|
|
23145
|
+
}
|
|
23146
|
+
requireBound(isAbsolute5(row.pluginParent) && resolve4(row.pluginParent) === row.pluginParent);
|
|
23147
|
+
for (const key of ["manifestSha256", "hooksSha256"])
|
|
23148
|
+
requireBound(typeof row[key] === "string" && /^[a-f0-9]{64}$/.test(row[key]));
|
|
23149
|
+
if (row.installation === "remote-receipt")
|
|
23150
|
+
requireBound(typeof row.receiptSha256 === "string" && /^[a-f0-9]{64}$/.test(row.receiptSha256));
|
|
23151
|
+
else
|
|
23152
|
+
requireBound(row.receiptSha256 === undefined);
|
|
23153
|
+
}
|
|
23120
23154
|
for (const skill of array2(witness.skills, 4096)) {
|
|
23121
23155
|
requireBound(object2(skill));
|
|
23122
23156
|
for (const key of ["name", "pluginId", "namespace", "pluginParent"])
|
|
@@ -33667,7 +33701,27 @@ var init_codex_settings_witness = __esm(() => {
|
|
|
33667
33701
|
// src/lib/codex-semantic-cache-witness.ts
|
|
33668
33702
|
import { createHash as createHash14 } from "crypto";
|
|
33669
33703
|
import { constants as constants7, closeSync as closeSync10, fstatSync as fstatSync10, lstatSync as lstatSync13, openSync as openSync10, readSync as readSync5, readdirSync as readdirSync7, realpathSync as realpathSync6 } from "fs";
|
|
33670
|
-
import { dirname as dirname13, isAbsolute as isAbsolute11, join as join19, relative as relative6, resolve as resolve12, sep as sep7 } from "path";
|
|
33704
|
+
import { basename as basename7, dirname as dirname13, isAbsolute as isAbsolute11, join as join19, relative as relative6, resolve as resolve12, sep as sep7 } from "path";
|
|
33705
|
+
function codexLocalMarketplaceMapsPlugin(text2, marketplace, plugin) {
|
|
33706
|
+
try {
|
|
33707
|
+
hashNativeJsonControls(text2);
|
|
33708
|
+
const value = JSON.parse(text2);
|
|
33709
|
+
const marketplaceInterface = plainObject(value) ? value.interface : undefined;
|
|
33710
|
+
const validInterface = typeof marketplaceInterface === "string" || Number.isSafeInteger(marketplaceInterface) || plainObject(marketplaceInterface) && exactKeys(marketplaceInterface, [], ["displayName"]) && typeof marketplaceInterface.displayName === "string" && marketplaceInterface.displayName.trim().length > 0;
|
|
33711
|
+
if (!plainObject(value) || !exactKeys(value, ["interface", "name", "plugins"]) || value.name !== marketplace || !validInterface || !Array.isArray(value.plugins) || value.plugins.length < 1 || value.plugins.length > 4096)
|
|
33712
|
+
return false;
|
|
33713
|
+
const rows = value.plugins.filter((row2) => plainObject(row2) && row2.name === plugin);
|
|
33714
|
+
if (rows.length !== 1)
|
|
33715
|
+
return false;
|
|
33716
|
+
const row = rows[0];
|
|
33717
|
+
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("\\"))
|
|
33718
|
+
return false;
|
|
33719
|
+
const parts = row.source.path.split("/");
|
|
33720
|
+
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;
|
|
33721
|
+
} catch {
|
|
33722
|
+
return false;
|
|
33723
|
+
}
|
|
33724
|
+
}
|
|
33671
33725
|
function defaultRead(path) {
|
|
33672
33726
|
const before = lstatSync13(path, { throwIfNoEntry: false, bigint: true });
|
|
33673
33727
|
if (before === undefined)
|
|
@@ -33729,7 +33783,7 @@ function validPluginParent(cacheRoot, pluginParent, namespace, pluginId) {
|
|
|
33729
33783
|
return parts.length === 2 && parts.every(identifier3) && parts[1] === namespace && pluginId === `${namespace}@${parts[0]}`;
|
|
33730
33784
|
}
|
|
33731
33785
|
function assertWitnessShape(value) {
|
|
33732
|
-
if (!plainObject(value) || !exactKeys(value, ["schema", "cacheRoot", "controls", "appOnlyParents", "skills", "sha256"]) || value.schema !== CODEX_SEMANTIC_CACHE_WITNESS_SCHEMA || typeof value.cacheRoot !== "string" || !isAbsolute11(value.cacheRoot) || resolve12(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)
|
|
33786
|
+
if (!plainObject(value) || !exactKeys(value, ["schema", "cacheRoot", "controls", "appOnlyParents", "skills", "sha256"], ["hookParents"]) || value.schema !== CODEX_SEMANTIC_CACHE_WITNESS_SCHEMA || typeof value.cacheRoot !== "string" || !isAbsolute11(value.cacheRoot) || resolve12(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)
|
|
33733
33787
|
refuse3();
|
|
33734
33788
|
const witness = value;
|
|
33735
33789
|
const controlParents = new Set;
|
|
@@ -33750,6 +33804,20 @@ function assertWitnessShape(value) {
|
|
|
33750
33804
|
refuse3();
|
|
33751
33805
|
appOnlyParentPaths.add(row.pluginParent);
|
|
33752
33806
|
}
|
|
33807
|
+
const hookParentPaths = new Set;
|
|
33808
|
+
const hookParents = witness.hookParents === undefined ? [] : witness.hookParents;
|
|
33809
|
+
if (!Array.isArray(hookParents) || hookParents.length > 4096)
|
|
33810
|
+
refuse3();
|
|
33811
|
+
for (const candidate of hookParents) {
|
|
33812
|
+
if (!plainObject(candidate))
|
|
33813
|
+
refuse3();
|
|
33814
|
+
const row = candidate;
|
|
33815
|
+
const remote = row.installation === "remote-receipt";
|
|
33816
|
+
const local = row.installation === "local-marketplace";
|
|
33817
|
+
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" || !isAbsolute11(row.marketplaceSourcePath) || resolve12(row.marketplaceSourcePath) !== row.marketplaceSourcePath || basename7(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))
|
|
33818
|
+
refuse3();
|
|
33819
|
+
hookParentPaths.add(row.pluginParent);
|
|
33820
|
+
}
|
|
33753
33821
|
const skillNames = new Set;
|
|
33754
33822
|
const qualifiedNames = new Set;
|
|
33755
33823
|
for (const candidate of witness.skills) {
|
|
@@ -33769,6 +33837,7 @@ function assertWitnessShape(value) {
|
|
|
33769
33837
|
cacheRoot: witness.cacheRoot,
|
|
33770
33838
|
controls: witness.controls,
|
|
33771
33839
|
appOnlyParents: witness.appOnlyParents,
|
|
33840
|
+
...witness.hookParents === undefined ? {} : { hookParents: witness.hookParents },
|
|
33772
33841
|
skills: witness.skills
|
|
33773
33842
|
};
|
|
33774
33843
|
if (hash3(projection) !== witness.sha256)
|
|
@@ -33959,10 +34028,128 @@ function appOnlyParentProjection(cacheRoot, parents2, read) {
|
|
|
33959
34028
|
}
|
|
33960
34029
|
return rows.sort((a, b) => a.pluginId.localeCompare(b.pluginId) || a.pluginParent.localeCompare(b.pluginParent));
|
|
33961
34030
|
}
|
|
33962
|
-
function
|
|
34031
|
+
function assertJsonValue(value, depth = 0, budget2 = { members: 0 }) {
|
|
34032
|
+
if (depth > 32 || ++budget2.members > 4096)
|
|
34033
|
+
refuse3();
|
|
34034
|
+
if (value === null || typeof value === "string" || typeof value === "boolean")
|
|
34035
|
+
return;
|
|
34036
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
34037
|
+
return;
|
|
34038
|
+
if (Array.isArray(value)) {
|
|
34039
|
+
for (const item of value)
|
|
34040
|
+
assertJsonValue(item, depth + 1, budget2);
|
|
34041
|
+
return;
|
|
34042
|
+
}
|
|
34043
|
+
if (!plainObject(value))
|
|
34044
|
+
refuse3();
|
|
34045
|
+
for (const [key, item] of Object.entries(value)) {
|
|
34046
|
+
if (!key || /[\x00-\x1f\x7f]/.test(key))
|
|
34047
|
+
refuse3();
|
|
34048
|
+
assertJsonValue(item, depth + 1, budget2);
|
|
34049
|
+
}
|
|
34050
|
+
}
|
|
34051
|
+
function reviewedHookControls(root, read) {
|
|
34052
|
+
const manifestPath = join19(root, ".codex-plugin/plugin.json"), hooksPath = join19(root, "hooks/hooks.json");
|
|
34053
|
+
let manifest, manifestSha256, hooks, hooksSha256;
|
|
34054
|
+
try {
|
|
34055
|
+
const manifestText = read(manifestPath);
|
|
34056
|
+
manifestSha256 = hashNativeJsonControls(manifestText, "version");
|
|
34057
|
+
manifest = JSON.parse(manifestText);
|
|
34058
|
+
const hooksText = read(hooksPath);
|
|
34059
|
+
hashNativeJsonControls(hooksText);
|
|
34060
|
+
hooksSha256 = createHash14("sha256").update(hooksText).digest("hex");
|
|
34061
|
+
hooks = JSON.parse(hooksText);
|
|
34062
|
+
} catch {
|
|
34063
|
+
return refuse3();
|
|
34064
|
+
}
|
|
34065
|
+
if (!plainObject(manifest) || !exactKeys(manifest, ["name", "version", "hooks"], ["description"]) || !identifier3(manifest.name) || typeof manifest.version !== "string" || manifest.version !== basename7(root) || manifest.hooks !== "./hooks/hooks.json" || manifest.description !== undefined && (typeof manifest.description !== "string" || !manifest.description.trim() || manifest.description.length > 1024))
|
|
34066
|
+
refuse3();
|
|
34067
|
+
const manifestRecord = manifest;
|
|
34068
|
+
if (!plainObject(hooks) || !exactKeys(hooks, ["hooks"], ["description"]) || !plainObject(hooks.hooks) || hooks.description !== undefined && typeof hooks.description !== "string")
|
|
34069
|
+
refuse3();
|
|
34070
|
+
const hookTable = hooks.hooks;
|
|
34071
|
+
const events = Object.entries(hookTable);
|
|
34072
|
+
if (!events.length || events.length > 32)
|
|
34073
|
+
refuse3();
|
|
34074
|
+
for (const [event, groups] of events) {
|
|
34075
|
+
if (!codexHookEvents.has(event) || !Array.isArray(groups) || !groups.length || groups.length > 32)
|
|
34076
|
+
refuse3();
|
|
34077
|
+
for (const group of groups) {
|
|
34078
|
+
if (!plainObject(group) || !exactKeys(group, ["hooks"]) || !Array.isArray(group.hooks) || !group.hooks.length || group.hooks.length > 32)
|
|
34079
|
+
refuse3();
|
|
34080
|
+
const handlers = group.hooks;
|
|
34081
|
+
for (const handler of handlers) {
|
|
34082
|
+
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))
|
|
34083
|
+
refuse3();
|
|
34084
|
+
assertJsonValue(handler.input);
|
|
34085
|
+
}
|
|
34086
|
+
}
|
|
34087
|
+
}
|
|
34088
|
+
return { namespace: manifestRecord.name, manifestSha256, hooksSha256 };
|
|
34089
|
+
}
|
|
34090
|
+
function reviewedHookParentProjection(cacheRoot, parents2, read) {
|
|
34091
|
+
if (!Array.isArray(parents2) || parents2.length > 4096)
|
|
34092
|
+
refuse3();
|
|
34093
|
+
const seen = new Set, rows = [];
|
|
34094
|
+
for (const parent of parents2) {
|
|
34095
|
+
const remote = parent?.installation === "remote-receipt", local = parent?.installation === "local-marketplace";
|
|
34096
|
+
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" || !isAbsolute11(parent.marketplaceSourcePath) || resolve12(parent.marketplaceSourcePath) !== parent.marketplaceSourcePath || basename7(parent.marketplaceSourcePath) !== "marketplace.json" || !digest(parent.marketplaceSha256)) || !remote && !local)
|
|
34097
|
+
refuse3();
|
|
34098
|
+
const parts = relative6(cacheRoot, parent.pluginParent).split(sep7);
|
|
34099
|
+
if (!isAbsolute11(parent.pluginParent) || resolve12(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))
|
|
34100
|
+
refuse3();
|
|
34101
|
+
seen.add(parent.pluginParent);
|
|
34102
|
+
const parentStat = lstatSync13(parent.pluginParent, { throwIfNoEntry: false });
|
|
34103
|
+
if (!parentStat?.isDirectory() || parentStat.isSymbolicLink() || realpathSync6(parent.pluginParent) !== parent.pluginParent)
|
|
34104
|
+
refuse3();
|
|
34105
|
+
const receiptPath = join19(parent.pluginParent, ".codex-remote-plugin-install.json"), receiptStat = lstatSync13(receiptPath, { throwIfNoEntry: false });
|
|
34106
|
+
let receiptText;
|
|
34107
|
+
if (remote) {
|
|
34108
|
+
if (!receiptStat?.isFile() || receiptStat.isSymbolicLink() || receiptStat.size > MAX_RECEIPT_BYTES)
|
|
34109
|
+
refuse3();
|
|
34110
|
+
try {
|
|
34111
|
+
receiptText = read(receiptPath);
|
|
34112
|
+
hashNativeJsonControls(receiptText);
|
|
34113
|
+
const receipt = JSON.parse(receiptText);
|
|
34114
|
+
if (!plainObject(receipt) || !exactKeys(receipt, ["schema_version", "remote_plugin_id"]) || receipt.schema_version !== 1 || receipt.remote_plugin_id !== parent.remotePluginId)
|
|
34115
|
+
refuse3();
|
|
34116
|
+
} catch {
|
|
34117
|
+
refuse3();
|
|
34118
|
+
}
|
|
34119
|
+
} else {
|
|
34120
|
+
const marketplaceSourcePath = parent.marketplaceSourcePath ?? refuse3();
|
|
34121
|
+
if (receiptStat !== undefined || !parent.marketplaceSha256)
|
|
34122
|
+
refuse3();
|
|
34123
|
+
let marketplaceText;
|
|
34124
|
+
try {
|
|
34125
|
+
marketplaceText = read(marketplaceSourcePath);
|
|
34126
|
+
} catch {
|
|
34127
|
+
return refuse3();
|
|
34128
|
+
}
|
|
34129
|
+
if (createHash14("sha256").update(marketplaceText).digest("hex") !== parent.marketplaceSha256 || !codexLocalMarketplaceMapsPlugin(marketplaceText, parts[0], parent.namespace))
|
|
34130
|
+
refuse3();
|
|
34131
|
+
}
|
|
34132
|
+
const materializations = readdirSync7(parent.pluginParent).filter((name) => name !== ".codex-remote-plugin-install.json").map((version2) => {
|
|
34133
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/.test(version2))
|
|
34134
|
+
refuse3();
|
|
34135
|
+
const root = join19(parent.pluginParent, version2), stat = lstatSync13(root, { throwIfNoEntry: false });
|
|
34136
|
+
if (!stat?.isDirectory() || stat.isSymbolicLink() || realpathSync6(root) !== root)
|
|
34137
|
+
refuse3();
|
|
34138
|
+
const controls = reviewedHookControls(root, read);
|
|
34139
|
+
if (controls.namespace !== parent.namespace)
|
|
34140
|
+
refuse3();
|
|
34141
|
+
return { manifestSha256: controls.manifestSha256, hooksSha256: controls.hooksSha256 };
|
|
34142
|
+
});
|
|
34143
|
+
if (!materializations.length || materializations.some((item) => canonical7(item) !== canonical7(materializations[0])))
|
|
34144
|
+
refuse3();
|
|
34145
|
+
rows.push({ ...parent, ...receiptText === undefined ? {} : { receiptSha256: createHash14("sha256").update(receiptText).digest("hex") }, ...materializations[0] });
|
|
34146
|
+
}
|
|
34147
|
+
return rows.sort((a, b) => a.pluginId.localeCompare(b.pluginId) || a.pluginParent.localeCompare(b.pluginParent));
|
|
34148
|
+
}
|
|
34149
|
+
function assertParents(cacheRoot, controls, appOnlyParents, hookParents, files, members2) {
|
|
33963
34150
|
const expected = new Set;
|
|
33964
34151
|
const expectedMarkets = new Set;
|
|
33965
|
-
for (const control of [...controls, ...appOnlyParents]) {
|
|
34152
|
+
for (const control of [...controls, ...appOnlyParents, ...hookParents]) {
|
|
33966
34153
|
const rel = relative6(cacheRoot, control.pluginParent), parts = rel.split(sep7);
|
|
33967
34154
|
if (resolve12(control.pluginParent) !== control.pluginParent || parts.length !== 2 || parts.some((part) => !identifier3(part)) || control.pluginId !== `${control.namespace}@${parts[0]}` || parts[1] !== control.namespace)
|
|
33968
34155
|
refuse3();
|
|
@@ -34003,7 +34190,9 @@ function assertParents(cacheRoot, controls, appOnlyParents, files, members2) {
|
|
|
34003
34190
|
refuse3();
|
|
34004
34191
|
if ([".app.json", ".mcp.json"].includes(base) && (parts.length !== 4 || dirname13(member) !== root))
|
|
34005
34192
|
refuse3();
|
|
34006
|
-
if (
|
|
34193
|
+
if ([".app.json", ".mcp.json"].includes(base) && hookParents.some((reviewed) => reviewed.pluginParent === parent))
|
|
34194
|
+
refuse3();
|
|
34195
|
+
if ((parts[3] === "hooks" || base === "hooks.json") && (![4, 5].includes(parts.length) || parts[3] !== "hooks" || (parts.length === 4 ? base !== "hooks" : base !== "hooks.json") || !hookParents.some((reviewed) => reviewed.pluginParent === join19(cacheRoot, parts[0], parts[1]))))
|
|
34007
34196
|
refuse3();
|
|
34008
34197
|
}
|
|
34009
34198
|
}
|
|
@@ -34113,13 +34302,14 @@ function captureCodexSemanticCacheWitness(options) {
|
|
|
34113
34302
|
const initialTree = treeSnapshot(options.cacheRoot);
|
|
34114
34303
|
const controls = controlProjection(options.controls, read);
|
|
34115
34304
|
const appOnlyParents = appOnlyParentProjection(options.cacheRoot, options.appOnlyParents ?? [], read);
|
|
34305
|
+
const hookParents = reviewedHookParentProjection(options.cacheRoot, options.reviewedHookParents ?? [], read);
|
|
34116
34306
|
const skillParents = new Set(controls.map((control) => control.pluginParent));
|
|
34117
|
-
if (appOnlyParents.some((parent) => skillParents.has(parent.pluginParent)))
|
|
34307
|
+
if (appOnlyParents.some((parent) => skillParents.has(parent.pluginParent)) || hookParents.some((parent) => skillParents.has(parent.pluginParent) || appOnlyParents.some((app) => app.pluginParent === parent.pluginParent)))
|
|
34118
34308
|
refuse3();
|
|
34119
34309
|
if (!reviewedCodexPluginCapabilitiesUnchanged(options.cacheRoot, options.controls, read, options.rules))
|
|
34120
34310
|
refuse3();
|
|
34121
34311
|
const files = initialTree.files;
|
|
34122
|
-
assertParents(options.cacheRoot, controls, appOnlyParents, files, initialTree.state.members);
|
|
34312
|
+
assertParents(options.cacheRoot, controls, appOnlyParents, hookParents, files, initialTree.state.members);
|
|
34123
34313
|
const expectedNamesByRoot = assertSkillMaterializations(options.cacheRoot, options.controls, files, read);
|
|
34124
34314
|
const docs = files.filter((path) => path.endsWith(`${sep7}SKILL.md`));
|
|
34125
34315
|
const skillRows = [];
|
|
@@ -34128,6 +34318,8 @@ function captureCodexSemanticCacheWitness(options) {
|
|
|
34128
34318
|
const rel = relative6(options.cacheRoot, document2).split(sep7);
|
|
34129
34319
|
if (appOnlyParents.some((parent) => parent.pluginParent === join19(options.cacheRoot, rel[0], rel[1])))
|
|
34130
34320
|
refuse3();
|
|
34321
|
+
if (hookParents.some((parent) => parent.pluginParent === join19(options.cacheRoot, rel[0], rel[1])))
|
|
34322
|
+
refuse3();
|
|
34131
34323
|
const documentStat = lstatSync13(document2, { throwIfNoEntry: false });
|
|
34132
34324
|
if (!documentStat?.isFile() || documentStat.isSymbolicLink() || documentStat.size > MAX_DOCUMENT_BYTES)
|
|
34133
34325
|
refuse3();
|
|
@@ -34191,7 +34383,7 @@ function captureCodexSemanticCacheWitness(options) {
|
|
|
34191
34383
|
tracked.verify();
|
|
34192
34384
|
const finalTree = treeSnapshot(options.cacheRoot);
|
|
34193
34385
|
assertSameTree(initialTree.state, finalTree.state, tracked.paths());
|
|
34194
|
-
const completeProjection = { schema: CODEX_SEMANTIC_CACHE_WITNESS_SCHEMA, cacheRoot: options.cacheRoot, controls, appOnlyParents, skills: uniqueSkills };
|
|
34386
|
+
const completeProjection = { schema: CODEX_SEMANTIC_CACHE_WITNESS_SCHEMA, cacheRoot: options.cacheRoot, controls, appOnlyParents, hookParents, skills: uniqueSkills };
|
|
34195
34387
|
return { ...completeProjection, sha256: hash3(completeProjection) };
|
|
34196
34388
|
} catch (error61) {
|
|
34197
34389
|
if (error61 instanceof Error && error61.message.startsWith("CODEX_SEMANTIC_CACHE_WITNESS_UNSUPPORTED"))
|
|
@@ -34207,6 +34399,7 @@ function assertCodexSemanticCacheWitnessUnchanged(previous, current) {
|
|
|
34207
34399
|
cacheRoot: previous.cacheRoot,
|
|
34208
34400
|
controls: previous.controls,
|
|
34209
34401
|
appOnlyParents: previous.appOnlyParents,
|
|
34402
|
+
...previous.hookParents === undefined ? {} : { hookParents: previous.hookParents },
|
|
34210
34403
|
skills: previous.skills
|
|
34211
34404
|
};
|
|
34212
34405
|
const currentProjection = {
|
|
@@ -34214,20 +34407,41 @@ function assertCodexSemanticCacheWitnessUnchanged(previous, current) {
|
|
|
34214
34407
|
cacheRoot: current.cacheRoot,
|
|
34215
34408
|
controls: current.controls,
|
|
34216
34409
|
appOnlyParents: current.appOnlyParents,
|
|
34410
|
+
...current.hookParents === undefined ? {} : { hookParents: current.hookParents },
|
|
34217
34411
|
skills: current.skills
|
|
34218
34412
|
};
|
|
34219
|
-
|
|
34413
|
+
const comparable = (projection) => ({ ...projection, hookParents: projection.hookParents ?? [] });
|
|
34414
|
+
if (hash3(priorProjection) !== previous.sha256 || hash3(currentProjection) !== current.sha256 || canonical7(comparable(priorProjection)) !== canonical7(comparable(currentProjection)))
|
|
34220
34415
|
refuse3();
|
|
34221
34416
|
}
|
|
34222
34417
|
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), refuse3 = () => {
|
|
34223
34418
|
throw new Error("CODEX_SEMANTIC_CACHE_WITNESS_UNSUPPORTED: review Codex plugin cache identity and controls");
|
|
34224
|
-
}, MAX_DOCUMENT_BYTES, MAX_RECEIPT_BYTES;
|
|
34419
|
+
}, MAX_DOCUMENT_BYTES, MAX_RECEIPT_BYTES, codexHookEvents;
|
|
34225
34420
|
var init_codex_semantic_cache_witness = __esm(() => {
|
|
34226
34421
|
init_claude_settings_witness();
|
|
34227
34422
|
init_codex_plugin_skill_controls();
|
|
34228
34423
|
init_codex_native_skill_catalog();
|
|
34229
34424
|
MAX_DOCUMENT_BYTES = 1024 * 1024;
|
|
34230
34425
|
MAX_RECEIPT_BYTES = 16 * 1024;
|
|
34426
|
+
codexHookEvents = new Set([
|
|
34427
|
+
"SessionStart",
|
|
34428
|
+
"UserPromptSubmit",
|
|
34429
|
+
"PreToolUse",
|
|
34430
|
+
"PostToolUse",
|
|
34431
|
+
"PostToolUseFailure",
|
|
34432
|
+
"Stop",
|
|
34433
|
+
"SubagentStart",
|
|
34434
|
+
"SubagentStop",
|
|
34435
|
+
"PreCompact",
|
|
34436
|
+
"Notification",
|
|
34437
|
+
"PermissionRequest",
|
|
34438
|
+
"SessionEnd",
|
|
34439
|
+
"ConfigChange",
|
|
34440
|
+
"WorktreeCreate",
|
|
34441
|
+
"WorktreeRemove",
|
|
34442
|
+
"TeammateIdle",
|
|
34443
|
+
"TaskComplete"
|
|
34444
|
+
]);
|
|
34231
34445
|
});
|
|
34232
34446
|
|
|
34233
34447
|
// src/lib/managed-policy.ts
|
|
@@ -35263,9 +35477,7 @@ function detectProjectSkills(cwd = process.cwd()) {
|
|
|
35263
35477
|
function extractEnvVars(text2) {
|
|
35264
35478
|
const envVars = new Set;
|
|
35265
35479
|
for (const pattern of [ENV_VAR_PATTERN, GENERIC_ENV_PATTERN]) {
|
|
35266
|
-
pattern
|
|
35267
|
-
let match;
|
|
35268
|
-
while ((match = pattern.exec(text2)) !== null) {
|
|
35480
|
+
for (const match of text2.matchAll(pattern)) {
|
|
35269
35481
|
envVars.add(match[1]);
|
|
35270
35482
|
}
|
|
35271
35483
|
}
|
|
@@ -35978,7 +36190,7 @@ var init_plugin_admission = __esm(() => {
|
|
|
35978
36190
|
|
|
35979
36191
|
// src/lib/plugin-discovery.ts
|
|
35980
36192
|
import { closeSync as closeSync15, constants as constants13, fstatSync as fstatSync15, lstatSync as lstatSync19, openSync as openSync15, opendirSync as opendirSync3, readSync as readSync10 } from "fs";
|
|
35981
|
-
import { basename as
|
|
36193
|
+
import { basename as basename8, dirname as dirname17, isAbsolute as isAbsolute17, join as join28, resolve as resolve18 } from "path";
|
|
35982
36194
|
function validateManagedPluginWitnesses(value) {
|
|
35983
36195
|
pluginNeed(Array.isArray(value) && value.length > 0 && value.length <= PLUGIN_PROJECTION_LIMITS.registrations, "Invalid managed plugin witness collection");
|
|
35984
36196
|
const seen = new Set;
|
|
@@ -36061,7 +36273,7 @@ function hashManagedPluginRegistry(path, managed) {
|
|
|
36061
36273
|
pluginNeed(/^(?:[A-Za-z0-9][A-Za-z0-9._+-]*-)?[a-f0-9]{12}$/.test(row.version) && row.installPath === join28(cacheRoot, row.version), "Managed plugin cache path or version is outside its registration");
|
|
36062
36274
|
const approval = (producer) => {
|
|
36063
36275
|
pluginText(producer);
|
|
36064
|
-
const digest2 = `sha256:${
|
|
36276
|
+
const digest2 = `sha256:${basename8(producer)}`;
|
|
36065
36277
|
const receipt2 = readPluginAdmissionReceipt(witness.storeRoot, witness.bindingId, digest2);
|
|
36066
36278
|
pluginNeed(receipt2.materializedPath === producer, "Managed producer path is not an approved immutable projection");
|
|
36067
36279
|
if (!verified.has(producer)) {
|
|
@@ -36127,7 +36339,7 @@ var init_plugin_discovery = __esm(() => {
|
|
|
36127
36339
|
// src/lib/claude-marketplace-registry.ts
|
|
36128
36340
|
import { createHash as createHash19 } from "crypto";
|
|
36129
36341
|
import { closeSync as closeSync16, constants as constants14, fstatSync as fstatSync16, lstatSync as lstatSync20, openSync as openSync16, readSync as readSync11 } from "fs";
|
|
36130
|
-
import { basename as
|
|
36342
|
+
import { basename as basename9, dirname as dirname18, isAbsolute as isAbsolute18, resolve as resolve19 } from "path";
|
|
36131
36343
|
function need8(value, reason2) {
|
|
36132
36344
|
if (!value)
|
|
36133
36345
|
throw new Error(`Claude marketplace registry ${reason2}`);
|
|
@@ -36147,7 +36359,7 @@ function parents2(path) {
|
|
|
36147
36359
|
}
|
|
36148
36360
|
function readRegistry2(path, budget2) {
|
|
36149
36361
|
absolutePath4(path);
|
|
36150
|
-
need8(
|
|
36362
|
+
need8(basename9(path) === "known_marketplaces.json", "requires known_marketplaces.json");
|
|
36151
36363
|
need8(Number.isSafeInteger(budget2.remaining) && budget2.remaining >= 0, "has an invalid byte budget");
|
|
36152
36364
|
const ancestors2 = parents2(path), initial = lstatSync20(path, { bigint: true });
|
|
36153
36365
|
need8(initial.isFile() && !initial.isSymbolicLink() && initial.size <= BigInt(CLAUDE_MARKETPLACE_REGISTRY_LIMITS.bytes), "is not a bounded regular file");
|
|
@@ -36355,7 +36567,7 @@ var init_codex_hook_discovery_recovery = __esm(() => {
|
|
|
36355
36567
|
// src/lib/agent-discovery.ts
|
|
36356
36568
|
import { createHash as createHash21 } from "crypto";
|
|
36357
36569
|
import { lstatSync as lstatSync21, readFileSync as readFileSync16, readdirSync as readdirSync8, realpathSync as realpathSync8 } from "fs";
|
|
36358
|
-
import { basename as
|
|
36570
|
+
import { basename as basename10, dirname as dirname19, isAbsolute as isAbsolute19, join as join29, relative as relative7, resolve as resolve20, sep as sep9 } from "path";
|
|
36359
36571
|
import { isDeepStrictEqual as isDeepStrictEqual4 } from "util";
|
|
36360
36572
|
function discoveryExecutable(agent) {
|
|
36361
36573
|
const command = DISCOVERY_RUNTIME_COMMANDS[agent];
|
|
@@ -36422,7 +36634,7 @@ function assertReviewedClaudeCacheClosures(home, config2, review, canonical9) {
|
|
|
36422
36634
|
throw new Error("Reviewed Claude enabled plugin registration requires an object with an installPath string");
|
|
36423
36635
|
}
|
|
36424
36636
|
if ([cacheAliasRoot, cacheRoot].some((root) => row.installPath === root || row.installPath.startsWith(root + sep9))) {
|
|
36425
|
-
if (!cachePath(row.installPath) || row.installPath.length > AGENT_POLICY_LIMITS.pathCharacters || row.version !== undefined && (typeof row.version !== "string" ||
|
|
36637
|
+
if (!cachePath(row.installPath) || row.installPath.length > AGENT_POLICY_LIMITS.pathCharacters || row.version !== undefined && (typeof row.version !== "string" || basename10(row.installPath) !== row.version)) {
|
|
36426
36638
|
throw new Error("Reviewed Claude discovery has a malformed active cache registration");
|
|
36427
36639
|
}
|
|
36428
36640
|
if (row.scope === "user" && (row.projectPath === undefined || row.projectPath === null)) {} else if (row.scope === "project" && typeof row.projectPath === "string" && isAbsolute19(row.projectPath) && resolve20(row.projectPath) === row.projectPath && row.projectPath.length <= AGENT_POLICY_LIMITS.pathCharacters) {} else
|
|
@@ -36684,7 +36896,7 @@ function absentRetiredClaudeRoots(binding) {
|
|
|
36684
36896
|
if (!targetValid || !targetScopes.has("user\x00"))
|
|
36685
36897
|
continue;
|
|
36686
36898
|
const active = rows[0]?.installPath;
|
|
36687
|
-
if (typeof active !== "string" || rows[0]?.version !==
|
|
36899
|
+
if (typeof active !== "string" || rows[0]?.version !== basename10(active) || dirname19(active) !== dirname19(root) || active === root || !lstatSync21(active, { throwIfNoEntry: false })?.isDirectory() || realpathSync8(active) !== active)
|
|
36688
36900
|
continue;
|
|
36689
36901
|
const activeManifest = full(join29(active, ".claude-plugin/plugin.json"));
|
|
36690
36902
|
if (!activeManifest || projected(activeManifest) !== activeManifest.sha256)
|
|
@@ -36693,14 +36905,15 @@ function absentRetiredClaudeRoots(binding) {
|
|
|
36693
36905
|
}
|
|
36694
36906
|
return [...result];
|
|
36695
36907
|
}
|
|
36696
|
-
function codexSemanticCacheSourceRole(source, cacheRoot, parents3) {
|
|
36908
|
+
function codexSemanticCacheSourceRole(source, cacheRoot, parents3, hookParents = []) {
|
|
36697
36909
|
if (!isAbsolute19(source.path) || resolve20(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")
|
|
36698
36910
|
return false;
|
|
36699
36911
|
const parts = relative7(cacheRoot, source.path).split(sep9);
|
|
36700
36912
|
if (parts.length < 3 || !parents3.includes(join29(cacheRoot, parts[0], parts[1])))
|
|
36701
36913
|
return false;
|
|
36702
36914
|
const tail = parts.slice(3).join("/");
|
|
36703
|
-
|
|
36915
|
+
const parent = join29(cacheRoot, parts[0], parts[1]);
|
|
36916
|
+
return parts.length === 5 && tail === ".codex-plugin/plugin.json" && source.sha256 !== null || parts.length === 4 && [".app.json", ".mcp.json"].includes(tail) && source.sha256 !== null || parts.length === 5 && tail === "hooks/hooks.json" && hookParents.includes(parent) && source.sha256 !== null || source.sha256 === null && (parts.length === 4 && tail === "SKILL.md" || parts.length === 5 && tail === "hooks/hooks.json");
|
|
36704
36917
|
}
|
|
36705
36918
|
function codexSemanticCacheDirectoryRole(path, cacheRoot) {
|
|
36706
36919
|
return isAbsolute19(path) && resolve20(path) === path && !/[\x00-\x1f\x7f]/.test(path) && (path === cacheRoot || path.startsWith(cacheRoot + sep9));
|
|
@@ -36732,20 +36945,28 @@ function verifyCodexSemanticCacheDiscovery(binding, reviewedRootAliases) {
|
|
|
36732
36945
|
const cacheRoot = proof.witness.cacheRoot;
|
|
36733
36946
|
if (controls.some((control) => dirname19(dirname19(control.pluginParent)) !== cacheRoot))
|
|
36734
36947
|
throw new Error("Codex semantic cache names another enrolled cache");
|
|
36735
|
-
const
|
|
36736
|
-
|
|
36948
|
+
const reviewedHookParents = proof.reviewedHookParents ?? [];
|
|
36949
|
+
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 || !isDeepStrictEqual4((proof.witness.hookParents ?? []).map(({ manifestSha256: _manifest, hooksSha256: _hooks, receiptSha256: _receipt, ...parent }) => parent), reviewedHookParents)) {
|
|
36950
|
+
throw new Error("Invalid reviewed native-hook cache role");
|
|
36951
|
+
}
|
|
36952
|
+
for (const parent of reviewedHookParents)
|
|
36953
|
+
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")))
|
|
36954
|
+
throw new Error("Local marketplace hook parent lost its enrolled source witness");
|
|
36955
|
+
const parents3 = [...new Set([...controls.map((control) => control.pluginParent), ...proof.appOnlyParents.map((parent) => parent.pluginParent), ...reviewedHookParents.map((parent) => parent.pluginParent)])];
|
|
36956
|
+
const hookParentPaths = reviewedHookParents.map((parent) => parent.pluginParent);
|
|
36957
|
+
const sources = binding.sources.filter((source) => codexSemanticCacheSourceRole(source, cacheRoot, parents3, hookParentPaths));
|
|
36737
36958
|
const directories = (binding.directories ?? []).filter((directory) => codexSemanticCacheDirectoryRole(directory.path, cacheRoot));
|
|
36738
36959
|
if (!directories.length || !isDeepStrictEqual4(sources, proof.supersededSources) || !isDeepStrictEqual4(directories, proof.supersededDirectories))
|
|
36739
36960
|
throw new Error("Codex semantic cache provenance changed");
|
|
36740
36961
|
const configPath = proof.configPath;
|
|
36741
|
-
if (!isAbsolute19(configPath) || resolve20(configPath) !== configPath ||
|
|
36962
|
+
if (!isAbsolute19(configPath) || resolve20(configPath) !== configPath || basename10(configPath) !== "config.toml" || /[\x00-\x1f\x7f]/.test(configPath))
|
|
36742
36963
|
throw new Error("Invalid semantic cache configuration source");
|
|
36743
36964
|
const configSource = binding.sources.find((source) => source.path === configPath && source.sha256 !== null && source.format === undefined && source.fields === undefined);
|
|
36744
36965
|
if (!configSource || projected(configSource) !== configSource.sha256)
|
|
36745
36966
|
throw new Error("Codex semantic cache requires unchanged reviewed configuration");
|
|
36746
36967
|
assertCodexSemanticCacheHookSafety(cacheRoot, parents3, configPath, proof.hookRootAlias);
|
|
36747
36968
|
const rules = parseConfig(read(configPath), configPath, true).skills?.config ?? [];
|
|
36748
|
-
const current = captureCodexSemanticCacheWitness({ cacheRoot, controls, appOnlyParents: proof.appOnlyParents, rules });
|
|
36969
|
+
const current = captureCodexSemanticCacheWitness({ cacheRoot, controls, appOnlyParents: proof.appOnlyParents, reviewedHookParents, rules });
|
|
36749
36970
|
assertCodexSemanticCacheWitnessUnchanged(proof.witness, current);
|
|
36750
36971
|
return proof;
|
|
36751
36972
|
}
|
|
@@ -36829,7 +37050,7 @@ function codexInstallationRoots(binding) {
|
|
|
36829
37050
|
const config2 = join29(dirname19(dirname19(cache)), "config.toml"), home = dirname19(dirname19(dirname19(cache)));
|
|
36830
37051
|
const configSource = binding.sources.find((source) => source.path === config2 && source.sha256 !== null && (!source.format || source.format === "toml" && source.fields?.includes("plugins")));
|
|
36831
37052
|
const nativeRoots = NATIVE_SKILL_ROOTS.filter(([agent]) => agent === "codex").map(([, path]) => join29(home, path));
|
|
36832
|
-
if (!configSource || proof.plugins.some((input2) => nativeRoots.some((root) => root === input2.sourceRoot || root.startsWith(input2.sourceRoot + sep9) || input2.sourceRoot.startsWith(root + sep9)) || binding.sources.some((source) =>
|
|
37053
|
+
if (!configSource || proof.plugins.some((input2) => nativeRoots.some((root) => root === input2.sourceRoot || root.startsWith(input2.sourceRoot + sep9) || input2.sourceRoot.startsWith(root + sep9)) || binding.sources.some((source) => basename10(source.path) === "config.toml" && (source.path === input2.sourceRoot || source.path.startsWith(input2.sourceRoot + sep9)))))
|
|
36833
37054
|
throw new Error("Native installation input overlaps configuration or loading roots");
|
|
36834
37055
|
if (proof.plugins.some((input2) => dirname19(dirname19(input2.pluginParent)) !== cache || !binding.sources.some((source) => source.path === join29(input2.sourceRoot, ".codex-plugin/plugin.json") && source.sha256 !== null && source.format === undefined && source.fields === undefined)))
|
|
36835
37056
|
throw new Error("Missing native installation input source witness");
|
|
@@ -36841,13 +37062,13 @@ function codexInstallationRoots(binding) {
|
|
|
36841
37062
|
});
|
|
36842
37063
|
}
|
|
36843
37064
|
function assertMarketplaceBinding(binding, source) {
|
|
36844
|
-
if (source.hashMode === "claude-plugin-manifest-v1" && (binding.agent !== "claude" ||
|
|
37065
|
+
if (source.hashMode === "claude-plugin-manifest-v1" && (binding.agent !== "claude" || basename10(source.path) !== "plugin.json" || !source.path.endsWith(join29(sep9, ".claude-plugin", "plugin.json"))))
|
|
36845
37066
|
throw new Error("Claude plugin manifest witnesses require Claude plugin discovery");
|
|
36846
|
-
if (source.hashMode === "sumi-settings-v1" && (binding.agent !== "sumi" || binding.method !== "reviewed" ||
|
|
37067
|
+
if (source.hashMode === "sumi-settings-v1" && (binding.agent !== "sumi" || binding.method !== "reviewed" || basename10(source.path) !== "sumi.json"))
|
|
36847
37068
|
throw new Error("Sumi settings witnesses require explicit reviewed Sumi configuration");
|
|
36848
|
-
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" ||
|
|
37069
|
+
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" || basename10(source.path) !== "config.toml"))
|
|
36849
37070
|
throw new Error("Codex settings witnesses require explicit reviewed Codex configuration");
|
|
36850
|
-
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" ||
|
|
37071
|
+
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" || basename10(source.path) !== "settings.json"))
|
|
36851
37072
|
throw new Error("Claude settings witnesses require explicit reviewed Claude configuration");
|
|
36852
37073
|
if ((source.hashMode === "claude-marketplace-registry" || source.hashMode === "claude-marketplace-registry-v2") && (binding.agent !== "claude" || binding.method !== "reviewed"))
|
|
36853
37074
|
throw new Error("Claude marketplace witnesses require explicit reviewed Claude discovery");
|
|
@@ -36996,7 +37217,7 @@ function resolveAgentDiscovery(options) {
|
|
|
36996
37217
|
throw new Error("Discovery review must include the agent configuration source");
|
|
36997
37218
|
const reviewedSources = supersedesSettingsProjection(agent, review.sources, canonical9(configPath)) ? sources.filter((source) => !isSupersededSettingsProjection(agent, canonical9(configPath), source)) : sources;
|
|
36998
37219
|
const reviewedSourcesWithManifestProjection = review.sources.map((source) => {
|
|
36999
|
-
if (agent !== "claude" || source.sha256 === null || source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || source.hashMode !== undefined && source.hashMode !== "bytes" ||
|
|
37220
|
+
if (agent !== "claude" || source.sha256 === null || source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || source.hashMode !== undefined && source.hashMode !== "bytes" || basename10(source.path) !== "plugin.json" || !source.path.endsWith(join29(sep9, ".claude-plugin", "plugin.json")))
|
|
37000
37221
|
return source;
|
|
37001
37222
|
const pluginRoot = dirname19(dirname19(source.path)), hooksPath = join29(pluginRoot, "hooks/hooks.json");
|
|
37002
37223
|
const hookStat = lstatSync21(hooksPath, { throwIfNoEntry: false });
|
|
@@ -37176,7 +37397,7 @@ var init_agent_discovery = __esm(() => {
|
|
|
37176
37397
|
// src/lib/authoring-path.ts
|
|
37177
37398
|
import { lstatSync as lstatSync22, realpathSync as realpathSync9 } from "fs";
|
|
37178
37399
|
import { homedir as homedir3 } from "os";
|
|
37179
|
-
import { basename as
|
|
37400
|
+
import { basename as basename11, dirname as dirname20, join as join30, resolve as resolve21, sep as sep10 } from "path";
|
|
37180
37401
|
function pathParts(path) {
|
|
37181
37402
|
return resolve21(path).split(sep10).filter(Boolean);
|
|
37182
37403
|
}
|
|
@@ -37195,7 +37416,7 @@ function physicalPath(path) {
|
|
|
37195
37416
|
let cursor = resolve21(path);
|
|
37196
37417
|
const suffix = [];
|
|
37197
37418
|
while (!lstatSync22(cursor, { throwIfNoEntry: false })) {
|
|
37198
|
-
suffix.unshift(
|
|
37419
|
+
suffix.unshift(basename11(cursor));
|
|
37199
37420
|
const parent = dirname20(cursor);
|
|
37200
37421
|
if (parent === cursor)
|
|
37201
37422
|
return resolve21(path);
|
|
@@ -37290,7 +37511,7 @@ import {
|
|
|
37290
37511
|
statSync as statSync8,
|
|
37291
37512
|
writeFileSync as writeFileSync6
|
|
37292
37513
|
} from "fs";
|
|
37293
|
-
import { basename as
|
|
37514
|
+
import { basename as basename12, dirname as dirname21, isAbsolute as isAbsolute20, join as join31, normalize as normalize4, relative as relative8, resolve as resolve22, sep as sep11 } from "path";
|
|
37294
37515
|
function getPortableSkillsRoot(options = {}) {
|
|
37295
37516
|
return resolvePortableSkillsRoot(options, true);
|
|
37296
37517
|
}
|
|
@@ -37388,7 +37609,7 @@ function physicalImportPath(path) {
|
|
|
37388
37609
|
let ancestor = resolve22(path);
|
|
37389
37610
|
const suffix = [];
|
|
37390
37611
|
while (!existsSync12(ancestor)) {
|
|
37391
|
-
suffix.unshift(
|
|
37612
|
+
suffix.unshift(basename12(ancestor));
|
|
37392
37613
|
ancestor = dirname21(ancestor);
|
|
37393
37614
|
}
|
|
37394
37615
|
return join31(realpathSync10(ancestor), ...suffix);
|
|
@@ -37413,8 +37634,8 @@ function portPortableSkill(sourcePath, options = {}) {
|
|
|
37413
37634
|
const explicitName = options.name != null;
|
|
37414
37635
|
const skillName = normalizeNewPortableSkillName(options.name ?? inferred.name);
|
|
37415
37636
|
if (isOfficialSkillName(skillName) && !options.allowShadow) {
|
|
37416
|
-
const sourceSlug = safeNormalizeName(
|
|
37417
|
-
const via = explicitName ? `Name '${skillName}' matches a bundled official skill.` : `Inferred name '${skillName}'${sourceSlug && sourceSlug !== skillName ? ` (from source folder '${
|
|
37637
|
+
const sourceSlug = safeNormalizeName(basename12(absoluteSource));
|
|
37638
|
+
const via = explicitName ? `Name '${skillName}' matches a bundled official skill.` : `Inferred name '${skillName}'${sourceSlug && sourceSlug !== skillName ? ` (from source folder '${basename12(absoluteSource)}')` : ""} matches a bundled official skill.`;
|
|
37418
37639
|
throw new Error(`${via} Importing it would shadow the official '${skillName}'. ` + `Pass --name to choose a different name, or --allow-shadow to override deliberately.`);
|
|
37419
37640
|
}
|
|
37420
37641
|
const readOnlyDestination = join31(resolvePortableSkillsRoot(options, false), skillName);
|
|
@@ -39043,13 +39264,13 @@ var init_remote_workspace_leave = __esm(() => {
|
|
|
39043
39264
|
|
|
39044
39265
|
// src/lib/auth-store.ts
|
|
39045
39266
|
import { chmodSync, existsSync as existsSync14, mkdirSync as mkdirSync9, readFileSync as readFileSync18, renameSync as renameSync4, statSync as statSync9, unlinkSync as unlinkSync4, writeFileSync as writeFileSync7 } from "fs";
|
|
39046
|
-
import { basename as
|
|
39267
|
+
import { basename as basename13, dirname as dirname22, join as join33 } from "path";
|
|
39047
39268
|
function getAuthFilePath(env = process.env) {
|
|
39048
39269
|
return skillsCredentialFilePath(env);
|
|
39049
39270
|
}
|
|
39050
39271
|
function getIdentityFilePath(env = process.env) {
|
|
39051
39272
|
const file2 = skillsCredentialFilePath(env);
|
|
39052
|
-
return join33(dirname22(file2),
|
|
39273
|
+
return join33(dirname22(file2), basename13(file2).replace(/^credentials/, "identity") + ".json");
|
|
39053
39274
|
}
|
|
39054
39275
|
function getApiUrl(action, env = process.env, options = {}) {
|
|
39055
39276
|
return requireSkillsApiOrigin(action, env, options);
|
package/bin/migrate.js
CHANGED
package/bin/server.js
CHANGED
|
@@ -24140,7 +24140,7 @@ restoreLaunchCwd();
|
|
|
24140
24140
|
// package.json
|
|
24141
24141
|
var package_default = {
|
|
24142
24142
|
name: "@hasna/skills",
|
|
24143
|
-
version: "0.10.
|
|
24143
|
+
version: "0.10.67",
|
|
24144
24144
|
description: "Skills library for AI coding agents",
|
|
24145
24145
|
type: "module",
|
|
24146
24146
|
bin: {
|
package/bin/worker.js
CHANGED
|
@@ -24143,7 +24143,7 @@ import { randomUUID as randomUUID6 } from "crypto";
|
|
|
24143
24143
|
// package.json
|
|
24144
24144
|
var package_default = {
|
|
24145
24145
|
name: "@hasna/skills",
|
|
24146
|
-
version: "0.10.
|
|
24146
|
+
version: "0.10.67",
|
|
24147
24147
|
description: "Skills library for AI coding agents",
|
|
24148
24148
|
type: "module",
|
|
24149
24149
|
bin: {
|