@hasna/skills 0.10.65 → 0.10.66
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/bin/index.js +362 -82
- package/bin/mcp.js +261 -40
- package/bin/migrate.js +1 -1
- package/bin/server.js +1 -1
- package/bin/worker.js +1 -1
- package/dist/index.js +330 -50
- 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/runtime-prerequisites.js +37 -3
- package/dist/sdk/index.js +341 -61
- package/package.json +1 -1
package/dist/sdk/index.js
CHANGED
|
@@ -32371,7 +32371,7 @@ var init_event_sink = __esm(() => {
|
|
|
32371
32371
|
init_dist();
|
|
32372
32372
|
});
|
|
32373
32373
|
// package.json
|
|
32374
|
-
var version = "0.10.
|
|
32374
|
+
var version = "0.10.66";
|
|
32375
32375
|
var package_default = {
|
|
32376
32376
|
name: "@hasna/skills",
|
|
32377
32377
|
version,
|
|
@@ -38326,7 +38326,7 @@ import {
|
|
|
38326
38326
|
writeFileSync as writeFileSync8
|
|
38327
38327
|
} from "fs";
|
|
38328
38328
|
import { homedir as homedir5 } from "os";
|
|
38329
|
-
import { basename as
|
|
38329
|
+
import { basename as basename15, dirname as dirname25, join as join35 } from "path";
|
|
38330
38330
|
|
|
38331
38331
|
// src/lib/sumi-settings-witness.ts
|
|
38332
38332
|
import { createHash as createHash8 } from "crypto";
|
|
@@ -40671,7 +40671,7 @@ function upgradeCodexSettingsWitnessV5(previous, reviewedSettingsPath) {
|
|
|
40671
40671
|
// src/lib/codex-semantic-cache-witness.ts
|
|
40672
40672
|
import { createHash as createHash13 } from "crypto";
|
|
40673
40673
|
import { constants as constants9, closeSync as closeSync12, fstatSync as fstatSync12, lstatSync as lstatSync10, openSync as openSync12, readSync as readSync6, readdirSync as readdirSync4, realpathSync as realpathSync9 } from "fs";
|
|
40674
|
-
import { dirname as dirname9, isAbsolute as isAbsolute8, join as join15, relative as relative6, resolve as resolve8, sep as sep5 } from "path";
|
|
40674
|
+
import { basename as basename5, dirname as dirname9, isAbsolute as isAbsolute8, join as join15, relative as relative6, resolve as resolve8, sep as sep5 } from "path";
|
|
40675
40675
|
var CODEX_SEMANTIC_CACHE_WITNESS_SCHEMA = "hasna.codex-semantic-cache-witness.v1";
|
|
40676
40676
|
var identifier4 = (value) => typeof value === "string" && /^[A-Za-z0-9_-]{1,64}$/.test(value);
|
|
40677
40677
|
var digest2 = (value) => typeof value === "string" && /^[a-f0-9]{64}$/.test(value);
|
|
@@ -40680,6 +40680,24 @@ var refuse5 = () => {
|
|
|
40680
40680
|
};
|
|
40681
40681
|
var MAX_DOCUMENT_BYTES = 1024 * 1024;
|
|
40682
40682
|
var MAX_RECEIPT_BYTES = 16 * 1024;
|
|
40683
|
+
function codexLocalMarketplaceMapsPlugin(text, marketplace, plugin) {
|
|
40684
|
+
try {
|
|
40685
|
+
hashNativeJsonControls(text);
|
|
40686
|
+
const value = JSON.parse(text);
|
|
40687
|
+
if (!plainObject(value) || !exactKeys2(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)
|
|
40688
|
+
return false;
|
|
40689
|
+
const rows = value.plugins.filter((row2) => plainObject(row2) && row2.name === plugin);
|
|
40690
|
+
if (rows.length !== 1)
|
|
40691
|
+
return false;
|
|
40692
|
+
const row = rows[0];
|
|
40693
|
+
if (!exactKeys2(row, ["name", "source"]) || !plainObject(row.source) || !exactKeys2(row.source, ["source", "path"]) || row.source.source !== "local" || typeof row.source.path !== "string" || !row.source.path.startsWith("./") || row.source.path.includes("\\"))
|
|
40694
|
+
return false;
|
|
40695
|
+
const parts = row.source.path.split("/");
|
|
40696
|
+
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;
|
|
40697
|
+
} catch {
|
|
40698
|
+
return false;
|
|
40699
|
+
}
|
|
40700
|
+
}
|
|
40683
40701
|
function defaultRead(path) {
|
|
40684
40702
|
const before = lstatSync10(path, { throwIfNoEntry: false, bigint: true });
|
|
40685
40703
|
if (before === undefined)
|
|
@@ -40741,7 +40759,7 @@ function validPluginParent(cacheRoot, pluginParent, namespace, pluginId) {
|
|
|
40741
40759
|
return parts.length === 2 && parts.every(identifier4) && parts[1] === namespace && pluginId === `${namespace}@${parts[0]}`;
|
|
40742
40760
|
}
|
|
40743
40761
|
function assertWitnessShape(value) {
|
|
40744
|
-
if (!plainObject(value) || !exactKeys2(value, ["schema", "cacheRoot", "controls", "appOnlyParents", "skills", "sha256"]) || value.schema !== CODEX_SEMANTIC_CACHE_WITNESS_SCHEMA || typeof value.cacheRoot !== "string" || !isAbsolute8(value.cacheRoot) || resolve8(value.cacheRoot) !== value.cacheRoot || !digest2(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)
|
|
40762
|
+
if (!plainObject(value) || !exactKeys2(value, ["schema", "cacheRoot", "controls", "appOnlyParents", "skills", "sha256"], ["hookParents"]) || value.schema !== CODEX_SEMANTIC_CACHE_WITNESS_SCHEMA || typeof value.cacheRoot !== "string" || !isAbsolute8(value.cacheRoot) || resolve8(value.cacheRoot) !== value.cacheRoot || !digest2(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)
|
|
40745
40763
|
refuse5();
|
|
40746
40764
|
const witness = value;
|
|
40747
40765
|
const controlParents = new Set;
|
|
@@ -40762,6 +40780,20 @@ function assertWitnessShape(value) {
|
|
|
40762
40780
|
refuse5();
|
|
40763
40781
|
appOnlyParentPaths.add(row.pluginParent);
|
|
40764
40782
|
}
|
|
40783
|
+
const hookParentPaths = new Set;
|
|
40784
|
+
const hookParents = witness.hookParents === undefined ? [] : witness.hookParents;
|
|
40785
|
+
if (!Array.isArray(hookParents) || hookParents.length > 4096)
|
|
40786
|
+
refuse5();
|
|
40787
|
+
for (const candidate of hookParents) {
|
|
40788
|
+
if (!plainObject(candidate))
|
|
40789
|
+
refuse5();
|
|
40790
|
+
const row = candidate;
|
|
40791
|
+
const remote = row.installation === "remote-receipt";
|
|
40792
|
+
const local = row.installation === "local-marketplace";
|
|
40793
|
+
if (!exactKeys2(row, ["role", "pluginId", "namespace", "pluginParent", "installation", "manifestSha256", "hooksSha256"], remote ? ["remotePluginId", "receiptSha256"] : local ? ["marketplaceSourcePath", "marketplaceSha256"] : []) || row.role !== "reviewed-hook" || !identifier4(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) || !digest2(row.receiptSha256)) || local && (typeof row.marketplaceSourcePath !== "string" || !isAbsolute8(row.marketplaceSourcePath) || resolve8(row.marketplaceSourcePath) !== row.marketplaceSourcePath || basename5(row.marketplaceSourcePath) !== "marketplace.json" || !digest2(row.marketplaceSha256)) || !remote && !local || !digest2(row.manifestSha256) || !digest2(row.hooksSha256) || hookParentPaths.has(row.pluginParent) || controlParents.has(row.pluginParent) || appOnlyParentPaths.has(row.pluginParent))
|
|
40794
|
+
refuse5();
|
|
40795
|
+
hookParentPaths.add(row.pluginParent);
|
|
40796
|
+
}
|
|
40765
40797
|
const skillNames = new Set;
|
|
40766
40798
|
const qualifiedNames = new Set;
|
|
40767
40799
|
for (const candidate of witness.skills) {
|
|
@@ -40781,6 +40813,7 @@ function assertWitnessShape(value) {
|
|
|
40781
40813
|
cacheRoot: witness.cacheRoot,
|
|
40782
40814
|
controls: witness.controls,
|
|
40783
40815
|
appOnlyParents: witness.appOnlyParents,
|
|
40816
|
+
...witness.hookParents === undefined ? {} : { hookParents: witness.hookParents },
|
|
40784
40817
|
skills: witness.skills
|
|
40785
40818
|
};
|
|
40786
40819
|
if (hash2(projection) !== witness.sha256)
|
|
@@ -40971,10 +41004,147 @@ function appOnlyParentProjection(cacheRoot, parents2, read) {
|
|
|
40971
41004
|
}
|
|
40972
41005
|
return rows.sort((a, b) => a.pluginId.localeCompare(b.pluginId) || a.pluginParent.localeCompare(b.pluginParent));
|
|
40973
41006
|
}
|
|
40974
|
-
|
|
41007
|
+
var codexHookEvents = new Set([
|
|
41008
|
+
"SessionStart",
|
|
41009
|
+
"UserPromptSubmit",
|
|
41010
|
+
"PreToolUse",
|
|
41011
|
+
"PostToolUse",
|
|
41012
|
+
"PostToolUseFailure",
|
|
41013
|
+
"Stop",
|
|
41014
|
+
"SubagentStart",
|
|
41015
|
+
"SubagentStop",
|
|
41016
|
+
"PreCompact",
|
|
41017
|
+
"Notification",
|
|
41018
|
+
"PermissionRequest",
|
|
41019
|
+
"SessionEnd",
|
|
41020
|
+
"ConfigChange",
|
|
41021
|
+
"WorktreeCreate",
|
|
41022
|
+
"WorktreeRemove",
|
|
41023
|
+
"TeammateIdle",
|
|
41024
|
+
"TaskComplete"
|
|
41025
|
+
]);
|
|
41026
|
+
function assertJsonValue(value, depth = 0, budget2 = { members: 0 }) {
|
|
41027
|
+
if (depth > 32 || ++budget2.members > 4096)
|
|
41028
|
+
refuse5();
|
|
41029
|
+
if (value === null || typeof value === "string" || typeof value === "boolean")
|
|
41030
|
+
return;
|
|
41031
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
41032
|
+
return;
|
|
41033
|
+
if (Array.isArray(value)) {
|
|
41034
|
+
for (const item of value)
|
|
41035
|
+
assertJsonValue(item, depth + 1, budget2);
|
|
41036
|
+
return;
|
|
41037
|
+
}
|
|
41038
|
+
if (!plainObject(value))
|
|
41039
|
+
refuse5();
|
|
41040
|
+
for (const [key, item] of Object.entries(value)) {
|
|
41041
|
+
if (!key || /[\x00-\x1f\x7f]/.test(key))
|
|
41042
|
+
refuse5();
|
|
41043
|
+
assertJsonValue(item, depth + 1, budget2);
|
|
41044
|
+
}
|
|
41045
|
+
}
|
|
41046
|
+
function reviewedHookControls(root, read) {
|
|
41047
|
+
const manifestPath = join15(root, ".codex-plugin/plugin.json"), hooksPath = join15(root, "hooks/hooks.json");
|
|
41048
|
+
let manifest, manifestSha256, hooks, hooksSha256;
|
|
41049
|
+
try {
|
|
41050
|
+
const manifestText = read(manifestPath);
|
|
41051
|
+
manifestSha256 = hashNativeJsonControls(manifestText, "version");
|
|
41052
|
+
manifest = JSON.parse(manifestText);
|
|
41053
|
+
const hooksText = read(hooksPath);
|
|
41054
|
+
hashNativeJsonControls(hooksText);
|
|
41055
|
+
hooksSha256 = createHash13("sha256").update(hooksText).digest("hex");
|
|
41056
|
+
hooks = JSON.parse(hooksText);
|
|
41057
|
+
} catch {
|
|
41058
|
+
return refuse5();
|
|
41059
|
+
}
|
|
41060
|
+
if (!plainObject(manifest) || !exactKeys2(manifest, ["name", "version", "hooks"], ["description"]) || !identifier4(manifest.name) || typeof manifest.version !== "string" || manifest.version !== basename5(root) || manifest.hooks !== "./hooks/hooks.json" || manifest.description !== undefined && (typeof manifest.description !== "string" || !manifest.description.trim() || manifest.description.length > 1024))
|
|
41061
|
+
refuse5();
|
|
41062
|
+
const manifestRecord = manifest;
|
|
41063
|
+
if (!plainObject(hooks) || !exactKeys2(hooks, ["hooks"]) || !plainObject(hooks.hooks))
|
|
41064
|
+
refuse5();
|
|
41065
|
+
const hookTable = hooks.hooks;
|
|
41066
|
+
const events = Object.entries(hookTable);
|
|
41067
|
+
if (!events.length || events.length > 32)
|
|
41068
|
+
refuse5();
|
|
41069
|
+
for (const [event, groups] of events) {
|
|
41070
|
+
if (!codexHookEvents.has(event) || !Array.isArray(groups) || !groups.length || groups.length > 32)
|
|
41071
|
+
refuse5();
|
|
41072
|
+
for (const group of groups) {
|
|
41073
|
+
if (!plainObject(group) || !exactKeys2(group, ["hooks"]) || !Array.isArray(group.hooks) || !group.hooks.length || group.hooks.length > 32)
|
|
41074
|
+
refuse5();
|
|
41075
|
+
const handlers = group.hooks;
|
|
41076
|
+
for (const handler of handlers) {
|
|
41077
|
+
if (!plainObject(handler) || !exactKeys2(handler, ["type", "server", "tool", "input"], ["timeout"]) || handler.type !== "mcp_tool" || !identifier4(handler.server) || !identifier4(handler.tool) || !plainObject(handler.input) || handler.timeout !== undefined && (!Number.isSafeInteger(handler.timeout) || Number(handler.timeout) < 1 || Number(handler.timeout) > 300))
|
|
41078
|
+
refuse5();
|
|
41079
|
+
assertJsonValue(handler.input);
|
|
41080
|
+
}
|
|
41081
|
+
}
|
|
41082
|
+
}
|
|
41083
|
+
return { namespace: manifestRecord.name, manifestSha256, hooksSha256 };
|
|
41084
|
+
}
|
|
41085
|
+
function reviewedHookParentProjection(cacheRoot, parents2, read) {
|
|
41086
|
+
if (!Array.isArray(parents2) || parents2.length > 4096)
|
|
41087
|
+
refuse5();
|
|
41088
|
+
const seen = new Set, rows = [];
|
|
41089
|
+
for (const parent of parents2) {
|
|
41090
|
+
const remote = parent?.installation === "remote-receipt", local = parent?.installation === "local-marketplace";
|
|
41091
|
+
if (!parent || !exactKeys2(parent, ["installation", "namespace", "pluginId", "pluginParent", "role"], remote ? ["remotePluginId"] : local ? ["marketplaceSourcePath", "marketplaceSha256"] : []) || parent.role !== "reviewed-hook" || !identifier4(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" || !isAbsolute8(parent.marketplaceSourcePath) || resolve8(parent.marketplaceSourcePath) !== parent.marketplaceSourcePath || basename5(parent.marketplaceSourcePath) !== "marketplace.json" || !digest2(parent.marketplaceSha256)) || !remote && !local)
|
|
41092
|
+
refuse5();
|
|
41093
|
+
const parts = relative6(cacheRoot, parent.pluginParent).split(sep5);
|
|
41094
|
+
if (!isAbsolute8(parent.pluginParent) || resolve8(parent.pluginParent) !== parent.pluginParent || parts.length !== 2 || parts.some((part) => !identifier4(part)) || parts[1] !== parent.namespace || parent.pluginId !== `${parent.namespace}@${parts[0]}` || seen.has(parent.pluginParent))
|
|
41095
|
+
refuse5();
|
|
41096
|
+
seen.add(parent.pluginParent);
|
|
41097
|
+
const parentStat = lstatSync10(parent.pluginParent, { throwIfNoEntry: false });
|
|
41098
|
+
if (!parentStat?.isDirectory() || parentStat.isSymbolicLink() || realpathSync9(parent.pluginParent) !== parent.pluginParent)
|
|
41099
|
+
refuse5();
|
|
41100
|
+
const receiptPath = join15(parent.pluginParent, ".codex-remote-plugin-install.json"), receiptStat = lstatSync10(receiptPath, { throwIfNoEntry: false });
|
|
41101
|
+
let receiptText;
|
|
41102
|
+
if (remote) {
|
|
41103
|
+
if (!receiptStat?.isFile() || receiptStat.isSymbolicLink() || receiptStat.size > MAX_RECEIPT_BYTES)
|
|
41104
|
+
refuse5();
|
|
41105
|
+
try {
|
|
41106
|
+
receiptText = read(receiptPath);
|
|
41107
|
+
hashNativeJsonControls(receiptText);
|
|
41108
|
+
const receipt = JSON.parse(receiptText);
|
|
41109
|
+
if (!plainObject(receipt) || !exactKeys2(receipt, ["schema_version", "remote_plugin_id"]) || receipt.schema_version !== 1 || receipt.remote_plugin_id !== parent.remotePluginId)
|
|
41110
|
+
refuse5();
|
|
41111
|
+
} catch {
|
|
41112
|
+
refuse5();
|
|
41113
|
+
}
|
|
41114
|
+
} else {
|
|
41115
|
+
const marketplaceSourcePath = parent.marketplaceSourcePath ?? refuse5();
|
|
41116
|
+
if (receiptStat !== undefined || !parent.marketplaceSha256)
|
|
41117
|
+
refuse5();
|
|
41118
|
+
let marketplaceText;
|
|
41119
|
+
try {
|
|
41120
|
+
marketplaceText = read(marketplaceSourcePath);
|
|
41121
|
+
} catch {
|
|
41122
|
+
return refuse5();
|
|
41123
|
+
}
|
|
41124
|
+
if (createHash13("sha256").update(marketplaceText).digest("hex") !== parent.marketplaceSha256 || !codexLocalMarketplaceMapsPlugin(marketplaceText, parts[0], parent.namespace))
|
|
41125
|
+
refuse5();
|
|
41126
|
+
}
|
|
41127
|
+
const materializations = readdirSync4(parent.pluginParent).filter((name) => name !== ".codex-remote-plugin-install.json").map((version2) => {
|
|
41128
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/.test(version2))
|
|
41129
|
+
refuse5();
|
|
41130
|
+
const root = join15(parent.pluginParent, version2), stat = lstatSync10(root, { throwIfNoEntry: false });
|
|
41131
|
+
if (!stat?.isDirectory() || stat.isSymbolicLink() || realpathSync9(root) !== root)
|
|
41132
|
+
refuse5();
|
|
41133
|
+
const controls = reviewedHookControls(root, read);
|
|
41134
|
+
if (controls.namespace !== parent.namespace)
|
|
41135
|
+
refuse5();
|
|
41136
|
+
return { manifestSha256: controls.manifestSha256, hooksSha256: controls.hooksSha256 };
|
|
41137
|
+
});
|
|
41138
|
+
if (!materializations.length || materializations.some((item) => canonical4(item) !== canonical4(materializations[0])))
|
|
41139
|
+
refuse5();
|
|
41140
|
+
rows.push({ ...parent, ...receiptText === undefined ? {} : { receiptSha256: createHash13("sha256").update(receiptText).digest("hex") }, ...materializations[0] });
|
|
41141
|
+
}
|
|
41142
|
+
return rows.sort((a, b) => a.pluginId.localeCompare(b.pluginId) || a.pluginParent.localeCompare(b.pluginParent));
|
|
41143
|
+
}
|
|
41144
|
+
function assertParents(cacheRoot, controls, appOnlyParents, hookParents, files, members) {
|
|
40975
41145
|
const expected = new Set;
|
|
40976
41146
|
const expectedMarkets = new Set;
|
|
40977
|
-
for (const control of [...controls, ...appOnlyParents]) {
|
|
41147
|
+
for (const control of [...controls, ...appOnlyParents, ...hookParents]) {
|
|
40978
41148
|
const rel = relative6(cacheRoot, control.pluginParent), parts = rel.split(sep5);
|
|
40979
41149
|
if (resolve8(control.pluginParent) !== control.pluginParent || parts.length !== 2 || parts.some((part) => !identifier4(part)) || control.pluginId !== `${control.namespace}@${parts[0]}` || parts[1] !== control.namespace)
|
|
40980
41150
|
refuse5();
|
|
@@ -41015,7 +41185,9 @@ function assertParents(cacheRoot, controls, appOnlyParents, files, members) {
|
|
|
41015
41185
|
refuse5();
|
|
41016
41186
|
if ([".app.json", ".mcp.json"].includes(base) && (parts.length !== 4 || dirname9(member) !== root))
|
|
41017
41187
|
refuse5();
|
|
41018
|
-
if (
|
|
41188
|
+
if ([".app.json", ".mcp.json"].includes(base) && hookParents.some((reviewed) => reviewed.pluginParent === parent))
|
|
41189
|
+
refuse5();
|
|
41190
|
+
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 === join15(cacheRoot, parts[0], parts[1]))))
|
|
41019
41191
|
refuse5();
|
|
41020
41192
|
}
|
|
41021
41193
|
}
|
|
@@ -41125,13 +41297,14 @@ function captureCodexSemanticCacheWitness(options) {
|
|
|
41125
41297
|
const initialTree = treeSnapshot(options.cacheRoot);
|
|
41126
41298
|
const controls = controlProjection(options.controls, read);
|
|
41127
41299
|
const appOnlyParents = appOnlyParentProjection(options.cacheRoot, options.appOnlyParents ?? [], read);
|
|
41300
|
+
const hookParents = reviewedHookParentProjection(options.cacheRoot, options.reviewedHookParents ?? [], read);
|
|
41128
41301
|
const skillParents = new Set(controls.map((control) => control.pluginParent));
|
|
41129
|
-
if (appOnlyParents.some((parent) => skillParents.has(parent.pluginParent)))
|
|
41302
|
+
if (appOnlyParents.some((parent) => skillParents.has(parent.pluginParent)) || hookParents.some((parent) => skillParents.has(parent.pluginParent) || appOnlyParents.some((app) => app.pluginParent === parent.pluginParent)))
|
|
41130
41303
|
refuse5();
|
|
41131
41304
|
if (!reviewedCodexPluginCapabilitiesUnchanged(options.cacheRoot, options.controls, read, options.rules))
|
|
41132
41305
|
refuse5();
|
|
41133
41306
|
const files = initialTree.files;
|
|
41134
|
-
assertParents(options.cacheRoot, controls, appOnlyParents, files, initialTree.state.members);
|
|
41307
|
+
assertParents(options.cacheRoot, controls, appOnlyParents, hookParents, files, initialTree.state.members);
|
|
41135
41308
|
const expectedNamesByRoot = assertSkillMaterializations(options.cacheRoot, options.controls, files, read);
|
|
41136
41309
|
const docs = files.filter((path) => path.endsWith(`${sep5}SKILL.md`));
|
|
41137
41310
|
const skillRows = [];
|
|
@@ -41140,6 +41313,8 @@ function captureCodexSemanticCacheWitness(options) {
|
|
|
41140
41313
|
const rel = relative6(options.cacheRoot, document).split(sep5);
|
|
41141
41314
|
if (appOnlyParents.some((parent) => parent.pluginParent === join15(options.cacheRoot, rel[0], rel[1])))
|
|
41142
41315
|
refuse5();
|
|
41316
|
+
if (hookParents.some((parent) => parent.pluginParent === join15(options.cacheRoot, rel[0], rel[1])))
|
|
41317
|
+
refuse5();
|
|
41143
41318
|
const documentStat = lstatSync10(document, { throwIfNoEntry: false });
|
|
41144
41319
|
if (!documentStat?.isFile() || documentStat.isSymbolicLink() || documentStat.size > MAX_DOCUMENT_BYTES)
|
|
41145
41320
|
refuse5();
|
|
@@ -41203,7 +41378,7 @@ function captureCodexSemanticCacheWitness(options) {
|
|
|
41203
41378
|
tracked.verify();
|
|
41204
41379
|
const finalTree = treeSnapshot(options.cacheRoot);
|
|
41205
41380
|
assertSameTree(initialTree.state, finalTree.state, tracked.paths());
|
|
41206
|
-
const completeProjection = { schema: CODEX_SEMANTIC_CACHE_WITNESS_SCHEMA, cacheRoot: options.cacheRoot, controls, appOnlyParents, skills: uniqueSkills };
|
|
41381
|
+
const completeProjection = { schema: CODEX_SEMANTIC_CACHE_WITNESS_SCHEMA, cacheRoot: options.cacheRoot, controls, appOnlyParents, hookParents, skills: uniqueSkills };
|
|
41207
41382
|
return { ...completeProjection, sha256: hash2(completeProjection) };
|
|
41208
41383
|
} catch (error) {
|
|
41209
41384
|
if (error instanceof Error && error.message.startsWith("CODEX_SEMANTIC_CACHE_WITNESS_UNSUPPORTED"))
|
|
@@ -41219,6 +41394,7 @@ function assertCodexSemanticCacheWitnessUnchanged(previous, current) {
|
|
|
41219
41394
|
cacheRoot: previous.cacheRoot,
|
|
41220
41395
|
controls: previous.controls,
|
|
41221
41396
|
appOnlyParents: previous.appOnlyParents,
|
|
41397
|
+
...previous.hookParents === undefined ? {} : { hookParents: previous.hookParents },
|
|
41222
41398
|
skills: previous.skills
|
|
41223
41399
|
};
|
|
41224
41400
|
const currentProjection = {
|
|
@@ -41226,9 +41402,11 @@ function assertCodexSemanticCacheWitnessUnchanged(previous, current) {
|
|
|
41226
41402
|
cacheRoot: current.cacheRoot,
|
|
41227
41403
|
controls: current.controls,
|
|
41228
41404
|
appOnlyParents: current.appOnlyParents,
|
|
41405
|
+
...current.hookParents === undefined ? {} : { hookParents: current.hookParents },
|
|
41229
41406
|
skills: current.skills
|
|
41230
41407
|
};
|
|
41231
|
-
|
|
41408
|
+
const comparable = (projection) => ({ ...projection, hookParents: projection.hookParents ?? [] });
|
|
41409
|
+
if (hash2(priorProjection) !== previous.sha256 || hash2(currentProjection) !== current.sha256 || canonical4(comparable(priorProjection)) !== canonical4(comparable(currentProjection)))
|
|
41232
41410
|
refuse5();
|
|
41233
41411
|
}
|
|
41234
41412
|
|
|
@@ -41257,7 +41435,7 @@ var NATIVE_SKILL_ROOTS = [
|
|
|
41257
41435
|
import { createHash as createHash28, randomUUID as randomUUID4 } from "crypto";
|
|
41258
41436
|
import { isDeepStrictEqual as isDeepStrictEqual8 } from "util";
|
|
41259
41437
|
import { existsSync as existsSync7, lstatSync as lstatSync26, statSync as statSync8, mkdirSync as mkdirSync7, readFileSync as readFileSync18, readdirSync as readdirSync9, opendirSync as opendirSync5, readlinkSync as readlinkSync7, realpathSync as realpathSync13, renameSync as renameSync4, rmdirSync as rmdirSync3, writeFileSync as writeFileSync5, unlinkSync as unlinkSync5, chmodSync, openSync as openSync21, closeSync as closeSync21, fsyncSync as fsyncSync7, fstatSync as fstatSync21, readSync as readSync14, constants as constants19, linkSync as linkSync3 } from "fs";
|
|
41260
|
-
import { dirname as dirname21, join as join30, resolve as resolve23, relative as relative8, isAbsolute as isAbsolute25, sep as sep10 } from "path";
|
|
41438
|
+
import { basename as basename11, dirname as dirname21, join as join30, resolve as resolve23, relative as relative8, isAbsolute as isAbsolute25, sep as sep10 } from "path";
|
|
41261
41439
|
import { homedir as homedir3 } from "os";
|
|
41262
41440
|
|
|
41263
41441
|
// src/lib/managed-policy.ts
|
|
@@ -41265,11 +41443,11 @@ import { closeSync as closeSync13, constants as constants10, fstatSync as fstatS
|
|
|
41265
41443
|
import { join as join17 } from "path";
|
|
41266
41444
|
|
|
41267
41445
|
// src/lib/agent-policy-limits.ts
|
|
41268
|
-
import { basename as
|
|
41446
|
+
import { basename as basename7, isAbsolute as isAbsolute10, join as join16, resolve as resolve10, sep as sep6 } from "path";
|
|
41269
41447
|
|
|
41270
41448
|
// src/lib/claude-marketplace-entry-witness.ts
|
|
41271
41449
|
import { createHash as createHash14 } from "crypto";
|
|
41272
|
-
import { basename as
|
|
41450
|
+
import { basename as basename6, dirname as dirname10, isAbsolute as isAbsolute9, resolve as resolve9 } from "path";
|
|
41273
41451
|
var CLAUDE_MARKETPLACE_ENTRY_HASH_MODE = "claude-marketplace-entry-v1";
|
|
41274
41452
|
var DOMAIN = "hasna.skills.claude-marketplace-entry.v1\x00";
|
|
41275
41453
|
var PATH_CHARACTERS = 4096;
|
|
@@ -41334,7 +41512,7 @@ var stringArray = (value) => value?.kind === "array" && value.items.every(isStri
|
|
|
41334
41512
|
var stringObject = (value) => value?.kind === "object" && value.entries.every(([, item]) => isString(item));
|
|
41335
41513
|
function claudeMarketplaceEntrySourceValid(source) {
|
|
41336
41514
|
const path = source?.path;
|
|
41337
|
-
return typeof path === "string" && path.length > 0 && path.length <= PATH_CHARACTERS && !/[\x00-\x1f\x7f]/.test(path) && isAbsolute9(path) && resolve9(path) === path &&
|
|
41515
|
+
return typeof path === "string" && path.length > 0 && path.length <= PATH_CHARACTERS && !/[\x00-\x1f\x7f]/.test(path) && isAbsolute9(path) && resolve9(path) === path && basename6(path) === "marketplace.json" && basename6(dirname10(path)) === ".claude-plugin" && typeof source.marketplace === "string" && NAME.test(source.marketplace) && !source.marketplace.includes("..") && typeof source.plugin === "string" && NAME.test(source.plugin);
|
|
41338
41516
|
}
|
|
41339
41517
|
function canonical5(value) {
|
|
41340
41518
|
if (value.kind === "string")
|
|
@@ -41604,10 +41782,10 @@ function assertAgentPolicyCollections(policy) {
|
|
|
41604
41782
|
}
|
|
41605
41783
|
}
|
|
41606
41784
|
if (value.codexSemanticCache !== undefined) {
|
|
41607
|
-
const proof = record3(value.codexSemanticCache,
|
|
41608
|
-
requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && Object.keys(proof).length
|
|
41785
|
+
const proof = record3(value.codexSemanticCache, 9), witness = record3(proof.witness, 7);
|
|
41786
|
+
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));
|
|
41609
41787
|
text(proof.configPath);
|
|
41610
|
-
requireBound(isAbsolute10(proof.configPath) && resolve10(proof.configPath) === proof.configPath &&
|
|
41788
|
+
requireBound(isAbsolute10(proof.configPath) && resolve10(proof.configPath) === proof.configPath && basename7(proof.configPath) === "config.toml");
|
|
41611
41789
|
text(witness.cacheRoot);
|
|
41612
41790
|
requireBound(isAbsolute10(witness.cacheRoot) && resolve10(witness.cacheRoot) === witness.cacheRoot);
|
|
41613
41791
|
if (proof.hookRootAlias !== null) {
|
|
@@ -41624,6 +41802,20 @@ function assertAgentPolicyCollections(policy) {
|
|
|
41624
41802
|
text(parent[key]);
|
|
41625
41803
|
requireBound(isAbsolute10(parent.pluginParent) && resolve10(parent.pluginParent) === parent.pluginParent);
|
|
41626
41804
|
}
|
|
41805
|
+
if (proof.reviewedHookParents !== undefined)
|
|
41806
|
+
for (const parent of array(proof.reviewedHookParents, 4096)) {
|
|
41807
|
+
requireBound(object4(parent) && parent.role === "reviewed-hook" && (parent.installation === "remote-receipt" && Object.keys(parent).length === 6 || parent.installation === "local-marketplace" && Object.keys(parent).length === 7));
|
|
41808
|
+
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");
|
|
41809
|
+
for (const key of ["pluginId", "namespace", "pluginParent", "installation"])
|
|
41810
|
+
text(parent[key]);
|
|
41811
|
+
if (parent.installation === "remote-receipt")
|
|
41812
|
+
text(parent.remotePluginId);
|
|
41813
|
+
else {
|
|
41814
|
+
text(parent.marketplaceSourcePath);
|
|
41815
|
+
requireBound(typeof parent.marketplaceSha256 === "string" && /^[a-f0-9]{64}$/.test(parent.marketplaceSha256) && isAbsolute10(parent.marketplaceSourcePath) && resolve10(parent.marketplaceSourcePath) === parent.marketplaceSourcePath && basename7(parent.marketplaceSourcePath) === "marketplace.json");
|
|
41816
|
+
}
|
|
41817
|
+
requireBound(isAbsolute10(parent.pluginParent) && resolve10(parent.pluginParent) === parent.pluginParent);
|
|
41818
|
+
}
|
|
41627
41819
|
for (const row of [...array(witness.controls, 4096), ...array(witness.appOnlyParents, 4096)]) {
|
|
41628
41820
|
requireBound(object4(row));
|
|
41629
41821
|
for (const key of ["pluginId", "namespace", "pluginParent"])
|
|
@@ -41632,6 +41824,26 @@ function assertAgentPolicyCollections(policy) {
|
|
|
41632
41824
|
if (row[key] !== undefined)
|
|
41633
41825
|
requireBound(typeof row[key] === "string" && /^[a-f0-9]{64}$/.test(row[key]));
|
|
41634
41826
|
}
|
|
41827
|
+
if (witness.hookParents !== undefined)
|
|
41828
|
+
for (const row of array(witness.hookParents, 4096)) {
|
|
41829
|
+
requireBound(object4(row) && row.role === "reviewed-hook" && (row.installation === "remote-receipt" && Object.keys(row).length === 9 || row.installation === "local-marketplace" && Object.keys(row).length === 9));
|
|
41830
|
+
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");
|
|
41831
|
+
for (const key of ["pluginId", "namespace", "pluginParent", "installation"])
|
|
41832
|
+
text(row[key]);
|
|
41833
|
+
if (row.installation === "remote-receipt")
|
|
41834
|
+
text(row.remotePluginId);
|
|
41835
|
+
else {
|
|
41836
|
+
text(row.marketplaceSourcePath);
|
|
41837
|
+
requireBound(typeof row.marketplaceSha256 === "string" && /^[a-f0-9]{64}$/.test(row.marketplaceSha256) && isAbsolute10(row.marketplaceSourcePath) && resolve10(row.marketplaceSourcePath) === row.marketplaceSourcePath && basename7(row.marketplaceSourcePath) === "marketplace.json");
|
|
41838
|
+
}
|
|
41839
|
+
requireBound(isAbsolute10(row.pluginParent) && resolve10(row.pluginParent) === row.pluginParent);
|
|
41840
|
+
for (const key of ["manifestSha256", "hooksSha256"])
|
|
41841
|
+
requireBound(typeof row[key] === "string" && /^[a-f0-9]{64}$/.test(row[key]));
|
|
41842
|
+
if (row.installation === "remote-receipt")
|
|
41843
|
+
requireBound(typeof row.receiptSha256 === "string" && /^[a-f0-9]{64}$/.test(row.receiptSha256));
|
|
41844
|
+
else
|
|
41845
|
+
requireBound(row.receiptSha256 === undefined);
|
|
41846
|
+
}
|
|
41635
41847
|
for (const skill of array(witness.skills, 4096)) {
|
|
41636
41848
|
requireBound(object4(skill));
|
|
41637
41849
|
for (const key of ["name", "pluginId", "namespace", "pluginParent"])
|
|
@@ -41661,13 +41873,13 @@ function assertAgentPolicyCollections(policy) {
|
|
|
41661
41873
|
if (source.hashMode === "claude-plugin-manifest-v1")
|
|
41662
41874
|
requireBound(agent === "claude" && value.agent === "claude" && ["automatic", "reviewed"].includes(value.method) && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute10(source.path) && resolve10(source.path) === source.path && source.path.endsWith(join16(sep6, ".claude-plugin", "plugin.json")) && source.managedPlugins === undefined);
|
|
41663
41875
|
if (source.hashMode === "sumi-settings-v1")
|
|
41664
|
-
requireBound(agent === "sumi" && value.agent === "sumi" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute10(source.path) && resolve10(source.path) === source.path &&
|
|
41876
|
+
requireBound(agent === "sumi" && value.agent === "sumi" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute10(source.path) && resolve10(source.path) === source.path && basename7(source.path) === "sumi.json");
|
|
41665
41877
|
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"))
|
|
41666
|
-
requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute10(source.path) && resolve10(source.path) === source.path &&
|
|
41878
|
+
requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute10(source.path) && resolve10(source.path) === source.path && basename7(source.path) === "config.toml");
|
|
41667
41879
|
if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || source.hashMode === "claude-settings-v4"))
|
|
41668
|
-
requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute10(source.path) && resolve10(source.path) === source.path &&
|
|
41880
|
+
requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute10(source.path) && resolve10(source.path) === source.path && basename7(source.path) === "settings.json");
|
|
41669
41881
|
if (source.hashMode === "claude-marketplace-registry" || source.hashMode === "claude-marketplace-registry-v2")
|
|
41670
|
-
requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute10(source.path) && resolve10(source.path) === source.path &&
|
|
41882
|
+
requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute10(source.path) && resolve10(source.path) === source.path && basename7(source.path) === "known_marketplaces.json");
|
|
41671
41883
|
if (source.hashMode === "claude-marketplace-entry-v1")
|
|
41672
41884
|
requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && claudeMarketplaceEntrySourceValid(source));
|
|
41673
41885
|
if (source.hashMode === "claude-plugin-registry") {
|
|
@@ -41832,7 +42044,7 @@ function isOwnedCliBridge(path, expectedPaths) {
|
|
|
41832
42044
|
// src/lib/agent-discovery.ts
|
|
41833
42045
|
import { createHash as createHash26 } from "crypto";
|
|
41834
42046
|
import { lstatSync as lstatSync24, readFileSync as readFileSync16, readdirSync as readdirSync8, realpathSync as realpathSync11 } from "fs";
|
|
41835
|
-
import { basename as
|
|
42047
|
+
import { basename as basename10, dirname as dirname20, isAbsolute as isAbsolute23, join as join29, relative as relative7, resolve as resolve22, sep as sep9 } from "path";
|
|
41836
42048
|
import { isDeepStrictEqual as isDeepStrictEqual6 } from "util";
|
|
41837
42049
|
|
|
41838
42050
|
// node_modules/yaml/dist/index.js
|
|
@@ -42523,7 +42735,7 @@ function projectReviewedClaudePluginManifest(text2, reviewedSha256) {
|
|
|
42523
42735
|
|
|
42524
42736
|
// src/lib/plugin-discovery.ts
|
|
42525
42737
|
import { closeSync as closeSync16, constants as constants13, fstatSync as fstatSync16, lstatSync as lstatSync19, openSync as openSync16, opendirSync as opendirSync4, readSync as readSync10 } from "fs";
|
|
42526
|
-
import { basename as
|
|
42738
|
+
import { basename as basename8, dirname as dirname16, isAbsolute as isAbsolute18, join as join26, resolve as resolve17 } from "path";
|
|
42527
42739
|
|
|
42528
42740
|
// src/lib/plugin-admission.ts
|
|
42529
42741
|
import { homedir as homedir2 } from "os";
|
|
@@ -44004,7 +44216,7 @@ function hashManagedPluginRegistry(path, managed) {
|
|
|
44004
44216
|
pluginNeed(/^(?:[A-Za-z0-9][A-Za-z0-9._+-]*-)?[a-f0-9]{12}$/.test(row.version) && row.installPath === join26(cacheRoot, row.version), "Managed plugin cache path or version is outside its registration");
|
|
44005
44217
|
const approval = (producer) => {
|
|
44006
44218
|
pluginText(producer);
|
|
44007
|
-
const digest3 = `sha256:${
|
|
44219
|
+
const digest3 = `sha256:${basename8(producer)}`;
|
|
44008
44220
|
const receipt2 = readPluginAdmissionReceipt(witness.storeRoot, witness.bindingId, digest3);
|
|
44009
44221
|
pluginNeed(receipt2.materializedPath === producer, "Managed producer path is not an approved immutable projection");
|
|
44010
44222
|
if (!verified.has(producer)) {
|
|
@@ -44068,7 +44280,7 @@ function captureManagedPluginRegistry(path, managedPlugins) {
|
|
|
44068
44280
|
// src/lib/claude-marketplace-registry.ts
|
|
44069
44281
|
import { createHash as createHash22 } from "crypto";
|
|
44070
44282
|
import { closeSync as closeSync17, constants as constants14, fstatSync as fstatSync17, lstatSync as lstatSync20, openSync as openSync17, readSync as readSync11 } from "fs";
|
|
44071
|
-
import { basename as
|
|
44283
|
+
import { basename as basename9, dirname as dirname17, isAbsolute as isAbsolute19, resolve as resolve18 } from "path";
|
|
44072
44284
|
var CLAUDE_MARKETPLACE_REGISTRY_LIMITS = Object.freeze({ bytes: 1024 * 1024, rows: 1024, depth: 32, nodes: 65536, stringCharacters: 16384, pathCharacters: 4096 });
|
|
44073
44285
|
function need6(value, reason2) {
|
|
44074
44286
|
if (!value)
|
|
@@ -44090,7 +44302,7 @@ function parents2(path) {
|
|
|
44090
44302
|
}
|
|
44091
44303
|
function readRegistry2(path, budget2) {
|
|
44092
44304
|
absolutePath3(path);
|
|
44093
|
-
need6(
|
|
44305
|
+
need6(basename9(path) === "known_marketplaces.json", "requires known_marketplaces.json");
|
|
44094
44306
|
need6(Number.isSafeInteger(budget2.remaining) && budget2.remaining >= 0, "has an invalid byte budget");
|
|
44095
44307
|
const ancestors2 = parents2(path), initial = lstatSync20(path, { bigint: true });
|
|
44096
44308
|
need6(initial.isFile() && !initial.isSymbolicLink() && initial.size <= BigInt(CLAUDE_MARKETPLACE_REGISTRY_LIMITS.bytes), "is not a bounded regular file");
|
|
@@ -44914,7 +45126,7 @@ function assertReviewedClaudeCacheClosures(home, config, review, canonical9) {
|
|
|
44914
45126
|
throw new Error("Reviewed Claude enabled plugin registration requires an object with an installPath string");
|
|
44915
45127
|
}
|
|
44916
45128
|
if ([cacheAliasRoot, cacheRoot].some((root2) => row.installPath === root2 || row.installPath.startsWith(root2 + sep9))) {
|
|
44917
|
-
if (!cachePath(row.installPath) || row.installPath.length > AGENT_POLICY_LIMITS.pathCharacters || row.version !== undefined && (typeof row.version !== "string" ||
|
|
45129
|
+
if (!cachePath(row.installPath) || row.installPath.length > AGENT_POLICY_LIMITS.pathCharacters || row.version !== undefined && (typeof row.version !== "string" || basename10(row.installPath) !== row.version)) {
|
|
44918
45130
|
throw new Error("Reviewed Claude discovery has a malformed active cache registration");
|
|
44919
45131
|
}
|
|
44920
45132
|
if (row.scope === "user" && (row.projectPath === undefined || row.projectPath === null)) {} else if (row.scope === "project" && typeof row.projectPath === "string" && isAbsolute23(row.projectPath) && resolve22(row.projectPath) === row.projectPath && row.projectPath.length <= AGENT_POLICY_LIMITS.pathCharacters) {} else
|
|
@@ -45192,7 +45404,7 @@ function absentRetiredClaudeRoots(binding) {
|
|
|
45192
45404
|
if (!targetValid || !targetScopes.has("user\x00"))
|
|
45193
45405
|
continue;
|
|
45194
45406
|
const active = rows[0]?.installPath;
|
|
45195
|
-
if (typeof active !== "string" || rows[0]?.version !==
|
|
45407
|
+
if (typeof active !== "string" || rows[0]?.version !== basename10(active) || dirname20(active) !== dirname20(root2) || active === root2 || !lstatSync24(active, { throwIfNoEntry: false })?.isDirectory() || realpathSync11(active) !== active)
|
|
45196
45408
|
continue;
|
|
45197
45409
|
const activeManifest = full(join29(active, ".claude-plugin/plugin.json"));
|
|
45198
45410
|
if (!activeManifest || projected(activeManifest) !== activeManifest.sha256)
|
|
@@ -45201,14 +45413,15 @@ function absentRetiredClaudeRoots(binding) {
|
|
|
45201
45413
|
}
|
|
45202
45414
|
return [...result];
|
|
45203
45415
|
}
|
|
45204
|
-
function codexSemanticCacheSourceRole(source, cacheRoot, parents3) {
|
|
45416
|
+
function codexSemanticCacheSourceRole(source, cacheRoot, parents3, hookParents = []) {
|
|
45205
45417
|
if (!isAbsolute23(source.path) || resolve22(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")
|
|
45206
45418
|
return false;
|
|
45207
45419
|
const parts = relative7(cacheRoot, source.path).split(sep9);
|
|
45208
45420
|
if (parts.length < 3 || !parents3.includes(join29(cacheRoot, parts[0], parts[1])))
|
|
45209
45421
|
return false;
|
|
45210
45422
|
const tail = parts.slice(3).join("/");
|
|
45211
|
-
|
|
45423
|
+
const parent = join29(cacheRoot, parts[0], parts[1]);
|
|
45424
|
+
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");
|
|
45212
45425
|
}
|
|
45213
45426
|
function codexSemanticCacheDirectoryRole(path, cacheRoot) {
|
|
45214
45427
|
return isAbsolute23(path) && resolve22(path) === path && !/[\x00-\x1f\x7f]/.test(path) && (path === cacheRoot || path.startsWith(cacheRoot + sep9));
|
|
@@ -45240,20 +45453,28 @@ function verifyCodexSemanticCacheDiscovery(binding, reviewedRootAliases) {
|
|
|
45240
45453
|
const cacheRoot = proof.witness.cacheRoot;
|
|
45241
45454
|
if (controls.some((control) => dirname20(dirname20(control.pluginParent)) !== cacheRoot))
|
|
45242
45455
|
throw new Error("Codex semantic cache names another enrolled cache");
|
|
45243
|
-
const
|
|
45244
|
-
|
|
45456
|
+
const reviewedHookParents = proof.reviewedHookParents ?? [];
|
|
45457
|
+
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 || !isDeepStrictEqual6((proof.witness.hookParents ?? []).map(({ manifestSha256: _manifest, hooksSha256: _hooks, receiptSha256: _receipt, ...parent }) => parent), reviewedHookParents)) {
|
|
45458
|
+
throw new Error("Invalid reviewed native-hook cache role");
|
|
45459
|
+
}
|
|
45460
|
+
for (const parent of reviewedHookParents)
|
|
45461
|
+
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")))
|
|
45462
|
+
throw new Error("Local marketplace hook parent lost its enrolled source witness");
|
|
45463
|
+
const parents3 = [...new Set([...controls.map((control) => control.pluginParent), ...proof.appOnlyParents.map((parent) => parent.pluginParent), ...reviewedHookParents.map((parent) => parent.pluginParent)])];
|
|
45464
|
+
const hookParentPaths = reviewedHookParents.map((parent) => parent.pluginParent);
|
|
45465
|
+
const sources = binding.sources.filter((source) => codexSemanticCacheSourceRole(source, cacheRoot, parents3, hookParentPaths));
|
|
45245
45466
|
const directories = (binding.directories ?? []).filter((directory) => codexSemanticCacheDirectoryRole(directory.path, cacheRoot));
|
|
45246
45467
|
if (!directories.length || !isDeepStrictEqual6(sources, proof.supersededSources) || !isDeepStrictEqual6(directories, proof.supersededDirectories))
|
|
45247
45468
|
throw new Error("Codex semantic cache provenance changed");
|
|
45248
45469
|
const configPath = proof.configPath;
|
|
45249
|
-
if (!isAbsolute23(configPath) || resolve22(configPath) !== configPath ||
|
|
45470
|
+
if (!isAbsolute23(configPath) || resolve22(configPath) !== configPath || basename10(configPath) !== "config.toml" || /[\x00-\x1f\x7f]/.test(configPath))
|
|
45250
45471
|
throw new Error("Invalid semantic cache configuration source");
|
|
45251
45472
|
const configSource = binding.sources.find((source) => source.path === configPath && source.sha256 !== null && source.format === undefined && source.fields === undefined);
|
|
45252
45473
|
if (!configSource || projected(configSource) !== configSource.sha256)
|
|
45253
45474
|
throw new Error("Codex semantic cache requires unchanged reviewed configuration");
|
|
45254
45475
|
assertCodexSemanticCacheHookSafety(cacheRoot, parents3, configPath, proof.hookRootAlias);
|
|
45255
45476
|
const rules = parseConfig(read2(configPath), configPath, true).skills?.config ?? [];
|
|
45256
|
-
const current = captureCodexSemanticCacheWitness({ cacheRoot, controls, appOnlyParents: proof.appOnlyParents, rules });
|
|
45477
|
+
const current = captureCodexSemanticCacheWitness({ cacheRoot, controls, appOnlyParents: proof.appOnlyParents, reviewedHookParents, rules });
|
|
45257
45478
|
assertCodexSemanticCacheWitnessUnchanged(proof.witness, current);
|
|
45258
45479
|
return proof;
|
|
45259
45480
|
}
|
|
@@ -45337,7 +45558,7 @@ function codexInstallationRoots(binding) {
|
|
|
45337
45558
|
const config = join29(dirname20(dirname20(cache)), "config.toml"), home = dirname20(dirname20(dirname20(cache)));
|
|
45338
45559
|
const configSource = binding.sources.find((source) => source.path === config && source.sha256 !== null && (!source.format || source.format === "toml" && source.fields?.includes("plugins")));
|
|
45339
45560
|
const nativeRoots = NATIVE_SKILL_ROOTS.filter(([agent]) => agent === "codex").map(([, path]) => join29(home, path));
|
|
45340
|
-
if (!configSource || proof.plugins.some((input) => nativeRoots.some((root2) => root2 === input.sourceRoot || root2.startsWith(input.sourceRoot + sep9) || input.sourceRoot.startsWith(root2 + sep9)) || binding.sources.some((source) =>
|
|
45561
|
+
if (!configSource || proof.plugins.some((input) => nativeRoots.some((root2) => root2 === input.sourceRoot || root2.startsWith(input.sourceRoot + sep9) || input.sourceRoot.startsWith(root2 + sep9)) || binding.sources.some((source) => basename10(source.path) === "config.toml" && (source.path === input.sourceRoot || source.path.startsWith(input.sourceRoot + sep9)))))
|
|
45341
45562
|
throw new Error("Native installation input overlaps configuration or loading roots");
|
|
45342
45563
|
if (proof.plugins.some((input) => dirname20(dirname20(input.pluginParent)) !== cache || !binding.sources.some((source) => source.path === join29(input.sourceRoot, ".codex-plugin/plugin.json") && source.sha256 !== null && source.format === undefined && source.fields === undefined)))
|
|
45343
45564
|
throw new Error("Missing native installation input source witness");
|
|
@@ -45349,13 +45570,13 @@ function codexInstallationRoots(binding) {
|
|
|
45349
45570
|
});
|
|
45350
45571
|
}
|
|
45351
45572
|
function assertMarketplaceBinding(binding, source) {
|
|
45352
|
-
if (source.hashMode === "claude-plugin-manifest-v1" && (binding.agent !== "claude" ||
|
|
45573
|
+
if (source.hashMode === "claude-plugin-manifest-v1" && (binding.agent !== "claude" || basename10(source.path) !== "plugin.json" || !source.path.endsWith(join29(sep9, ".claude-plugin", "plugin.json"))))
|
|
45353
45574
|
throw new Error("Claude plugin manifest witnesses require Claude plugin discovery");
|
|
45354
|
-
if (source.hashMode === "sumi-settings-v1" && (binding.agent !== "sumi" || binding.method !== "reviewed" ||
|
|
45575
|
+
if (source.hashMode === "sumi-settings-v1" && (binding.agent !== "sumi" || binding.method !== "reviewed" || basename10(source.path) !== "sumi.json"))
|
|
45355
45576
|
throw new Error("Sumi settings witnesses require explicit reviewed Sumi configuration");
|
|
45356
|
-
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" ||
|
|
45577
|
+
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"))
|
|
45357
45578
|
throw new Error("Codex settings witnesses require explicit reviewed Codex configuration");
|
|
45358
|
-
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" ||
|
|
45579
|
+
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"))
|
|
45359
45580
|
throw new Error("Claude settings witnesses require explicit reviewed Claude configuration");
|
|
45360
45581
|
if ((source.hashMode === "claude-marketplace-registry" || source.hashMode === "claude-marketplace-registry-v2") && (binding.agent !== "claude" || binding.method !== "reviewed"))
|
|
45361
45582
|
throw new Error("Claude marketplace witnesses require explicit reviewed Claude discovery");
|
|
@@ -45473,7 +45694,7 @@ function verifyAutomaticDiscoveryClosure(binding, options) {
|
|
|
45473
45694
|
const current = resolveAgentDiscovery({ home: options.home, agent: binding.agent, canonical: options.canonical, executable: runtime });
|
|
45474
45695
|
if (JSON.stringify(current) === JSON.stringify(binding))
|
|
45475
45696
|
return;
|
|
45476
|
-
const reviewedWithRuntime = (binding.builtinNames?.length ?? 0) > 0 || binding.sources.some((source) =>
|
|
45697
|
+
const reviewedWithRuntime = (binding.builtinNames?.length ?? 0) > 0 || binding.sources.some((source) => basename10(source.path) === "package.json");
|
|
45477
45698
|
const otherwiseCurrent = current.method === binding.method && JSON.stringify(current.roots) === JSON.stringify(binding.roots) && JSON.stringify(current.directories) === JSON.stringify(binding.directories) && current.sources.every((source) => binding.sources.some((saved) => isDeepStrictEqual6(saved, source)));
|
|
45478
45699
|
if (command && gap && runtime === null && reviewedWithRuntime && otherwiseCurrent)
|
|
45479
45700
|
throw discoveryRootUnresolved(binding.agent, command, gap);
|
|
@@ -45616,7 +45837,7 @@ function resolveAgentDiscovery(options) {
|
|
|
45616
45837
|
throw new Error("Discovery review must include the agent configuration source");
|
|
45617
45838
|
const reviewedSources = supersedesSettingsProjection(agent, review.sources, canonical9(configPath)) ? sources.filter((source) => !isSupersededSettingsProjection(agent, canonical9(configPath), source)) : sources;
|
|
45618
45839
|
const reviewedSourcesWithManifestProjection = review.sources.map((source) => {
|
|
45619
|
-
if (agent !== "claude" || source.sha256 === null || source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || source.hashMode !== undefined && source.hashMode !== "bytes" ||
|
|
45840
|
+
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")))
|
|
45620
45841
|
return source;
|
|
45621
45842
|
const pluginRoot = dirname20(dirname20(source.path)), hooksPath = join29(pluginRoot, "hooks/hooks.json");
|
|
45622
45843
|
const hookStat = lstatSync24(hooksPath, { throwIfNoEntry: false });
|
|
@@ -47524,7 +47745,7 @@ function planAgentSettingsWitnessUpgrade(options) {
|
|
|
47524
47745
|
return { dataDir: dataDir2, profileId: policy.profileId, changes: [{ path: join30(dataDir2, "agent-policy.json"), before: snapshot2.text, after }], nativeSkills: [], observedPolicy: { path: join30(dataDir2, "agent-policy.json"), before: snapshot2.text }, observedSettings: { path: configPath, before: settings }, discoveryBefore: [replacement], discoveryAfter: [replacement], ...policy.bridge.discoveryExecutables ? { discoveryExecutables: policy.bridge.discoveryExecutables } : {}, rootAliases: aliases, managedAgentChecks: { home, agents: [options.agent] }, settingsWitnessUpgrade: { agent: options.agent, path: configPath, fromHashMode: previous.hashMode ?? "bytes", fromSha256: previous.sha256, toHashMode: next.hashMode, toSha256: next.sha256, reviewedPreimage: options.reviewedPreimage, currentSettingsSha256: options.expectedSettingsSha256, replacedWitnesses: replaced.map((source) => ({ hashMode: source.hashMode ?? "bytes", sha256: source.sha256 })) } };
|
|
47525
47746
|
}
|
|
47526
47747
|
function planCodexSemanticCacheWitnessUpgrade(options) {
|
|
47527
|
-
if (options.agent !== "codex" || !/^[a-f0-9]{64}$/.test(options.expectedPolicySha256) || !/^[a-f0-9]{64}$/.test(options.expectedSettingsSha256) || options.expectedCacheWitnessSha256 !== undefined && !/^[a-f0-9]{64}$/.test(options.expectedCacheWitnessSha256) || !Array.isArray(options.appOnlyParents) || options.appOnlyParents.length > 4096 || new Set(options.appOnlyParents).size !== options.appOnlyParents.length)
|
|
47748
|
+
if (options.agent !== "codex" || !/^[a-f0-9]{64}$/.test(options.expectedPolicySha256) || !/^[a-f0-9]{64}$/.test(options.expectedSettingsSha256) || options.expectedCacheWitnessSha256 !== undefined && !/^[a-f0-9]{64}$/.test(options.expectedCacheWitnessSha256) || !Array.isArray(options.appOnlyParents) || options.appOnlyParents.length > 4096 || new Set(options.appOnlyParents).size !== options.appOnlyParents.length || options.reviewedHookParents !== undefined && (!Array.isArray(options.reviewedHookParents) || options.reviewedHookParents.length > 4096 || new Set(options.reviewedHookParents).size !== options.reviewedHookParents.length))
|
|
47528
47749
|
throw new Error("Invalid Codex semantic cache upgrade request");
|
|
47529
47750
|
const home = resolve23(options.home ?? homedir3()), dataDir2 = options.dataDir ?? getDataDirReadOnly();
|
|
47530
47751
|
const snapshot2 = readManagedSkillPolicySnapshot(dataDir2);
|
|
@@ -47548,14 +47769,23 @@ function planCodexSemanticCacheWitnessUpgrade(options) {
|
|
|
47548
47769
|
throw new Error("Native settings preimage changed");
|
|
47549
47770
|
const boundedRead = (path) => new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(readNativeBytes(path, 1024 * 1024));
|
|
47550
47771
|
const unchangedFullSource = (path) => {
|
|
47551
|
-
const
|
|
47552
|
-
if (
|
|
47553
|
-
throw new Error("Cache upgrade
|
|
47772
|
+
const sources = binding.sources.filter((source2) => source2.path === path && source2.sha256 !== null && source2.format === undefined && source2.fields === undefined && source2.reviewArtifact === undefined && (source2.hashMode === undefined || source2.hashMode === "bytes"));
|
|
47773
|
+
if (sources.length !== 1)
|
|
47774
|
+
throw new Error("Cache upgrade requires one unambiguous prior full identity source");
|
|
47775
|
+
const source = sources[0];
|
|
47554
47776
|
const text2 = boundedRead(path);
|
|
47555
47777
|
if (sha5(text2) !== source.sha256)
|
|
47556
47778
|
throw new Error("Reviewed cache identity source changed");
|
|
47557
47779
|
return text2;
|
|
47558
47780
|
};
|
|
47781
|
+
const unchangedReviewedHookSource = (path) => {
|
|
47782
|
+
const sources = binding.sources.filter((source) => source.path === path);
|
|
47783
|
+
if (!sources.length)
|
|
47784
|
+
throw new Error("Cache upgrade lacks prior full identity source");
|
|
47785
|
+
if (sources.length !== 1)
|
|
47786
|
+
throw new Error("Reviewed hook identity source is ambiguous");
|
|
47787
|
+
return unchangedFullSource(path);
|
|
47788
|
+
};
|
|
47559
47789
|
const appOnlyParents = options.appOnlyParents.map((parent) => {
|
|
47560
47790
|
const parts = relative8(cacheRoot, parent).split(sep10);
|
|
47561
47791
|
if (!isAbsolute25(parent) || resolve23(parent) !== parent || parts.length !== 2 || parts.some((part) => !/^[A-Za-z0-9_-]{1,64}$/.test(part)) || controls.some((control) => control.pluginParent === parent))
|
|
@@ -47570,11 +47800,60 @@ function planCodexSemanticCacheWitnessUpgrade(options) {
|
|
|
47570
47800
|
unchangedFullSource(source.path);
|
|
47571
47801
|
return { role: "app-only", pluginId: `${parts[1]}@${parts[0]}`, namespace: parts[1], pluginParent: parent, remotePluginId: receipt.remote_plugin_id };
|
|
47572
47802
|
}).sort((a, b) => a.pluginParent.localeCompare(b.pluginParent));
|
|
47573
|
-
const
|
|
47803
|
+
const reviewedHookParents = (options.reviewedHookParents ?? []).map((parent) => {
|
|
47804
|
+
const parts = relative8(cacheRoot, parent).split(sep10);
|
|
47805
|
+
if (!isAbsolute25(parent) || resolve23(parent) !== parent || parts.length !== 2 || parts.some((part) => !/^[A-Za-z0-9_-]{1,64}$/.test(part)) || controls.some((control) => control.pluginParent === parent) || appOnlyParents.some((role) => role.pluginParent === parent))
|
|
47806
|
+
throw new Error("Unsupported reviewed native-hook parent role");
|
|
47807
|
+
const receiptPath = join30(parent, ".codex-remote-plugin-install.json"), receiptStat = lstatSync26(receiptPath, { throwIfNoEntry: false });
|
|
47808
|
+
let identity5;
|
|
47809
|
+
if (receiptStat) {
|
|
47810
|
+
if (!receiptStat.isFile() || receiptStat.isSymbolicLink() || receiptStat.size > 16 * 1024)
|
|
47811
|
+
throw new Error("Invalid reviewed native-hook install receipt");
|
|
47812
|
+
const receiptText = unchangedReviewedHookSource(receiptPath);
|
|
47813
|
+
let receipt;
|
|
47814
|
+
try {
|
|
47815
|
+
hashNativeJsonControls(receiptText);
|
|
47816
|
+
receipt = JSON.parse(receiptText);
|
|
47817
|
+
} catch {
|
|
47818
|
+
throw new Error("Invalid reviewed native-hook install receipt");
|
|
47819
|
+
}
|
|
47820
|
+
if (!receipt || Array.isArray(receipt) || Object.keys(receipt).length !== 2 || receipt.schema_version !== 1 || typeof receipt.remote_plugin_id !== "string" || !/^[A-Za-z0-9_~-]{1,1024}$/.test(receipt.remote_plugin_id))
|
|
47821
|
+
throw new Error("Invalid reviewed native-hook install receipt");
|
|
47822
|
+
identity5 = { role: "reviewed-hook", pluginId: `${parts[1]}@${parts[0]}`, namespace: parts[1], pluginParent: parent, installation: "remote-receipt", remotePluginId: receipt.remote_plugin_id };
|
|
47823
|
+
} else {
|
|
47824
|
+
const pluginId2 = `${parts[1]}@${parts[0]}`;
|
|
47825
|
+
const marketplaceSources = binding.sources.filter((source2) => basename11(source2.path) === "marketplace.json" && source2.sha256 !== null && source2.format === undefined && source2.fields === undefined && source2.reviewArtifact === undefined && (source2.hashMode === undefined || source2.hashMode === "bytes"));
|
|
47826
|
+
const matches = marketplaceSources.flatMap((source2) => {
|
|
47827
|
+
const text2 = unchangedFullSource(source2.path);
|
|
47828
|
+
return codexLocalMarketplaceMapsPlugin(text2, parts[0], parts[1]) ? [{ source: source2, text: text2 }] : [];
|
|
47829
|
+
});
|
|
47830
|
+
if (matches.length !== 1)
|
|
47831
|
+
throw new Error("Local marketplace hook parent lacks one exact enrolled marketplace source");
|
|
47832
|
+
const { source } = matches[0];
|
|
47833
|
+
const config = Bun.TOML.parse(settings);
|
|
47834
|
+
if (config.plugins?.[pluginId2]?.enabled !== true)
|
|
47835
|
+
throw new Error("Local marketplace hook parent is not enabled in the unchanged Codex settings");
|
|
47836
|
+
identity5 = { role: "reviewed-hook", pluginId: pluginId2, namespace: parts[1], pluginParent: parent, installation: "local-marketplace", marketplaceSourcePath: source.path, marketplaceSha256: source.sha256 };
|
|
47837
|
+
}
|
|
47838
|
+
const versions = readdirSync9(parent).filter((name) => name !== ".codex-remote-plugin-install.json");
|
|
47839
|
+
if (!versions.length || versions.length > 4096)
|
|
47840
|
+
throw new Error("Reviewed native-hook parent has no bounded materializations");
|
|
47841
|
+
for (const version2 of versions) {
|
|
47842
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$/.test(version2))
|
|
47843
|
+
throw new Error("Invalid reviewed native-hook version identity");
|
|
47844
|
+
const root2 = join30(parent, version2), stat2 = lstatSync26(root2, { throwIfNoEntry: false });
|
|
47845
|
+
if (!stat2?.isDirectory() || stat2.isSymbolicLink() || realpathSync13(root2) !== root2)
|
|
47846
|
+
throw new Error("Invalid reviewed native-hook materialization");
|
|
47847
|
+
unchangedReviewedHookSource(join30(root2, ".codex-plugin/plugin.json"));
|
|
47848
|
+
unchangedReviewedHookSource(join30(root2, "hooks/hooks.json"));
|
|
47849
|
+
}
|
|
47850
|
+
return identity5;
|
|
47851
|
+
}).sort((a, b) => a.pluginParent.localeCompare(b.pluginParent));
|
|
47852
|
+
const parents3 = [...new Set([...controls.map((control) => control.pluginParent), ...appOnlyParents.map((parent) => parent.pluginParent), ...reviewedHookParents.map((parent) => parent.pluginParent)])];
|
|
47574
47853
|
const reviewedAlias = aliases.find((alias) => alias.agent === "codex");
|
|
47575
47854
|
const hookRootAlias = reviewedAlias ? { alias: reviewedAlias.alias, target: reviewedAlias.target } : null;
|
|
47576
47855
|
assertCodexSemanticCacheHookSafety(cacheRoot, parents3, configPath, hookRootAlias);
|
|
47577
|
-
const supersededSources = binding.sources.filter((source) => codexSemanticCacheSourceRole(source, cacheRoot, parents3));
|
|
47856
|
+
const supersededSources = binding.sources.filter((source) => codexSemanticCacheSourceRole(source, cacheRoot, parents3, reviewedHookParents.map((parent) => parent.pluginParent)));
|
|
47578
47857
|
for (const source of supersededSources)
|
|
47579
47858
|
if ([".app.json", ".mcp.json"].includes(source.path.split(sep10).at(-1)))
|
|
47580
47859
|
unchangedFullSource(source.path);
|
|
@@ -47582,7 +47861,7 @@ function planCodexSemanticCacheWitnessUpgrade(options) {
|
|
|
47582
47861
|
if (!supersededDirectories.some((directory) => directory.path === cacheRoot) || (binding.directories ?? []).some((directory) => cacheRoot.startsWith(directory.path + sep10)))
|
|
47583
47862
|
throw new Error("Cache upgrade requires exact cache directory coverage without an unproved ancestor projection");
|
|
47584
47863
|
const rules = Bun.TOML.parse(settings).skills?.config ?? [];
|
|
47585
|
-
const witness = captureCodexSemanticCacheWitness({ cacheRoot, controls, appOnlyParents, rules, read: boundedRead });
|
|
47864
|
+
const witness = captureCodexSemanticCacheWitness({ cacheRoot, controls, appOnlyParents, reviewedHookParents, rules, read: boundedRead });
|
|
47586
47865
|
if (options.expectedCacheWitnessSha256 !== undefined && witness.sha256 !== options.expectedCacheWitnessSha256)
|
|
47587
47866
|
throw new Error("Reviewed semantic cache preimage changed");
|
|
47588
47867
|
const replacement = { ...binding, codexDisabledPluginSkills: controls, codexSemanticCache: {
|
|
@@ -47591,6 +47870,7 @@ function planCodexSemanticCacheWitnessUpgrade(options) {
|
|
|
47591
47870
|
hookRootAlias,
|
|
47592
47871
|
witness,
|
|
47593
47872
|
appOnlyParents,
|
|
47873
|
+
reviewedHookParents,
|
|
47594
47874
|
previousPolicySha256: options.expectedPolicySha256,
|
|
47595
47875
|
supersededSources,
|
|
47596
47876
|
supersededDirectories
|
|
@@ -47609,7 +47889,7 @@ function planCodexSemanticCacheWitnessUpgrade(options) {
|
|
|
47609
47889
|
rootAliases: aliases,
|
|
47610
47890
|
managedAgentChecks: { home, agents: ["codex"] },
|
|
47611
47891
|
...policy.bridge.discoveryExecutables ? { discoveryExecutables: policy.bridge.discoveryExecutables } : {},
|
|
47612
|
-
cacheWitnessUpgrade: { ...options, home, dataDir: dataDir2, appOnlyParents: appOnlyParents.map((parent) => parent.pluginParent) }
|
|
47892
|
+
cacheWitnessUpgrade: { ...options, home, dataDir: dataDir2, appOnlyParents: appOnlyParents.map((parent) => parent.pluginParent), reviewedHookParents: reviewedHookParents.map((parent) => parent.pluginParent) }
|
|
47613
47893
|
};
|
|
47614
47894
|
}
|
|
47615
47895
|
function planReviewedArtifactMigration(options) {
|
|
@@ -48148,7 +48428,7 @@ import {
|
|
|
48148
48428
|
statSync as statSync11,
|
|
48149
48429
|
writeFileSync as writeFileSync7
|
|
48150
48430
|
} from "fs";
|
|
48151
|
-
import { basename as
|
|
48431
|
+
import { basename as basename14, dirname as dirname24, isAbsolute as isAbsolute26, join as join34, normalize as normalize4, relative as relative10, resolve as resolve25, sep as sep13 } from "path";
|
|
48152
48432
|
|
|
48153
48433
|
// src/lib/registry-data/index.ts
|
|
48154
48434
|
var SKILLS = [];
|
|
@@ -48673,7 +48953,7 @@ import {
|
|
|
48673
48953
|
realpathSync as realpathSync14,
|
|
48674
48954
|
writeFileSync as writeFileSync6
|
|
48675
48955
|
} from "fs";
|
|
48676
|
-
import { basename as
|
|
48956
|
+
import { basename as basename12, dirname as dirname22, join as join32, relative as relative9 } from "path";
|
|
48677
48957
|
var ANY_SEGMENT_COPY_EXCLUDES = new Set([
|
|
48678
48958
|
".git",
|
|
48679
48959
|
".DS_Store",
|
|
@@ -48723,11 +49003,11 @@ function normalizeNewPortableSkillName(name) {
|
|
|
48723
49003
|
throw new Error(`Invalid skill name '${name}'. Include letters or numbers.`);
|
|
48724
49004
|
return normalized;
|
|
48725
49005
|
}
|
|
48726
|
-
function readPortableSkillManifest(skillPath, fallbackName =
|
|
49006
|
+
function readPortableSkillManifest(skillPath, fallbackName = basename12(skillPath)) {
|
|
48727
49007
|
return readManifest(skillPath, fallbackName, normalizePortableSkillName);
|
|
48728
49008
|
}
|
|
48729
49009
|
function readPortableSkillManifestForImport(skillPath) {
|
|
48730
|
-
return readManifest(skillPath,
|
|
49010
|
+
return readManifest(skillPath, basename12(skillPath), normalizeNewPortableSkillName);
|
|
48731
49011
|
}
|
|
48732
49012
|
function readManifest(skillPath, fallbackName, normalizeName) {
|
|
48733
49013
|
const skillJsonPath = join32(skillPath, "skill.json");
|
|
@@ -49281,7 +49561,7 @@ function inferRuntimeFromCommands(commands) {
|
|
|
49281
49561
|
function readJsonObject(path) {
|
|
49282
49562
|
const parsed = JSON.parse(readFileSync20(path, "utf-8"));
|
|
49283
49563
|
if (!isRecord3(parsed))
|
|
49284
|
-
throw new Error(`${
|
|
49564
|
+
throw new Error(`${basename12(path)} must contain a JSON object`);
|
|
49285
49565
|
return parsed;
|
|
49286
49566
|
}
|
|
49287
49567
|
function hasPackageDependencies(pkgPath) {
|
|
@@ -49319,7 +49599,7 @@ function escapeJsString(value) {
|
|
|
49319
49599
|
// src/lib/authoring-path.ts
|
|
49320
49600
|
import { lstatSync as lstatSync28, realpathSync as realpathSync15 } from "fs";
|
|
49321
49601
|
import { homedir as homedir4 } from "os";
|
|
49322
|
-
import { basename as
|
|
49602
|
+
import { basename as basename13, dirname as dirname23, join as join33, resolve as resolve24, sep as sep12 } from "path";
|
|
49323
49603
|
var NATIVE_DISCOVERY_ROOTS = NATIVE_SKILL_ROOTS.map(([, path]) => path.split("/"));
|
|
49324
49604
|
function pathParts(path) {
|
|
49325
49605
|
return resolve24(path).split(sep12).filter(Boolean);
|
|
@@ -49339,7 +49619,7 @@ function physicalPath(path) {
|
|
|
49339
49619
|
let cursor = resolve24(path);
|
|
49340
49620
|
const suffix = [];
|
|
49341
49621
|
while (!lstatSync28(cursor, { throwIfNoEntry: false })) {
|
|
49342
|
-
suffix.unshift(
|
|
49622
|
+
suffix.unshift(basename13(cursor));
|
|
49343
49623
|
const parent = dirname23(cursor);
|
|
49344
49624
|
if (parent === cursor)
|
|
49345
49625
|
return resolve24(path);
|
|
@@ -49558,7 +49838,7 @@ function physicalImportPath(path) {
|
|
|
49558
49838
|
let ancestor = resolve25(path);
|
|
49559
49839
|
const suffix = [];
|
|
49560
49840
|
while (!existsSync10(ancestor)) {
|
|
49561
|
-
suffix.unshift(
|
|
49841
|
+
suffix.unshift(basename14(ancestor));
|
|
49562
49842
|
ancestor = dirname24(ancestor);
|
|
49563
49843
|
}
|
|
49564
49844
|
return join34(realpathSync16(ancestor), ...suffix);
|
|
@@ -49583,8 +49863,8 @@ function portPortableSkill(sourcePath, options = {}) {
|
|
|
49583
49863
|
const explicitName = options.name != null;
|
|
49584
49864
|
const skillName = normalizeNewPortableSkillName(options.name ?? inferred.name);
|
|
49585
49865
|
if (isOfficialSkillName(skillName) && !options.allowShadow) {
|
|
49586
|
-
const sourceSlug = safeNormalizeName(
|
|
49587
|
-
const via = explicitName ? `Name '${skillName}' matches a bundled official skill.` : `Inferred name '${skillName}'${sourceSlug && sourceSlug !== skillName ? ` (from source folder '${
|
|
49866
|
+
const sourceSlug = safeNormalizeName(basename14(absoluteSource));
|
|
49867
|
+
const via = explicitName ? `Name '${skillName}' matches a bundled official skill.` : `Inferred name '${skillName}'${sourceSlug && sourceSlug !== skillName ? ` (from source folder '${basename14(absoluteSource)}')` : ""} matches a bundled official skill.`;
|
|
49588
49868
|
throw new Error(`${via} Importing it would shadow the official '${skillName}'. ` + `Pass --name to choose a different name, or --allow-shadow to override deliberately.`);
|
|
49589
49869
|
}
|
|
49590
49870
|
const readOnlyDestination = join34(resolvePortableSkillsRoot(options, false), skillName);
|
|
@@ -50112,7 +50392,7 @@ function writeManagedSkillDirUnlocked(dir, skillMd, options, assertCurrent) {
|
|
|
50112
50392
|
return { action, path: skillMdPath };
|
|
50113
50393
|
const parentDir = dirname25(dir);
|
|
50114
50394
|
mkdirSync10(parentDir, { recursive: true });
|
|
50115
|
-
const transactionDir = mkdtempSync2(join35(parentDir, `.hasna-skills-write-${
|
|
50395
|
+
const transactionDir = mkdtempSync2(join35(parentDir, `.hasna-skills-write-${basename15(dir)}-`));
|
|
50116
50396
|
const candidateDir = join35(transactionDir, "candidate");
|
|
50117
50397
|
const backupDir = join35(transactionDir, "backup");
|
|
50118
50398
|
const candidateSkillMdPath = join35(candidateDir, "SKILL.md");
|