@hasna/skills 0.10.41 → 0.10.42
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 +15 -0
- package/bin/index.js +205 -75
- package/bin/mcp.js +138 -19
- package/bin/migrate.js +1 -1
- package/bin/server.js +1 -1
- package/bin/worker.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +163 -31
- package/dist/lib/agent-discovery.d.ts +1 -1
- package/dist/lib/agent-integration.d.ts +1 -1
- package/dist/lib/codex-settings-witness.d.ts +13 -0
- package/dist/sdk/index.js +161 -31
- package/package.json +1 -1
package/dist/sdk/index.js
CHANGED
|
@@ -32373,7 +32373,7 @@ var init_event_sink = __esm(() => {
|
|
|
32373
32373
|
// package.json
|
|
32374
32374
|
var package_default = {
|
|
32375
32375
|
name: "@hasna/skills",
|
|
32376
|
-
version: "0.10.
|
|
32376
|
+
version: "0.10.42",
|
|
32377
32377
|
description: "Skills library for AI coding agents",
|
|
32378
32378
|
type: "module",
|
|
32379
32379
|
bin: {
|
|
@@ -39217,6 +39217,7 @@ function projectRegularCodexMcp(config, source) {
|
|
|
39217
39217
|
|
|
39218
39218
|
// src/lib/codex-settings-witness.ts
|
|
39219
39219
|
import { createHash as createHash9 } from "crypto";
|
|
39220
|
+
import { isDeepStrictEqual as isDeepStrictEqual4 } from "util";
|
|
39220
39221
|
var sha2 = (text) => createHash9("sha256").update(text).digest("hex");
|
|
39221
39222
|
var EFFORT2 = new Set(["none", "minimal", "low", "medium", "high", "xhigh"]);
|
|
39222
39223
|
var VERBOSITY2 = new Set(["low", "medium", "high"]);
|
|
@@ -39328,7 +39329,7 @@ function disablesOneSkill(entry) {
|
|
|
39328
39329
|
return selector.length === 1 && typeof entry[selector[0]] === "string" && entry[selector[0]].length > 0;
|
|
39329
39330
|
}
|
|
39330
39331
|
function inference(target, version) {
|
|
39331
|
-
const keys2 = version
|
|
39332
|
+
const keys2 = version >= 3 ? [...INFERENCE, "service_tier", "plan_mode_reasoning_effort", "personality"] : INFERENCE;
|
|
39332
39333
|
for (const key of keys2)
|
|
39333
39334
|
if (Object.hasOwn(target, key)) {
|
|
39334
39335
|
const value = target[key];
|
|
@@ -39336,7 +39337,7 @@ function inference(target, version) {
|
|
|
39336
39337
|
need3(typeof value === "string" && MODEL.test(value));
|
|
39337
39338
|
else if (key === "personality")
|
|
39338
39339
|
need3(typeof value === "string" && ["none", "friendly", "pragmatic"].includes(value));
|
|
39339
|
-
else if (version
|
|
39340
|
+
else if (version >= 3 && key !== "model_verbosity") {
|
|
39340
39341
|
need3(typeof value === "string" && value.length <= 128 && !/[\x00-\x1f\x7f]/.test(value));
|
|
39341
39342
|
if (key !== "service_tier")
|
|
39342
39343
|
need3(value.length > 0);
|
|
@@ -39345,6 +39346,115 @@ function inference(target, version) {
|
|
|
39345
39346
|
delete target[key];
|
|
39346
39347
|
}
|
|
39347
39348
|
}
|
|
39349
|
+
function projectModelAvailabilityNux(config, text) {
|
|
39350
|
+
const tui = config.tui, counts = isRecord(tui) ? tui.model_availability_nux : undefined;
|
|
39351
|
+
if (isRecord(tui) && !Object.keys(tui).length) {
|
|
39352
|
+
delete config.tui;
|
|
39353
|
+
return { config, numericSource: text };
|
|
39354
|
+
}
|
|
39355
|
+
if (!isRecord(counts) || Object.keys(counts).length > 256 || !Object.values(counts).every((value) => typeof value === "number" && Number.isInteger(value) && value >= 0 && value <= 4294967295))
|
|
39356
|
+
return { config, numericSource: text };
|
|
39357
|
+
const expected = structuredClone(config);
|
|
39358
|
+
delete expected.tui.model_availability_nux;
|
|
39359
|
+
const stripEmptyTui = (value) => {
|
|
39360
|
+
if (isRecord(value.tui) && !Object.keys(value.tui).length)
|
|
39361
|
+
delete value.tui;
|
|
39362
|
+
};
|
|
39363
|
+
stripEmptyTui(expected);
|
|
39364
|
+
const headers = [];
|
|
39365
|
+
const spans = [];
|
|
39366
|
+
const integer = /^(?:\+?(?:0|[1-9](?:_?\d)*)|0x[0-9a-fA-F](?:_?[0-9a-fA-F])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*)$/;
|
|
39367
|
+
const counterIntegers = (span) => {
|
|
39368
|
+
let values = 0;
|
|
39369
|
+
for (let at = 0;at < span.length; ) {
|
|
39370
|
+
const char = span[at];
|
|
39371
|
+
if (char === "#") {
|
|
39372
|
+
while (at < span.length && span[at] !== `
|
|
39373
|
+
`)
|
|
39374
|
+
at++;
|
|
39375
|
+
continue;
|
|
39376
|
+
}
|
|
39377
|
+
if (char === '"' || char === "'") {
|
|
39378
|
+
const quote = char;
|
|
39379
|
+
at++;
|
|
39380
|
+
while (at < span.length) {
|
|
39381
|
+
if (quote === '"' && span[at] === "\\") {
|
|
39382
|
+
at += 2;
|
|
39383
|
+
continue;
|
|
39384
|
+
}
|
|
39385
|
+
if (span[at++] === quote)
|
|
39386
|
+
break;
|
|
39387
|
+
}
|
|
39388
|
+
continue;
|
|
39389
|
+
}
|
|
39390
|
+
if (char !== "=") {
|
|
39391
|
+
at++;
|
|
39392
|
+
continue;
|
|
39393
|
+
}
|
|
39394
|
+
at++;
|
|
39395
|
+
while (at < span.length && /\s/.test(span[at]))
|
|
39396
|
+
at++;
|
|
39397
|
+
if (span[at] === "{") {
|
|
39398
|
+
at++;
|
|
39399
|
+
continue;
|
|
39400
|
+
}
|
|
39401
|
+
const start = at;
|
|
39402
|
+
while (at < span.length && !/[\s,\]{}#]/.test(span[at]))
|
|
39403
|
+
at++;
|
|
39404
|
+
if (!integer.test(span.slice(start, at)))
|
|
39405
|
+
return false;
|
|
39406
|
+
values++;
|
|
39407
|
+
}
|
|
39408
|
+
return values === Object.keys(counts).length;
|
|
39409
|
+
};
|
|
39410
|
+
let attempts = 0;
|
|
39411
|
+
const realPrefix = (end) => {
|
|
39412
|
+
if (++attempts > 256)
|
|
39413
|
+
return false;
|
|
39414
|
+
try {
|
|
39415
|
+
Bun.TOML.parse(text.slice(0, end));
|
|
39416
|
+
return true;
|
|
39417
|
+
} catch {
|
|
39418
|
+
return false;
|
|
39419
|
+
}
|
|
39420
|
+
};
|
|
39421
|
+
for (const match of text.matchAll(/^[ \t]*\[[^\r\n]+\][ \t]*(?:#[^\r\n]*)?(?:\r?\n|$)/gm)) {
|
|
39422
|
+
const start = match.index, end = start + match[0].length;
|
|
39423
|
+
if (realPrefix(end))
|
|
39424
|
+
headers.push({ start, end });
|
|
39425
|
+
}
|
|
39426
|
+
for (let at = 0;at < headers.length; at++) {
|
|
39427
|
+
const header = headers[at];
|
|
39428
|
+
let parsed;
|
|
39429
|
+
try {
|
|
39430
|
+
parsed = Bun.TOML.parse(text.slice(header.start, header.end));
|
|
39431
|
+
} catch {
|
|
39432
|
+
continue;
|
|
39433
|
+
}
|
|
39434
|
+
if (isRecord(parsed.tui) && isRecord(parsed.tui.model_availability_nux) && !Object.keys(parsed.tui.model_availability_nux).length && Object.keys(parsed).length === 1 && Object.keys(parsed.tui).length === 1)
|
|
39435
|
+
spans.push({ start: header.start, end: headers[at + 1]?.start ?? text.length });
|
|
39436
|
+
}
|
|
39437
|
+
for (const match of text.matchAll(/^[ \t]*(?:(?:tui|"tui"|'tui')[ \t]*\.[ \t]*)?(?:model_availability_nux|"model_availability_nux"|'model_availability_nux')[ \t]*=[ \t]*\{[^\r\n]*(?:\r?\n|$)/gm)) {
|
|
39438
|
+
const start = match.index, end = start + match[0].length;
|
|
39439
|
+
if (realPrefix(end))
|
|
39440
|
+
spans.push({ start, end });
|
|
39441
|
+
}
|
|
39442
|
+
for (const { start, end } of spans) {
|
|
39443
|
+
if (!counterIntegers(text.slice(start, end)))
|
|
39444
|
+
continue;
|
|
39445
|
+
const remaining = text.slice(0, start) + text.slice(end);
|
|
39446
|
+
let parsed;
|
|
39447
|
+
try {
|
|
39448
|
+
parsed = Bun.TOML.parse(remaining);
|
|
39449
|
+
} catch {
|
|
39450
|
+
continue;
|
|
39451
|
+
}
|
|
39452
|
+
stripEmptyTui(parsed);
|
|
39453
|
+
if (isDeepStrictEqual4(parsed, expected))
|
|
39454
|
+
return { config: expected, numericSource: remaining };
|
|
39455
|
+
}
|
|
39456
|
+
return { config, numericSource: text };
|
|
39457
|
+
}
|
|
39348
39458
|
function settingsDigest2(text, version = 2) {
|
|
39349
39459
|
let config;
|
|
39350
39460
|
try {
|
|
@@ -39353,7 +39463,8 @@ function settingsDigest2(text, version = 2) {
|
|
|
39353
39463
|
throw new Error("Invalid Codex settings witness");
|
|
39354
39464
|
}
|
|
39355
39465
|
need3(isRecord(config));
|
|
39356
|
-
const
|
|
39466
|
+
const mcp = version >= 3 ? projectRegularCodexMcp(config, text) : { config, numericSource: text };
|
|
39467
|
+
const projected = version === 4 ? projectModelAvailabilityNux(mcp.config, mcp.numericSource) : mcp;
|
|
39357
39468
|
normalize2(projected.config, version);
|
|
39358
39469
|
return sha2(`hasna.skills.codex-settings.v${version}\x00${JSON.stringify([canonical3(projected.config), numericTokens2(projected.numericSource)])}`);
|
|
39359
39470
|
}
|
|
@@ -39398,6 +39509,25 @@ function upgradeCodexSettingsWitnessV3(previous, reviewedSettingsPath) {
|
|
|
39398
39509
|
throw new Error("Codex settings outside the reviewed V3 contract changed; explicit discovery review required");
|
|
39399
39510
|
return { path: previous.path, hashMode: "codex-settings-v3", sha256: sha2562 };
|
|
39400
39511
|
}
|
|
39512
|
+
function hashCodexSettingsReplacementV4(text, budget = { remaining: 256 * 1024 * 1024 }) {
|
|
39513
|
+
need3(Buffer.byteLength(text) <= 1024 * 1024 && budget.remaining >= Buffer.byteLength(text));
|
|
39514
|
+
budget.remaining -= Buffer.byteLength(text);
|
|
39515
|
+
return settingsDigest2(text, 4);
|
|
39516
|
+
}
|
|
39517
|
+
function captureCodexSettingsV4(path, budget = { remaining: 256 * 1024 * 1024 }) {
|
|
39518
|
+
return { path, hashMode: "codex-settings-v4", sha256: settingsDigest2(readNativeSettingsWitnessFile(path, budget, "config.toml"), 4) };
|
|
39519
|
+
}
|
|
39520
|
+
function upgradeCodexSettingsWitnessV4(previous, reviewedSettingsPath) {
|
|
39521
|
+
need3(previous && Object.keys(previous).every((key) => ["path", "hashMode", "sha256"].includes(key)) && (previous.hashMode === undefined || ["bytes", "codex-settings-v1", "codex-settings-v2", "codex-settings-v3"].includes(previous.hashMode)) && /^[a-f0-9]{64}$/.test(previous.sha256));
|
|
39522
|
+
const budget = { remaining: 2 * 1024 * 1024 };
|
|
39523
|
+
const before = readNativeSettingsWitnessFile(reviewedSettingsPath, budget, "config.toml"), current = readNativeSettingsWitnessFile(previous.path, budget, "config.toml");
|
|
39524
|
+
const original = previous.hashMode === "codex-settings-v3" ? settingsDigest2(before, 3) : previous.hashMode === "codex-settings-v2" ? settingsDigest2(before, 2) : previous.hashMode === "codex-settings-v1" ? hashCodexSettingsReplacement(before) : sha2(before);
|
|
39525
|
+
need3(original === previous.sha256);
|
|
39526
|
+
const sha2562 = settingsDigest2(current, 4);
|
|
39527
|
+
if (settingsDigest2(before, 4) !== sha2562)
|
|
39528
|
+
throw new Error("Codex settings outside the reviewed V4 contract changed; explicit discovery review required");
|
|
39529
|
+
return { path: previous.path, hashMode: "codex-settings-v4", sha256: sha2562 };
|
|
39530
|
+
}
|
|
39401
39531
|
|
|
39402
39532
|
// src/lib/native-discovery-roots.ts
|
|
39403
39533
|
var NATIVE_SKILL_ROOTS = [
|
|
@@ -39422,7 +39552,7 @@ var NATIVE_SKILL_ROOTS = [
|
|
|
39422
39552
|
|
|
39423
39553
|
// src/lib/agent-integration.ts
|
|
39424
39554
|
import { createHash as createHash20, randomUUID as randomUUID3 } from "crypto";
|
|
39425
|
-
import { isDeepStrictEqual as
|
|
39555
|
+
import { isDeepStrictEqual as isDeepStrictEqual7 } from "util";
|
|
39426
39556
|
import { existsSync as existsSync7, lstatSync as lstatSync21, statSync as statSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync15, readdirSync as readdirSync8, opendirSync as opendirSync5, readlinkSync as readlinkSync4, realpathSync as realpathSync9, renameSync as renameSync3, rmdirSync as rmdirSync3, writeFileSync as writeFileSync4, unlinkSync as unlinkSync4, chmodSync, openSync as openSync16, closeSync as closeSync16, fsyncSync as fsyncSync4, fstatSync as fstatSync16, readSync as readSync11, constants as constants13, linkSync as linkSync3 } from "fs";
|
|
39427
39557
|
import { dirname as dirname16, join as join25, resolve as resolve17, relative as relative5, isAbsolute as isAbsolute18, sep as sep6 } from "path";
|
|
39428
39558
|
import { homedir as homedir3 } from "os";
|
|
@@ -39566,8 +39696,8 @@ function assertAgentPolicyCollections(policy) {
|
|
|
39566
39696
|
text(source.path);
|
|
39567
39697
|
requireBound(source.sha256 === null || typeof source.sha256 === "string" && /^[a-f0-9]{64}$/.test(source.sha256));
|
|
39568
39698
|
if (source.hashMode !== undefined)
|
|
39569
|
-
requireBound(["bytes", "path-bytes", "claude-plugin-registry", "claude-marketplace-registry", "claude-settings-v1", "claude-settings-v2", "claude-settings-v3", "claude-marketplace-registry-v2", "codex-settings-v1", "codex-settings-v2", "codex-settings-v3"].includes(source.hashMode) && source.format === undefined && source.fields === undefined && (source.hashMode === "bytes" || source.sha256 !== null));
|
|
39570
|
-
if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3")
|
|
39699
|
+
requireBound(["bytes", "path-bytes", "claude-plugin-registry", "claude-marketplace-registry", "claude-settings-v1", "claude-settings-v2", "claude-settings-v3", "claude-marketplace-registry-v2", "codex-settings-v1", "codex-settings-v2", "codex-settings-v3", "codex-settings-v4"].includes(source.hashMode) && source.format === undefined && source.fields === undefined && (source.hashMode === "bytes" || source.sha256 !== null));
|
|
39700
|
+
if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4"))
|
|
39571
39701
|
requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute7(source.path) && resolve6(source.path) === source.path && basename5(source.path) === "config.toml");
|
|
39572
39702
|
if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3")
|
|
39573
39703
|
requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute7(source.path) && resolve6(source.path) === source.path && basename5(source.path) === "settings.json");
|
|
@@ -39727,7 +39857,7 @@ function isOwnedCliBridge(path, expectedPaths) {
|
|
|
39727
39857
|
import { createHash as createHash19 } from "crypto";
|
|
39728
39858
|
import { lstatSync as lstatSync20, readFileSync as readFileSync14, readdirSync as readdirSync7, realpathSync as realpathSync8 } from "fs";
|
|
39729
39859
|
import { basename as basename8, dirname as dirname15, isAbsolute as isAbsolute17, join as join24, resolve as resolve16, sep as sep5 } from "path";
|
|
39730
|
-
import { isDeepStrictEqual as
|
|
39860
|
+
import { isDeepStrictEqual as isDeepStrictEqual5 } from "util";
|
|
39731
39861
|
|
|
39732
39862
|
// node_modules/yaml/dist/index.js
|
|
39733
39863
|
var composer = require_composer();
|
|
@@ -42228,19 +42358,19 @@ function projectNativeDiscoveryFields(text2, format, fields2, path) {
|
|
|
42228
42358
|
return digest2(JSON.stringify(Object.fromEntries(fields2.map((field2) => [field2, object5[field2] ?? null]))));
|
|
42229
42359
|
}
|
|
42230
42360
|
function isSupersededCodexProjection(agent, configPath, source) {
|
|
42231
|
-
return agent === "codex" && source.path === configPath && source.format === "toml" &&
|
|
42361
|
+
return agent === "codex" && source.path === configPath && source.format === "toml" && isDeepStrictEqual5(source.fields, [...CODEX_DISCOVERY_PROJECTION_FIELDS]);
|
|
42232
42362
|
}
|
|
42233
42363
|
function supersedesCodexProjection(sources, configPath) {
|
|
42234
|
-
return sources.some((source) => source.path === configPath && (source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3"));
|
|
42364
|
+
return sources.some((source) => source.path === configPath && (source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")));
|
|
42235
42365
|
}
|
|
42236
42366
|
function projected(source, changes, budget = discoveryByteBudget()) {
|
|
42237
|
-
if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3") {
|
|
42367
|
+
if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")) {
|
|
42238
42368
|
if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
|
|
42239
42369
|
throw new Error("Codex settings witnesses require exact typed metadata");
|
|
42240
|
-
const current = (source.hashMode === "codex-settings-v3" ? captureCodexSettingsV3 : source.hashMode === "codex-settings-v2" ? captureCodexSettingsV2 : captureCodexSettings)(source.path, budget).sha256;
|
|
42370
|
+
const current = (source.hashMode === "codex-settings-v4" ? captureCodexSettingsV4 : source.hashMode === "codex-settings-v3" ? captureCodexSettingsV3 : source.hashMode === "codex-settings-v2" ? captureCodexSettingsV2 : captureCodexSettings)(source.path, budget).sha256;
|
|
42241
42371
|
if (current !== source.sha256)
|
|
42242
42372
|
throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
|
|
42243
|
-
return changes?.has(source.path) ? (source.hashMode === "codex-settings-v3" ? hashCodexSettingsReplacementV3 : source.hashMode === "codex-settings-v2" ? hashCodexSettingsReplacementV2 : hashCodexSettingsReplacement)(changes.get(source.path), budget) : current;
|
|
42373
|
+
return changes?.has(source.path) ? (source.hashMode === "codex-settings-v4" ? hashCodexSettingsReplacementV4 : source.hashMode === "codex-settings-v3" ? hashCodexSettingsReplacementV3 : source.hashMode === "codex-settings-v2" ? hashCodexSettingsReplacementV2 : hashCodexSettingsReplacement)(changes.get(source.path), budget) : current;
|
|
42244
42374
|
}
|
|
42245
42375
|
if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") {
|
|
42246
42376
|
if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
|
|
@@ -42336,7 +42466,7 @@ function captureRetiredCodexDiscovery(binding, controls, rules) {
|
|
|
42336
42466
|
return current;
|
|
42337
42467
|
const installation = codexInstallationRoots(binding);
|
|
42338
42468
|
const directories = (binding.directories ?? []).filter((directory) => !installation.some((root2) => directory.path === root2 || directory.path.startsWith(root2 + sep5) || root2.startsWith(directory.path + sep5)));
|
|
42339
|
-
if (previous &&
|
|
42469
|
+
if (previous && isDeepStrictEqual5(previous.roots, roots) && isDeepStrictEqual5(previous.parents, parents3) && isDeepStrictEqual5(previous.directories.map((item) => item.path), directories.map((item) => item.path)))
|
|
42340
42470
|
return { ...current, codexRetiredMaterializations: previous };
|
|
42341
42471
|
return { ...current, codexRetiredMaterializations: { roots, parents: parents3, directories: captureDiscoveryDirectoryProjection(directories.map((item) => item.path), roots) } };
|
|
42342
42472
|
}
|
|
@@ -42412,7 +42542,7 @@ function verifyAgentDiscovery(binding, codexRecovery) {
|
|
|
42412
42542
|
if (omitted.some((root2) => !retiredRoots.includes(root2)))
|
|
42413
42543
|
throw new Error("Missing reviewed directory membership inventory; provide a fresh discovery review");
|
|
42414
42544
|
const current = captureDiscoveryDirectoryProjection(ordinary.map((item) => item.path), retiredRoots).map(({ entries, ...item }) => item);
|
|
42415
|
-
if (!
|
|
42545
|
+
if (!isDeepStrictEqual5(current, projection))
|
|
42416
42546
|
throw new Error("Native discovery directory membership changed outside retired Codex roots");
|
|
42417
42547
|
}
|
|
42418
42548
|
} else
|
|
@@ -42471,7 +42601,7 @@ function codexInstallationRoots(binding) {
|
|
|
42471
42601
|
});
|
|
42472
42602
|
}
|
|
42473
42603
|
function assertMarketplaceBinding(binding, source) {
|
|
42474
|
-
if ((source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3") && (binding.agent !== "codex" || binding.method !== "reviewed" || basename8(source.path) !== "config.toml"))
|
|
42604
|
+
if ((source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")) && (binding.agent !== "codex" || binding.method !== "reviewed" || basename8(source.path) !== "config.toml"))
|
|
42475
42605
|
throw new Error("Codex settings witnesses require explicit reviewed Codex configuration");
|
|
42476
42606
|
if ((source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") && (binding.agent !== "claude" || binding.method !== "reviewed" || basename8(source.path) !== "settings.json"))
|
|
42477
42607
|
throw new Error("Claude settings witnesses require explicit reviewed Claude configuration");
|
|
@@ -42672,10 +42802,10 @@ function resolveAgentDiscovery(options) {
|
|
|
42672
42802
|
verifyAgentDiscovery(retained);
|
|
42673
42803
|
if (!retained.sources.some((source) => source.path === canonical6(configPath) && source.format === undefined && source.fields === undefined))
|
|
42674
42804
|
unresolved("retained review is missing the full agent configuration source");
|
|
42675
|
-
if (retained.sources.some((source) => (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3"))) && source.path !== canonical6(configPath)))
|
|
42805
|
+
if (retained.sources.some((source) => (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")))) && source.path !== canonical6(configPath)))
|
|
42676
42806
|
unresolved("retained settings witness names another configuration source");
|
|
42677
42807
|
const covered = supersedesCodexProjection(retained.sources, canonical6(configPath)) ? sources.filter((source) => !isSupersededCodexProjection(agent, canonical6(configPath), source)) : sources;
|
|
42678
|
-
if (covered.some((source) => !retained.sources.some((saved) =>
|
|
42808
|
+
if (covered.some((source) => !retained.sources.some((saved) => isDeepStrictEqual5(saved, source))) || [...roots].some((root2) => !retained.roots.includes(root2)) || agent === "gemini" && JSON.stringify(retained.builtinNames) !== JSON.stringify(builtinNames))
|
|
42679
42809
|
unresolved("retained review is missing current runtime discovery coverage");
|
|
42680
42810
|
return retained;
|
|
42681
42811
|
}
|
|
@@ -42689,7 +42819,7 @@ function resolveAgentDiscovery(options) {
|
|
|
42689
42819
|
if (review.sources.some((source) => source.format !== undefined || source.fields !== undefined))
|
|
42690
42820
|
throw new Error("Explicit discovery reviews require full source-file hashes");
|
|
42691
42821
|
verifyAgentDiscovery(supplied);
|
|
42692
|
-
if (review.sources.some((source) => (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3"))) && source.path !== canonical6(configPath)))
|
|
42822
|
+
if (review.sources.some((source) => (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || (source.hashMode === "claude-settings-v3" || (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || (source.hashMode === "codex-settings-v3" || source.hashMode === "codex-settings-v4")))) && source.path !== canonical6(configPath)))
|
|
42693
42823
|
throw new Error("Semantic settings witnesses must name the configured Claude configuration source");
|
|
42694
42824
|
if (!review.sources.some((source) => source.path === canonical6(configPath)))
|
|
42695
42825
|
throw new Error("Discovery review must include the agent configuration source");
|
|
@@ -42877,7 +43007,7 @@ export default async ({ directory }) => {
|
|
|
42877
43007
|
}
|
|
42878
43008
|
|
|
42879
43009
|
// src/lib/agent-codex.ts
|
|
42880
|
-
import { isDeepStrictEqual as
|
|
43010
|
+
import { isDeepStrictEqual as isDeepStrictEqual6 } from "util";
|
|
42881
43011
|
var CODEX_SKILL_CONFIG_SECTIONS = /^\[\[skills\.config\]\][^\n]*(?:\n(?!\s*\[)[^\n]*)*/gm;
|
|
42882
43012
|
var codexPathConfigRefusal = () => new Error("Codex skill path controls require ordinary [[skills.config]] TOML tables or a native single-line inline array; preserve and review unsupported inline, dotted, or malformed definitions before running skills hook install");
|
|
42883
43013
|
function splitTopLevel(value, delimiter2) {
|
|
@@ -43008,7 +43138,7 @@ function normalizeCodexInlinePathConfig(text2) {
|
|
|
43008
43138
|
const expectedWithoutConfig = structuredClone(before);
|
|
43009
43139
|
delete expectedWithoutConfig.skills.config;
|
|
43010
43140
|
try {
|
|
43011
|
-
if (
|
|
43141
|
+
if (isDeepStrictEqual6(Bun.TOML.parse(text2.replace(CODEX_SKILL_CONFIG_SECTIONS, "")), expectedWithoutConfig))
|
|
43012
43142
|
return text2;
|
|
43013
43143
|
} catch {}
|
|
43014
43144
|
const matches = [];
|
|
@@ -43061,7 +43191,7 @@ function normalizeCodexInlinePathConfig(text2) {
|
|
|
43061
43191
|
try {
|
|
43062
43192
|
const after = Bun.TOML.parse(candidate2);
|
|
43063
43193
|
const expected = structuredClone(before);
|
|
43064
|
-
if (
|
|
43194
|
+
if (isDeepStrictEqual6(after, expected))
|
|
43065
43195
|
matches.push(candidate2);
|
|
43066
43196
|
} catch {}
|
|
43067
43197
|
}
|
|
@@ -43077,11 +43207,11 @@ function assertCodexPathConfigEditable(text2) {
|
|
|
43077
43207
|
delete expected.skills.config;
|
|
43078
43208
|
try {
|
|
43079
43209
|
const withoutSections = Bun.TOML.parse(text2.replace(CODEX_SKILL_CONFIG_SECTIONS, ""));
|
|
43080
|
-
if (
|
|
43210
|
+
if (isDeepStrictEqual6(withoutSections, expected))
|
|
43081
43211
|
return;
|
|
43082
43212
|
const normalized = normalizeCodexInlinePathConfig(text2);
|
|
43083
43213
|
const withoutNormalizedSections = Bun.TOML.parse(normalized.replace(CODEX_SKILL_CONFIG_SECTIONS, ""));
|
|
43084
|
-
if (
|
|
43214
|
+
if (isDeepStrictEqual6(withoutNormalizedSections, expected))
|
|
43085
43215
|
return;
|
|
43086
43216
|
} catch {}
|
|
43087
43217
|
throw codexPathConfigRefusal();
|
|
@@ -43119,7 +43249,7 @@ function disableCodexBundledSkills(text2) {
|
|
|
43119
43249
|
const candidates = new Set;
|
|
43120
43250
|
const consider = (candidate2) => {
|
|
43121
43251
|
try {
|
|
43122
|
-
if (
|
|
43252
|
+
if (isDeepStrictEqual6(Bun.TOML.parse(candidate2), expected))
|
|
43123
43253
|
candidates.add(candidate2);
|
|
43124
43254
|
} catch {}
|
|
43125
43255
|
};
|
|
@@ -43950,7 +44080,7 @@ function projectedHookExecutable(command, expectedResolved) {
|
|
|
43950
44080
|
hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
|
|
43951
44081
|
const recheck = () => {
|
|
43952
44082
|
try {
|
|
43953
|
-
if (realpathSync9(command) !== resolved || linkIdentity(lstatSync21(command, { bigint: true })) !== linkIdentity(link) || !
|
|
44083
|
+
if (realpathSync9(command) !== resolved || linkIdentity(lstatSync21(command, { bigint: true })) !== linkIdentity(link) || !isDeepStrictEqual7(parents3(), parentIdentity) || !isDeepStrictEqual7(parents3(resolved), resolvedParentIdentity))
|
|
43954
44084
|
hookProjectionRefusal("EXECUTABLE_UNVERIFIED");
|
|
43955
44085
|
projectedHookAcl(cli.file, cli.stat);
|
|
43956
44086
|
projectedHookAcl(manifest.file, manifest.stat);
|
|
@@ -44171,7 +44301,7 @@ function atomicWrite2(path, content) {
|
|
|
44171
44301
|
}
|
|
44172
44302
|
}
|
|
44173
44303
|
function planAgentSettingsWitnessUpgrade(options) {
|
|
44174
|
-
if (options.targetCodexVersion !== undefined && (options.agent !== "codex" || ![2, 3].includes(options.targetCodexVersion)))
|
|
44304
|
+
if (options.targetCodexVersion !== undefined && (options.agent !== "codex" || ![2, 3, 4].includes(options.targetCodexVersion)))
|
|
44175
44305
|
throw new Error("Invalid Codex witness target version");
|
|
44176
44306
|
const home = resolve17(options.home ?? homedir3()), dataDir2 = options.dataDir ?? getDataDirReadOnly();
|
|
44177
44307
|
const snapshot2 = readManagedSkillPolicySnapshot(dataDir2);
|
|
@@ -44194,21 +44324,21 @@ function planAgentSettingsWitnessUpgrade(options) {
|
|
|
44194
44324
|
throw new Error("Settings witness upgrade requires a preserved settings preimage");
|
|
44195
44325
|
const replaced = [previous];
|
|
44196
44326
|
if (options.agent === "codex") {
|
|
44197
|
-
if (previous.hashMode !== undefined && previous.hashMode !== "bytes" && previous.hashMode !== "codex-settings-v1" && !(options.targetCodexVersion === 3 && previous.hashMode === "codex-settings-v2"))
|
|
44327
|
+
if (previous.hashMode !== undefined && previous.hashMode !== "bytes" && previous.hashMode !== "codex-settings-v1" && !((options.targetCodexVersion === 3 || options.targetCodexVersion === 4) && previous.hashMode === "codex-settings-v2") && !(options.targetCodexVersion === 4 && previous.hashMode === "codex-settings-v3"))
|
|
44198
44328
|
throw new Error("Codex settings witness upgrade requires an eligible preserved configuration witness");
|
|
44199
44329
|
const preimage = readCodexSettingsPreimage(options.reviewedPreimage);
|
|
44200
44330
|
for (const source of binding.sources) {
|
|
44201
44331
|
if (source === previous || source.path !== configPath)
|
|
44202
44332
|
continue;
|
|
44203
44333
|
const fields2 = source.fields;
|
|
44204
|
-
if (source.hashMode !== undefined || source.format !== "toml" || !Array.isArray(fields2) || !
|
|
44334
|
+
if (source.hashMode !== undefined || source.format !== "toml" || !Array.isArray(fields2) || !isDeepStrictEqual7(fields2, [...CODEX_DISCOVERY_PROJECTION_FIELDS]) || typeof source.sha256 !== "string")
|
|
44205
44335
|
throw new Error("Codex settings witness upgrade found an unrecognized configuration witness");
|
|
44206
44336
|
if (projectNativeDiscoveryFields(preimage, "toml", fields2, configPath) !== source.sha256)
|
|
44207
44337
|
throw new Error("Reviewed preimage does not explain the Codex discovery projection witness");
|
|
44208
44338
|
replaced.push(source);
|
|
44209
44339
|
}
|
|
44210
44340
|
}
|
|
44211
|
-
const next = options.agent === "claude" ? upgradeClaudeSettingsWitness(previous, options.reviewedPreimage) : options.targetCodexVersion === 3 ? upgradeCodexSettingsWitnessV3(previous, options.reviewedPreimage) : upgradeCodexSettingsWitness(previous, options.reviewedPreimage);
|
|
44341
|
+
const next = options.agent === "claude" ? upgradeClaudeSettingsWitness(previous, options.reviewedPreimage) : options.targetCodexVersion === 4 ? upgradeCodexSettingsWitnessV4(previous, options.reviewedPreimage) : options.targetCodexVersion === 3 ? upgradeCodexSettingsWitnessV3(previous, options.reviewedPreimage) : upgradeCodexSettingsWitness(previous, options.reviewedPreimage);
|
|
44212
44342
|
const rebound = [];
|
|
44213
44343
|
for (const source of binding.sources) {
|
|
44214
44344
|
if (!replaced.includes(source)) {
|
|
@@ -44254,7 +44384,7 @@ function applyAgentIntegrationUnlocked(plan, options = {}, assertCurrent) {
|
|
|
44254
44384
|
const upgrade = plan.settingsWitnessUpgrade;
|
|
44255
44385
|
if (!plan.managedAgentChecks || !plan.observedPolicy?.before)
|
|
44256
44386
|
throw new Error("Invalid settings witness upgrade plan");
|
|
44257
|
-
const verified = planAgentSettingsWitnessUpgrade({ agent: upgrade.agent, ...upgrade.agent === "codex" ? { targetCodexVersion: upgrade.toHashMode === "codex-settings-v3" ? 3 : 2 } : {}, reviewedPreimage: upgrade.reviewedPreimage, home: plan.managedAgentChecks.home, dataDir: plan.dataDir, expectedPolicySha256: sha4(plan.observedPolicy.before), expectedSettingsSha256: upgrade.currentSettingsSha256 });
|
|
44387
|
+
const verified = planAgentSettingsWitnessUpgrade({ agent: upgrade.agent, ...upgrade.agent === "codex" ? { targetCodexVersion: upgrade.toHashMode === "codex-settings-v4" ? 4 : upgrade.toHashMode === "codex-settings-v3" ? 3 : 2 } : {}, reviewedPreimage: upgrade.reviewedPreimage, home: plan.managedAgentChecks.home, dataDir: plan.dataDir, expectedPolicySha256: sha4(plan.observedPolicy.before), expectedSettingsSha256: upgrade.currentSettingsSha256 });
|
|
44258
44388
|
if (JSON.stringify(verified.changes) !== JSON.stringify(plan.changes) || JSON.stringify(verified.settingsWitnessUpgrade) !== JSON.stringify(upgrade))
|
|
44259
44389
|
throw new Error("Settings witness upgrade plan changed");
|
|
44260
44390
|
provenDiscovery = verified.discoveryBefore[0];
|