@hasna/skills 0.10.26 → 0.10.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -0
- package/bin/index.js +436 -326
- package/bin/mcp.js +263 -117
- 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 +325 -218
- package/dist/lib/agent-discovery.d.ts +1 -1
- package/dist/lib/agent-integration.d.ts +1 -0
- package/dist/lib/codex-local-mcp-controls.d.ts +4 -0
- package/dist/lib/codex-mcp-discovery-projection.d.ts +7 -0
- package/dist/lib/codex-settings-witness.d.ts +15 -0
- package/dist/sdk/index.js +422 -317
- package/package.json +1 -1
package/bin/index.js
CHANGED
|
@@ -36868,7 +36868,7 @@ var package_default;
|
|
|
36868
36868
|
var init_package = __esm(() => {
|
|
36869
36869
|
package_default = {
|
|
36870
36870
|
name: "@hasna/skills",
|
|
36871
|
-
version: "0.10.
|
|
36871
|
+
version: "0.10.27",
|
|
36872
36872
|
description: "Skills library for AI coding agents",
|
|
36873
36873
|
type: "module",
|
|
36874
36874
|
bin: {
|
|
@@ -39994,8 +39994,8 @@ function assertAgentPolicyCollections(policy) {
|
|
|
39994
39994
|
text(source.path);
|
|
39995
39995
|
requireBound(source.sha256 === null || typeof source.sha256 === "string" && /^[a-f0-9]{64}$/.test(source.sha256));
|
|
39996
39996
|
if (source.hashMode !== undefined)
|
|
39997
|
-
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"].includes(source.hashMode) && source.format === undefined && source.fields === undefined && (source.hashMode === "bytes" || source.sha256 !== null));
|
|
39998
|
-
if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2")
|
|
39997
|
+
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));
|
|
39998
|
+
if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3")
|
|
39999
39999
|
requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute2(source.path) && resolve3(source.path) === source.path && basename2(source.path) === "config.toml");
|
|
40000
40000
|
if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3")
|
|
40001
40001
|
requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute2(source.path) && resolve3(source.path) === source.path && basename2(source.path) === "settings.json");
|
|
@@ -50634,6 +50634,72 @@ async function prepareSkillDependencies(skillPath, env3, timeoutMs = DEFAULT_PRE
|
|
|
50634
50634
|
var DEPENDENCY_PREPARATION_MARKER = ".skills-dependency-preparation", RECOVERY = "Skill dependency preparation is incomplete. Confirm no installer is running, successfully run bun install --no-save in the skill directory, then remove only .skills-dependency-preparation. See docs/skill-standard.md#recovering-interrupted-dependency-preparation.", DEFAULT_PREPARATION_TIMEOUT_MS = 60000;
|
|
50635
50635
|
var init_dependency_preparation = () => {};
|
|
50636
50636
|
|
|
50637
|
+
// src/lib/codex-local-mcp-controls.ts
|
|
50638
|
+
function isCodexLocalStdioMcpServer(name, server) {
|
|
50639
|
+
const identifier2 = (value) => typeof value === "string" && /^[A-Za-z0-9_-]{1,64}$/.test(value);
|
|
50640
|
+
const refuse = () => {
|
|
50641
|
+
throw new Error("Unsupported Codex local stdio MCP controls");
|
|
50642
|
+
};
|
|
50643
|
+
const object4 = (v) => Boolean(v && typeof v === "object" && !Array.isArray(v) && !(v instanceof Date));
|
|
50644
|
+
const textField = (v, empty = false) => typeof v === "string" && (empty || Boolean(v.trim())) && Buffer.byteLength(v) <= 16384 && !/[\x00-\x1f\x7f]/.test(v);
|
|
50645
|
+
const envName = (v) => typeof v === "string" && /^[A-Za-z_][A-Za-z0-9_]{0,255}$/.test(v);
|
|
50646
|
+
const optional = (v, valid) => v === undefined || v === null || valid(v);
|
|
50647
|
+
const stringList = (v) => Array.isArray(v) && v.length <= 256 && v.every((item) => textField(item));
|
|
50648
|
+
const approval = (v) => ["auto", "prompt", "writes", "approve"].includes(v);
|
|
50649
|
+
const duration = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0;
|
|
50650
|
+
const positiveInteger = (v) => Number.isSafeInteger(v) && v > 0;
|
|
50651
|
+
const fields = [
|
|
50652
|
+
"command",
|
|
50653
|
+
"args",
|
|
50654
|
+
"cwd",
|
|
50655
|
+
"env",
|
|
50656
|
+
"env_vars",
|
|
50657
|
+
"enabled",
|
|
50658
|
+
"required",
|
|
50659
|
+
"environment_id",
|
|
50660
|
+
"startup_readiness",
|
|
50661
|
+
"supports_parallel_tool_calls",
|
|
50662
|
+
"tool_input_schema_max_bytes",
|
|
50663
|
+
"startup_timeout_sec",
|
|
50664
|
+
"startup_timeout_ms",
|
|
50665
|
+
"tool_timeout_sec",
|
|
50666
|
+
"default_tools_approval_mode",
|
|
50667
|
+
"enabled_tools",
|
|
50668
|
+
"disabled_tools",
|
|
50669
|
+
"omit_tools_from",
|
|
50670
|
+
"tools",
|
|
50671
|
+
"name"
|
|
50672
|
+
];
|
|
50673
|
+
try {
|
|
50674
|
+
if (!identifier2(name) || !object4(server) || !Object.keys(server).every((key) => fields.includes(key)) || !textField(server.command) || !optional(server.args, (v) => Array.isArray(v) && v.length <= 256 && v.every((arg) => textField(arg, true))) || !optional(server.cwd, textField) || !optional(server.env, (v) => object4(v) && Object.keys(v).length <= 256 && Object.entries(v).every(([key, value]) => envName(key) && textField(value, true))) || !["enabled", "required", "supports_parallel_tool_calls"].every((key) => optional(server[key], (v) => typeof v === "boolean")) || !optional(server.environment_id, (v) => v === "local") || !optional(server.startup_readiness, (v) => ["connection", "catalog"].includes(v)) || !optional(server.tool_input_schema_max_bytes, positiveInteger) || !["startup_timeout_sec", "tool_timeout_sec"].every((key) => optional(server[key], duration)) || !optional(server.startup_timeout_ms, (v) => Number.isSafeInteger(v) && v >= 0) || !optional(server.default_tools_approval_mode, approval) || !["enabled_tools", "disabled_tools"].every((key) => optional(server[key], stringList)) || !optional(server.omit_tools_from, (v) => Array.isArray(v) && v.length <= 256 && v.every((item) => ["code_mode", "deferred", "direct"].includes(item))) || !optional(server.name, textField))
|
|
50675
|
+
refuse();
|
|
50676
|
+
if (server.env_vars !== undefined && server.env_vars !== null) {
|
|
50677
|
+
if (!Array.isArray(server.env_vars) || server.env_vars.length > 256)
|
|
50678
|
+
refuse();
|
|
50679
|
+
const names = server.env_vars.map((entry) => {
|
|
50680
|
+
if (envName(entry))
|
|
50681
|
+
return entry;
|
|
50682
|
+
if (!object4(entry) || !Object.keys(entry).every((key) => ["name", "source"].includes(key)) || !envName(entry.name) || !optional(entry.source, (v) => v === "local"))
|
|
50683
|
+
refuse();
|
|
50684
|
+
return entry.name;
|
|
50685
|
+
});
|
|
50686
|
+
if (new Set(names).size !== names.length)
|
|
50687
|
+
refuse();
|
|
50688
|
+
}
|
|
50689
|
+
if (server.tools !== undefined && server.tools !== null) {
|
|
50690
|
+
if (!object4(server.tools) || Object.keys(server.tools).length > 256)
|
|
50691
|
+
refuse();
|
|
50692
|
+
for (const [tool, config] of Object.entries(server.tools)) {
|
|
50693
|
+
if (!textField(tool) || !object4(config) || !Object.keys(config).every((key) => ["approval_mode", "output_token_limit"].includes(key)) || !optional(config.approval_mode, approval) || !optional(config.output_token_limit, positiveInteger))
|
|
50694
|
+
refuse();
|
|
50695
|
+
}
|
|
50696
|
+
}
|
|
50697
|
+
return true;
|
|
50698
|
+
} catch {
|
|
50699
|
+
return false;
|
|
50700
|
+
}
|
|
50701
|
+
}
|
|
50702
|
+
|
|
50637
50703
|
// src/lib/claude-settings-witness.ts
|
|
50638
50704
|
import { createHash as createHash8 } from "crypto";
|
|
50639
50705
|
import { closeSync as closeSync6, constants as constants6, fstatSync as fstatSync6, lstatSync as lstatSync11, openSync as openSync6, readSync as readSync4 } from "fs";
|
|
@@ -51290,65 +51356,14 @@ function mcpControls(path, read2) {
|
|
|
51290
51356
|
refuse2();
|
|
51291
51357
|
}
|
|
51292
51358
|
const object5 = (v) => Boolean(v && typeof v === "object" && !Array.isArray(v));
|
|
51293
|
-
const textField = (v, empty = false) => typeof v === "string" && (empty || Boolean(v.trim())) && Buffer.byteLength(v) <= 16384 && !/[\x00-\x1f\x7f]/.test(v);
|
|
51294
|
-
const envName = (v) => typeof v === "string" && /^[A-Za-z_][A-Za-z0-9_]{0,255}$/.test(v);
|
|
51295
|
-
const optional = (v, valid) => v === undefined || v === null || valid(v);
|
|
51296
|
-
const stringList = (v) => Array.isArray(v) && v.length <= 256 && v.every((item) => textField(item));
|
|
51297
|
-
const approval = (v) => ["auto", "prompt", "writes", "approve"].includes(v);
|
|
51298
|
-
const duration = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0;
|
|
51299
|
-
const positiveInteger = (v) => Number.isSafeInteger(v) && v > 0;
|
|
51300
|
-
const fields = [
|
|
51301
|
-
"command",
|
|
51302
|
-
"args",
|
|
51303
|
-
"cwd",
|
|
51304
|
-
"env",
|
|
51305
|
-
"env_vars",
|
|
51306
|
-
"enabled",
|
|
51307
|
-
"required",
|
|
51308
|
-
"environment_id",
|
|
51309
|
-
"startup_readiness",
|
|
51310
|
-
"supports_parallel_tool_calls",
|
|
51311
|
-
"tool_input_schema_max_bytes",
|
|
51312
|
-
"startup_timeout_sec",
|
|
51313
|
-
"startup_timeout_ms",
|
|
51314
|
-
"tool_timeout_sec",
|
|
51315
|
-
"default_tools_approval_mode",
|
|
51316
|
-
"enabled_tools",
|
|
51317
|
-
"disabled_tools",
|
|
51318
|
-
"omit_tools_from",
|
|
51319
|
-
"tools",
|
|
51320
|
-
"name"
|
|
51321
|
-
];
|
|
51322
51359
|
if (!object5(value) || Object.keys(value).length !== 1 || !object5(value.mcpServers))
|
|
51323
51360
|
refuse2();
|
|
51324
51361
|
const servers = Object.entries(value.mcpServers);
|
|
51325
51362
|
if (!servers.length || servers.length > 256)
|
|
51326
51363
|
refuse2();
|
|
51327
|
-
for (const [name, server] of servers)
|
|
51328
|
-
if (!
|
|
51364
|
+
for (const [name, server] of servers)
|
|
51365
|
+
if (!isCodexLocalStdioMcpServer(name, server))
|
|
51329
51366
|
refuse2();
|
|
51330
|
-
if (server.env_vars !== undefined && server.env_vars !== null) {
|
|
51331
|
-
if (!Array.isArray(server.env_vars) || server.env_vars.length > 256)
|
|
51332
|
-
refuse2();
|
|
51333
|
-
const names = server.env_vars.map((entry) => {
|
|
51334
|
-
if (envName(entry))
|
|
51335
|
-
return entry;
|
|
51336
|
-
if (!object5(entry) || !Object.keys(entry).every((key) => ["name", "source"].includes(key)) || !envName(entry.name) || !optional(entry.source, (v) => v === "local"))
|
|
51337
|
-
refuse2();
|
|
51338
|
-
return entry.name;
|
|
51339
|
-
});
|
|
51340
|
-
if (new Set(names).size !== names.length)
|
|
51341
|
-
refuse2();
|
|
51342
|
-
}
|
|
51343
|
-
if (server.tools !== undefined && server.tools !== null) {
|
|
51344
|
-
if (!object5(server.tools) || Object.keys(server.tools).length > 256)
|
|
51345
|
-
refuse2();
|
|
51346
|
-
for (const [tool, config] of Object.entries(server.tools)) {
|
|
51347
|
-
if (!textField(tool) || !object5(config) || !Object.keys(config).every((key) => ["approval_mode", "output_token_limit"].includes(key)) || !optional(config.approval_mode, approval) || !optional(config.output_token_limit, positiveInteger))
|
|
51348
|
-
refuse2();
|
|
51349
|
-
}
|
|
51350
|
-
}
|
|
51351
|
-
}
|
|
51352
51367
|
return sha2562;
|
|
51353
51368
|
}
|
|
51354
51369
|
function rootControls(root, read2) {
|
|
@@ -51728,6 +51743,71 @@ var init_codex_settings_witness_v1 = __esm(() => {
|
|
|
51728
51743
|
VERBOSITY = new Set(["low", "medium", "high"]);
|
|
51729
51744
|
});
|
|
51730
51745
|
|
|
51746
|
+
// src/lib/codex-mcp-discovery-projection.ts
|
|
51747
|
+
import { isDeepStrictEqual as isDeepStrictEqual3 } from "util";
|
|
51748
|
+
function record2(value) {
|
|
51749
|
+
return !!value && typeof value === "object" && !Array.isArray(value) && !(value instanceof Date);
|
|
51750
|
+
}
|
|
51751
|
+
function localStdio(name, row) {
|
|
51752
|
+
return name !== "codex_apps" && name !== "_codex_apps" && isCodexLocalStdioMcpServer(name, row);
|
|
51753
|
+
}
|
|
51754
|
+
function stripEmptyParent(config) {
|
|
51755
|
+
if (record2(config.mcp_servers) && !Object.keys(config.mcp_servers).length)
|
|
51756
|
+
delete config.mcp_servers;
|
|
51757
|
+
return config;
|
|
51758
|
+
}
|
|
51759
|
+
function projectRegularCodexMcp(config, source) {
|
|
51760
|
+
const unchanged2 = { config, numericSource: source };
|
|
51761
|
+
if (!record2(config.mcp_servers))
|
|
51762
|
+
return unchanged2;
|
|
51763
|
+
const candidates = Object.entries(config.mcp_servers).filter(([name, row]) => localStdio(name, row)).map(([name]) => name);
|
|
51764
|
+
if (!candidates.length)
|
|
51765
|
+
return unchanged2;
|
|
51766
|
+
const headers = [];
|
|
51767
|
+
let attempts = 0;
|
|
51768
|
+
for (const match of source.matchAll(/^[ \t]*\[{1,2}[^\r\n]*\]{1,2}[ \t]*(?:#[^\r\n]*)?(?:\r?\n|$)/gm)) {
|
|
51769
|
+
if (++attempts > 256)
|
|
51770
|
+
return unchanged2;
|
|
51771
|
+
try {
|
|
51772
|
+
Bun.TOML.parse(source.slice(0, match.index));
|
|
51773
|
+
} catch {
|
|
51774
|
+
continue;
|
|
51775
|
+
}
|
|
51776
|
+
let header;
|
|
51777
|
+
try {
|
|
51778
|
+
header = Bun.TOML.parse(match[0]);
|
|
51779
|
+
} catch {
|
|
51780
|
+
return unchanged2;
|
|
51781
|
+
}
|
|
51782
|
+
const path = [];
|
|
51783
|
+
while (record2(header) && Object.keys(header).length === 1) {
|
|
51784
|
+
const key = Object.keys(header)[0];
|
|
51785
|
+
path.push(key);
|
|
51786
|
+
header = header[key];
|
|
51787
|
+
}
|
|
51788
|
+
headers.push({ start: match.index, path });
|
|
51789
|
+
}
|
|
51790
|
+
const names = candidates.filter((name) => headers.filter((header) => header.path.length === 2 && header.path[0] === "mcp_servers" && header.path[1] === name).length === 1);
|
|
51791
|
+
if (!names.length)
|
|
51792
|
+
return unchanged2;
|
|
51793
|
+
const selected = headers.map((header, index) => ({ ...header, end: headers[index + 1]?.start ?? source.length })).filter((header) => header.path[0] === "mcp_servers" && names.includes(header.path[1]));
|
|
51794
|
+
let numericSource = source;
|
|
51795
|
+
for (const range2 of selected.reverse())
|
|
51796
|
+
numericSource = numericSource.slice(0, range2.start) + numericSource.slice(range2.end);
|
|
51797
|
+
const expected = structuredClone(config);
|
|
51798
|
+
for (const name of names)
|
|
51799
|
+
delete expected.mcp_servers[name];
|
|
51800
|
+
stripEmptyParent(expected);
|
|
51801
|
+
try {
|
|
51802
|
+
if (!isDeepStrictEqual3(stripEmptyParent(Bun.TOML.parse(numericSource)), expected))
|
|
51803
|
+
return unchanged2;
|
|
51804
|
+
} catch {
|
|
51805
|
+
return unchanged2;
|
|
51806
|
+
}
|
|
51807
|
+
return { config: expected, numericSource };
|
|
51808
|
+
}
|
|
51809
|
+
var init_codex_mcp_discovery_projection = () => {};
|
|
51810
|
+
|
|
51731
51811
|
// src/lib/codex-settings-witness.ts
|
|
51732
51812
|
import { createHash as createHash10 } from "crypto";
|
|
51733
51813
|
function need4(value) {
|
|
@@ -51800,7 +51880,7 @@ function canonical4(value, depth = 0, budget = { remaining: 65536 }) {
|
|
|
51800
51880
|
need4(isRecord3(value));
|
|
51801
51881
|
return ["object", Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, child]) => [key, canonical4(child, depth + 1, budget)])];
|
|
51802
51882
|
}
|
|
51803
|
-
function normalize3(config) {
|
|
51883
|
+
function normalize3(config, version = 2) {
|
|
51804
51884
|
if (isRecord3(config.hooks)) {
|
|
51805
51885
|
delete config.hooks.state;
|
|
51806
51886
|
if (!Object.keys(config.hooks).length)
|
|
@@ -51818,11 +51898,11 @@ function normalize3(config) {
|
|
|
51818
51898
|
if (!Object.keys(skills).length)
|
|
51819
51899
|
delete config.skills;
|
|
51820
51900
|
}
|
|
51821
|
-
inference(config);
|
|
51901
|
+
inference(config, version);
|
|
51822
51902
|
if (isRecord3(config.profiles)) {
|
|
51823
51903
|
for (const profile of Object.values(config.profiles))
|
|
51824
51904
|
if (isRecord3(profile))
|
|
51825
|
-
inference(profile);
|
|
51905
|
+
inference(profile, version);
|
|
51826
51906
|
}
|
|
51827
51907
|
}
|
|
51828
51908
|
function disablesOneSkill(entry) {
|
|
@@ -51834,18 +51914,23 @@ function disablesOneSkill(entry) {
|
|
|
51834
51914
|
const selector = ["path", "name"].filter((key) => Object.hasOwn(entry, key));
|
|
51835
51915
|
return selector.length === 1 && typeof entry[selector[0]] === "string" && entry[selector[0]].length > 0;
|
|
51836
51916
|
}
|
|
51837
|
-
function inference(target) {
|
|
51838
|
-
|
|
51917
|
+
function inference(target, version) {
|
|
51918
|
+
const keys2 = version === 3 ? [...INFERENCE, "service_tier", "plan_mode_reasoning_effort"] : INFERENCE;
|
|
51919
|
+
for (const key of keys2)
|
|
51839
51920
|
if (Object.hasOwn(target, key)) {
|
|
51840
51921
|
const value = target[key];
|
|
51841
51922
|
if (key === "model")
|
|
51842
51923
|
need4(typeof value === "string" && MODEL.test(value));
|
|
51843
|
-
else
|
|
51924
|
+
else if (version === 3 && key !== "model_verbosity") {
|
|
51925
|
+
need4(typeof value === "string" && value.length <= 128 && !/[\x00-\x1f\x7f]/.test(value));
|
|
51926
|
+
if (key !== "service_tier")
|
|
51927
|
+
need4(value.length > 0);
|
|
51928
|
+
} else
|
|
51844
51929
|
need4(typeof value === "string" && (key === "model_reasoning_effort" ? EFFORT2.has(value) : VERBOSITY2.has(value)));
|
|
51845
51930
|
delete target[key];
|
|
51846
51931
|
}
|
|
51847
51932
|
}
|
|
51848
|
-
function settingsDigest2(text2) {
|
|
51933
|
+
function settingsDigest2(text2, version = 2) {
|
|
51849
51934
|
let config;
|
|
51850
51935
|
try {
|
|
51851
51936
|
config = Bun.TOML.parse(text2);
|
|
@@ -51853,8 +51938,9 @@ function settingsDigest2(text2) {
|
|
|
51853
51938
|
throw new Error("Invalid Codex settings witness");
|
|
51854
51939
|
}
|
|
51855
51940
|
need4(isRecord3(config));
|
|
51856
|
-
|
|
51857
|
-
|
|
51941
|
+
const projected = version === 3 ? projectRegularCodexMcp(config, text2) : { config, numericSource: text2 };
|
|
51942
|
+
normalize3(projected.config, version);
|
|
51943
|
+
return sha2(`hasna.skills.codex-settings.v${version}\x00${JSON.stringify([canonical4(projected.config), numericTokens2(projected.numericSource)])}`);
|
|
51858
51944
|
}
|
|
51859
51945
|
function hashCodexSettingsReplacementV2(text2, budget = { remaining: 256 * 1024 * 1024 }) {
|
|
51860
51946
|
need4(Buffer.byteLength(text2) <= 1024 * 1024 && budget.remaining >= Buffer.byteLength(text2));
|
|
@@ -51878,10 +51964,30 @@ function upgradeCodexSettingsWitness(previous, reviewedSettingsPath) {
|
|
|
51878
51964
|
throw new Error("Codex non-preference settings changed; explicit discovery review required");
|
|
51879
51965
|
return { path: previous.path, hashMode: "codex-settings-v2", sha256: sha2562 };
|
|
51880
51966
|
}
|
|
51967
|
+
function hashCodexSettingsReplacementV3(text2, budget = { remaining: 256 * 1024 * 1024 }) {
|
|
51968
|
+
need4(Buffer.byteLength(text2) <= 1024 * 1024 && budget.remaining >= Buffer.byteLength(text2));
|
|
51969
|
+
budget.remaining -= Buffer.byteLength(text2);
|
|
51970
|
+
return settingsDigest2(text2, 3);
|
|
51971
|
+
}
|
|
51972
|
+
function captureCodexSettingsV3(path, budget = { remaining: 256 * 1024 * 1024 }) {
|
|
51973
|
+
return { path, hashMode: "codex-settings-v3", sha256: settingsDigest2(readNativeSettingsWitnessFile(path, budget, "config.toml"), 3) };
|
|
51974
|
+
}
|
|
51975
|
+
function upgradeCodexSettingsWitnessV3(previous, reviewedSettingsPath) {
|
|
51976
|
+
need4(previous && Object.keys(previous).every((key) => ["path", "hashMode", "sha256"].includes(key)) && (previous.hashMode === undefined || ["bytes", "codex-settings-v1", "codex-settings-v2"].includes(previous.hashMode)) && /^[a-f0-9]{64}$/.test(previous.sha256));
|
|
51977
|
+
const budget = { remaining: 2 * 1024 * 1024 };
|
|
51978
|
+
const before2 = readNativeSettingsWitnessFile(reviewedSettingsPath, budget, "config.toml"), current = readNativeSettingsWitnessFile(previous.path, budget, "config.toml");
|
|
51979
|
+
const original = previous.hashMode === "codex-settings-v2" ? settingsDigest2(before2) : previous.hashMode === "codex-settings-v1" ? hashCodexSettingsReplacement(before2) : sha2(before2);
|
|
51980
|
+
need4(original === previous.sha256);
|
|
51981
|
+
const sha2562 = settingsDigest2(current, 3);
|
|
51982
|
+
if (settingsDigest2(before2, 3) !== sha2562)
|
|
51983
|
+
throw new Error("Codex settings outside the reviewed V3 contract changed; explicit discovery review required");
|
|
51984
|
+
return { path: previous.path, hashMode: "codex-settings-v3", sha256: sha2562 };
|
|
51985
|
+
}
|
|
51881
51986
|
var sha2 = (text2) => createHash10("sha256").update(text2).digest("hex"), EFFORT2, VERBOSITY2, MODEL, CODEX_DISCOVERY_PROJECTION_FIELDS, INFERENCE;
|
|
51882
51987
|
var init_codex_settings_witness = __esm(() => {
|
|
51883
51988
|
init_codex_settings_witness_v1();
|
|
51884
51989
|
init_codex_settings_witness_v1();
|
|
51990
|
+
init_codex_mcp_discovery_projection();
|
|
51885
51991
|
init_claude_settings_witness();
|
|
51886
51992
|
EFFORT2 = new Set(["none", "minimal", "low", "medium", "high", "xhigh"]);
|
|
51887
51993
|
VERBOSITY2 = new Set(["low", "medium", "high"]);
|
|
@@ -52019,7 +52125,7 @@ var init_agent_bridge = __esm(() => {
|
|
|
52019
52125
|
});
|
|
52020
52126
|
|
|
52021
52127
|
// src/lib/agent-codex.ts
|
|
52022
|
-
import { isDeepStrictEqual as
|
|
52128
|
+
import { isDeepStrictEqual as isDeepStrictEqual4 } from "util";
|
|
52023
52129
|
function splitTopLevel(value, delimiter) {
|
|
52024
52130
|
const result2 = [];
|
|
52025
52131
|
let start = 0, square = 0, curly = 0, quote = null, escaped = false;
|
|
@@ -52148,7 +52254,7 @@ function normalizeCodexInlinePathConfig(text2) {
|
|
|
52148
52254
|
const expectedWithoutConfig = structuredClone(before2);
|
|
52149
52255
|
delete expectedWithoutConfig.skills.config;
|
|
52150
52256
|
try {
|
|
52151
|
-
if (
|
|
52257
|
+
if (isDeepStrictEqual4(Bun.TOML.parse(text2.replace(CODEX_SKILL_CONFIG_SECTIONS, "")), expectedWithoutConfig))
|
|
52152
52258
|
return text2;
|
|
52153
52259
|
} catch {}
|
|
52154
52260
|
const matches2 = [];
|
|
@@ -52201,7 +52307,7 @@ function normalizeCodexInlinePathConfig(text2) {
|
|
|
52201
52307
|
try {
|
|
52202
52308
|
const after2 = Bun.TOML.parse(candidate);
|
|
52203
52309
|
const expected = structuredClone(before2);
|
|
52204
|
-
if (
|
|
52310
|
+
if (isDeepStrictEqual4(after2, expected))
|
|
52205
52311
|
matches2.push(candidate);
|
|
52206
52312
|
} catch {}
|
|
52207
52313
|
}
|
|
@@ -52217,11 +52323,11 @@ function assertCodexPathConfigEditable(text2) {
|
|
|
52217
52323
|
delete expected.skills.config;
|
|
52218
52324
|
try {
|
|
52219
52325
|
const withoutSections = Bun.TOML.parse(text2.replace(CODEX_SKILL_CONFIG_SECTIONS, ""));
|
|
52220
|
-
if (
|
|
52326
|
+
if (isDeepStrictEqual4(withoutSections, expected))
|
|
52221
52327
|
return;
|
|
52222
52328
|
const normalized = normalizeCodexInlinePathConfig(text2);
|
|
52223
52329
|
const withoutNormalizedSections = Bun.TOML.parse(normalized.replace(CODEX_SKILL_CONFIG_SECTIONS, ""));
|
|
52224
|
-
if (
|
|
52330
|
+
if (isDeepStrictEqual4(withoutNormalizedSections, expected))
|
|
52225
52331
|
return;
|
|
52226
52332
|
} catch {}
|
|
52227
52333
|
throw codexPathConfigRefusal();
|
|
@@ -52259,7 +52365,7 @@ function disableCodexBundledSkills(text2) {
|
|
|
52259
52365
|
const candidates = new Set;
|
|
52260
52366
|
const consider = (candidate) => {
|
|
52261
52367
|
try {
|
|
52262
|
-
if (
|
|
52368
|
+
if (isDeepStrictEqual4(Bun.TOML.parse(candidate), expected))
|
|
52263
52369
|
candidates.add(candidate);
|
|
52264
52370
|
} catch {}
|
|
52265
52371
|
};
|
|
@@ -52290,7 +52396,7 @@ var init_agent_codex = __esm(() => {
|
|
|
52290
52396
|
|
|
52291
52397
|
// src/lib/agent-integration.ts
|
|
52292
52398
|
import { createHash as createHash12, randomUUID as randomUUID5 } from "crypto";
|
|
52293
|
-
import { isDeepStrictEqual as
|
|
52399
|
+
import { isDeepStrictEqual as isDeepStrictEqual5 } from "util";
|
|
52294
52400
|
import { existsSync as existsSync12, lstatSync as lstatSync15, statSync as statSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync13, readdirSync as readdirSync8, opendirSync as opendirSync3, readlinkSync as readlinkSync4, realpathSync as realpathSync6, renameSync as renameSync2, rmdirSync as rmdirSync2, writeFileSync as writeFileSync4, unlinkSync as unlinkSync3, chmodSync, openSync as openSync8, closeSync as closeSync8, fsyncSync as fsyncSync2, fstatSync as fstatSync8, readSync as readSync6, constants as constants8, linkSync } from "fs";
|
|
52295
52401
|
import { dirname as dirname11, join as join21, resolve as resolve11, relative as relative5, isAbsolute as isAbsolute11, sep as sep5 } from "path";
|
|
52296
52402
|
import { homedir as homedir3 } from "os";
|
|
@@ -52500,14 +52606,14 @@ function parseNativeMigrationTargetManifest(input) {
|
|
|
52500
52606
|
}
|
|
52501
52607
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
52502
52608
|
throw new Error("Invalid native migration target manifest");
|
|
52503
|
-
const
|
|
52504
|
-
if (
|
|
52609
|
+
const record3 = value;
|
|
52610
|
+
if (record3.schema !== "hasna.skills-native-migration-targets.v1" || Object.keys(record3).some((key) => !["schema", "targets"].includes(key)))
|
|
52505
52611
|
throw new Error("Unsupported native migration target manifest schema");
|
|
52506
|
-
if (!Array.isArray(
|
|
52612
|
+
if (!Array.isArray(record3.targets) || record3.targets.length === 0 || record3.targets.length > 1000)
|
|
52507
52613
|
throw new Error("Native migration target manifest must contain 1 to 1000 targets");
|
|
52508
52614
|
const targets = [];
|
|
52509
52615
|
const identities = new Set;
|
|
52510
|
-
for (const target of
|
|
52616
|
+
for (const target of record3.targets) {
|
|
52511
52617
|
if (!target || typeof target !== "object" || Array.isArray(target))
|
|
52512
52618
|
throw new Error("Invalid native migration target");
|
|
52513
52619
|
const item = target;
|
|
@@ -53045,6 +53151,8 @@ function atomicWrite2(path, content) {
|
|
|
53045
53151
|
}
|
|
53046
53152
|
}
|
|
53047
53153
|
function planAgentSettingsWitnessUpgrade(options) {
|
|
53154
|
+
if (options.targetCodexVersion !== undefined && (options.agent !== "codex" || ![2, 3].includes(options.targetCodexVersion)))
|
|
53155
|
+
throw new Error("Invalid Codex witness target version");
|
|
53048
53156
|
const home = resolve11(options.home ?? homedir3()), dataDir3 = options.dataDir ?? getDataDirReadOnly();
|
|
53049
53157
|
const snapshot = readManagedSkillPolicySnapshot(dataDir3);
|
|
53050
53158
|
if (!snapshot || sha3(snapshot.text) !== options.expectedPolicySha256)
|
|
@@ -53066,21 +53174,21 @@ function planAgentSettingsWitnessUpgrade(options) {
|
|
|
53066
53174
|
throw new Error("Settings witness upgrade requires a preserved settings preimage");
|
|
53067
53175
|
const replaced = [previous];
|
|
53068
53176
|
if (options.agent === "codex") {
|
|
53069
|
-
if (previous.hashMode !== undefined && previous.hashMode !== "bytes" && previous.hashMode !== "codex-settings-v1")
|
|
53070
|
-
throw new Error("Codex settings witness upgrade requires
|
|
53177
|
+
if (previous.hashMode !== undefined && previous.hashMode !== "bytes" && previous.hashMode !== "codex-settings-v1" && !(options.targetCodexVersion === 3 && previous.hashMode === "codex-settings-v2"))
|
|
53178
|
+
throw new Error("Codex settings witness upgrade requires an eligible preserved configuration witness");
|
|
53071
53179
|
const preimage = readCodexSettingsPreimage(options.reviewedPreimage);
|
|
53072
53180
|
for (const source of binding.sources) {
|
|
53073
53181
|
if (source === previous || source.path !== configPath)
|
|
53074
53182
|
continue;
|
|
53075
53183
|
const fields = source.fields;
|
|
53076
|
-
if (source.hashMode !== undefined || source.format !== "toml" || !Array.isArray(fields) || !
|
|
53184
|
+
if (source.hashMode !== undefined || source.format !== "toml" || !Array.isArray(fields) || !isDeepStrictEqual5(fields, [...CODEX_DISCOVERY_PROJECTION_FIELDS]) || typeof source.sha256 !== "string")
|
|
53077
53185
|
throw new Error("Codex settings witness upgrade found an unrecognized configuration witness");
|
|
53078
53186
|
if (projectNativeDiscoveryFields(preimage, "toml", fields, configPath) !== source.sha256)
|
|
53079
53187
|
throw new Error("Reviewed preimage does not explain the Codex discovery projection witness");
|
|
53080
53188
|
replaced.push(source);
|
|
53081
53189
|
}
|
|
53082
53190
|
}
|
|
53083
|
-
const next = options.agent === "claude" ? upgradeClaudeSettingsWitness(previous, options.reviewedPreimage) : upgradeCodexSettingsWitness(previous, options.reviewedPreimage);
|
|
53191
|
+
const next = options.agent === "claude" ? upgradeClaudeSettingsWitness(previous, options.reviewedPreimage) : options.targetCodexVersion === 3 ? upgradeCodexSettingsWitnessV3(previous, options.reviewedPreimage) : upgradeCodexSettingsWitness(previous, options.reviewedPreimage);
|
|
53084
53192
|
const rebound = [];
|
|
53085
53193
|
for (const source of binding.sources) {
|
|
53086
53194
|
if (!replaced.includes(source)) {
|
|
@@ -53117,7 +53225,7 @@ function applyAgentIntegration(plan) {
|
|
|
53117
53225
|
const upgrade = plan.settingsWitnessUpgrade;
|
|
53118
53226
|
if (!plan.managedAgentChecks || !plan.observedPolicy?.before)
|
|
53119
53227
|
throw new Error("Invalid settings witness upgrade plan");
|
|
53120
|
-
const verified = planAgentSettingsWitnessUpgrade({ agent: upgrade.agent, reviewedPreimage: upgrade.reviewedPreimage, home: plan.managedAgentChecks.home, dataDir: plan.dataDir, expectedPolicySha256: sha3(plan.observedPolicy.before), expectedSettingsSha256: upgrade.currentSettingsSha256 });
|
|
53228
|
+
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: sha3(plan.observedPolicy.before), expectedSettingsSha256: upgrade.currentSettingsSha256 });
|
|
53121
53229
|
if (JSON.stringify(verified.changes) !== JSON.stringify(plan.changes) || JSON.stringify(verified.settingsWitnessUpgrade) !== JSON.stringify(upgrade))
|
|
53122
53230
|
throw new Error("Settings witness upgrade plan changed");
|
|
53123
53231
|
provenDiscovery = verified.discoveryBefore[0];
|
|
@@ -53653,15 +53761,15 @@ function migrateOwnerLayout(options = {}) {
|
|
|
53653
53761
|
moved.push(name);
|
|
53654
53762
|
}
|
|
53655
53763
|
createLazyDirs(appDir, created);
|
|
53656
|
-
const
|
|
53764
|
+
const record3 = {
|
|
53657
53765
|
version: 1,
|
|
53658
53766
|
migratedAt: new Date().toISOString(),
|
|
53659
53767
|
moved,
|
|
53660
53768
|
note: "installed/ and legacy flat skill dirs moved into skills/; custom/ retained"
|
|
53661
53769
|
};
|
|
53662
|
-
writeFileSync5(layoutMigrationRecordPath(appDir), `${JSON.stringify(
|
|
53770
|
+
writeFileSync5(layoutMigrationRecordPath(appDir), `${JSON.stringify(record3, null, 2)}
|
|
53663
53771
|
`);
|
|
53664
|
-
return { status: "migrated", moved, created, record:
|
|
53772
|
+
return { status: "migrated", moved, created, record: record3 };
|
|
53665
53773
|
}
|
|
53666
53774
|
var LOGS_DIRNAME = "logs", OUTPUTS_DIRNAME = "outputs", LEGACY_CUSTOM_DIRNAME = "custom";
|
|
53667
53775
|
var init_home_migration = __esm(() => {
|
|
@@ -56461,7 +56569,7 @@ var sameStat = (a, b) => ["dev", "ino", "uid", "nlink", "mode", "size", "mtimeNs
|
|
|
56461
56569
|
var init_codex_hook_trust_files = () => {};
|
|
56462
56570
|
|
|
56463
56571
|
// src/lib/codex-hook-trust-layout.ts
|
|
56464
|
-
import { isDeepStrictEqual as
|
|
56572
|
+
import { isDeepStrictEqual as isDeepStrictEqual6 } from "util";
|
|
56465
56573
|
function codexTrustTextWitness(text2, keys2, canonicalize = true) {
|
|
56466
56574
|
const parsed = Bun.TOML.parse(text2), wanted = new Set(keys2);
|
|
56467
56575
|
const headers = [...text2.matchAll(/^[ \t]*(\[[^\r\n]+\])[ \t]*(#[^\r\n]*)?(?:\r?\n|$)/gm)];
|
|
@@ -56526,7 +56634,7 @@ function codexTrustTextWitness(text2, keys2, canonicalize = true) {
|
|
|
56526
56634
|
if (expected.hooks)
|
|
56527
56635
|
delete expected.hooks.state;
|
|
56528
56636
|
try {
|
|
56529
|
-
if (!
|
|
56637
|
+
if (!isDeepStrictEqual6(prune(Bun.TOML.parse(noState)), prune(expected)))
|
|
56530
56638
|
throw fail2();
|
|
56531
56639
|
} catch {
|
|
56532
56640
|
throw fail2();
|
|
@@ -56596,13 +56704,13 @@ var init_codex_hook_trust_layout = () => {};
|
|
|
56596
56704
|
|
|
56597
56705
|
// src/lib/codex-hook-additions-review.ts
|
|
56598
56706
|
import { isAbsolute as isAbsolute16 } from "path";
|
|
56599
|
-
import { isDeepStrictEqual as
|
|
56707
|
+
import { isDeepStrictEqual as isDeepStrictEqual7 } from "util";
|
|
56600
56708
|
function exactKeys2(value, keys2) {
|
|
56601
|
-
need6(value && typeof value === "object" && !Array.isArray(value) &&
|
|
56709
|
+
need6(value && typeof value === "object" && !Array.isArray(value) && isDeepStrictEqual7(Object.keys(value).sort(), [...keys2].sort()), "RECONCILE_ADDITIONS_REVIEW_SCHEMA");
|
|
56602
56710
|
}
|
|
56603
56711
|
function readReviewedAdditionTrustStates(proof, before2, current, journalHooks) {
|
|
56604
56712
|
const captured = proofs.get(proof);
|
|
56605
|
-
need6(!!captured && captured.before.file === before2.file && captured.before.sha256 === before2.sha256 && captured.current.file === current.file && captured.current.sha256 === current.sha256 &&
|
|
56713
|
+
need6(!!captured && captured.before.file === before2.file && captured.before.sha256 === before2.sha256 && captured.current.file === current.file && captured.current.sha256 === current.sha256 && isDeepStrictEqual7(captured.journalHooks, journalHooks.map(({ key, currentHash }) => ({ key, currentHash }))), "RECONCILE_ADDITIONS_PROOF_CHANGED");
|
|
56606
56714
|
captured.recheck();
|
|
56607
56715
|
unchanged2(before2);
|
|
56608
56716
|
unchanged2(current);
|
|
@@ -56625,7 +56733,7 @@ function reviewNativeHookAdditions(options) {
|
|
|
56625
56733
|
expectedProducer.hooks.state ??= {};
|
|
56626
56734
|
for (const hook of options.journalHooks)
|
|
56627
56735
|
expectedProducer.hooks.state[hook.key] = { ...expectedProducer.hooks.state[hook.key], enabled: true, trusted_hash: hook.currentHash };
|
|
56628
|
-
need6(
|
|
56736
|
+
need6(isDeepStrictEqual7(expectedProducer, producer) && codexTrustReconcileWitness(options.configBefore.text, originalKeys) === codexTrustReconcileWitness(producerConfig.text, originalKeys) && codexTrustUnmanagedSemantic(options.configBefore.text, originalKeys) === codexTrustUnmanagedSemantic(producerConfig.text, originalKeys), "RECONCILE_ADDITIONS_PRODUCER_PREIMAGE");
|
|
56629
56737
|
need6(Array.isArray(review.additions) && review.additions.length > 0 && review.additions.length <= 20, "RECONCILE_ADDITIONS_REVIEW_SCHEMA");
|
|
56630
56738
|
const expectedHooks = JSON.parse(options.hooksBefore.text), currentHooks = JSON.parse(options.hooksCurrent.text), expectedConfig = structuredClone(producer);
|
|
56631
56739
|
need6(expectedHooks.hooks && typeof expectedHooks.hooks === "object" && !Array.isArray(expectedHooks.hooks), "RECONCILE_ADDITIONS_DECLARATIONS");
|
|
@@ -56654,9 +56762,9 @@ function reviewNativeHookAdditions(options) {
|
|
|
56654
56762
|
expectedHooks.hooks[event] = [...groups, { ...event === "PreToolUse" ? { matcher: hook.matcher } : {}, hooks: [{ type: "command", command: hook.command, timeout: hook.timeoutSec }] }];
|
|
56655
56763
|
expectedConfig.hooks.state[key] = trustState;
|
|
56656
56764
|
}
|
|
56657
|
-
need6(
|
|
56765
|
+
need6(isDeepStrictEqual7(expectedHooks, currentHooks), "RECONCILE_ADDITIONS_DECLARATIONS");
|
|
56658
56766
|
const keys2 = added.map((hook) => hook.key);
|
|
56659
|
-
need6(
|
|
56767
|
+
need6(isDeepStrictEqual7(expectedConfig, structure(options.configCurrent.text)) && codexTrustReconcileWitness(producerConfig.text, keys2) === codexTrustReconcileWitness(options.configCurrent.text, keys2) && codexTrustUnmanagedSemantic(producerConfig.text, keys2) === codexTrustUnmanagedSemantic(options.configCurrent.text, keys2), "RECONCILE_ADDITIONS_CONFIG");
|
|
56660
56768
|
const inputs = [reviewFile, producerConfig, producerHooks, options.intent, options.policy, options.configBefore, options.configCurrent, options.hooksBefore, options.hooksCurrent];
|
|
56661
56769
|
const recheck = () => {
|
|
56662
56770
|
for (const input of inputs)
|
|
@@ -56679,7 +56787,7 @@ var init_codex_hook_additions_review = __esm(() => {
|
|
|
56679
56787
|
|
|
56680
56788
|
// src/lib/codex-hook-discovery-recovery.ts
|
|
56681
56789
|
import { createHash as createHash17 } from "crypto";
|
|
56682
|
-
import { isDeepStrictEqual as
|
|
56790
|
+
import { isDeepStrictEqual as isDeepStrictEqual8 } from "util";
|
|
56683
56791
|
function createCodexHookDiscoveryRecovery(binding, before2, current, hooks, additions) {
|
|
56684
56792
|
const journalHooks = hooks.map(({ key, currentHash }) => ({ key, currentHash }));
|
|
56685
56793
|
const additionStates = additions ? readReviewedAdditionTrustStates(additions, before2, current, journalHooks) : [];
|
|
@@ -56693,11 +56801,11 @@ function createCodexHookDiscoveryRecovery(binding, before2, current, hooks, addi
|
|
|
56693
56801
|
need6(binding.agent === "codex" && binding.method === "reviewed" && raw.length === 1 && raw[0].sha256 === before2.sha256 && before2.sha256 !== current.sha256, "RECONCILE_DISCOVERY_CONFIG_WITNESS");
|
|
56694
56802
|
need6(raw[0].format === undefined && raw[0].fields === undefined && raw[0].managedPlugins === undefined, "RECONCILE_DISCOVERY_CONFIG_WITNESS");
|
|
56695
56803
|
const typed = binding.sources.filter((source) => source.path === current.file && source.format === "toml");
|
|
56696
|
-
need6(typed.length === 1 && typed[0].hashMode === undefined &&
|
|
56804
|
+
need6(typed.length === 1 && typed[0].hashMode === undefined && isDeepStrictEqual8(typed[0].fields, fields), "RECONCILE_DISCOVERY_TYPED_WITNESS");
|
|
56697
56805
|
const original = structure2(before2.text), actual = structure2(current.text);
|
|
56698
56806
|
const project = (value) => Object.fromEntries(fields.map((field2) => [field2, value[field2] ?? null]));
|
|
56699
56807
|
const projection = sha4(JSON.stringify(project(original)));
|
|
56700
|
-
need6(typed[0].sha256 === projection && sha4(JSON.stringify(project(actual))) === projection &&
|
|
56808
|
+
need6(typed[0].sha256 === projection && sha4(JSON.stringify(project(actual))) === projection && isDeepStrictEqual8(project(original), project(actual)), "RECONCILE_DISCOVERY_TYPED_WITNESS");
|
|
56701
56809
|
const keys2 = [...journalHooks.map((hook) => hook.key), ...additionStates.map((hook) => hook.key)];
|
|
56702
56810
|
need6(journalHooks.length > 0 && keys2.length <= 100 && new Set(keys2).size === keys2.length && journalHooks.every((hook) => typeof hook.key === "string" && /^sha256:[a-f0-9]{64}$/.test(hook.currentHash)), "RECONCILE_DISCOVERY_TRUST_WITNESS");
|
|
56703
56811
|
const expected = structuredClone(original);
|
|
@@ -56707,7 +56815,7 @@ function createCodexHookDiscoveryRecovery(binding, before2, current, hooks, addi
|
|
|
56707
56815
|
expected.hooks.state[hook.key] = { ...expected.hooks.state[hook.key], enabled: true, trusted_hash: hook.currentHash };
|
|
56708
56816
|
for (const { key, state } of additionStates)
|
|
56709
56817
|
expected.hooks.state[key] = { ...state };
|
|
56710
|
-
need6(
|
|
56818
|
+
need6(isDeepStrictEqual8(expected, actual) && codexTrustReconcileWitness(before2.text, keys2) === codexTrustReconcileWitness(current.text, keys2) && codexTrustUnmanagedSemantic(before2.text, keys2) === codexTrustUnmanagedSemantic(current.text, keys2), "RECONCILE_DISCOVERY_TRUST_WITNESS");
|
|
56711
56819
|
unchanged2(before2);
|
|
56712
56820
|
unchanged2(current);
|
|
56713
56821
|
const witness = Object.freeze({ configPath: current.file, beforeSha256: before2.sha256, currentSha256: current.sha256, discoverySha256: sha4(JSON.stringify(binding)), typedProjectionSha256: projection });
|
|
@@ -56742,7 +56850,7 @@ var init_codex_hook_discovery_recovery = __esm(() => {
|
|
|
56742
56850
|
import { createHash as createHash18 } from "crypto";
|
|
56743
56851
|
import { lstatSync as lstatSync21, readFileSync as readFileSync18, readdirSync as readdirSync11, realpathSync as realpathSync7 } from "fs";
|
|
56744
56852
|
import { basename as basename9, dirname as dirname17, isAbsolute as isAbsolute17, join as join32, resolve as resolve16, sep as sep6 } from "path";
|
|
56745
|
-
import { isDeepStrictEqual as
|
|
56853
|
+
import { isDeepStrictEqual as isDeepStrictEqual9 } from "util";
|
|
56746
56854
|
function parseConfig(text3, path, toml = false) {
|
|
56747
56855
|
try {
|
|
56748
56856
|
const value = toml ? Bun.TOML.parse(text3) : JSON.parse(text3);
|
|
@@ -56781,19 +56889,19 @@ function projectNativeDiscoveryFields(text3, format, fields2, path) {
|
|
|
56781
56889
|
return digest(JSON.stringify(Object.fromEntries(fields2.map((field2) => [field2, object5[field2] ?? null]))));
|
|
56782
56890
|
}
|
|
56783
56891
|
function isSupersededCodexProjection(agent, configPath, source) {
|
|
56784
|
-
return agent === "codex" && source.path === configPath && source.format === "toml" &&
|
|
56892
|
+
return agent === "codex" && source.path === configPath && source.format === "toml" && isDeepStrictEqual9(source.fields, [...CODEX_DISCOVERY_PROJECTION_FIELDS]);
|
|
56785
56893
|
}
|
|
56786
56894
|
function supersedesCodexProjection(sources, configPath) {
|
|
56787
|
-
return sources.some((source) => source.path === configPath && source.hashMode === "codex-settings-v2");
|
|
56895
|
+
return sources.some((source) => source.path === configPath && (source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3"));
|
|
56788
56896
|
}
|
|
56789
56897
|
function projected(source, changes, budget = discoveryByteBudget()) {
|
|
56790
|
-
if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2") {
|
|
56898
|
+
if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3") {
|
|
56791
56899
|
if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
|
|
56792
56900
|
throw new Error("Codex settings witnesses require exact typed metadata");
|
|
56793
|
-
const current = (source.hashMode === "codex-settings-v2" ? captureCodexSettingsV2 : captureCodexSettings)(source.path, budget).sha256;
|
|
56901
|
+
const current = (source.hashMode === "codex-settings-v3" ? captureCodexSettingsV3 : source.hashMode === "codex-settings-v2" ? captureCodexSettingsV2 : captureCodexSettings)(source.path, budget).sha256;
|
|
56794
56902
|
if (current !== source.sha256)
|
|
56795
56903
|
throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
|
|
56796
|
-
return changes?.has(source.path) ? (source.hashMode === "codex-settings-v2" ? hashCodexSettingsReplacementV2 : hashCodexSettingsReplacement)(changes.get(source.path), budget) : current;
|
|
56904
|
+
return changes?.has(source.path) ? (source.hashMode === "codex-settings-v3" ? hashCodexSettingsReplacementV3 : source.hashMode === "codex-settings-v2" ? hashCodexSettingsReplacementV2 : hashCodexSettingsReplacement)(changes.get(source.path), budget) : current;
|
|
56797
56905
|
}
|
|
56798
56906
|
if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") {
|
|
56799
56907
|
if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
|
|
@@ -56893,7 +57001,7 @@ function codexInstallationRoots(binding) {
|
|
|
56893
57001
|
});
|
|
56894
57002
|
}
|
|
56895
57003
|
function assertMarketplaceBinding(binding, source) {
|
|
56896
|
-
if ((source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2") && (binding.agent !== "codex" || binding.method !== "reviewed" || basename9(source.path) !== "config.toml"))
|
|
57004
|
+
if ((source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3") && (binding.agent !== "codex" || binding.method !== "reviewed" || basename9(source.path) !== "config.toml"))
|
|
56897
57005
|
throw new Error("Codex settings witnesses require explicit reviewed Codex configuration");
|
|
56898
57006
|
if ((source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") && (binding.agent !== "claude" || binding.method !== "reviewed" || basename9(source.path) !== "settings.json"))
|
|
56899
57007
|
throw new Error("Claude settings witnesses require explicit reviewed Claude configuration");
|
|
@@ -57031,10 +57139,10 @@ function resolveAgentDiscovery(options) {
|
|
|
57031
57139
|
verifyAgentDiscovery(retained);
|
|
57032
57140
|
if (!retained.sources.some((source) => source.path === canonical6(configPath) && source.format === undefined && source.fields === undefined))
|
|
57033
57141
|
unresolved("retained review is missing the full agent configuration source");
|
|
57034
|
-
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.path !== canonical6(configPath)))
|
|
57142
|
+
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)))
|
|
57035
57143
|
unresolved("retained settings witness names another configuration source");
|
|
57036
57144
|
const covered = supersedesCodexProjection(retained.sources, canonical6(configPath)) ? sources.filter((source) => !isSupersededCodexProjection(agent, canonical6(configPath), source)) : sources;
|
|
57037
|
-
if (covered.some((source) => !retained.sources.some((saved) =>
|
|
57145
|
+
if (covered.some((source) => !retained.sources.some((saved) => isDeepStrictEqual9(saved, source))) || [...roots].some((root2) => !retained.roots.includes(root2)) || agent === "gemini" && JSON.stringify(retained.builtinNames) !== JSON.stringify(builtinNames))
|
|
57038
57146
|
unresolved("retained review is missing current runtime discovery coverage");
|
|
57039
57147
|
return retained;
|
|
57040
57148
|
}
|
|
@@ -57048,7 +57156,7 @@ function resolveAgentDiscovery(options) {
|
|
|
57048
57156
|
if (review.sources.some((source) => source.format !== undefined || source.fields !== undefined))
|
|
57049
57157
|
throw new Error("Explicit discovery reviews require full source-file hashes");
|
|
57050
57158
|
verifyAgentDiscovery(supplied);
|
|
57051
|
-
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.path !== canonical6(configPath)))
|
|
57159
|
+
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)))
|
|
57052
57160
|
throw new Error("Semantic settings witnesses must name the configured Claude configuration source");
|
|
57053
57161
|
if (!review.sources.some((source) => source.path === canonical6(configPath)))
|
|
57054
57162
|
throw new Error("Discovery review must include the agent configuration source");
|
|
@@ -59698,14 +59806,14 @@ function readIdentity(env3 = process.env) {
|
|
|
59698
59806
|
const parsed = JSON.parse(readFileSync20(getIdentityFilePath(env3), "utf-8"));
|
|
59699
59807
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
59700
59808
|
return {};
|
|
59701
|
-
const
|
|
59809
|
+
const record3 = parsed;
|
|
59702
59810
|
const selected = resolveSkillsApiOrigin(env3)?.origin;
|
|
59703
|
-
const bound = typeof
|
|
59811
|
+
const bound = typeof record3.apiUrl === "string" ? record3.apiUrl : readCredentialValue(SKILLS_BOUND_API_URL, env3) ?? readStoredApiUrl(env3) ?? defaultFleetGatewayBaseUrl("skills");
|
|
59704
59812
|
if (selected && normalizeSkillsApiOrigin(bound) !== selected)
|
|
59705
59813
|
return {};
|
|
59706
59814
|
const identity5 = {};
|
|
59707
59815
|
for (const field2 of ["email", "orgId", "orgSlug", "userId"]) {
|
|
59708
|
-
const value =
|
|
59816
|
+
const value = record3[field2];
|
|
59709
59817
|
if (typeof value === "string" && value.length > 0)
|
|
59710
59818
|
identity5[field2] = value;
|
|
59711
59819
|
}
|
|
@@ -59842,12 +59950,12 @@ function readStoredCredential(env3 = process.env) {
|
|
|
59842
59950
|
const origin = normalizeSkillsApiOrigin(readCredentialValue(SKILLS_BOUND_API_URL, env3) ?? readStoredApiUrl(env3) ?? defaultFleetGatewayBaseUrl("skills"));
|
|
59843
59951
|
let storedBy = "external";
|
|
59844
59952
|
let urlWrittenByLogin = false;
|
|
59845
|
-
const
|
|
59846
|
-
const recordedFor =
|
|
59847
|
-
if (
|
|
59848
|
-
storedBy =
|
|
59953
|
+
const record3 = apiKey ? readIdentityRecord(env3) : null;
|
|
59954
|
+
const recordedFor = record3 && typeof record3.apiUrl === "string" ? safeOrigin(record3.apiUrl) : null;
|
|
59955
|
+
if (record3 && recordedFor === origin) {
|
|
59956
|
+
storedBy = record3.issuedBy === "sign-in" || record3.issuedBy === "api-key" ? record3.issuedBy : "legacy";
|
|
59849
59957
|
const fileUrl = readStoredApiUrl(env3);
|
|
59850
|
-
urlWrittenByLogin = storedBy !== "legacy" &&
|
|
59958
|
+
urlWrittenByLogin = storedBy !== "legacy" && record3.urlWrittenBy === "login" && fileUrl !== null && safeOrigin(fileUrl) === origin;
|
|
59851
59959
|
}
|
|
59852
59960
|
return { file, apiKey: apiKey ?? null, origin, storedBy, urlWrittenByLogin };
|
|
59853
59961
|
}
|
|
@@ -59877,9 +59985,9 @@ function saveApiUrl(apiUrl, env3 = process.env) {
|
|
|
59877
59985
|
values2[SKILLS_BOUND_API_URL] = normalizeSkillsApiOrigin(readStoredApiUrl(env3) ?? defaultFleetGatewayBaseUrl("skills"));
|
|
59878
59986
|
}
|
|
59879
59987
|
const file = writeCredentialValues(values2, env3);
|
|
59880
|
-
const
|
|
59881
|
-
if (
|
|
59882
|
-
const { urlWrittenBy: _dropped, ...rest2 } =
|
|
59988
|
+
const record3 = readIdentityRecord(env3);
|
|
59989
|
+
if (record3 && "urlWrittenBy" in record3) {
|
|
59990
|
+
const { urlWrittenBy: _dropped, ...rest2 } = record3;
|
|
59883
59991
|
const identityFile = getIdentityFilePath(env3);
|
|
59884
59992
|
writeFileSync10(identityFile, JSON.stringify(rest2, null, 2) + `
|
|
59885
59993
|
`, { mode: 384 });
|
|
@@ -59918,7 +60026,7 @@ function invitationEmailIds(invitationId, challengeId) {
|
|
|
59918
60026
|
}
|
|
59919
60027
|
function invitationEmailInput(action, input) {
|
|
59920
60028
|
const keys2 = ["invitationId", "token", "challengeId", "confirm", ...action === "accept" ? ["code"] : []];
|
|
59921
|
-
if (!
|
|
60029
|
+
if (!record3(input) || Object.keys(input).length !== keys2.length || keys2.some((key) => !Object.hasOwn(input, key)))
|
|
59922
60030
|
throw new InvitationEmailInputError;
|
|
59923
60031
|
const value = { ...input };
|
|
59924
60032
|
const ids = invitationEmailIds(value.invitationId, value.challengeId);
|
|
@@ -59947,12 +60055,12 @@ async function requestInvitationEmail(origin, action, input) {
|
|
|
59947
60055
|
signal: AbortSignal.timeout(15000)
|
|
59948
60056
|
});
|
|
59949
60057
|
const parsed = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(await readBoundedResponse(response, 4096)));
|
|
59950
|
-
if (!response.ok &&
|
|
60058
|
+
if (!response.ok && record3(parsed) && typeof parsed.code === "string" && Object.hasOwn(refusals, parsed.code)) {
|
|
59951
60059
|
const code = parsed.code;
|
|
59952
60060
|
if (response.status === refusals[code][0])
|
|
59953
60061
|
throw new RemoteInvitationEmailError(code);
|
|
59954
60062
|
}
|
|
59955
|
-
if (!
|
|
60063
|
+
if (!record3(parsed))
|
|
59956
60064
|
throw new RemoteInvitationEmailUnconfirmedError(action);
|
|
59957
60065
|
if (action === "challenge" && response.status === 202 && parsed.challengeId === value.challengeId && parsed.expiresIn === 600 && typeof parsed.message === "string" && parsed.message.length <= 256) {
|
|
59958
60066
|
return { challengeId: value.challengeId, message: "If this invitation is eligible, a verification code will arrive. Delivery is not confirmed.", expiresIn: 600 };
|
|
@@ -59971,7 +60079,7 @@ function invitationEmailCustomerError(error) {
|
|
|
59971
60079
|
return { code: error.code, error: error.message };
|
|
59972
60080
|
return { code: "INVITATION_EMAIL_UNAVAILABLE", error: "Unable to prepare this recovery action. Check the explicit server and stable profile. No credential was saved." };
|
|
59973
60081
|
}
|
|
59974
|
-
var InvitationEmailInputError, refusals, RemoteInvitationEmailError, RemoteInvitationEmailUnconfirmedError,
|
|
60082
|
+
var InvitationEmailInputError, refusals, RemoteInvitationEmailError, RemoteInvitationEmailUnconfirmedError, record3 = (v) => !!v && typeof v === "object" && !Array.isArray(v), uuid = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v);
|
|
59975
60083
|
var init_remote_invitation_recovery = __esm(() => {
|
|
59976
60084
|
init_fleet_credentials();
|
|
59977
60085
|
init_remote_files();
|
|
@@ -60018,7 +60126,7 @@ function workspaceExpectedUserId(value) {
|
|
|
60018
60126
|
return value;
|
|
60019
60127
|
}
|
|
60020
60128
|
function workspaceContext(value) {
|
|
60021
|
-
if (!
|
|
60129
|
+
if (!record4(value) || Object.keys(value).sort().join(",") !== "membershipId,userId" || !uuid2(value.userId) || !uuid2(value.membershipId))
|
|
60022
60130
|
throw new WorkspaceContextInputError;
|
|
60023
60131
|
return { userId: value.userId, membershipId: value.membershipId };
|
|
60024
60132
|
}
|
|
@@ -60026,15 +60134,15 @@ function invalid2() {
|
|
|
60026
60134
|
throw new Error(invalidWorkspaceResult);
|
|
60027
60135
|
}
|
|
60028
60136
|
function organization(v) {
|
|
60029
|
-
if (!
|
|
60137
|
+
if (!record4(v) || !uuid2(v.id) || !text3(v.slug) || !text3(v.name))
|
|
60030
60138
|
return invalid2();
|
|
60031
60139
|
return { id: v.id, slug: v.slug, name: v.name };
|
|
60032
60140
|
}
|
|
60033
60141
|
function parseAccountWorkspaces(value) {
|
|
60034
|
-
if (!
|
|
60142
|
+
if (!record4(value) || !Array.isArray(value.workspaces) || !value.workspaces.length || value.workspaces.length > 1000)
|
|
60035
60143
|
return invalid2();
|
|
60036
60144
|
const workspaces = value.workspaces.map((v) => {
|
|
60037
|
-
if (!
|
|
60145
|
+
if (!record4(v) || !uuid2(v.membershipId) || !role(v.role) || typeof v.current !== "boolean")
|
|
60038
60146
|
return invalid2();
|
|
60039
60147
|
return { membershipId: v.membershipId, organization: organization(v.organization), role: v.role, current: v.current };
|
|
60040
60148
|
});
|
|
@@ -60043,10 +60151,10 @@ function parseAccountWorkspaces(value) {
|
|
|
60043
60151
|
return { workspaces };
|
|
60044
60152
|
}
|
|
60045
60153
|
function parseWorkspaceIdentity(value, expectedUserId) {
|
|
60046
|
-
if (!
|
|
60154
|
+
if (!record4(value))
|
|
60047
60155
|
return invalid2();
|
|
60048
60156
|
const user = value.user;
|
|
60049
|
-
if (!
|
|
60157
|
+
if (!record4(user) || !uuid2(user.id) || !uuid2(user.membershipId) || !text3(user.email, 320) || !(user.displayName === null || text3(user.displayName)) || !role(user.role))
|
|
60050
60158
|
return invalid2();
|
|
60051
60159
|
if (user.id !== expectedUserId)
|
|
60052
60160
|
throw new WorkspaceIdentityMismatchError;
|
|
@@ -60064,20 +60172,20 @@ function parseWorkspaceSession(value, expected) {
|
|
|
60064
60172
|
return { token: sessionToken(value.token), ...identity5 };
|
|
60065
60173
|
}
|
|
60066
60174
|
function parseWorkspaceLogin(value, expectedUserId) {
|
|
60067
|
-
const user =
|
|
60068
|
-
if (!
|
|
60175
|
+
const user = record4(value) && value.user;
|
|
60176
|
+
if (!record4(value) || !record4(user) || !uuid2(user.id))
|
|
60069
60177
|
return invalid2();
|
|
60070
60178
|
if (expectedUserId !== undefined && user.id !== expectedUserId)
|
|
60071
60179
|
throw new WorkspaceIdentityMismatchError;
|
|
60072
60180
|
return { token: sessionToken(value.token), userId: user.id };
|
|
60073
60181
|
}
|
|
60074
60182
|
function workspaceSelectionFailure(value, status) {
|
|
60075
|
-
if (!
|
|
60183
|
+
if (!record4(value) || typeof value.code !== "string" || !Object.hasOwn(workspaceSelectionFailures, value.code))
|
|
60076
60184
|
return null;
|
|
60077
60185
|
const code = value.code;
|
|
60078
60186
|
return workspaceSelectionFailures[code][0] === status ? code : null;
|
|
60079
60187
|
}
|
|
60080
|
-
var
|
|
60188
|
+
var record4 = (v) => !!v && typeof v === "object" && !Array.isArray(v), uuid2 = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), text3 = (v, max2 = 1024) => typeof v === "string" && !!v.trim() && v.length <= max2 && !/[\p{Cc}\p{Cs}\u2028\u2029]/u.test(v), role = (v) => typeof v === "string" && ["owner", "admin", "member", "viewer"].includes(v), invalidWorkspaceResult = "The server returned an invalid workspace selection result.", WorkspaceContextInputError, WorkspaceIdentityMismatchError, workspaceSelectionFailures;
|
|
60081
60189
|
var init_remote_workspace_selection = __esm(() => {
|
|
60082
60190
|
WorkspaceContextInputError = class WorkspaceContextInputError extends Error {
|
|
60083
60191
|
constructor() {
|
|
@@ -60108,7 +60216,7 @@ function checkedPublicationDeclaration(value) {
|
|
|
60108
60216
|
return bad();
|
|
60109
60217
|
try {
|
|
60110
60218
|
const manifest = JSON.parse(value.manifestText);
|
|
60111
|
-
if (!
|
|
60219
|
+
if (!record5(manifest) || manifest.version !== value.version || validatePortableManifestContract(manifest, { strict: true }).length || !hash3(manifest.provenance?.content_hash))
|
|
60112
60220
|
return bad();
|
|
60113
60221
|
} catch {
|
|
60114
60222
|
return bad();
|
|
@@ -60166,7 +60274,7 @@ async function boundedJson(url, init, token, mutation, budget = 15000, signal) {
|
|
|
60166
60274
|
return invalid3();
|
|
60167
60275
|
}
|
|
60168
60276
|
if (!response.ok) {
|
|
60169
|
-
const code =
|
|
60277
|
+
const code = record5(body) && typeof body.code === "string" && Object.hasOwn(failures, body.code) ? body.code : null;
|
|
60170
60278
|
if (code && failures[code][0] === response.status)
|
|
60171
60279
|
throw new PrivatePublicationError(code, failures[code][1], mutation && code === "PUBLICATION_UNCERTAIN", response.status);
|
|
60172
60280
|
throw new PrivatePublicationError("PUBLICATION_REQUEST_FAILED", "The publication request was refused. Inspect its status before retrying.", mutation && response.status >= 500, response.status);
|
|
@@ -60221,8 +60329,8 @@ class RemotePrivatePublicationsClient {
|
|
|
60221
60329
|
if (options.timeoutMs !== undefined && (!Number.isSafeInteger(options.timeoutMs) || options.timeoutMs < 1 || options.timeoutMs > 15000))
|
|
60222
60330
|
return bad();
|
|
60223
60331
|
const response = await boundedJson(skillsApiRequestUrl(this.apiOrigin, "/api/v1/capabilities"), {}, this.#token, false, options.timeoutMs, options.signal);
|
|
60224
|
-
const p =
|
|
60225
|
-
if (!
|
|
60332
|
+
const p = record5(response) && response.privatePublishing;
|
|
60333
|
+
if (!record5(response) || response.contractVersion !== 1 || response.apiVersion !== 1 || !exact(p, ["contractVersion", "enabled", "authentication", "maxArchiveBytes", "uploadMaxTtlSeconds", "executionEnabled"]) || p.contractVersion !== 1 || typeof p.enabled !== "boolean" || p.authentication !== "interactive-session" || p.maxArchiveBytes !== PRIVATE_PUBLICATION_MAX_BYTES || p.uploadMaxTtlSeconds !== 300 || typeof p.executionEnabled !== "boolean")
|
|
60226
60334
|
throw new PrivatePublicationError("PUBLICATION_CONTRACT_UNAVAILABLE", "This server does not support the hosted private publication contract.");
|
|
60227
60335
|
return Object.freeze({ ...p });
|
|
60228
60336
|
}
|
|
@@ -60238,7 +60346,7 @@ class RemotePrivatePublicationsClient {
|
|
|
60238
60346
|
async#view(path, method2, skillId, intentId, declaration, options = {}) {
|
|
60239
60347
|
const value = await boundedJson(path, { method: method2, ...method2 === "GET" ? {} : { body: JSON.stringify(declaration ?? {}) } }, this.#token, method2 !== "GET", options.timeoutMs, options.signal);
|
|
60240
60348
|
try {
|
|
60241
|
-
if (!
|
|
60349
|
+
if (!record5(value) || !Object.keys(value).every((k) => k === "upload" || k === "changed") || value.changed !== undefined && typeof value.changed !== "boolean")
|
|
60242
60350
|
return invalid3();
|
|
60243
60351
|
return checkedPublicationView(value.upload, skillId, intentId, declaration);
|
|
60244
60352
|
} catch (error) {
|
|
@@ -60363,7 +60471,7 @@ var PRIVATE_PUBLICATION_MAX_BYTES, failures, PrivatePublicationError, bad = () =
|
|
|
60363
60471
|
throw new PrivatePublicationError("INVALID_PUBLICATION_INPUT", "Invalid publication input or recovery data.");
|
|
60364
60472
|
}, invalid3 = () => {
|
|
60365
60473
|
throw new PrivatePublicationError("INVALID_PUBLICATION_RESPONSE", "The server returned an invalid publication result.");
|
|
60366
|
-
}, publicationUuid = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), hash3 = (v) => typeof v === "string" && /^[a-f0-9]{64}$/.test(v),
|
|
60474
|
+
}, publicationUuid = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), hash3 = (v) => typeof v === "string" && /^[a-f0-9]{64}$/.test(v), record5 = (v) => !!v && typeof v === "object" && !Array.isArray(v), exact = (v, keys2) => record5(v) && Object.keys(v).sort().join(",") === keys2.sort().join(","), date = (v) => typeof v === "string" && /^\d{4}-\d\d-\d\dT[0-9:.]+(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(v) && Number.isFinite(Date.parse(v)), publicationSha256 = (bytes) => createHash19("sha256").update(bytes).digest("hex");
|
|
60367
60475
|
var init_remote_private_publications = __esm(() => {
|
|
60368
60476
|
init_fleet_credentials();
|
|
60369
60477
|
init_remote_workspace_selection();
|
|
@@ -60406,7 +60514,7 @@ var init_remote_private_publications = __esm(() => {
|
|
|
60406
60514
|
|
|
60407
60515
|
// src/lib/remote-invitations.ts
|
|
60408
60516
|
function invitationFailure(value, status) {
|
|
60409
|
-
if (!
|
|
60517
|
+
if (!record6(value) || typeof value.code !== "string" || !Object.hasOwn(invitationFailures, value.code))
|
|
60410
60518
|
return null;
|
|
60411
60519
|
const code = value.code;
|
|
60412
60520
|
return invitationFailures[code][0] === status ? code : null;
|
|
@@ -60415,7 +60523,7 @@ function invitationId(value) {
|
|
|
60415
60523
|
return uuid3(value) ? value : inputFailure();
|
|
60416
60524
|
}
|
|
60417
60525
|
function invitationInput(action, input) {
|
|
60418
|
-
if (!
|
|
60526
|
+
if (!record6(input))
|
|
60419
60527
|
return inputFailure();
|
|
60420
60528
|
const keys2 = {
|
|
60421
60529
|
list: ["after"],
|
|
@@ -60466,7 +60574,7 @@ function invalid4() {
|
|
|
60466
60574
|
throw new RemoteWorkspaceInvitationReadError;
|
|
60467
60575
|
}
|
|
60468
60576
|
function projection(v, organizationId) {
|
|
60469
|
-
if (!
|
|
60577
|
+
if (!record6(v) || !uuid3(v.id) || v.organizationId !== organizationId || !email(v.email) || v.email !== v.email.trim().toLowerCase() || !role2(v.role) || !Number.isInteger(v.generation) || Number(v.generation) < 1 || Number(v.generation) > 10 || typeof v.status !== "string" || !["pending", "expired", "accepted", "revoked"].includes(v.status) || !timestamp(v.expiresAt) || !timestamp(v.createdAt) || !record6(v.delivery) || typeof v.delivery.state !== "string" || !["queued", "sending", "uncertain", "provider_accepted", "failed", "cancelled"].includes(v.delivery.state) || !Number.isInteger(v.delivery.attempts) || Number(v.delivery.attempts) < 0 || Number(v.delivery.attempts) > 5)
|
|
60470
60578
|
return invalid4();
|
|
60471
60579
|
return {
|
|
60472
60580
|
id: v.id,
|
|
@@ -60481,7 +60589,7 @@ function projection(v, organizationId) {
|
|
|
60481
60589
|
};
|
|
60482
60590
|
}
|
|
60483
60591
|
function parseInvitationResult(action, value, input, organizationId) {
|
|
60484
|
-
if (!
|
|
60592
|
+
if (!record6(value))
|
|
60485
60593
|
return invalid4();
|
|
60486
60594
|
const request = input;
|
|
60487
60595
|
if (action === "accept") {
|
|
@@ -60512,7 +60620,7 @@ function parseInvitationResult(action, value, input, organizationId) {
|
|
|
60512
60620
|
return invalid4();
|
|
60513
60621
|
return { invitation, changed: value.changed };
|
|
60514
60622
|
}
|
|
60515
|
-
var WorkspaceInvitationInputError, invitationFailures, RemoteWorkspaceInvitationError, RemoteWorkspaceInvitationUnconfirmedError, RemoteWorkspaceInvitationReadError,
|
|
60623
|
+
var WorkspaceInvitationInputError, invitationFailures, RemoteWorkspaceInvitationError, RemoteWorkspaceInvitationUnconfirmedError, RemoteWorkspaceInvitationReadError, record6 = (v) => !!v && typeof v === "object" && !Array.isArray(v), uuid3 = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), role2 = (v) => typeof v === "string" && ["owner", "admin", "member", "viewer"].includes(v), email = (v) => typeof v === "string" && v.length <= 254 && !/[\p{Cc}\p{Cs}\u2028\u2029\s]/u.test(v) && /^[^@]+@[^@]+\.[^@]+$/.test(v), timestamp = (v) => typeof v === "string" && v.length <= 40 && /^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(?:\.\d{1,6})?(?:Z|[+-]\d\d:\d\d)$/.test(v) && Number.isFinite(Date.parse(v)), inputFailure = () => {
|
|
60516
60624
|
throw new WorkspaceInvitationInputError;
|
|
60517
60625
|
};
|
|
60518
60626
|
var init_remote_invitations = __esm(() => {
|
|
@@ -60566,7 +60674,7 @@ var init_remote_invitations = __esm(() => {
|
|
|
60566
60674
|
|
|
60567
60675
|
// src/lib/remote-workspace.ts
|
|
60568
60676
|
function workspaceMembersQuery(options = {}) {
|
|
60569
|
-
if (!
|
|
60677
|
+
if (!record7(options) || Object.keys(options).some((key) => key !== "limit" && key !== "cursor") || options.limit !== undefined && (!Number.isInteger(options.limit) || options.limit < 1 || options.limit > 100) || options.cursor !== undefined && !cursor(options.cursor))
|
|
60570
60678
|
throw new Error("Use a roster limit from 1 to 100 and an unchanged continuation cursor.");
|
|
60571
60679
|
const query = new URLSearchParams;
|
|
60572
60680
|
if (options.limit !== undefined)
|
|
@@ -60582,7 +60690,7 @@ function timestamp2(value) {
|
|
|
60582
60690
|
return Number.isFinite(time) && new Date(time).toISOString().slice(0, 23) === value.slice(0, 23);
|
|
60583
60691
|
}
|
|
60584
60692
|
function parseMember(row, fail3) {
|
|
60585
|
-
if (!
|
|
60693
|
+
if (!record7(row) || !uuid4(row.membershipId) || !uuid4(row.userId) || typeof row.email !== "string" || !row.email || !(row.displayName === null || typeof row.displayName === "string") || !isRole(row.role) || !timestamp2(row.createdAt))
|
|
60586
60694
|
return fail3();
|
|
60587
60695
|
return {
|
|
60588
60696
|
membershipId: row.membershipId,
|
|
@@ -60594,7 +60702,7 @@ function parseMember(row, fail3) {
|
|
|
60594
60702
|
};
|
|
60595
60703
|
}
|
|
60596
60704
|
function mutationInput(membershipId, input, roleChange) {
|
|
60597
|
-
if (typeof membershipId !== "string" || !uuid4(membershipId) || membershipId !== membershipId.toLowerCase() || !
|
|
60705
|
+
if (typeof membershipId !== "string" || !uuid4(membershipId) || membershipId !== membershipId.toLowerCase() || !record7(input) || Object.keys(input).sort().join(",") !== (roleChange ? "expectedRole,role" : "expectedRole"))
|
|
60598
60706
|
throw new WorkspaceMemberInputError;
|
|
60599
60707
|
const expectedRole = input.expectedRole, role3 = roleChange ? input.role : undefined;
|
|
60600
60708
|
if (!isRole(expectedRole) || roleChange && !isRole(role3))
|
|
@@ -60613,7 +60721,7 @@ function parseWorkspaceMemberRoleResult(value, membershipId, role3) {
|
|
|
60613
60721
|
const fail3 = () => {
|
|
60614
60722
|
throw new Error(invalidMemberResult);
|
|
60615
60723
|
};
|
|
60616
|
-
if (!
|
|
60724
|
+
if (!record7(value) || !uuid4(value.organizationId) || typeof value.changed !== "boolean")
|
|
60617
60725
|
return fail3();
|
|
60618
60726
|
const member = parseMember(value.member, fail3);
|
|
60619
60727
|
if (member.membershipId !== membershipId || member.role !== role3)
|
|
@@ -60621,12 +60729,12 @@ function parseWorkspaceMemberRoleResult(value, membershipId, role3) {
|
|
|
60621
60729
|
return { organizationId: value.organizationId, member, changed: value.changed };
|
|
60622
60730
|
}
|
|
60623
60731
|
function parseWorkspaceMemberRemovalResult(value, membershipId) {
|
|
60624
|
-
if (!
|
|
60732
|
+
if (!record7(value) || !uuid4(value.organizationId) || value.membershipId !== membershipId || value.removed !== true || typeof value.alreadyRemoved !== "boolean")
|
|
60625
60733
|
throw new Error(invalidMemberResult);
|
|
60626
60734
|
return { organizationId: value.organizationId, membershipId, removed: true, alreadyRemoved: value.alreadyRemoved };
|
|
60627
60735
|
}
|
|
60628
60736
|
function workspaceMemberFailure(value, status) {
|
|
60629
|
-
if (!
|
|
60737
|
+
if (!record7(value) || typeof value.code !== "string" || !Object.hasOwn(workspaceMemberFailures, value.code))
|
|
60630
60738
|
return null;
|
|
60631
60739
|
const code = value.code;
|
|
60632
60740
|
return workspaceMemberFailures[code][0] === status ? code : null;
|
|
@@ -60635,14 +60743,14 @@ function parseWorkspaceMembersPage(value) {
|
|
|
60635
60743
|
const fail3 = () => {
|
|
60636
60744
|
throw new Error("The server returned an invalid workspace roster.");
|
|
60637
60745
|
};
|
|
60638
|
-
if (!
|
|
60746
|
+
if (!record7(value) || !uuid4(value.organizationId) || !Array.isArray(value.members) || value.members.length > 100 || !(value.nextCursor === null || cursor(value.nextCursor)) || !value.members.length && value.nextCursor !== null)
|
|
60639
60747
|
return fail3();
|
|
60640
60748
|
const members = value.members.map((row) => parseMember(row, fail3));
|
|
60641
60749
|
if (new Set(members.map((row) => row.membershipId)).size !== members.length)
|
|
60642
60750
|
return fail3();
|
|
60643
60751
|
return { organizationId: value.organizationId, members, nextCursor: value.nextCursor };
|
|
60644
60752
|
}
|
|
60645
|
-
var
|
|
60753
|
+
var record7 = (value) => !!value && typeof value === "object" && !Array.isArray(value), cursor = (value) => typeof value === "string" && /^[A-Za-z0-9_-]{1,512}$/.test(value), uuid4 = (value) => typeof value === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i.test(value), isRole = (value) => typeof value === "string" && ["owner", "admin", "member", "viewer"].includes(value), WorkspaceMemberInputError, invalidMemberResult = "The server returned an invalid workspace member result. Refresh the roster before another action.", workspaceMemberFailures;
|
|
60646
60754
|
var init_remote_workspace = __esm(() => {
|
|
60647
60755
|
WorkspaceMemberInputError = class WorkspaceMemberInputError extends Error {
|
|
60648
60756
|
constructor() {
|
|
@@ -75977,8 +76085,8 @@ function rewriteKeyNames(ctx) {
|
|
|
75977
76085
|
bySchema.set(entry.schema, entry);
|
|
75978
76086
|
}
|
|
75979
76087
|
const rewrites = new Map;
|
|
75980
|
-
for (const
|
|
75981
|
-
const seen = ctx.seen.get(
|
|
76088
|
+
for (const record8 of pendingRecords.get(ctx) ?? []) {
|
|
76089
|
+
const seen = ctx.seen.get(record8);
|
|
75982
76090
|
const names = (seen?.def ?? seen?.schema)?.propertyNames;
|
|
75983
76091
|
if (!names || names === true || rewrites.has(names))
|
|
75984
76092
|
continue;
|
|
@@ -77079,7 +77187,7 @@ __export(exports_schemas2, {
|
|
|
77079
77187
|
strictObject: () => strictObject,
|
|
77080
77188
|
set: () => set2,
|
|
77081
77189
|
refine: () => refine,
|
|
77082
|
-
record: () =>
|
|
77190
|
+
record: () => record8,
|
|
77083
77191
|
readonly: () => readonly,
|
|
77084
77192
|
promise: () => promise,
|
|
77085
77193
|
preprocess: () => preprocess,
|
|
@@ -77459,7 +77567,7 @@ function tuple(items, _paramsOrRest, _params) {
|
|
|
77459
77567
|
...exports_util.normalizeParams(params)
|
|
77460
77568
|
});
|
|
77461
77569
|
}
|
|
77462
|
-
function
|
|
77570
|
+
function record8(keyType, valueType, params) {
|
|
77463
77571
|
if (!valueType || !valueType._zod) {
|
|
77464
77572
|
return new ZodRecord({
|
|
77465
77573
|
type: "record",
|
|
@@ -77699,7 +77807,7 @@ function _instanceof(cls, params = {}) {
|
|
|
77699
77807
|
}
|
|
77700
77808
|
function json(params) {
|
|
77701
77809
|
const jsonSchema = lazy(() => {
|
|
77702
|
-
return union2([string2(params), number2(), boolean2(), _null3(), array2(jsonSchema),
|
|
77810
|
+
return union2([string2(params), number2(), boolean2(), _null3(), array2(jsonSchema), record8(string2(), jsonSchema)]);
|
|
77703
77811
|
});
|
|
77704
77812
|
return jsonSchema;
|
|
77705
77813
|
}
|
|
@@ -79518,7 +79626,7 @@ __export(exports_external, {
|
|
|
79518
79626
|
regexes: () => exports_regexes,
|
|
79519
79627
|
regex: () => _regex,
|
|
79520
79628
|
refine: () => refine,
|
|
79521
|
-
record: () =>
|
|
79629
|
+
record: () => record8,
|
|
79522
79630
|
readonly: () => readonly,
|
|
79523
79631
|
property: () => _property,
|
|
79524
79632
|
properties: () => _properties,
|
|
@@ -80131,44 +80239,44 @@ var init_remote_recurring = __esm(() => {
|
|
|
80131
80239
|
|
|
80132
80240
|
// src/lib/remote-run-contract.ts
|
|
80133
80241
|
function normalizeRemoteSkillRunContract(payload, fallbackSkill) {
|
|
80134
|
-
const
|
|
80242
|
+
const record9 = isRecord4(payload) ? payload : {};
|
|
80135
80243
|
return {
|
|
80136
80244
|
contractVersion: REMOTE_SKILL_RUN_CONTRACT_VERSION,
|
|
80137
|
-
...pickString(
|
|
80138
|
-
skill: pickStringValue(
|
|
80139
|
-
...pickString(
|
|
80140
|
-
...pickString(
|
|
80141
|
-
...pickNumber(
|
|
80142
|
-
...pickString(
|
|
80143
|
-
...pickString(
|
|
80144
|
-
...pickString(
|
|
80145
|
-
...pickString(
|
|
80146
|
-
...pickNumber(
|
|
80147
|
-
...pickString(
|
|
80148
|
-
...hasOwn(
|
|
80149
|
-
...pickString(
|
|
80150
|
-
...pickString(
|
|
80151
|
-
...pickString(
|
|
80152
|
-
...pickString(
|
|
80153
|
-
...hasOwn(
|
|
80245
|
+
...pickString(record9, "id"),
|
|
80246
|
+
skill: pickStringValue(record9, "skill") ?? fallbackSkill,
|
|
80247
|
+
...pickString(record9, "requestedSlug"),
|
|
80248
|
+
...pickString(record9, "status"),
|
|
80249
|
+
...pickNumber(record9, "exitCode"),
|
|
80250
|
+
...pickString(record9, "correlationId"),
|
|
80251
|
+
...pickString(record9, "createdAt"),
|
|
80252
|
+
...pickString(record9, "startedAt"),
|
|
80253
|
+
...pickString(record9, "completedAt"),
|
|
80254
|
+
...pickNumber(record9, "durationMs"),
|
|
80255
|
+
...pickString(record9, "outputType"),
|
|
80256
|
+
...hasOwn(record9, "outputPreview") ? { outputPreview: record9.outputPreview } : {},
|
|
80257
|
+
...pickString(record9, "errorCode"),
|
|
80258
|
+
...pickString(record9, "errorMessage"),
|
|
80259
|
+
...pickString(record9, "error"),
|
|
80260
|
+
...pickString(record9, "code"),
|
|
80261
|
+
...hasOwn(record9, "details") ? { details: record9.details } : {}
|
|
80154
80262
|
};
|
|
80155
80263
|
}
|
|
80156
80264
|
function isRecord4(value) {
|
|
80157
80265
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
80158
80266
|
}
|
|
80159
|
-
function hasOwn(
|
|
80160
|
-
return Object.prototype.hasOwnProperty.call(
|
|
80267
|
+
function hasOwn(record9, key) {
|
|
80268
|
+
return Object.prototype.hasOwnProperty.call(record9, key);
|
|
80161
80269
|
}
|
|
80162
|
-
function pickString(
|
|
80163
|
-
const value = pickStringValue(
|
|
80270
|
+
function pickString(record9, key) {
|
|
80271
|
+
const value = pickStringValue(record9, key);
|
|
80164
80272
|
return value === undefined ? {} : { [key]: value };
|
|
80165
80273
|
}
|
|
80166
|
-
function pickStringValue(
|
|
80167
|
-
const value =
|
|
80274
|
+
function pickStringValue(record9, key) {
|
|
80275
|
+
const value = record9[key];
|
|
80168
80276
|
return typeof value === "string" ? value : undefined;
|
|
80169
80277
|
}
|
|
80170
|
-
function pickNumber(
|
|
80171
|
-
const value =
|
|
80278
|
+
function pickNumber(record9, key) {
|
|
80279
|
+
const value = record9[key];
|
|
80172
80280
|
return typeof value === "number" && Number.isFinite(value) ? { [key]: value } : {};
|
|
80173
80281
|
}
|
|
80174
80282
|
var REMOTE_SKILL_RUN_CONTRACT_VERSION = 1;
|
|
@@ -80391,7 +80499,7 @@ var init_remote_quote_errors = __esm(() => {
|
|
|
80391
80499
|
function parseSkillsAccess(value) {
|
|
80392
80500
|
if (value === undefined)
|
|
80393
80501
|
return {};
|
|
80394
|
-
if (!
|
|
80502
|
+
if (!record9(value))
|
|
80395
80503
|
throw new Error("Invalid Skills permission contract");
|
|
80396
80504
|
const result2 = {};
|
|
80397
80505
|
if (value.scopes !== undefined) {
|
|
@@ -80400,7 +80508,7 @@ function parseSkillsAccess(value) {
|
|
|
80400
80508
|
result2.scopes = [...value.scopes];
|
|
80401
80509
|
}
|
|
80402
80510
|
if (value.permissions !== undefined) {
|
|
80403
|
-
if (!
|
|
80511
|
+
if (!record9(value.permissions))
|
|
80404
80512
|
throw new Error("Invalid Skills permission contract");
|
|
80405
80513
|
result2.permissions = {};
|
|
80406
80514
|
for (const name of permissionNames) {
|
|
@@ -80418,7 +80526,7 @@ function assertSkillsPermission(access, permission) {
|
|
|
80418
80526
|
if (access.permissions?.[permission] === false)
|
|
80419
80527
|
throw new RemoteSkillsPermissionError(permission);
|
|
80420
80528
|
}
|
|
80421
|
-
var permissionNames,
|
|
80529
|
+
var permissionNames, record9 = (value) => value !== null && typeof value === "object" && !Array.isArray(value), RemoteSkillsPermissionError;
|
|
80422
80530
|
var init_remote_permissions = __esm(() => {
|
|
80423
80531
|
permissionNames = [
|
|
80424
80532
|
"read",
|
|
@@ -81233,13 +81341,13 @@ class RemoteSkillsClient {
|
|
|
81233
81341
|
return normalizeUpdatedSincePage(await response.json());
|
|
81234
81342
|
}
|
|
81235
81343
|
}
|
|
81236
|
-
function requireOptionalString(
|
|
81237
|
-
if (
|
|
81344
|
+
function requireOptionalString(record10, field2) {
|
|
81345
|
+
if (record10[field2] === undefined)
|
|
81238
81346
|
return;
|
|
81239
|
-
if (typeof
|
|
81347
|
+
if (typeof record10[field2] !== "string") {
|
|
81240
81348
|
throw new Error(`Remote payload did not match the expected contract (${field2} must be a string when present)`);
|
|
81241
81349
|
}
|
|
81242
|
-
return
|
|
81350
|
+
return record10[field2];
|
|
81243
81351
|
}
|
|
81244
81352
|
function isVersionRecord(value) {
|
|
81245
81353
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -81261,19 +81369,19 @@ function normalizePin(entry) {
|
|
|
81261
81369
|
if (!entry || typeof entry !== "object") {
|
|
81262
81370
|
throw new Error("Remote pin payload did not match the expected contract (expected an object)");
|
|
81263
81371
|
}
|
|
81264
|
-
const
|
|
81265
|
-
const slug2 = typeof
|
|
81372
|
+
const record10 = entry;
|
|
81373
|
+
const slug2 = typeof record10.slug === "string" && record10.slug.trim() ? record10.slug.trim() : undefined;
|
|
81266
81374
|
if (!slug2) {
|
|
81267
81375
|
throw new Error("Remote pin payload did not match the expected contract (missing slug)");
|
|
81268
81376
|
}
|
|
81269
81377
|
let metadata;
|
|
81270
|
-
if (
|
|
81271
|
-
if (!
|
|
81378
|
+
if (record10.metadata !== undefined) {
|
|
81379
|
+
if (!record10.metadata || typeof record10.metadata !== "object" || Array.isArray(record10.metadata)) {
|
|
81272
81380
|
throw new Error("Remote pin payload did not match the expected contract (metadata must be a JSON object when present)");
|
|
81273
81381
|
}
|
|
81274
|
-
metadata =
|
|
81382
|
+
metadata = record10.metadata;
|
|
81275
81383
|
}
|
|
81276
|
-
const pinnedAt = requireOptionalString(
|
|
81384
|
+
const pinnedAt = requireOptionalString(record10, "pinnedAt");
|
|
81277
81385
|
return {
|
|
81278
81386
|
slug: slug2,
|
|
81279
81387
|
...pinnedAt !== undefined ? { pinnedAt } : {},
|
|
@@ -81290,16 +81398,16 @@ function normalizeSkillSummary(entry) {
|
|
|
81290
81398
|
if (!entry || typeof entry !== "object") {
|
|
81291
81399
|
throw new Error("Remote skill payload did not match the expected contract (expected an object)");
|
|
81292
81400
|
}
|
|
81293
|
-
const
|
|
81294
|
-
const slug2 = typeof
|
|
81401
|
+
const record10 = entry;
|
|
81402
|
+
const slug2 = typeof record10.slug === "string" && record10.slug.trim() ? record10.slug.trim() : undefined;
|
|
81295
81403
|
if (!slug2) {
|
|
81296
81404
|
throw new Error("Remote skill payload did not match the expected contract (missing slug)");
|
|
81297
81405
|
}
|
|
81298
81406
|
return {
|
|
81299
81407
|
slug: slug2,
|
|
81300
|
-
...requireOptionalString(
|
|
81301
|
-
...requireOptionalString(
|
|
81302
|
-
...requireOptionalString(
|
|
81408
|
+
...requireOptionalString(record10, "name") !== undefined ? { name: requireOptionalString(record10, "name") } : {},
|
|
81409
|
+
...requireOptionalString(record10, "version") !== undefined ? { version: requireOptionalString(record10, "version") } : {},
|
|
81410
|
+
...requireOptionalString(record10, "updatedAt") !== undefined ? { updatedAt: requireOptionalString(record10, "updatedAt") } : {}
|
|
81303
81411
|
};
|
|
81304
81412
|
}
|
|
81305
81413
|
function normalizeSkillSummaryList(payload) {
|
|
@@ -81356,12 +81464,12 @@ function normalizeUpdatedSincePage(payload) {
|
|
|
81356
81464
|
if (!payload || typeof payload !== "object") {
|
|
81357
81465
|
throw new Error("Updated-since payload did not match the expected contract (expected an object)");
|
|
81358
81466
|
}
|
|
81359
|
-
const
|
|
81360
|
-
if (!Array.isArray(
|
|
81467
|
+
const record10 = payload;
|
|
81468
|
+
if (!Array.isArray(record10.skills)) {
|
|
81361
81469
|
throw new Error("Updated-since payload did not match the expected contract (missing skills array)");
|
|
81362
81470
|
}
|
|
81363
|
-
const skills =
|
|
81364
|
-
const nextCursor =
|
|
81471
|
+
const skills = record10.skills.map(normalizeSkillSummary);
|
|
81472
|
+
const nextCursor = record10.nextCursor === undefined || record10.nextCursor === null ? null : record10.nextCursor;
|
|
81365
81473
|
if (nextCursor !== null && typeof nextCursor !== "string") {
|
|
81366
81474
|
throw new Error("Updated-since payload did not match the expected contract (nextCursor must be a string or absent)");
|
|
81367
81475
|
}
|
|
@@ -81497,10 +81605,10 @@ async function requestAuthApi(instance, path, options) {
|
|
|
81497
81605
|
const text4 = await res.text();
|
|
81498
81606
|
const body = text4 ? parseJsonBody(text4) : {};
|
|
81499
81607
|
if (!res.ok) {
|
|
81500
|
-
const
|
|
81501
|
-
const detail = typeof
|
|
81502
|
-
const error61 = typeof
|
|
81503
|
-
const code = typeof
|
|
81608
|
+
const record10 = isRecord6(body) ? body : {};
|
|
81609
|
+
const detail = typeof record10.detail === "string" ? record10.detail : undefined;
|
|
81610
|
+
const error61 = typeof record10.error === "string" ? record10.error : undefined;
|
|
81611
|
+
const code = typeof record10.code === "string" ? record10.code : undefined;
|
|
81504
81612
|
throw new HostedApiError(detail || error61 || `${res.status} ${res.statusText}`, {
|
|
81505
81613
|
status: res.status,
|
|
81506
81614
|
code,
|
|
@@ -81738,24 +81846,24 @@ function clampIntervalMs(seconds) {
|
|
|
81738
81846
|
return Math.min(MAX_INTERVAL_MS, Math.max(MIN_INTERVAL_MS, Math.round(seconds * 1000)));
|
|
81739
81847
|
}
|
|
81740
81848
|
function parseDeviceAuthorizationStart(body) {
|
|
81741
|
-
const
|
|
81742
|
-
if (typeof
|
|
81743
|
-
throw new Error(typeof
|
|
81849
|
+
const record10 = isRecord7(body) ? body : {};
|
|
81850
|
+
if (typeof record10.error === "string") {
|
|
81851
|
+
throw new Error(typeof record10.detail === "string" ? record10.detail : record10.error);
|
|
81744
81852
|
}
|
|
81745
|
-
const deviceCode = boundedText(
|
|
81746
|
-
const userCode = boundedText(
|
|
81747
|
-
const verificationUri = httpUrl2(
|
|
81853
|
+
const deviceCode = boundedText(record10.deviceCode, 512);
|
|
81854
|
+
const userCode = boundedText(record10.userCode, 64);
|
|
81855
|
+
const verificationUri = httpUrl2(record10.verificationUri);
|
|
81748
81856
|
if (!deviceCode || !userCode || !verificationUri) {
|
|
81749
81857
|
throw new Error("The Skills server returned an incomplete device sign-in (deviceCode, userCode and verificationUri are required)");
|
|
81750
81858
|
}
|
|
81751
|
-
const verificationUriComplete = httpUrl2(
|
|
81859
|
+
const verificationUriComplete = httpUrl2(record10.verificationUriComplete);
|
|
81752
81860
|
return {
|
|
81753
81861
|
deviceCode,
|
|
81754
81862
|
userCode,
|
|
81755
81863
|
verificationUri,
|
|
81756
81864
|
...verificationUriComplete ? { verificationUriComplete } : {},
|
|
81757
|
-
expiresIn: positiveNumber(
|
|
81758
|
-
interval: positiveNumber(
|
|
81865
|
+
expiresIn: positiveNumber(record10.expiresIn, DEFAULT_EXPIRES_IN_SECONDS),
|
|
81866
|
+
interval: positiveNumber(record10.interval, DEFAULT_INTERVAL_SECONDS)
|
|
81759
81867
|
};
|
|
81760
81868
|
}
|
|
81761
81869
|
async function startDeviceAuthorization(origin, client2 = SKILLS_CLI_DEVICE_CLIENT) {
|
|
@@ -81833,9 +81941,9 @@ async function pollDeviceAuthorization(input2) {
|
|
|
81833
81941
|
throw error61;
|
|
81834
81942
|
}
|
|
81835
81943
|
}
|
|
81836
|
-
const
|
|
81837
|
-
const code = typeof
|
|
81838
|
-
if (code === "authorization_pending" || code === undefined &&
|
|
81944
|
+
const record10 = isRecord7(body) ? body : {};
|
|
81945
|
+
const code = typeof record10.error === "string" ? record10.error : undefined;
|
|
81946
|
+
if (code === "authorization_pending" || code === undefined && record10.status === "pending") {
|
|
81839
81947
|
await wait();
|
|
81840
81948
|
continue;
|
|
81841
81949
|
}
|
|
@@ -81851,8 +81959,8 @@ async function pollDeviceAuthorization(input2) {
|
|
|
81851
81959
|
if (code === "access_denied")
|
|
81852
81960
|
return { status: "denied" };
|
|
81853
81961
|
if (code)
|
|
81854
|
-
throw new Error(typeof
|
|
81855
|
-
return { status: "authorized", result:
|
|
81962
|
+
throw new Error(typeof record10.detail === "string" ? record10.detail : code);
|
|
81963
|
+
return { status: "authorized", result: record10 };
|
|
81856
81964
|
}
|
|
81857
81965
|
}
|
|
81858
81966
|
function pendingDeviceSignInStem(env3) {
|
|
@@ -82138,10 +82246,10 @@ async function readSignedInAccount(env3 = process.env) {
|
|
|
82138
82246
|
const body = await new RemoteSkillsAuthClient(connection.apiOrigin).request("/api/auth/whoami", {
|
|
82139
82247
|
headers: { Authorization: `Bearer ${connection.apiKey}` }
|
|
82140
82248
|
});
|
|
82141
|
-
const
|
|
82142
|
-
const data = isRecord7(
|
|
82143
|
-
const user = isRecord7(
|
|
82144
|
-
const organization2 = isRecord7(
|
|
82249
|
+
const record10 = isRecord7(body) ? body : {};
|
|
82250
|
+
const data = isRecord7(record10.data) ? record10.data : {};
|
|
82251
|
+
const user = isRecord7(record10.user) ? record10.user : isRecord7(data.user) ? data.user : {};
|
|
82252
|
+
const organization2 = isRecord7(record10.organization) ? record10.organization : isRecord7(data.organization) ? data.organization : {};
|
|
82145
82253
|
const email4 = boundedText(user.email, 320);
|
|
82146
82254
|
const org = boundedText(organization2.slug, 200) ?? boundedText(organization2.name, 200);
|
|
82147
82255
|
return { ...base2, ...email4 ? { email: email4 } : {}, ...org ? { organization: org } : {} };
|
|
@@ -82941,16 +83049,16 @@ function installBundleAtomically(name, entries, options = {}, marker = {}) {
|
|
|
82941
83049
|
}
|
|
82942
83050
|
return { path: target, created };
|
|
82943
83051
|
}
|
|
82944
|
-
function writePullMarker(dir,
|
|
83052
|
+
function writePullMarker(dir, record10) {
|
|
82945
83053
|
const marker = {
|
|
82946
83054
|
managedBy: "@hasna/skills",
|
|
82947
|
-
skill:
|
|
82948
|
-
source:
|
|
82949
|
-
...
|
|
82950
|
-
...
|
|
82951
|
-
...
|
|
82952
|
-
...
|
|
82953
|
-
...
|
|
83055
|
+
skill: record10.skill,
|
|
83056
|
+
source: record10.source ?? "pull",
|
|
83057
|
+
...record10.version ? { version: record10.version } : {},
|
|
83058
|
+
...record10.contentHash ? { contentHash: record10.contentHash } : {},
|
|
83059
|
+
...record10.sourceCommit ? { sourceCommit: record10.sourceCommit } : {},
|
|
83060
|
+
...record10.signature ? { signature: record10.signature } : {},
|
|
83061
|
+
...record10.revisionId ? { revisionId: record10.revisionId } : {},
|
|
82954
83062
|
syncedAt: new Date().toISOString()
|
|
82955
83063
|
};
|
|
82956
83064
|
writeFileSync12(join38(dir, PULL_MARKER_FILE), `${JSON.stringify(marker, null, 2)}
|
|
@@ -82965,19 +83073,19 @@ async function safeMeta(client2, slug2) {
|
|
|
82965
83073
|
}
|
|
82966
83074
|
if (!raw || typeof raw !== "object")
|
|
82967
83075
|
return null;
|
|
82968
|
-
const
|
|
82969
|
-
const kind =
|
|
82970
|
-
const tags = Array.isArray(
|
|
83076
|
+
const record10 = raw;
|
|
83077
|
+
const kind = record10.kind === "instruction" || record10.kind === "executable" ? record10.kind : undefined;
|
|
83078
|
+
const tags = Array.isArray(record10.tags) ? record10.tags.filter((tag) => typeof tag === "string" && tag.trim().length > 0) : undefined;
|
|
82971
83079
|
return {
|
|
82972
|
-
...str(
|
|
82973
|
-
...str(
|
|
82974
|
-
...str(
|
|
83080
|
+
...str(record10.displayName) ? { displayName: str(record10.displayName) } : {},
|
|
83081
|
+
...str(record10.description) ? { description: str(record10.description) } : {},
|
|
83082
|
+
...str(record10.category) ? { category: str(record10.category) } : {},
|
|
82975
83083
|
...tags && tags.length ? { tags } : {},
|
|
82976
|
-
...str(
|
|
83084
|
+
...str(record10.version) ? { version: str(record10.version) } : {},
|
|
82977
83085
|
...kind ? { kind } : {},
|
|
82978
|
-
...REVISION_ID_PATTERN.test(str(
|
|
82979
|
-
...typeof
|
|
82980
|
-
...str(
|
|
83086
|
+
...REVISION_ID_PATTERN.test(str(record10.revisionId) ?? "") ? { revisionId: str(record10.revisionId) } : {},
|
|
83087
|
+
...typeof record10.skillMd === "string" && record10.skillMd.length > 0 ? { skillMd: record10.skillMd } : {},
|
|
83088
|
+
...str(record10.publishedSource) ? { publishedSource: str(record10.publishedSource) } : {}
|
|
82981
83089
|
};
|
|
82982
83090
|
}
|
|
82983
83091
|
function pickCorpusOptions(options) {
|
|
@@ -82986,8 +83094,8 @@ function pickCorpusOptions(options) {
|
|
|
82986
83094
|
function extractSlug(entry) {
|
|
82987
83095
|
if (!entry || typeof entry !== "object")
|
|
82988
83096
|
return;
|
|
82989
|
-
const
|
|
82990
|
-
return str(
|
|
83097
|
+
const record10 = entry;
|
|
83098
|
+
return str(record10.slug) ?? str(record10.name);
|
|
82991
83099
|
}
|
|
82992
83100
|
function dedupe(values2) {
|
|
82993
83101
|
return [...new Set(values2)];
|
|
@@ -83138,7 +83246,7 @@ var init_skill_context = __esm(() => {
|
|
|
83138
83246
|
|
|
83139
83247
|
// src/lib/session-reconciliation.ts
|
|
83140
83248
|
import { createHash as createHash24 } from "crypto";
|
|
83141
|
-
import { isDeepStrictEqual as
|
|
83249
|
+
import { isDeepStrictEqual as isDeepStrictEqual10 } from "util";
|
|
83142
83250
|
function exactTimestamp(value) {
|
|
83143
83251
|
const parsed = value === undefined ? Number.NaN : Date.parse(value);
|
|
83144
83252
|
if (!Number.isFinite(parsed) || new Date(parsed).toISOString() !== value) {
|
|
@@ -83195,7 +83303,7 @@ async function reconcileSkillSessionIfSafe(sessionId, profileId, options = {}) {
|
|
|
83195
83303
|
for (const key of old.loaded) {
|
|
83196
83304
|
const previous = oldByKey.get(key);
|
|
83197
83305
|
const current = targetBySlug.get(previous.slug);
|
|
83198
|
-
if (!current || !
|
|
83306
|
+
if (!current || !isDeepStrictEqual10({ ...previous, profileRevision: target.profileRevision }, current)) {
|
|
83199
83307
|
throw new SkillSelectionError("SESSION_RECONCILIATION_REQUIRED", "A loaded Skills selection was removed or changed; review skills sessions reconcile before changing this session's pin.");
|
|
83200
83308
|
}
|
|
83201
83309
|
}
|
|
@@ -85348,8 +85456,8 @@ function writeRollbackRecord(mode, entries, appDir = getDataDir()) {
|
|
|
85348
85456
|
const dir = join41(appDir, ROLLBACK_DIRNAME);
|
|
85349
85457
|
mkdirSync14(dir, { recursive: true });
|
|
85350
85458
|
const file2 = join41(dir, `${mode}-${Date.now()}.json`);
|
|
85351
|
-
const
|
|
85352
|
-
writeFileSync14(file2, `${JSON.stringify(
|
|
85459
|
+
const record10 = { version: 1, mode, timestamp: new Date().toISOString(), entries };
|
|
85460
|
+
writeFileSync14(file2, `${JSON.stringify(record10, null, 2)}
|
|
85353
85461
|
`);
|
|
85354
85462
|
return file2;
|
|
85355
85463
|
}
|
|
@@ -87549,7 +87657,7 @@ function selectedSecretBindingsTemplate(scope, names, createClient2 = createSecr
|
|
|
87549
87657
|
function refuse3(code, message) {
|
|
87550
87658
|
throw new SkillSelectionError(code, message);
|
|
87551
87659
|
}
|
|
87552
|
-
function
|
|
87660
|
+
function record10(value) {
|
|
87553
87661
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
87554
87662
|
}
|
|
87555
87663
|
function exactKeys3(value, keys2) {
|
|
@@ -87592,7 +87700,7 @@ function readSelectedSecretBindings(path) {
|
|
|
87592
87700
|
}
|
|
87593
87701
|
}
|
|
87594
87702
|
function validateSelectedSecretBindings(value, scope, names) {
|
|
87595
|
-
if (!
|
|
87703
|
+
if (!record10(value) || !exactKeys3(value, ["schema", "selection", "consumer", "secretsAuthority", "bindings"]) || value.schema !== "hasna.skills-secret-bindings.v1" || !record10(value.selection) || !exactKeys3(value.selection, ["authority", "workspaceId", "profileId", "profileRevision", "slug", "version", "bundleDigest"]) || !record10(value.consumer) || !exactKeys3(value.consumer, ["stationId", "workspaceDirectory"]) || !record10(value.bindings)) {
|
|
87596
87704
|
return refuse3("INVALID_SECRET_BINDINGS", "Secret bindings do not match the hasna.skills-secret-bindings.v1 contract.");
|
|
87597
87705
|
}
|
|
87598
87706
|
for (const [key, expected] of Object.entries({ authority: scope.selection.authority, workspaceId: scope.selection.workspaceId, profileId: scope.profileId, profileRevision: scope.selection.profileRevision, slug: scope.selection.slug, version: scope.selection.version, bundleDigest: scope.selection.bundleDigest })) {
|
|
@@ -87795,7 +87903,7 @@ var init_execution_grants = __esm(() => {
|
|
|
87795
87903
|
});
|
|
87796
87904
|
|
|
87797
87905
|
// src/lib/execution-grant-client.ts
|
|
87798
|
-
import { isDeepStrictEqual as
|
|
87906
|
+
import { isDeepStrictEqual as isDeepStrictEqual11 } from "util";
|
|
87799
87907
|
function id(value) {
|
|
87800
87908
|
if (!grantIdentifier(value))
|
|
87801
87909
|
throw new Error("Invalid execution grant profile or revision identifier.");
|
|
@@ -87847,7 +87955,7 @@ async function saveExecutionGrantPolicy(profileId, grants, revision) {
|
|
|
87847
87955
|
headers: revision === undefined ? { "If-None-Match": "*" } : { "If-Match": `"${revision}"` },
|
|
87848
87956
|
body: JSON.stringify({ grants: snapshot2 })
|
|
87849
87957
|
}));
|
|
87850
|
-
if (policy.profileId !== profileId || policy.previousRevision !== (revision ?? null) || !
|
|
87958
|
+
if (policy.profileId !== profileId || policy.previousRevision !== (revision ?? null) || !isDeepStrictEqual11(policy.grants, snapshot2)) {
|
|
87851
87959
|
throw new Error("The API did not preserve the reviewed execution grant policy; read it before retrying.");
|
|
87852
87960
|
}
|
|
87853
87961
|
return policy;
|
|
@@ -87858,7 +87966,7 @@ async function resolveExecutionGrant(input2) {
|
|
|
87858
87966
|
if (!grantRecord(value) || Object.keys(value).length !== 3 || !grantIdentifier(value.policyRevision) || !grantIdentifier(value.grantId) || !grantRecord(value.bindings)) {
|
|
87859
87967
|
throw new SkillSelectionError("INVALID_EXECUTION_GRANT", "The Skills API returned an invalid execution grant.");
|
|
87860
87968
|
}
|
|
87861
|
-
if (!
|
|
87969
|
+
if (!isDeepStrictEqual11(value.bindings.selection, snapshot2.selection) || !isDeepStrictEqual11(value.bindings.consumer, snapshot2.consumer)) {
|
|
87862
87970
|
throw new SkillSelectionError("EXECUTION_GRANT_SCOPE_MISMATCH", "The Skills API returned a grant for a different selection or consumer.");
|
|
87863
87971
|
}
|
|
87864
87972
|
return value;
|
|
@@ -92235,7 +92343,7 @@ function createSkillRun(params, targetDir = process.cwd()) {
|
|
|
92235
92343
|
mkdirSync16(logsDir, { recursive: true });
|
|
92236
92344
|
mkdirSync16(exportDir, { recursive: true });
|
|
92237
92345
|
mkdirSync16(join46(root2, "tmp"), { recursive: true });
|
|
92238
|
-
const
|
|
92346
|
+
const record11 = {
|
|
92239
92347
|
id: id2,
|
|
92240
92348
|
skill: skillName,
|
|
92241
92349
|
status: params.status ?? "running",
|
|
@@ -92253,10 +92361,10 @@ function createSkillRun(params, targetDir = process.cwd()) {
|
|
|
92253
92361
|
logsDir: toProjectRelative(targetDir, logsDir)
|
|
92254
92362
|
}
|
|
92255
92363
|
};
|
|
92256
|
-
const context = { targetDir, runDir, exportDir, logsDir, record:
|
|
92364
|
+
const context = { targetDir, runDir, exportDir, logsDir, record: record11 };
|
|
92257
92365
|
writeRunRecord(context);
|
|
92258
92366
|
writeArtifactsManifest(context, []);
|
|
92259
|
-
appendRunEvent(context, "created", { status:
|
|
92367
|
+
appendRunEvent(context, "created", { status: record11.status });
|
|
92260
92368
|
return context;
|
|
92261
92369
|
}
|
|
92262
92370
|
function completeSkillRun(context, patch) {
|
|
@@ -92306,9 +92414,9 @@ function listSkillRuns(targetDir = process.cwd(), limit = 50) {
|
|
|
92306
92414
|
if (!statSync16(dayDir).isDirectory())
|
|
92307
92415
|
continue;
|
|
92308
92416
|
for (const runId2 of readdirSync18(dayDir).sort().reverse()) {
|
|
92309
|
-
const
|
|
92310
|
-
if (
|
|
92311
|
-
records.push(
|
|
92417
|
+
const record11 = readRunRecord(join46(dayDir, runId2));
|
|
92418
|
+
if (record11)
|
|
92419
|
+
records.push(record11);
|
|
92312
92420
|
if (records.length >= limit)
|
|
92313
92421
|
return records;
|
|
92314
92422
|
}
|
|
@@ -92320,9 +92428,9 @@ function findSkillRun(runId2, targetDir = process.cwd()) {
|
|
|
92320
92428
|
if (!existsSync27(runsRoot))
|
|
92321
92429
|
return null;
|
|
92322
92430
|
for (const day of readdirSync18(runsRoot)) {
|
|
92323
|
-
const
|
|
92324
|
-
if (
|
|
92325
|
-
return
|
|
92431
|
+
const record11 = readRunRecord(join46(runsRoot, day, runId2));
|
|
92432
|
+
if (record11)
|
|
92433
|
+
return record11;
|
|
92326
92434
|
}
|
|
92327
92435
|
return null;
|
|
92328
92436
|
}
|
|
@@ -92549,7 +92657,7 @@ var init_types2 = __esm(() => {
|
|
|
92549
92657
|
});
|
|
92550
92658
|
FormElicitationCapabilitySchema = intersection2(object5({
|
|
92551
92659
|
applyDefaults: boolean2().optional()
|
|
92552
|
-
}),
|
|
92660
|
+
}), record8(string2(), unknown()));
|
|
92553
92661
|
ElicitationCapabilitySchema = preprocess((value) => {
|
|
92554
92662
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
92555
92663
|
if (Object.keys(value).length === 0) {
|
|
@@ -92560,7 +92668,7 @@ var init_types2 = __esm(() => {
|
|
|
92560
92668
|
}, intersection2(object5({
|
|
92561
92669
|
form: FormElicitationCapabilitySchema.optional(),
|
|
92562
92670
|
url: AssertObjectSchema.optional()
|
|
92563
|
-
}),
|
|
92671
|
+
}), record8(string2(), unknown()).optional()));
|
|
92564
92672
|
ClientTasksCapabilitySchema = looseObject({
|
|
92565
92673
|
list: AssertObjectSchema.optional(),
|
|
92566
92674
|
cancel: AssertObjectSchema.optional(),
|
|
@@ -92583,7 +92691,7 @@ var init_types2 = __esm(() => {
|
|
|
92583
92691
|
}).optional()
|
|
92584
92692
|
});
|
|
92585
92693
|
ClientCapabilitiesSchema = object5({
|
|
92586
|
-
experimental:
|
|
92694
|
+
experimental: record8(string2(), AssertObjectSchema).optional(),
|
|
92587
92695
|
sampling: object5({
|
|
92588
92696
|
context: AssertObjectSchema.optional(),
|
|
92589
92697
|
tools: AssertObjectSchema.optional()
|
|
@@ -92593,7 +92701,7 @@ var init_types2 = __esm(() => {
|
|
|
92593
92701
|
listChanged: boolean2().optional()
|
|
92594
92702
|
}).optional(),
|
|
92595
92703
|
tasks: ClientTasksCapabilitySchema.optional(),
|
|
92596
|
-
extensions:
|
|
92704
|
+
extensions: record8(string2(), AssertObjectSchema).optional()
|
|
92597
92705
|
});
|
|
92598
92706
|
InitializeRequestParamsSchema = BaseRequestParamsSchema.extend({
|
|
92599
92707
|
protocolVersion: string2(),
|
|
@@ -92605,7 +92713,7 @@ var init_types2 = __esm(() => {
|
|
|
92605
92713
|
params: InitializeRequestParamsSchema
|
|
92606
92714
|
});
|
|
92607
92715
|
ServerCapabilitiesSchema = object5({
|
|
92608
|
-
experimental:
|
|
92716
|
+
experimental: record8(string2(), AssertObjectSchema).optional(),
|
|
92609
92717
|
logging: AssertObjectSchema.optional(),
|
|
92610
92718
|
completions: AssertObjectSchema.optional(),
|
|
92611
92719
|
prompts: object5({
|
|
@@ -92619,7 +92727,7 @@ var init_types2 = __esm(() => {
|
|
|
92619
92727
|
listChanged: boolean2().optional()
|
|
92620
92728
|
}).optional(),
|
|
92621
92729
|
tasks: ServerTasksCapabilitySchema.optional(),
|
|
92622
|
-
extensions:
|
|
92730
|
+
extensions: record8(string2(), AssertObjectSchema).optional()
|
|
92623
92731
|
});
|
|
92624
92732
|
InitializeResultSchema = ResultSchema.extend({
|
|
92625
92733
|
protocolVersion: string2(),
|
|
@@ -92706,7 +92814,7 @@ var init_types2 = __esm(() => {
|
|
|
92706
92814
|
ResourceContentsSchema = object5({
|
|
92707
92815
|
uri: string2(),
|
|
92708
92816
|
mimeType: optional(string2()),
|
|
92709
|
-
_meta:
|
|
92817
|
+
_meta: record8(string2(), unknown()).optional()
|
|
92710
92818
|
});
|
|
92711
92819
|
TextResourceContentsSchema = ResourceContentsSchema.extend({
|
|
92712
92820
|
text: string2()
|
|
@@ -92811,7 +92919,7 @@ var init_types2 = __esm(() => {
|
|
|
92811
92919
|
});
|
|
92812
92920
|
GetPromptRequestParamsSchema = BaseRequestParamsSchema.extend({
|
|
92813
92921
|
name: string2(),
|
|
92814
|
-
arguments:
|
|
92922
|
+
arguments: record8(string2(), string2()).optional()
|
|
92815
92923
|
});
|
|
92816
92924
|
GetPromptRequestSchema = RequestSchema.extend({
|
|
92817
92925
|
method: literal("prompts/get"),
|
|
@@ -92821,34 +92929,34 @@ var init_types2 = __esm(() => {
|
|
|
92821
92929
|
type: literal("text"),
|
|
92822
92930
|
text: string2(),
|
|
92823
92931
|
annotations: AnnotationsSchema.optional(),
|
|
92824
|
-
_meta:
|
|
92932
|
+
_meta: record8(string2(), unknown()).optional()
|
|
92825
92933
|
});
|
|
92826
92934
|
ImageContentSchema = object5({
|
|
92827
92935
|
type: literal("image"),
|
|
92828
92936
|
data: Base64Schema,
|
|
92829
92937
|
mimeType: string2(),
|
|
92830
92938
|
annotations: AnnotationsSchema.optional(),
|
|
92831
|
-
_meta:
|
|
92939
|
+
_meta: record8(string2(), unknown()).optional()
|
|
92832
92940
|
});
|
|
92833
92941
|
AudioContentSchema = object5({
|
|
92834
92942
|
type: literal("audio"),
|
|
92835
92943
|
data: Base64Schema,
|
|
92836
92944
|
mimeType: string2(),
|
|
92837
92945
|
annotations: AnnotationsSchema.optional(),
|
|
92838
|
-
_meta:
|
|
92946
|
+
_meta: record8(string2(), unknown()).optional()
|
|
92839
92947
|
});
|
|
92840
92948
|
ToolUseContentSchema = object5({
|
|
92841
92949
|
type: literal("tool_use"),
|
|
92842
92950
|
name: string2(),
|
|
92843
92951
|
id: string2(),
|
|
92844
|
-
input:
|
|
92845
|
-
_meta:
|
|
92952
|
+
input: record8(string2(), unknown()),
|
|
92953
|
+
_meta: record8(string2(), unknown()).optional()
|
|
92846
92954
|
});
|
|
92847
92955
|
EmbeddedResourceSchema = object5({
|
|
92848
92956
|
type: literal("resource"),
|
|
92849
92957
|
resource: union2([TextResourceContentsSchema, BlobResourceContentsSchema]),
|
|
92850
92958
|
annotations: AnnotationsSchema.optional(),
|
|
92851
|
-
_meta:
|
|
92959
|
+
_meta: record8(string2(), unknown()).optional()
|
|
92852
92960
|
});
|
|
92853
92961
|
ResourceLinkSchema = ResourceSchema.extend({
|
|
92854
92962
|
type: literal("resource_link")
|
|
@@ -92888,17 +92996,17 @@ var init_types2 = __esm(() => {
|
|
|
92888
92996
|
description: string2().optional(),
|
|
92889
92997
|
inputSchema: object5({
|
|
92890
92998
|
type: literal("object"),
|
|
92891
|
-
properties:
|
|
92999
|
+
properties: record8(string2(), AssertObjectSchema).optional(),
|
|
92892
93000
|
required: array2(string2()).optional()
|
|
92893
93001
|
}).catchall(unknown()),
|
|
92894
93002
|
outputSchema: object5({
|
|
92895
93003
|
type: literal("object"),
|
|
92896
|
-
properties:
|
|
93004
|
+
properties: record8(string2(), AssertObjectSchema).optional(),
|
|
92897
93005
|
required: array2(string2()).optional()
|
|
92898
93006
|
}).catchall(unknown()).optional(),
|
|
92899
93007
|
annotations: ToolAnnotationsSchema.optional(),
|
|
92900
93008
|
execution: ToolExecutionSchema.optional(),
|
|
92901
|
-
_meta:
|
|
93009
|
+
_meta: record8(string2(), unknown()).optional()
|
|
92902
93010
|
});
|
|
92903
93011
|
ListToolsRequestSchema = PaginatedRequestSchema.extend({
|
|
92904
93012
|
method: literal("tools/list")
|
|
@@ -92908,7 +93016,7 @@ var init_types2 = __esm(() => {
|
|
|
92908
93016
|
});
|
|
92909
93017
|
CallToolResultSchema = ResultSchema.extend({
|
|
92910
93018
|
content: array2(ContentBlockSchema).default([]),
|
|
92911
|
-
structuredContent:
|
|
93019
|
+
structuredContent: record8(string2(), unknown()).optional(),
|
|
92912
93020
|
isError: boolean2().optional()
|
|
92913
93021
|
});
|
|
92914
93022
|
CompatibilityCallToolResultSchema = CallToolResultSchema.or(ResultSchema.extend({
|
|
@@ -92916,7 +93024,7 @@ var init_types2 = __esm(() => {
|
|
|
92916
93024
|
}));
|
|
92917
93025
|
CallToolRequestParamsSchema = TaskAugmentedRequestParamsSchema.extend({
|
|
92918
93026
|
name: string2(),
|
|
92919
|
-
arguments:
|
|
93027
|
+
arguments: record8(string2(), unknown()).optional()
|
|
92920
93028
|
});
|
|
92921
93029
|
CallToolRequestSchema = RequestSchema.extend({
|
|
92922
93030
|
method: literal("tools/call"),
|
|
@@ -92965,7 +93073,7 @@ var init_types2 = __esm(() => {
|
|
|
92965
93073
|
content: array2(ContentBlockSchema).default([]),
|
|
92966
93074
|
structuredContent: object5({}).loose().optional(),
|
|
92967
93075
|
isError: boolean2().optional(),
|
|
92968
|
-
_meta:
|
|
93076
|
+
_meta: record8(string2(), unknown()).optional()
|
|
92969
93077
|
});
|
|
92970
93078
|
SamplingContentSchema = discriminatedUnion("type", [TextContentSchema, ImageContentSchema, AudioContentSchema]);
|
|
92971
93079
|
SamplingMessageContentBlockSchema = discriminatedUnion("type", [
|
|
@@ -92978,7 +93086,7 @@ var init_types2 = __esm(() => {
|
|
|
92978
93086
|
SamplingMessageSchema = object5({
|
|
92979
93087
|
role: RoleSchema,
|
|
92980
93088
|
content: union2([SamplingMessageContentBlockSchema, array2(SamplingMessageContentBlockSchema)]),
|
|
92981
|
-
_meta:
|
|
93089
|
+
_meta: record8(string2(), unknown()).optional()
|
|
92982
93090
|
});
|
|
92983
93091
|
CreateMessageRequestParamsSchema = TaskAugmentedRequestParamsSchema.extend({
|
|
92984
93092
|
messages: array2(SamplingMessageSchema),
|
|
@@ -93091,7 +93199,7 @@ var init_types2 = __esm(() => {
|
|
|
93091
93199
|
message: string2(),
|
|
93092
93200
|
requestedSchema: object5({
|
|
93093
93201
|
type: literal("object"),
|
|
93094
|
-
properties:
|
|
93202
|
+
properties: record8(string2(), PrimitiveSchemaDefinitionSchema),
|
|
93095
93203
|
required: array2(string2()).optional()
|
|
93096
93204
|
})
|
|
93097
93205
|
});
|
|
@@ -93115,7 +93223,7 @@ var init_types2 = __esm(() => {
|
|
|
93115
93223
|
});
|
|
93116
93224
|
ElicitResultSchema = ResultSchema.extend({
|
|
93117
93225
|
action: _enum2(["accept", "decline", "cancel"]),
|
|
93118
|
-
content: preprocess((val) => val === null ? undefined : val,
|
|
93226
|
+
content: preprocess((val) => val === null ? undefined : val, record8(string2(), union2([string2(), number2(), boolean2(), array2(string2())])).optional())
|
|
93119
93227
|
});
|
|
93120
93228
|
ResourceTemplateReferenceSchema = object5({
|
|
93121
93229
|
type: literal("ref/resource"),
|
|
@@ -93132,7 +93240,7 @@ var init_types2 = __esm(() => {
|
|
|
93132
93240
|
value: string2()
|
|
93133
93241
|
}),
|
|
93134
93242
|
context: object5({
|
|
93135
|
-
arguments:
|
|
93243
|
+
arguments: record8(string2(), string2()).optional()
|
|
93136
93244
|
}).optional()
|
|
93137
93245
|
});
|
|
93138
93246
|
CompleteRequestSchema = RequestSchema.extend({
|
|
@@ -93149,7 +93257,7 @@ var init_types2 = __esm(() => {
|
|
|
93149
93257
|
RootSchema = object5({
|
|
93150
93258
|
uri: string2().startsWith("file://"),
|
|
93151
93259
|
name: string2().optional(),
|
|
93152
|
-
_meta:
|
|
93260
|
+
_meta: record8(string2(), unknown()).optional()
|
|
93153
93261
|
});
|
|
93154
93262
|
ListRootsRequestSchema = RequestSchema.extend({
|
|
93155
93263
|
method: literal("roots/list"),
|
|
@@ -112311,7 +112419,7 @@ var init_create_sync_config = __esm(() => {
|
|
|
112311
112419
|
});
|
|
112312
112420
|
|
|
112313
112421
|
// src/lib/codex-native-config.ts
|
|
112314
|
-
import { isDeepStrictEqual as
|
|
112422
|
+
import { isDeepStrictEqual as isDeepStrictEqual12 } from "util";
|
|
112315
112423
|
function isRecord8(value) {
|
|
112316
112424
|
if (!value || typeof value !== "object")
|
|
112317
112425
|
return false;
|
|
@@ -112333,7 +112441,7 @@ function decimalIdentity(text4) {
|
|
|
112333
112441
|
return `${match[1]}${coefficient}e${exponent}`;
|
|
112334
112442
|
}
|
|
112335
112443
|
function codexNativeConfigEqual(native, expected) {
|
|
112336
|
-
if (
|
|
112444
|
+
if (isDeepStrictEqual12(native, expected))
|
|
112337
112445
|
return true;
|
|
112338
112446
|
if (typeof expected === "number") {
|
|
112339
112447
|
if (!Number.isFinite(expected) || !isRecord8(native))
|
|
@@ -112359,7 +112467,7 @@ var init_codex_native_config = () => {};
|
|
|
112359
112467
|
// src/lib/codex-hook-trust-identity.ts
|
|
112360
112468
|
import { realpathSync as realpathSync16 } from "fs";
|
|
112361
112469
|
import { dirname as dirname33, isAbsolute as isAbsolute27, join as join59 } from "path";
|
|
112362
|
-
import { isDeepStrictEqual as
|
|
112470
|
+
import { isDeepStrictEqual as isDeepStrictEqual13 } from "util";
|
|
112363
112471
|
function inspectRecordedSkillsCli(command, expected) {
|
|
112364
112472
|
need6(isAbsolute27(command) && !command.includes("\x00"), "RECONCILE_RECORDED_COMMAND_REQUIRED");
|
|
112365
112473
|
const resolved = realpathSync16(command);
|
|
@@ -112369,7 +112477,7 @@ function inspectRecordedSkillsCli(command, expected) {
|
|
|
112369
112477
|
need6(pkg.name === "@hasna/skills" && /^\d+\.\d+\.\d+$/.test(pkg.version) && pkg.bin?.skills === "bin/index.js" && resolved === join59(dirname33(manifest.file), "bin/index.js"), "SKILLS_PACKAGE_MISMATCH");
|
|
112370
112478
|
need6((cli.stat.mode & 0o100n) !== 0n, "SKILLS_COMMAND_NOT_EXECUTABLE");
|
|
112371
112479
|
const receipt = { path: resolved, version: pkg.version, sha256: cli.sha256, manifestSha256: manifest.sha256 };
|
|
112372
|
-
need6(
|
|
112480
|
+
need6(isDeepStrictEqual13(receipt, expected), "RECONCILE_SKILLS_BINDING_CHANGED");
|
|
112373
112481
|
return { receipt, recheck() {
|
|
112374
112482
|
need6(realpathSync16(command) === resolved, "SKILLS_COMMAND_CHANGED");
|
|
112375
112483
|
unchanged2(cli);
|
|
@@ -112405,19 +112513,19 @@ var init_codex_hook_trust_identity = __esm(() => {
|
|
|
112405
112513
|
});
|
|
112406
112514
|
|
|
112407
112515
|
// src/lib/codex-hook-policy-recovery.ts
|
|
112408
|
-
import { isDeepStrictEqual as
|
|
112516
|
+
import { isDeepStrictEqual as isDeepStrictEqual14 } from "util";
|
|
112409
112517
|
function reviewedClaudeDiscoveryChange(beforeText, currentText, options) {
|
|
112410
112518
|
need6(typeof options.reason === "string" && options.reason.trim().length > 0 && options.reason.length <= 512 && !/[\x00-\x1f\x7f]/.test(options.reason), "RECONCILE_RECOVERY_REASON_REQUIRED");
|
|
112411
112519
|
need6(options.reviewedPlanDigest === undefined || /^[a-f0-9]{64}$/.test(options.reviewedPlanDigest), "RECONCILE_RECOVERY_PLAN_CHANGED");
|
|
112412
112520
|
const before2 = parseManagedSkillPolicy(beforeText), current = parseManagedSkillPolicy(currentText);
|
|
112413
112521
|
const oldDiscovery = before2.bridge?.discovery?.claude, newDiscovery = current.bridge?.discovery?.claude;
|
|
112414
112522
|
need6(oldDiscovery?.agent === "claude" && newDiscovery?.agent === "claude" && oldDiscovery.method === "reviewed" && newDiscovery.method === "reviewed", "RECONCILE_POLICY_CHANGED");
|
|
112415
|
-
const changes = ["roots", "sources"].filter((key) => !
|
|
112523
|
+
const changes = ["roots", "sources"].filter((key) => !isDeepStrictEqual14(oldDiscovery[key], newDiscovery[key])).map((key) => ({ path: `bridge.discovery.claude.${key}`, before: oldDiscovery[key], after: newDiscovery[key] }));
|
|
112416
112524
|
need6(changes.length > 0, "RECONCILE_POLICY_CHANGED");
|
|
112417
112525
|
const compared = structuredClone(current);
|
|
112418
112526
|
compared.bridge.discovery.claude.roots = oldDiscovery.roots;
|
|
112419
112527
|
compared.bridge.discovery.claude.sources = oldDiscovery.sources;
|
|
112420
|
-
need6(
|
|
112528
|
+
need6(isDeepStrictEqual14(before2, compared), "RECONCILE_POLICY_CHANGED");
|
|
112421
112529
|
verifyAgentDiscovery(newDiscovery);
|
|
112422
112530
|
return { reason: options.reason, changes };
|
|
112423
112531
|
}
|
|
@@ -112433,7 +112541,7 @@ import { createHash as createHash31, randomUUID as randomUUID11 } from "crypto";
|
|
|
112433
112541
|
import { execFileSync } from "child_process";
|
|
112434
112542
|
import { dirname as dirname34, isAbsolute as isAbsolute28, join as join60, resolve as resolve25 } from "path";
|
|
112435
112543
|
import { homedir as homedir12 } from "os";
|
|
112436
|
-
import { isDeepStrictEqual as
|
|
112544
|
+
import { isDeepStrictEqual as isDeepStrictEqual15 } from "util";
|
|
112437
112545
|
function verifyReleaseArtifact(proof, skillsCli) {
|
|
112438
112546
|
need6(isAbsolute28(proof.packageTarPath) && !proof.packageTarPath.includes("\x00"), "RECONCILE_RELEASE_PROVENANCE_PATH");
|
|
112439
112547
|
const tarPath = realpathSync17(proof.packageTarPath);
|
|
@@ -112475,7 +112583,7 @@ async function reconcileCodexNativeHooks(options, connect = connectCodexHookRpc)
|
|
|
112475
112583
|
const configSha256 = intent.configSha256 ?? configBefore.sha256, configVersion = intent.configVersion ?? intent.expectedVersion;
|
|
112476
112584
|
const digestInput = { version: 1, home: intent.home ?? home, configPath: intent.configPath, ...intent.nativeConfigPath !== undefined ? { nativeConfigPath: intent.nativeConfigPath } : {}, configSha256, configVersion, policySha256: intent.policySha256, hooksSha256: intent.hooksSha256, skillsCli: intent.skillsCli, nativeVersion: intent.nativeVersion, declarations, admitted };
|
|
112477
112585
|
need6(makePlanDigest(digestInput) === intent.planDigest, "RECONCILE_PLAN_CHANGED");
|
|
112478
|
-
need6(
|
|
112586
|
+
need6(isDeepStrictEqual15(intent.hooks, admitted.filter((hook) => !hook.enabled || hook.trustStatus !== "trusted")), "RECONCILE_INTENT_HOOKS_CHANGED");
|
|
112479
112587
|
need6(configBefore.sha256 === (intent.beforeSha256 ?? intent.configSha256) && hooksBefore.sha256 === intent.hooksSha256 && policyBefore.sha256 === intent.policySha256, "RECONCILE_JOURNAL_CHANGED");
|
|
112480
112588
|
const policyCurrent = snapshot(join60(dataDir3, "agent-policy.json"), true);
|
|
112481
112589
|
const { claudeDiscoveryRecovery: claudeRecovery, nativeHookAdditionsRecovery: additionsRecovery } = options;
|
|
@@ -112488,7 +112596,7 @@ async function reconcileCodexNativeHooks(options, connect = connectCodexHookRpc)
|
|
|
112488
112596
|
if (policyCurrent.sha256 !== policyBefore.sha256 && !claudeRecovery) {
|
|
112489
112597
|
need6(options.supersedeBinding === true, "RECONCILE_POLICY_CHANGED");
|
|
112490
112598
|
const oldPolicy = JSON.parse(policyBefore.text), currentPolicy = JSON.parse(policyCurrent.text);
|
|
112491
|
-
need6(
|
|
112599
|
+
need6(isDeepStrictEqual15(withoutCodexCommand(oldPolicy), withoutCodexCommand(currentPolicy)), "RECONCILE_POLICY_CHANGED");
|
|
112492
112600
|
supersededBinding = true;
|
|
112493
112601
|
}
|
|
112494
112602
|
if (supersededBinding || recovery) {
|
|
@@ -112524,7 +112632,7 @@ async function reconcileCodexNativeHooks(options, connect = connectCodexHookRpc)
|
|
|
112524
112632
|
need6(state?.enabled === true && typeof state.trusted_hash === "string" && /^sha256:[a-f0-9]{64}$/.test(state.trusted_hash), "RECONCILE_CONFIG_DRIFT");
|
|
112525
112633
|
}
|
|
112526
112634
|
} else
|
|
112527
|
-
need6(
|
|
112635
|
+
need6(isDeepStrictEqual15(expectedConfig, current), "RECONCILE_CONFIG_DRIFT");
|
|
112528
112636
|
const configDiscoveryRecovery = recovery && binding.discovery?.codex ? createCodexHookDiscoveryRecovery(binding.discovery.codex, configBefore, currentConfig, intent.hooks, additions?.trustProof) : undefined;
|
|
112529
112637
|
assertManagedAgentBridge("codex", { home, dataDir: dataDir3, projectDir: home, codexDiscoveryRecovery: configDiscoveryRecovery });
|
|
112530
112638
|
const recoveryCli = recovery ? bindSkillsCli("skills", options.reviewedSkillsCli) : undefined;
|
|
@@ -112533,14 +112641,14 @@ async function reconcileCodexNativeHooks(options, connect = connectCodexHookRpc)
|
|
|
112533
112641
|
const skillsCli = recovery ? inspectRecordedSkillsCli(binding.commands.codex, intent.skillsCli) : bindSkillsCli(binding.commands.codex, options.reviewedSkillsCli);
|
|
112534
112642
|
if (supersededBinding)
|
|
112535
112643
|
verifyReleaseArtifact(options.releaseProof, skillsCli);
|
|
112536
|
-
const skillsBindingChanged = !
|
|
112644
|
+
const skillsBindingChanged = !isDeepStrictEqual15(skillsCli.receipt, intent.skillsCli);
|
|
112537
112645
|
need6(!skillsBindingChanged || supersededBinding, "RECONCILE_SKILLS_BINDING_CHANGED");
|
|
112538
112646
|
if (!additions && hooksCurrent.sha256 !== intent.hooksSha256 && hooksCurrent.sha256 !== hooksBefore.sha256) {
|
|
112539
112647
|
need6(supersededBinding, "RECONCILE_HOOKS_CHANGED");
|
|
112540
112648
|
const currentDeclarations = JSON.parse(hooksCurrent.text).hooks;
|
|
112541
112649
|
for (const [event, [nativeEvent]] of Object.entries(eventNames)) {
|
|
112542
112650
|
const command = renderAgentHookCommand(binding.commands.codex, "codex", binding.profiles.codex, event);
|
|
112543
|
-
need6(
|
|
112651
|
+
need6(isDeepStrictEqual15(currentDeclarations?.[event], [{ hooks: [{ type: "command", command, timeout: 15 }] }]), "RECONCILE_BINDING_HOOK_CHANGED");
|
|
112544
112652
|
}
|
|
112545
112653
|
}
|
|
112546
112654
|
rpc = await connect({ command: options.codexCommand ?? "codex", home, codexHome });
|
|
@@ -112563,9 +112671,9 @@ async function reconcileCodexNativeHooks(options, connect = connectCodexHookRpc)
|
|
|
112563
112671
|
delete identity5.command;
|
|
112564
112672
|
return identity5;
|
|
112565
112673
|
};
|
|
112566
|
-
need6(
|
|
112674
|
+
need6(isDeepStrictEqual15(stable(actual), stable(expected)), "RECONCILE_NATIVE_IDENTITY_CHANGED");
|
|
112567
112675
|
if (!plannedKeys.has(expected.key))
|
|
112568
|
-
need6(
|
|
112676
|
+
need6(isDeepStrictEqual15(actual, expected), "RECONCILE_UNRELATED_HOOK_CHANGED");
|
|
112569
112677
|
}
|
|
112570
112678
|
for (const wanted of intent.hooks) {
|
|
112571
112679
|
const matches2 = nativeHooks.filter((h2) => h2.key === wanted.key || h2.key === wanted.key.replace(join60(home, ".codex/hooks.json"), hooksPath));
|
|
@@ -112584,7 +112692,7 @@ async function reconcileCodexNativeHooks(options, connect = connectCodexHookRpc)
|
|
|
112584
112692
|
const layers = config2?.layers?.filter((layer) => layer.name?.type === "user" && layer.name.file === nativeConfigPath && !layer.name.profile);
|
|
112585
112693
|
need6(layers?.length === 1 && !layers[0].disabledReason && codexNativeConfigEqual(layers[0].config, current), "RECONCILE_NATIVE_CONFIG_MISMATCH");
|
|
112586
112694
|
const finalDiscovery = await rpc.request("hooks/list", { cwds: [home] });
|
|
112587
|
-
need6(Array.isArray(finalDiscovery?.data) && finalDiscovery.data.length === 1 && finalDiscovery.data[0].cwd === home && !finalDiscovery.data[0].errors?.length && !finalDiscovery.data[0].warnings?.length && (!recordedNativeHooks ||
|
|
112695
|
+
need6(Array.isArray(finalDiscovery?.data) && finalDiscovery.data.length === 1 && finalDiscovery.data[0].cwd === home && !finalDiscovery.data[0].errors?.length && !finalDiscovery.data[0].warnings?.length && (!recordedNativeHooks || isDeepStrictEqual15(finalDiscovery.data[0].hooks.map(safeNativeHook), nativeHooks.map(safeNativeHook))), "RECONCILE_NATIVE_STATE_CHANGED");
|
|
112588
112696
|
const finalConfig = await rpc.request("config/read", { includeLayers: true, cwd: home });
|
|
112589
112697
|
const finalLayers = finalConfig?.layers?.filter((layer) => layer.name?.type === "user" && layer.name.file === nativeConfigPath && !layer.name.profile);
|
|
112590
112698
|
need6(finalLayers?.length === 1 && !finalLayers[0].disabledReason && codexNativeConfigEqual(finalLayers[0].config, current), "RECONCILE_NATIVE_CONFIG_CHANGED");
|
|
@@ -112645,7 +112753,7 @@ async function enrollCodexNativeHooks(options = {}, connect = connectCodexHookRp
|
|
|
112645
112753
|
const groups = declarations[event];
|
|
112646
112754
|
need6(Array.isArray(groups), "DECLARATION_CHANGED");
|
|
112647
112755
|
const matches2 = groups.flatMap((group, gi) => (group.hooks ?? []).flatMap((entry, hi) => entry.command === command ? [{ group, entry, gi, hi }] : []));
|
|
112648
|
-
need6(matches2.length === 1 &&
|
|
112756
|
+
need6(matches2.length === 1 && isDeepStrictEqual15(matches2[0].group, { hooks: [{ type: "command", command, timeout: 15 }] }), "DECLARATION_CHANGED");
|
|
112649
112757
|
expected.push({ event: nativeEvent, key: `${join60(home, ".codex/hooks.json")}:${label}:${matches2[0].gi}:${matches2[0].hi}`, command });
|
|
112650
112758
|
}
|
|
112651
112759
|
codexTrustTextWitness(configFile.text, expected.map((h) => h.key));
|
|
@@ -112711,7 +112819,7 @@ async function enrollCodexNativeHooks(options = {}, connect = connectCodexHookRp
|
|
|
112711
112819
|
save(join60(journal, "hooks.before.json"), hooksFile.bytes);
|
|
112712
112820
|
save(join60(journal, "policy.before.json"), policyFile.bytes);
|
|
112713
112821
|
save(join60(journal, "intent.json"), json2({ ...digestInput, planDigest, hooks: planned, nativeHooks: discovered.map(safeNativeHook) }));
|
|
112714
|
-
need6(
|
|
112822
|
+
need6(isDeepStrictEqual15(admit(await list2()), admitted), "NATIVE_DISCOVERY_CHANGED");
|
|
112715
112823
|
checkInputs();
|
|
112716
112824
|
let result2;
|
|
112717
112825
|
try {
|
|
@@ -112725,7 +112833,7 @@ async function enrollCodexNativeHooks(options = {}, connect = connectCodexHookRp
|
|
|
112725
112833
|
expectedConfig.hooks.state ??= {};
|
|
112726
112834
|
for (const h of planned)
|
|
112727
112835
|
expectedConfig.hooks.state[h.key] = { ...expectedConfig.hooks.state[h.key], enabled: true, trusted_hash: h.currentHash };
|
|
112728
|
-
need6(
|
|
112836
|
+
need6(isDeepStrictEqual15(structure3(after2.text), expectedConfig) && codexTrustTextWitness(after2.text, keys3) === preservationText, "PRESERVATION_FAILED");
|
|
112729
112837
|
const savedConfig = snapshot(join60(journal, "config.before.toml"), true);
|
|
112730
112838
|
need6(savedConfig.sha256 === configFile.sha256, "JOURNAL_CHANGED");
|
|
112731
112839
|
const discoveryTransition = binding.discovery?.codex ? createCodexHookDiscoveryRecovery(binding.discovery.codex, savedConfig, after2, planned) : undefined;
|
|
@@ -112733,8 +112841,8 @@ async function enrollCodexNativeHooks(options = {}, connect = connectCodexHookRp
|
|
|
112733
112841
|
unchanged2(hooksFile);
|
|
112734
112842
|
assertManagedAgentBridge("codex", { home, dataDir: dataDir3, projectDir: home, codexDiscoveryRecovery: discoveryTransition });
|
|
112735
112843
|
const current = await list2(), confirmed = admit(current);
|
|
112736
|
-
need6(confirmed.every((h) => h.enabled && h.trustStatus === "trusted") &&
|
|
112737
|
-
need6(
|
|
112844
|
+
need6(confirmed.every((h) => h.enabled && h.trustStatus === "trusted") && isDeepStrictEqual15(confirmed.map((h) => [h.key, h.currentHash]), admitted.map((h) => [h.key, h.currentHash])), "NATIVE_NOT_ELIGIBLE");
|
|
112845
|
+
need6(isDeepStrictEqual15(current.filter((h) => !keys3.includes(h.key)), discovered.filter((h) => !keys3.includes(h.key))), "UNRELATED_HOOK_CHANGED");
|
|
112738
112846
|
unchanged2(after2);
|
|
112739
112847
|
unchanged2(savedConfig);
|
|
112740
112848
|
unchanged2(hooksFile);
|
|
@@ -113004,17 +113112,19 @@ function registerAgentIntegration(parent) {
|
|
|
113004
113112
|
process.exitCode = 1;
|
|
113005
113113
|
}
|
|
113006
113114
|
});
|
|
113007
|
-
hook.command("witness").requiredOption("--kind <kind>", "claude-settings-v3, claude-settings-v2, codex-settings-v2, codex-settings-v1 or claude-marketplace-registry-v2").requiredOption("--path <path>", "Canonical absolute path to the reviewed settings or registry file").option("--json", "Output the discovery witness as JSON", false).description("Capture an explicit versioned review witness without installing it").action(async (options) => {
|
|
113008
|
-
const capture2 = options.kind === "codex-settings-v2" ? captureCodexSettingsV2 : options.kind === "codex-settings-v1" ? captureCodexSettings : options.kind === "claude-settings-v3" ? captureClaudeSettingsV3 : options.kind === "claude-settings-v2" ? captureClaudeSettingsV2 : options.kind === "claude-marketplace-registry-v2" ? captureClaudeMarketplaceRegistryV2 : null;
|
|
113115
|
+
hook.command("witness").requiredOption("--kind <kind>", "claude-settings-v3, claude-settings-v2, codex-settings-v3, codex-settings-v2, codex-settings-v1 or claude-marketplace-registry-v2").requiredOption("--path <path>", "Canonical absolute path to the reviewed settings or registry file").option("--json", "Output the discovery witness as JSON", false).description("Capture an explicit versioned review witness without installing it").action(async (options) => {
|
|
113116
|
+
const capture2 = options.kind === "codex-settings-v3" ? captureCodexSettingsV3 : options.kind === "codex-settings-v2" ? captureCodexSettingsV2 : options.kind === "codex-settings-v1" ? captureCodexSettings : options.kind === "claude-settings-v3" ? captureClaudeSettingsV3 : options.kind === "claude-settings-v2" ? captureClaudeSettingsV2 : options.kind === "claude-marketplace-registry-v2" ? captureClaudeMarketplaceRegistryV2 : null;
|
|
113009
113117
|
if (!capture2)
|
|
113010
|
-
throw new Error("Unsupported witness kind; select claude-settings-v3, claude-settings-v2, codex-settings-v2, codex-settings-v1 or claude-marketplace-registry-v2");
|
|
113118
|
+
throw new Error("Unsupported witness kind; select claude-settings-v3, claude-settings-v2, codex-settings-v3, codex-settings-v2, codex-settings-v1 or claude-marketplace-registry-v2");
|
|
113011
113119
|
await writeCliOutput(JSON.stringify(capture2(options.path), null, 2));
|
|
113012
113120
|
});
|
|
113013
|
-
hook.command("rebind-settings").requiredOption("--agent <agent>", "claude or codex").requiredOption("--reviewed-preimage <path>", "Exact preserved legacy settings.json or config.toml").requiredOption("--expected-policy-sha256 <sha256>", "Exact current managed policy bytes").requiredOption("--expected-settings-sha256 <sha256>", "Exact current native settings bytes").option("--apply", "Apply the explicit semantic witness upgrade with preservation and readback", false).option("--json", "Return the metadata-only plan or receipt", false).description("Explicitly migrate a legacy native settings witness after proving only known preferences changed").action(async (options) => {
|
|
113121
|
+
hook.command("rebind-settings").requiredOption("--agent <agent>", "claude or codex").requiredOption("--reviewed-preimage <path>", "Exact preserved legacy settings.json or config.toml").requiredOption("--expected-policy-sha256 <sha256>", "Exact current managed policy bytes").requiredOption("--expected-settings-sha256 <sha256>", "Exact current native settings bytes").option("--codex-witness-version <version>", "Explicit target: 2 (legacy default) or 3 (service tier and model-advertised effort)").option("--apply", "Apply the explicit semantic witness upgrade with preservation and readback", false).option("--json", "Return the metadata-only plan or receipt", false).description("Explicitly migrate a legacy native settings witness after proving only known preferences changed").action(async (options) => {
|
|
113014
113122
|
try {
|
|
113015
113123
|
if (!["claude", "codex"].includes(options.agent))
|
|
113016
113124
|
throw new Error("Settings witness rebind accepts claude or codex");
|
|
113017
|
-
|
|
113125
|
+
if (options.codexWitnessVersion !== undefined && !["2", "3"].includes(options.codexWitnessVersion))
|
|
113126
|
+
throw new Error("Codex witness version accepts 2 or 3");
|
|
113127
|
+
const plan = planAgentSettingsWitnessUpgrade({ ...options.codexWitnessVersion !== undefined ? { targetCodexVersion: Number(options.codexWitnessVersion) } : {}, agent: options.agent, reviewedPreimage: options.reviewedPreimage, expectedPolicySha256: options.expectedPolicySha256, expectedSettingsSha256: options.expectedSettingsSha256 });
|
|
113018
113128
|
const result2 = options.apply ? applyAgentIntegration(plan) : { changed: [], backups: [] };
|
|
113019
113129
|
const receipt = { applied: options.apply, settingsWitnessUpgrade: plan.settingsWitnessUpgrade, ...result2 };
|
|
113020
113130
|
await writeCliOutput(options.json ? JSON.stringify(receipt) : `Settings witness ${options.apply ? "upgraded" : "planned"} for ${options.agent}. Native configuration was not changed.`);
|
|
@@ -115013,21 +115123,21 @@ async function readPublishRevision(client2, slug2) {
|
|
|
115013
115123
|
throw new PushSkillError("Publishing was refused because the current skill revision could not be verified.", ["Check the configured instance and connection, then retry the push. No upload was attempted."]);
|
|
115014
115124
|
}
|
|
115015
115125
|
const body = lookup.body;
|
|
115016
|
-
const
|
|
115017
|
-
const nestedError =
|
|
115018
|
-
const code2 = typeof
|
|
115126
|
+
const record12 = body !== null && typeof body === "object" && !Array.isArray(body) ? body : undefined;
|
|
115127
|
+
const nestedError = record12?.error;
|
|
115128
|
+
const code2 = typeof record12?.code === "string" ? record12.code : nestedError !== null && typeof nestedError === "object" && !Array.isArray(nestedError) ? nestedError.code : undefined;
|
|
115019
115129
|
if (lookup.status === 404 && code2 === "SKILL_NOT_FOUND")
|
|
115020
115130
|
return;
|
|
115021
115131
|
if (lookup.status < 200 || lookup.status >= 300) {
|
|
115022
115132
|
throw new PushSkillError(`Publishing was refused because the current skill lookup failed: HTTP ${lookup.status}.`, ["Only an explicit SKILL_NOT_FOUND response establishes an initial publish. Check access and server compatibility before retrying."]);
|
|
115023
115133
|
}
|
|
115024
|
-
const revision =
|
|
115025
|
-
if (
|
|
115026
|
-
if (
|
|
115134
|
+
const revision = record12?.revisionId;
|
|
115135
|
+
if (record12?.publicationState === "catalogue-only") {
|
|
115136
|
+
if (record12.name === slug2 && (record12.slug === undefined || record12.slug === slug2) && revision === null)
|
|
115027
115137
|
return;
|
|
115028
115138
|
throw new PushSkillError("Publishing was refused because the catalogue-only response had contradictory identity or revision state.", ["Check the configured instance and server compatibility. No upload was attempted."]);
|
|
115029
115139
|
}
|
|
115030
|
-
if (
|
|
115140
|
+
if (record12?.slug !== slug2 || typeof revision !== "string" || revision.length === 0 || revision !== revision.trim() || !/^[\x21-\x7e]+$/.test(revision)) {
|
|
115031
115141
|
throw new PushSkillError("Publishing was refused because the current skill response did not contain a matching slug and valid revision.", ["Check the configured instance and server compatibility. No upload was attempted."]);
|
|
115032
115142
|
}
|
|
115033
115143
|
return revision;
|
|
@@ -116709,14 +116819,14 @@ function resolveCorpusRootReadOnly(options) {
|
|
|
116709
116819
|
}
|
|
116710
116820
|
return { root: join65(appDir, INSTALLED_SKILLS_DIRNAME), migrationPending: true };
|
|
116711
116821
|
}
|
|
116712
|
-
function remoteRowToSkill(
|
|
116713
|
-
const slug2 = typeof
|
|
116822
|
+
function remoteRowToSkill(record12) {
|
|
116823
|
+
const slug2 = typeof record12.slug === "string" ? record12.slug : typeof record12.name === "string" ? record12.name : undefined;
|
|
116714
116824
|
if (!slug2)
|
|
116715
116825
|
return;
|
|
116716
116826
|
return {
|
|
116717
116827
|
slug: slug2,
|
|
116718
|
-
version: typeof
|
|
116719
|
-
sha256: typeof
|
|
116828
|
+
version: typeof record12.version === "string" ? record12.version : undefined,
|
|
116829
|
+
sha256: typeof record12.bundleSha256 === "string" && record12.bundleSha256 ? record12.bundleSha256 : undefined
|
|
116720
116830
|
};
|
|
116721
116831
|
}
|
|
116722
116832
|
function recheckLocalSide(plannedLocal, localDir, ops = {
|