@hasna/skills 0.10.64 → 0.10.66
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -1
- package/bin/index.js +511 -211
- package/bin/mcp.js +335 -40
- package/bin/migrate.js +1 -1
- package/bin/server.js +1 -1
- package/bin/worker.js +1 -1
- package/dist/index.js +426 -61
- 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/hook-diagnostics.d.ts +2 -0
- package/dist/runtime-prerequisites.js +133 -14
- package/dist/sdk/index.js +437 -72
- 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.66",
|
|
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,25 @@ 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
|
+
if (!plainObject(value) || !exactKeys(value, ["interface", "name", "plugins"]) || value.name !== marketplace || !(typeof value.interface === "string" || Number.isSafeInteger(value.interface)) || !Array.isArray(value.plugins) || value.plugins.length < 1 || value.plugins.length > 4096)
|
|
33710
|
+
return false;
|
|
33711
|
+
const rows = value.plugins.filter((row2) => plainObject(row2) && row2.name === plugin);
|
|
33712
|
+
if (rows.length !== 1)
|
|
33713
|
+
return false;
|
|
33714
|
+
const row = rows[0];
|
|
33715
|
+
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("\\"))
|
|
33716
|
+
return false;
|
|
33717
|
+
const parts = row.source.path.split("/");
|
|
33718
|
+
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;
|
|
33719
|
+
} catch {
|
|
33720
|
+
return false;
|
|
33721
|
+
}
|
|
33722
|
+
}
|
|
33671
33723
|
function defaultRead(path) {
|
|
33672
33724
|
const before = lstatSync13(path, { throwIfNoEntry: false, bigint: true });
|
|
33673
33725
|
if (before === undefined)
|
|
@@ -33729,7 +33781,7 @@ function validPluginParent(cacheRoot, pluginParent, namespace, pluginId) {
|
|
|
33729
33781
|
return parts.length === 2 && parts.every(identifier3) && parts[1] === namespace && pluginId === `${namespace}@${parts[0]}`;
|
|
33730
33782
|
}
|
|
33731
33783
|
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)
|
|
33784
|
+
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
33785
|
refuse3();
|
|
33734
33786
|
const witness = value;
|
|
33735
33787
|
const controlParents = new Set;
|
|
@@ -33750,6 +33802,20 @@ function assertWitnessShape(value) {
|
|
|
33750
33802
|
refuse3();
|
|
33751
33803
|
appOnlyParentPaths.add(row.pluginParent);
|
|
33752
33804
|
}
|
|
33805
|
+
const hookParentPaths = new Set;
|
|
33806
|
+
const hookParents = witness.hookParents === undefined ? [] : witness.hookParents;
|
|
33807
|
+
if (!Array.isArray(hookParents) || hookParents.length > 4096)
|
|
33808
|
+
refuse3();
|
|
33809
|
+
for (const candidate of hookParents) {
|
|
33810
|
+
if (!plainObject(candidate))
|
|
33811
|
+
refuse3();
|
|
33812
|
+
const row = candidate;
|
|
33813
|
+
const remote = row.installation === "remote-receipt";
|
|
33814
|
+
const local = row.installation === "local-marketplace";
|
|
33815
|
+
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))
|
|
33816
|
+
refuse3();
|
|
33817
|
+
hookParentPaths.add(row.pluginParent);
|
|
33818
|
+
}
|
|
33753
33819
|
const skillNames = new Set;
|
|
33754
33820
|
const qualifiedNames = new Set;
|
|
33755
33821
|
for (const candidate of witness.skills) {
|
|
@@ -33769,6 +33835,7 @@ function assertWitnessShape(value) {
|
|
|
33769
33835
|
cacheRoot: witness.cacheRoot,
|
|
33770
33836
|
controls: witness.controls,
|
|
33771
33837
|
appOnlyParents: witness.appOnlyParents,
|
|
33838
|
+
...witness.hookParents === undefined ? {} : { hookParents: witness.hookParents },
|
|
33772
33839
|
skills: witness.skills
|
|
33773
33840
|
};
|
|
33774
33841
|
if (hash3(projection) !== witness.sha256)
|
|
@@ -33959,10 +34026,128 @@ function appOnlyParentProjection(cacheRoot, parents2, read) {
|
|
|
33959
34026
|
}
|
|
33960
34027
|
return rows.sort((a, b) => a.pluginId.localeCompare(b.pluginId) || a.pluginParent.localeCompare(b.pluginParent));
|
|
33961
34028
|
}
|
|
33962
|
-
function
|
|
34029
|
+
function assertJsonValue(value, depth = 0, budget2 = { members: 0 }) {
|
|
34030
|
+
if (depth > 32 || ++budget2.members > 4096)
|
|
34031
|
+
refuse3();
|
|
34032
|
+
if (value === null || typeof value === "string" || typeof value === "boolean")
|
|
34033
|
+
return;
|
|
34034
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
34035
|
+
return;
|
|
34036
|
+
if (Array.isArray(value)) {
|
|
34037
|
+
for (const item of value)
|
|
34038
|
+
assertJsonValue(item, depth + 1, budget2);
|
|
34039
|
+
return;
|
|
34040
|
+
}
|
|
34041
|
+
if (!plainObject(value))
|
|
34042
|
+
refuse3();
|
|
34043
|
+
for (const [key, item] of Object.entries(value)) {
|
|
34044
|
+
if (!key || /[\x00-\x1f\x7f]/.test(key))
|
|
34045
|
+
refuse3();
|
|
34046
|
+
assertJsonValue(item, depth + 1, budget2);
|
|
34047
|
+
}
|
|
34048
|
+
}
|
|
34049
|
+
function reviewedHookControls(root, read) {
|
|
34050
|
+
const manifestPath = join19(root, ".codex-plugin/plugin.json"), hooksPath = join19(root, "hooks/hooks.json");
|
|
34051
|
+
let manifest, manifestSha256, hooks, hooksSha256;
|
|
34052
|
+
try {
|
|
34053
|
+
const manifestText = read(manifestPath);
|
|
34054
|
+
manifestSha256 = hashNativeJsonControls(manifestText, "version");
|
|
34055
|
+
manifest = JSON.parse(manifestText);
|
|
34056
|
+
const hooksText = read(hooksPath);
|
|
34057
|
+
hashNativeJsonControls(hooksText);
|
|
34058
|
+
hooksSha256 = createHash14("sha256").update(hooksText).digest("hex");
|
|
34059
|
+
hooks = JSON.parse(hooksText);
|
|
34060
|
+
} catch {
|
|
34061
|
+
return refuse3();
|
|
34062
|
+
}
|
|
34063
|
+
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))
|
|
34064
|
+
refuse3();
|
|
34065
|
+
const manifestRecord = manifest;
|
|
34066
|
+
if (!plainObject(hooks) || !exactKeys(hooks, ["hooks"]) || !plainObject(hooks.hooks))
|
|
34067
|
+
refuse3();
|
|
34068
|
+
const hookTable = hooks.hooks;
|
|
34069
|
+
const events = Object.entries(hookTable);
|
|
34070
|
+
if (!events.length || events.length > 32)
|
|
34071
|
+
refuse3();
|
|
34072
|
+
for (const [event, groups] of events) {
|
|
34073
|
+
if (!codexHookEvents.has(event) || !Array.isArray(groups) || !groups.length || groups.length > 32)
|
|
34074
|
+
refuse3();
|
|
34075
|
+
for (const group of groups) {
|
|
34076
|
+
if (!plainObject(group) || !exactKeys(group, ["hooks"]) || !Array.isArray(group.hooks) || !group.hooks.length || group.hooks.length > 32)
|
|
34077
|
+
refuse3();
|
|
34078
|
+
const handlers = group.hooks;
|
|
34079
|
+
for (const handler of handlers) {
|
|
34080
|
+
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))
|
|
34081
|
+
refuse3();
|
|
34082
|
+
assertJsonValue(handler.input);
|
|
34083
|
+
}
|
|
34084
|
+
}
|
|
34085
|
+
}
|
|
34086
|
+
return { namespace: manifestRecord.name, manifestSha256, hooksSha256 };
|
|
34087
|
+
}
|
|
34088
|
+
function reviewedHookParentProjection(cacheRoot, parents2, read) {
|
|
34089
|
+
if (!Array.isArray(parents2) || parents2.length > 4096)
|
|
34090
|
+
refuse3();
|
|
34091
|
+
const seen = new Set, rows = [];
|
|
34092
|
+
for (const parent of parents2) {
|
|
34093
|
+
const remote = parent?.installation === "remote-receipt", local = parent?.installation === "local-marketplace";
|
|
34094
|
+
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)
|
|
34095
|
+
refuse3();
|
|
34096
|
+
const parts = relative6(cacheRoot, parent.pluginParent).split(sep7);
|
|
34097
|
+
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))
|
|
34098
|
+
refuse3();
|
|
34099
|
+
seen.add(parent.pluginParent);
|
|
34100
|
+
const parentStat = lstatSync13(parent.pluginParent, { throwIfNoEntry: false });
|
|
34101
|
+
if (!parentStat?.isDirectory() || parentStat.isSymbolicLink() || realpathSync6(parent.pluginParent) !== parent.pluginParent)
|
|
34102
|
+
refuse3();
|
|
34103
|
+
const receiptPath = join19(parent.pluginParent, ".codex-remote-plugin-install.json"), receiptStat = lstatSync13(receiptPath, { throwIfNoEntry: false });
|
|
34104
|
+
let receiptText;
|
|
34105
|
+
if (remote) {
|
|
34106
|
+
if (!receiptStat?.isFile() || receiptStat.isSymbolicLink() || receiptStat.size > MAX_RECEIPT_BYTES)
|
|
34107
|
+
refuse3();
|
|
34108
|
+
try {
|
|
34109
|
+
receiptText = read(receiptPath);
|
|
34110
|
+
hashNativeJsonControls(receiptText);
|
|
34111
|
+
const receipt = JSON.parse(receiptText);
|
|
34112
|
+
if (!plainObject(receipt) || !exactKeys(receipt, ["schema_version", "remote_plugin_id"]) || receipt.schema_version !== 1 || receipt.remote_plugin_id !== parent.remotePluginId)
|
|
34113
|
+
refuse3();
|
|
34114
|
+
} catch {
|
|
34115
|
+
refuse3();
|
|
34116
|
+
}
|
|
34117
|
+
} else {
|
|
34118
|
+
const marketplaceSourcePath = parent.marketplaceSourcePath ?? refuse3();
|
|
34119
|
+
if (receiptStat !== undefined || !parent.marketplaceSha256)
|
|
34120
|
+
refuse3();
|
|
34121
|
+
let marketplaceText;
|
|
34122
|
+
try {
|
|
34123
|
+
marketplaceText = read(marketplaceSourcePath);
|
|
34124
|
+
} catch {
|
|
34125
|
+
return refuse3();
|
|
34126
|
+
}
|
|
34127
|
+
if (createHash14("sha256").update(marketplaceText).digest("hex") !== parent.marketplaceSha256 || !codexLocalMarketplaceMapsPlugin(marketplaceText, parts[0], parent.namespace))
|
|
34128
|
+
refuse3();
|
|
34129
|
+
}
|
|
34130
|
+
const materializations = readdirSync7(parent.pluginParent).filter((name) => name !== ".codex-remote-plugin-install.json").map((version2) => {
|
|
34131
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/.test(version2))
|
|
34132
|
+
refuse3();
|
|
34133
|
+
const root = join19(parent.pluginParent, version2), stat = lstatSync13(root, { throwIfNoEntry: false });
|
|
34134
|
+
if (!stat?.isDirectory() || stat.isSymbolicLink() || realpathSync6(root) !== root)
|
|
34135
|
+
refuse3();
|
|
34136
|
+
const controls = reviewedHookControls(root, read);
|
|
34137
|
+
if (controls.namespace !== parent.namespace)
|
|
34138
|
+
refuse3();
|
|
34139
|
+
return { manifestSha256: controls.manifestSha256, hooksSha256: controls.hooksSha256 };
|
|
34140
|
+
});
|
|
34141
|
+
if (!materializations.length || materializations.some((item) => canonical7(item) !== canonical7(materializations[0])))
|
|
34142
|
+
refuse3();
|
|
34143
|
+
rows.push({ ...parent, ...receiptText === undefined ? {} : { receiptSha256: createHash14("sha256").update(receiptText).digest("hex") }, ...materializations[0] });
|
|
34144
|
+
}
|
|
34145
|
+
return rows.sort((a, b) => a.pluginId.localeCompare(b.pluginId) || a.pluginParent.localeCompare(b.pluginParent));
|
|
34146
|
+
}
|
|
34147
|
+
function assertParents(cacheRoot, controls, appOnlyParents, hookParents, files, members2) {
|
|
33963
34148
|
const expected = new Set;
|
|
33964
34149
|
const expectedMarkets = new Set;
|
|
33965
|
-
for (const control of [...controls, ...appOnlyParents]) {
|
|
34150
|
+
for (const control of [...controls, ...appOnlyParents, ...hookParents]) {
|
|
33966
34151
|
const rel = relative6(cacheRoot, control.pluginParent), parts = rel.split(sep7);
|
|
33967
34152
|
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
34153
|
refuse3();
|
|
@@ -34003,7 +34188,9 @@ function assertParents(cacheRoot, controls, appOnlyParents, files, members2) {
|
|
|
34003
34188
|
refuse3();
|
|
34004
34189
|
if ([".app.json", ".mcp.json"].includes(base) && (parts.length !== 4 || dirname13(member) !== root))
|
|
34005
34190
|
refuse3();
|
|
34006
|
-
if (
|
|
34191
|
+
if ([".app.json", ".mcp.json"].includes(base) && hookParents.some((reviewed) => reviewed.pluginParent === parent))
|
|
34192
|
+
refuse3();
|
|
34193
|
+
if (parts.includes("hooks") && (![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
34194
|
refuse3();
|
|
34008
34195
|
}
|
|
34009
34196
|
}
|
|
@@ -34113,13 +34300,14 @@ function captureCodexSemanticCacheWitness(options) {
|
|
|
34113
34300
|
const initialTree = treeSnapshot(options.cacheRoot);
|
|
34114
34301
|
const controls = controlProjection(options.controls, read);
|
|
34115
34302
|
const appOnlyParents = appOnlyParentProjection(options.cacheRoot, options.appOnlyParents ?? [], read);
|
|
34303
|
+
const hookParents = reviewedHookParentProjection(options.cacheRoot, options.reviewedHookParents ?? [], read);
|
|
34116
34304
|
const skillParents = new Set(controls.map((control) => control.pluginParent));
|
|
34117
|
-
if (appOnlyParents.some((parent) => skillParents.has(parent.pluginParent)))
|
|
34305
|
+
if (appOnlyParents.some((parent) => skillParents.has(parent.pluginParent)) || hookParents.some((parent) => skillParents.has(parent.pluginParent) || appOnlyParents.some((app) => app.pluginParent === parent.pluginParent)))
|
|
34118
34306
|
refuse3();
|
|
34119
34307
|
if (!reviewedCodexPluginCapabilitiesUnchanged(options.cacheRoot, options.controls, read, options.rules))
|
|
34120
34308
|
refuse3();
|
|
34121
34309
|
const files = initialTree.files;
|
|
34122
|
-
assertParents(options.cacheRoot, controls, appOnlyParents, files, initialTree.state.members);
|
|
34310
|
+
assertParents(options.cacheRoot, controls, appOnlyParents, hookParents, files, initialTree.state.members);
|
|
34123
34311
|
const expectedNamesByRoot = assertSkillMaterializations(options.cacheRoot, options.controls, files, read);
|
|
34124
34312
|
const docs = files.filter((path) => path.endsWith(`${sep7}SKILL.md`));
|
|
34125
34313
|
const skillRows = [];
|
|
@@ -34128,6 +34316,8 @@ function captureCodexSemanticCacheWitness(options) {
|
|
|
34128
34316
|
const rel = relative6(options.cacheRoot, document2).split(sep7);
|
|
34129
34317
|
if (appOnlyParents.some((parent) => parent.pluginParent === join19(options.cacheRoot, rel[0], rel[1])))
|
|
34130
34318
|
refuse3();
|
|
34319
|
+
if (hookParents.some((parent) => parent.pluginParent === join19(options.cacheRoot, rel[0], rel[1])))
|
|
34320
|
+
refuse3();
|
|
34131
34321
|
const documentStat = lstatSync13(document2, { throwIfNoEntry: false });
|
|
34132
34322
|
if (!documentStat?.isFile() || documentStat.isSymbolicLink() || documentStat.size > MAX_DOCUMENT_BYTES)
|
|
34133
34323
|
refuse3();
|
|
@@ -34191,7 +34381,7 @@ function captureCodexSemanticCacheWitness(options) {
|
|
|
34191
34381
|
tracked.verify();
|
|
34192
34382
|
const finalTree = treeSnapshot(options.cacheRoot);
|
|
34193
34383
|
assertSameTree(initialTree.state, finalTree.state, tracked.paths());
|
|
34194
|
-
const completeProjection = { schema: CODEX_SEMANTIC_CACHE_WITNESS_SCHEMA, cacheRoot: options.cacheRoot, controls, appOnlyParents, skills: uniqueSkills };
|
|
34384
|
+
const completeProjection = { schema: CODEX_SEMANTIC_CACHE_WITNESS_SCHEMA, cacheRoot: options.cacheRoot, controls, appOnlyParents, hookParents, skills: uniqueSkills };
|
|
34195
34385
|
return { ...completeProjection, sha256: hash3(completeProjection) };
|
|
34196
34386
|
} catch (error61) {
|
|
34197
34387
|
if (error61 instanceof Error && error61.message.startsWith("CODEX_SEMANTIC_CACHE_WITNESS_UNSUPPORTED"))
|
|
@@ -34207,6 +34397,7 @@ function assertCodexSemanticCacheWitnessUnchanged(previous, current) {
|
|
|
34207
34397
|
cacheRoot: previous.cacheRoot,
|
|
34208
34398
|
controls: previous.controls,
|
|
34209
34399
|
appOnlyParents: previous.appOnlyParents,
|
|
34400
|
+
...previous.hookParents === undefined ? {} : { hookParents: previous.hookParents },
|
|
34210
34401
|
skills: previous.skills
|
|
34211
34402
|
};
|
|
34212
34403
|
const currentProjection = {
|
|
@@ -34214,20 +34405,41 @@ function assertCodexSemanticCacheWitnessUnchanged(previous, current) {
|
|
|
34214
34405
|
cacheRoot: current.cacheRoot,
|
|
34215
34406
|
controls: current.controls,
|
|
34216
34407
|
appOnlyParents: current.appOnlyParents,
|
|
34408
|
+
...current.hookParents === undefined ? {} : { hookParents: current.hookParents },
|
|
34217
34409
|
skills: current.skills
|
|
34218
34410
|
};
|
|
34219
|
-
|
|
34411
|
+
const comparable = (projection) => ({ ...projection, hookParents: projection.hookParents ?? [] });
|
|
34412
|
+
if (hash3(priorProjection) !== previous.sha256 || hash3(currentProjection) !== current.sha256 || canonical7(comparable(priorProjection)) !== canonical7(comparable(currentProjection)))
|
|
34220
34413
|
refuse3();
|
|
34221
34414
|
}
|
|
34222
34415
|
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
34416
|
throw new Error("CODEX_SEMANTIC_CACHE_WITNESS_UNSUPPORTED: review Codex plugin cache identity and controls");
|
|
34224
|
-
}, MAX_DOCUMENT_BYTES, MAX_RECEIPT_BYTES;
|
|
34417
|
+
}, MAX_DOCUMENT_BYTES, MAX_RECEIPT_BYTES, codexHookEvents;
|
|
34225
34418
|
var init_codex_semantic_cache_witness = __esm(() => {
|
|
34226
34419
|
init_claude_settings_witness();
|
|
34227
34420
|
init_codex_plugin_skill_controls();
|
|
34228
34421
|
init_codex_native_skill_catalog();
|
|
34229
34422
|
MAX_DOCUMENT_BYTES = 1024 * 1024;
|
|
34230
34423
|
MAX_RECEIPT_BYTES = 16 * 1024;
|
|
34424
|
+
codexHookEvents = new Set([
|
|
34425
|
+
"SessionStart",
|
|
34426
|
+
"UserPromptSubmit",
|
|
34427
|
+
"PreToolUse",
|
|
34428
|
+
"PostToolUse",
|
|
34429
|
+
"PostToolUseFailure",
|
|
34430
|
+
"Stop",
|
|
34431
|
+
"SubagentStart",
|
|
34432
|
+
"SubagentStop",
|
|
34433
|
+
"PreCompact",
|
|
34434
|
+
"Notification",
|
|
34435
|
+
"PermissionRequest",
|
|
34436
|
+
"SessionEnd",
|
|
34437
|
+
"ConfigChange",
|
|
34438
|
+
"WorktreeCreate",
|
|
34439
|
+
"WorktreeRemove",
|
|
34440
|
+
"TeammateIdle",
|
|
34441
|
+
"TaskComplete"
|
|
34442
|
+
]);
|
|
34231
34443
|
});
|
|
34232
34444
|
|
|
34233
34445
|
// src/lib/managed-policy.ts
|
|
@@ -34337,6 +34549,79 @@ var init_agent_bridge = __esm(() => {
|
|
|
34337
34549
|
// src/lib/agent-codex.ts
|
|
34338
34550
|
var init_agent_codex = () => {};
|
|
34339
34551
|
|
|
34552
|
+
// src/lib/hook-diagnostics.ts
|
|
34553
|
+
var CONTEXT_ERROR_CODES, HOOK_REFUSAL_REASON_CODES, OPTIONAL_CONTEXT_FAILURES;
|
|
34554
|
+
var init_hook_diagnostics = __esm(() => {
|
|
34555
|
+
CONTEXT_ERROR_CODES = new Set([
|
|
34556
|
+
"SKILLS_API_CREDENTIAL_UNAVAILABLE",
|
|
34557
|
+
"SKILLS_API_UNAVAILABLE",
|
|
34558
|
+
"SKILLS_API_UNAUTHORIZED",
|
|
34559
|
+
"SKILLS_API_FORBIDDEN",
|
|
34560
|
+
"SKILLS_API_RESOURCE_UNAVAILABLE",
|
|
34561
|
+
"SESSION_WRITE_BUSY",
|
|
34562
|
+
"SKILLS_CONTEXT_FAILED",
|
|
34563
|
+
"SKILLS_STORAGE_FULL",
|
|
34564
|
+
"PROFILE_LOCK_MISMATCH",
|
|
34565
|
+
"PROFILE_IDENTITY_MISMATCH",
|
|
34566
|
+
"PROFILE_APPLIED_REPORT_FAILED",
|
|
34567
|
+
"CACHED_AUTHORITY_REQUIRED",
|
|
34568
|
+
"CACHED_PROFILE_EXPIRED",
|
|
34569
|
+
"CACHED_PROFILE_MISSING",
|
|
34570
|
+
"CACHED_BUNDLE_MISSING",
|
|
34571
|
+
"INVALID_CONTEXT_INPUT",
|
|
34572
|
+
"CONTEXT_INPUT_TOO_LARGE",
|
|
34573
|
+
"INVALID_CONTEXT_BUDGET",
|
|
34574
|
+
"INVALID_SELECTION",
|
|
34575
|
+
"INVALID_SELECTION_ALIASES",
|
|
34576
|
+
"INVALID_RECEIPT",
|
|
34577
|
+
"INVALID_CACHE_FILE",
|
|
34578
|
+
"UNSAFE_CACHE_PATH",
|
|
34579
|
+
"RECEIPT_TOO_LARGE",
|
|
34580
|
+
"BUNDLE_DIGEST_MISMATCH",
|
|
34581
|
+
"BUNDLE_IDENTITY_MISMATCH",
|
|
34582
|
+
"BUNDLE_UNAVAILABLE",
|
|
34583
|
+
"BUNDLE_TOO_LARGE",
|
|
34584
|
+
"SKILL_NOT_SELECTED",
|
|
34585
|
+
"INVALID_SESSION",
|
|
34586
|
+
"SESSION_PARENT_NOT_FOUND",
|
|
34587
|
+
"SESSION_PARENT_MISMATCH",
|
|
34588
|
+
"SESSION_NOT_FOUND",
|
|
34589
|
+
"SESSION_GENERATION_CHANGED",
|
|
34590
|
+
"SESSION_GENERATION_EXHAUSTED",
|
|
34591
|
+
"SESSION_PARENT_CHANGED",
|
|
34592
|
+
"SESSION_RECEIPT_CHANGED",
|
|
34593
|
+
"SESSION_RECONCILIATION_REQUIRED",
|
|
34594
|
+
"SESSION_RENEWAL_TIMEOUT",
|
|
34595
|
+
"SESSION_CONTEXT_CONFLICT",
|
|
34596
|
+
"SESSION_RECONCILIATION_INCOMPLETE",
|
|
34597
|
+
"SESSION_WRITE_LOCKED",
|
|
34598
|
+
"SESSION_WRITE_LOCK_CHANGED",
|
|
34599
|
+
"SESSION_LOCK_RECOVERY_INCOMPLETE"
|
|
34600
|
+
]);
|
|
34601
|
+
HOOK_REFUSAL_REASON_CODES = Object.freeze([
|
|
34602
|
+
...CONTEXT_ERROR_CODES,
|
|
34603
|
+
"SKILLS_HOOK_FAILED",
|
|
34604
|
+
"SKILLS_HOOK_TIMEOUT",
|
|
34605
|
+
"SKILLS_HOOK_INVALID_RESPONSE"
|
|
34606
|
+
]);
|
|
34607
|
+
OPTIONAL_CONTEXT_FAILURES = new Set([
|
|
34608
|
+
"SKILLS_API_CREDENTIAL_UNAVAILABLE",
|
|
34609
|
+
"SKILLS_API_UNAVAILABLE",
|
|
34610
|
+
"SKILLS_API_UNAUTHORIZED",
|
|
34611
|
+
"SKILLS_API_FORBIDDEN",
|
|
34612
|
+
"SKILLS_API_RESOURCE_UNAVAILABLE",
|
|
34613
|
+
"CACHED_PROFILE_EXPIRED",
|
|
34614
|
+
"CACHED_PROFILE_MISSING",
|
|
34615
|
+
"CACHED_BUNDLE_MISSING",
|
|
34616
|
+
"SESSION_RECONCILIATION_REQUIRED",
|
|
34617
|
+
"SESSION_RENEWAL_TIMEOUT",
|
|
34618
|
+
"SESSION_WRITE_BUSY",
|
|
34619
|
+
"SESSION_PARENT_CHANGED",
|
|
34620
|
+
"SESSION_CONTEXT_CONFLICT",
|
|
34621
|
+
"SKILLS_HOOK_TIMEOUT"
|
|
34622
|
+
]);
|
|
34623
|
+
});
|
|
34624
|
+
|
|
34340
34625
|
// src/lib/agent-sumi.ts
|
|
34341
34626
|
import { spawnSync as spawnSync4 } from "child_process";
|
|
34342
34627
|
import { accessSync, constants as constants9, existsSync as existsSync8, lstatSync as lstatSync15, realpathSync as realpathSync7, statSync as statSync7 } from "fs";
|
|
@@ -34464,6 +34749,7 @@ function sumiConfigPath(home, cwd = process.cwd(), env = process.env) {
|
|
|
34464
34749
|
}
|
|
34465
34750
|
var SUMI_PATH_SELECTORS, SUMI_PATH_KEYS, SUMI_PATH_OUTPUT_LIMIT, SumiPathResolverError;
|
|
34466
34751
|
var init_agent_sumi = __esm(() => {
|
|
34752
|
+
init_hook_diagnostics();
|
|
34467
34753
|
SUMI_PATH_SELECTORS = ["SUMI_HOME", "SUMI_CONFIG_DIR", "XDG_DATA_HOME", "XDG_CACHE_HOME", "XDG_CONFIG_HOME", "XDG_STATE_HOME"];
|
|
34468
34754
|
SUMI_PATH_KEYS = ["data", "cache", "config", "state"];
|
|
34469
34755
|
SUMI_PATH_OUTPUT_LIMIT = 128 * 1024;
|
|
@@ -35904,7 +36190,7 @@ var init_plugin_admission = __esm(() => {
|
|
|
35904
36190
|
|
|
35905
36191
|
// src/lib/plugin-discovery.ts
|
|
35906
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";
|
|
35907
|
-
import { basename as
|
|
36193
|
+
import { basename as basename8, dirname as dirname17, isAbsolute as isAbsolute17, join as join28, resolve as resolve18 } from "path";
|
|
35908
36194
|
function validateManagedPluginWitnesses(value) {
|
|
35909
36195
|
pluginNeed(Array.isArray(value) && value.length > 0 && value.length <= PLUGIN_PROJECTION_LIMITS.registrations, "Invalid managed plugin witness collection");
|
|
35910
36196
|
const seen = new Set;
|
|
@@ -35987,7 +36273,7 @@ function hashManagedPluginRegistry(path, managed) {
|
|
|
35987
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");
|
|
35988
36274
|
const approval = (producer) => {
|
|
35989
36275
|
pluginText(producer);
|
|
35990
|
-
const digest2 = `sha256:${
|
|
36276
|
+
const digest2 = `sha256:${basename8(producer)}`;
|
|
35991
36277
|
const receipt2 = readPluginAdmissionReceipt(witness.storeRoot, witness.bindingId, digest2);
|
|
35992
36278
|
pluginNeed(receipt2.materializedPath === producer, "Managed producer path is not an approved immutable projection");
|
|
35993
36279
|
if (!verified.has(producer)) {
|
|
@@ -36053,7 +36339,7 @@ var init_plugin_discovery = __esm(() => {
|
|
|
36053
36339
|
// src/lib/claude-marketplace-registry.ts
|
|
36054
36340
|
import { createHash as createHash19 } from "crypto";
|
|
36055
36341
|
import { closeSync as closeSync16, constants as constants14, fstatSync as fstatSync16, lstatSync as lstatSync20, openSync as openSync16, readSync as readSync11 } from "fs";
|
|
36056
|
-
import { basename as
|
|
36342
|
+
import { basename as basename9, dirname as dirname18, isAbsolute as isAbsolute18, resolve as resolve19 } from "path";
|
|
36057
36343
|
function need8(value, reason2) {
|
|
36058
36344
|
if (!value)
|
|
36059
36345
|
throw new Error(`Claude marketplace registry ${reason2}`);
|
|
@@ -36073,7 +36359,7 @@ function parents2(path) {
|
|
|
36073
36359
|
}
|
|
36074
36360
|
function readRegistry2(path, budget2) {
|
|
36075
36361
|
absolutePath4(path);
|
|
36076
|
-
need8(
|
|
36362
|
+
need8(basename9(path) === "known_marketplaces.json", "requires known_marketplaces.json");
|
|
36077
36363
|
need8(Number.isSafeInteger(budget2.remaining) && budget2.remaining >= 0, "has an invalid byte budget");
|
|
36078
36364
|
const ancestors2 = parents2(path), initial = lstatSync20(path, { bigint: true });
|
|
36079
36365
|
need8(initial.isFile() && !initial.isSymbolicLink() && initial.size <= BigInt(CLAUDE_MARKETPLACE_REGISTRY_LIMITS.bytes), "is not a bounded regular file");
|
|
@@ -36281,7 +36567,7 @@ var init_codex_hook_discovery_recovery = __esm(() => {
|
|
|
36281
36567
|
// src/lib/agent-discovery.ts
|
|
36282
36568
|
import { createHash as createHash21 } from "crypto";
|
|
36283
36569
|
import { lstatSync as lstatSync21, readFileSync as readFileSync16, readdirSync as readdirSync8, realpathSync as realpathSync8 } from "fs";
|
|
36284
|
-
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";
|
|
36285
36571
|
import { isDeepStrictEqual as isDeepStrictEqual4 } from "util";
|
|
36286
36572
|
function discoveryExecutable(agent) {
|
|
36287
36573
|
const command = DISCOVERY_RUNTIME_COMMANDS[agent];
|
|
@@ -36348,7 +36634,7 @@ function assertReviewedClaudeCacheClosures(home, config2, review, canonical9) {
|
|
|
36348
36634
|
throw new Error("Reviewed Claude enabled plugin registration requires an object with an installPath string");
|
|
36349
36635
|
}
|
|
36350
36636
|
if ([cacheAliasRoot, cacheRoot].some((root) => row.installPath === root || row.installPath.startsWith(root + sep9))) {
|
|
36351
|
-
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)) {
|
|
36352
36638
|
throw new Error("Reviewed Claude discovery has a malformed active cache registration");
|
|
36353
36639
|
}
|
|
36354
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
|
|
@@ -36610,7 +36896,7 @@ function absentRetiredClaudeRoots(binding) {
|
|
|
36610
36896
|
if (!targetValid || !targetScopes.has("user\x00"))
|
|
36611
36897
|
continue;
|
|
36612
36898
|
const active = rows[0]?.installPath;
|
|
36613
|
-
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)
|
|
36614
36900
|
continue;
|
|
36615
36901
|
const activeManifest = full(join29(active, ".claude-plugin/plugin.json"));
|
|
36616
36902
|
if (!activeManifest || projected(activeManifest) !== activeManifest.sha256)
|
|
@@ -36619,14 +36905,15 @@ function absentRetiredClaudeRoots(binding) {
|
|
|
36619
36905
|
}
|
|
36620
36906
|
return [...result];
|
|
36621
36907
|
}
|
|
36622
|
-
function codexSemanticCacheSourceRole(source, cacheRoot, parents3) {
|
|
36908
|
+
function codexSemanticCacheSourceRole(source, cacheRoot, parents3, hookParents = []) {
|
|
36623
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")
|
|
36624
36910
|
return false;
|
|
36625
36911
|
const parts = relative7(cacheRoot, source.path).split(sep9);
|
|
36626
36912
|
if (parts.length < 3 || !parents3.includes(join29(cacheRoot, parts[0], parts[1])))
|
|
36627
36913
|
return false;
|
|
36628
36914
|
const tail = parts.slice(3).join("/");
|
|
36629
|
-
|
|
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");
|
|
36630
36917
|
}
|
|
36631
36918
|
function codexSemanticCacheDirectoryRole(path, cacheRoot) {
|
|
36632
36919
|
return isAbsolute19(path) && resolve20(path) === path && !/[\x00-\x1f\x7f]/.test(path) && (path === cacheRoot || path.startsWith(cacheRoot + sep9));
|
|
@@ -36658,20 +36945,28 @@ function verifyCodexSemanticCacheDiscovery(binding, reviewedRootAliases) {
|
|
|
36658
36945
|
const cacheRoot = proof.witness.cacheRoot;
|
|
36659
36946
|
if (controls.some((control) => dirname19(dirname19(control.pluginParent)) !== cacheRoot))
|
|
36660
36947
|
throw new Error("Codex semantic cache names another enrolled cache");
|
|
36661
|
-
const
|
|
36662
|
-
|
|
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));
|
|
36663
36958
|
const directories = (binding.directories ?? []).filter((directory) => codexSemanticCacheDirectoryRole(directory.path, cacheRoot));
|
|
36664
36959
|
if (!directories.length || !isDeepStrictEqual4(sources, proof.supersededSources) || !isDeepStrictEqual4(directories, proof.supersededDirectories))
|
|
36665
36960
|
throw new Error("Codex semantic cache provenance changed");
|
|
36666
36961
|
const configPath = proof.configPath;
|
|
36667
|
-
if (!isAbsolute19(configPath) || resolve20(configPath) !== configPath ||
|
|
36962
|
+
if (!isAbsolute19(configPath) || resolve20(configPath) !== configPath || basename10(configPath) !== "config.toml" || /[\x00-\x1f\x7f]/.test(configPath))
|
|
36668
36963
|
throw new Error("Invalid semantic cache configuration source");
|
|
36669
36964
|
const configSource = binding.sources.find((source) => source.path === configPath && source.sha256 !== null && source.format === undefined && source.fields === undefined);
|
|
36670
36965
|
if (!configSource || projected(configSource) !== configSource.sha256)
|
|
36671
36966
|
throw new Error("Codex semantic cache requires unchanged reviewed configuration");
|
|
36672
36967
|
assertCodexSemanticCacheHookSafety(cacheRoot, parents3, configPath, proof.hookRootAlias);
|
|
36673
36968
|
const rules = parseConfig(read(configPath), configPath, true).skills?.config ?? [];
|
|
36674
|
-
const current = captureCodexSemanticCacheWitness({ cacheRoot, controls, appOnlyParents: proof.appOnlyParents, rules });
|
|
36969
|
+
const current = captureCodexSemanticCacheWitness({ cacheRoot, controls, appOnlyParents: proof.appOnlyParents, reviewedHookParents, rules });
|
|
36675
36970
|
assertCodexSemanticCacheWitnessUnchanged(proof.witness, current);
|
|
36676
36971
|
return proof;
|
|
36677
36972
|
}
|
|
@@ -36755,7 +37050,7 @@ function codexInstallationRoots(binding) {
|
|
|
36755
37050
|
const config2 = join29(dirname19(dirname19(cache)), "config.toml"), home = dirname19(dirname19(dirname19(cache)));
|
|
36756
37051
|
const configSource = binding.sources.find((source) => source.path === config2 && source.sha256 !== null && (!source.format || source.format === "toml" && source.fields?.includes("plugins")));
|
|
36757
37052
|
const nativeRoots = NATIVE_SKILL_ROOTS.filter(([agent]) => agent === "codex").map(([, path]) => join29(home, path));
|
|
36758
|
-
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)))))
|
|
36759
37054
|
throw new Error("Native installation input overlaps configuration or loading roots");
|
|
36760
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)))
|
|
36761
37056
|
throw new Error("Missing native installation input source witness");
|
|
@@ -36767,13 +37062,13 @@ function codexInstallationRoots(binding) {
|
|
|
36767
37062
|
});
|
|
36768
37063
|
}
|
|
36769
37064
|
function assertMarketplaceBinding(binding, source) {
|
|
36770
|
-
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"))))
|
|
36771
37066
|
throw new Error("Claude plugin manifest witnesses require Claude plugin discovery");
|
|
36772
|
-
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"))
|
|
36773
37068
|
throw new Error("Sumi settings witnesses require explicit reviewed Sumi configuration");
|
|
36774
|
-
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"))
|
|
36775
37070
|
throw new Error("Codex settings witnesses require explicit reviewed Codex configuration");
|
|
36776
|
-
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"))
|
|
36777
37072
|
throw new Error("Claude settings witnesses require explicit reviewed Claude configuration");
|
|
36778
37073
|
if ((source.hashMode === "claude-marketplace-registry" || source.hashMode === "claude-marketplace-registry-v2") && (binding.agent !== "claude" || binding.method !== "reviewed"))
|
|
36779
37074
|
throw new Error("Claude marketplace witnesses require explicit reviewed Claude discovery");
|
|
@@ -36922,7 +37217,7 @@ function resolveAgentDiscovery(options) {
|
|
|
36922
37217
|
throw new Error("Discovery review must include the agent configuration source");
|
|
36923
37218
|
const reviewedSources = supersedesSettingsProjection(agent, review.sources, canonical9(configPath)) ? sources.filter((source) => !isSupersededSettingsProjection(agent, canonical9(configPath), source)) : sources;
|
|
36924
37219
|
const reviewedSourcesWithManifestProjection = review.sources.map((source) => {
|
|
36925
|
-
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")))
|
|
36926
37221
|
return source;
|
|
36927
37222
|
const pluginRoot = dirname19(dirname19(source.path)), hooksPath = join29(pluginRoot, "hooks/hooks.json");
|
|
36928
37223
|
const hookStat = lstatSync21(hooksPath, { throwIfNoEntry: false });
|
|
@@ -37102,7 +37397,7 @@ var init_agent_discovery = __esm(() => {
|
|
|
37102
37397
|
// src/lib/authoring-path.ts
|
|
37103
37398
|
import { lstatSync as lstatSync22, realpathSync as realpathSync9 } from "fs";
|
|
37104
37399
|
import { homedir as homedir3 } from "os";
|
|
37105
|
-
import { basename as
|
|
37400
|
+
import { basename as basename11, dirname as dirname20, join as join30, resolve as resolve21, sep as sep10 } from "path";
|
|
37106
37401
|
function pathParts(path) {
|
|
37107
37402
|
return resolve21(path).split(sep10).filter(Boolean);
|
|
37108
37403
|
}
|
|
@@ -37121,7 +37416,7 @@ function physicalPath(path) {
|
|
|
37121
37416
|
let cursor = resolve21(path);
|
|
37122
37417
|
const suffix = [];
|
|
37123
37418
|
while (!lstatSync22(cursor, { throwIfNoEntry: false })) {
|
|
37124
|
-
suffix.unshift(
|
|
37419
|
+
suffix.unshift(basename11(cursor));
|
|
37125
37420
|
const parent = dirname20(cursor);
|
|
37126
37421
|
if (parent === cursor)
|
|
37127
37422
|
return resolve21(path);
|
|
@@ -37216,7 +37511,7 @@ import {
|
|
|
37216
37511
|
statSync as statSync8,
|
|
37217
37512
|
writeFileSync as writeFileSync6
|
|
37218
37513
|
} from "fs";
|
|
37219
|
-
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";
|
|
37220
37515
|
function getPortableSkillsRoot(options = {}) {
|
|
37221
37516
|
return resolvePortableSkillsRoot(options, true);
|
|
37222
37517
|
}
|
|
@@ -37314,7 +37609,7 @@ function physicalImportPath(path) {
|
|
|
37314
37609
|
let ancestor = resolve22(path);
|
|
37315
37610
|
const suffix = [];
|
|
37316
37611
|
while (!existsSync12(ancestor)) {
|
|
37317
|
-
suffix.unshift(
|
|
37612
|
+
suffix.unshift(basename12(ancestor));
|
|
37318
37613
|
ancestor = dirname21(ancestor);
|
|
37319
37614
|
}
|
|
37320
37615
|
return join31(realpathSync10(ancestor), ...suffix);
|
|
@@ -37339,8 +37634,8 @@ function portPortableSkill(sourcePath, options = {}) {
|
|
|
37339
37634
|
const explicitName = options.name != null;
|
|
37340
37635
|
const skillName = normalizeNewPortableSkillName(options.name ?? inferred.name);
|
|
37341
37636
|
if (isOfficialSkillName(skillName) && !options.allowShadow) {
|
|
37342
|
-
const sourceSlug = safeNormalizeName(
|
|
37343
|
-
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.`;
|
|
37344
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.`);
|
|
37345
37640
|
}
|
|
37346
37641
|
const readOnlyDestination = join31(resolvePortableSkillsRoot(options, false), skillName);
|
|
@@ -38969,13 +39264,13 @@ var init_remote_workspace_leave = __esm(() => {
|
|
|
38969
39264
|
|
|
38970
39265
|
// src/lib/auth-store.ts
|
|
38971
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";
|
|
38972
|
-
import { basename as
|
|
39267
|
+
import { basename as basename13, dirname as dirname22, join as join33 } from "path";
|
|
38973
39268
|
function getAuthFilePath(env = process.env) {
|
|
38974
39269
|
return skillsCredentialFilePath(env);
|
|
38975
39270
|
}
|
|
38976
39271
|
function getIdentityFilePath(env = process.env) {
|
|
38977
39272
|
const file2 = skillsCredentialFilePath(env);
|
|
38978
|
-
return join33(dirname22(file2),
|
|
39273
|
+
return join33(dirname22(file2), basename13(file2).replace(/^credentials/, "identity") + ".json");
|
|
38979
39274
|
}
|
|
38980
39275
|
function getApiUrl(action, env = process.env, options = {}) {
|
|
38981
39276
|
return requireSkillsApiOrigin(action, env, options);
|