@hasna/skills 0.10.26 → 0.10.28
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 +29 -0
- package/bin/index.js +438 -326
- package/bin/mcp.js +265 -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 +327 -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 +424 -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.28",
|
|
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,25 @@ 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", "personality"] : 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 (key === "personality")
|
|
51925
|
+
need4(typeof value === "string" && ["none", "friendly", "pragmatic"].includes(value));
|
|
51926
|
+
else if (version === 3 && key !== "model_verbosity") {
|
|
51927
|
+
need4(typeof value === "string" && value.length <= 128 && !/[\x00-\x1f\x7f]/.test(value));
|
|
51928
|
+
if (key !== "service_tier")
|
|
51929
|
+
need4(value.length > 0);
|
|
51930
|
+
} else
|
|
51844
51931
|
need4(typeof value === "string" && (key === "model_reasoning_effort" ? EFFORT2.has(value) : VERBOSITY2.has(value)));
|
|
51845
51932
|
delete target[key];
|
|
51846
51933
|
}
|
|
51847
51934
|
}
|
|
51848
|
-
function settingsDigest2(text2) {
|
|
51935
|
+
function settingsDigest2(text2, version = 2) {
|
|
51849
51936
|
let config;
|
|
51850
51937
|
try {
|
|
51851
51938
|
config = Bun.TOML.parse(text2);
|
|
@@ -51853,8 +51940,9 @@ function settingsDigest2(text2) {
|
|
|
51853
51940
|
throw new Error("Invalid Codex settings witness");
|
|
51854
51941
|
}
|
|
51855
51942
|
need4(isRecord3(config));
|
|
51856
|
-
|
|
51857
|
-
|
|
51943
|
+
const projected = version === 3 ? projectRegularCodexMcp(config, text2) : { config, numericSource: text2 };
|
|
51944
|
+
normalize3(projected.config, version);
|
|
51945
|
+
return sha2(`hasna.skills.codex-settings.v${version}\x00${JSON.stringify([canonical4(projected.config), numericTokens2(projected.numericSource)])}`);
|
|
51858
51946
|
}
|
|
51859
51947
|
function hashCodexSettingsReplacementV2(text2, budget = { remaining: 256 * 1024 * 1024 }) {
|
|
51860
51948
|
need4(Buffer.byteLength(text2) <= 1024 * 1024 && budget.remaining >= Buffer.byteLength(text2));
|
|
@@ -51878,10 +51966,30 @@ function upgradeCodexSettingsWitness(previous, reviewedSettingsPath) {
|
|
|
51878
51966
|
throw new Error("Codex non-preference settings changed; explicit discovery review required");
|
|
51879
51967
|
return { path: previous.path, hashMode: "codex-settings-v2", sha256: sha2562 };
|
|
51880
51968
|
}
|
|
51969
|
+
function hashCodexSettingsReplacementV3(text2, budget = { remaining: 256 * 1024 * 1024 }) {
|
|
51970
|
+
need4(Buffer.byteLength(text2) <= 1024 * 1024 && budget.remaining >= Buffer.byteLength(text2));
|
|
51971
|
+
budget.remaining -= Buffer.byteLength(text2);
|
|
51972
|
+
return settingsDigest2(text2, 3);
|
|
51973
|
+
}
|
|
51974
|
+
function captureCodexSettingsV3(path, budget = { remaining: 256 * 1024 * 1024 }) {
|
|
51975
|
+
return { path, hashMode: "codex-settings-v3", sha256: settingsDigest2(readNativeSettingsWitnessFile(path, budget, "config.toml"), 3) };
|
|
51976
|
+
}
|
|
51977
|
+
function upgradeCodexSettingsWitnessV3(previous, reviewedSettingsPath) {
|
|
51978
|
+
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));
|
|
51979
|
+
const budget = { remaining: 2 * 1024 * 1024 };
|
|
51980
|
+
const before2 = readNativeSettingsWitnessFile(reviewedSettingsPath, budget, "config.toml"), current = readNativeSettingsWitnessFile(previous.path, budget, "config.toml");
|
|
51981
|
+
const original = previous.hashMode === "codex-settings-v2" ? settingsDigest2(before2) : previous.hashMode === "codex-settings-v1" ? hashCodexSettingsReplacement(before2) : sha2(before2);
|
|
51982
|
+
need4(original === previous.sha256);
|
|
51983
|
+
const sha2562 = settingsDigest2(current, 3);
|
|
51984
|
+
if (settingsDigest2(before2, 3) !== sha2562)
|
|
51985
|
+
throw new Error("Codex settings outside the reviewed V3 contract changed; explicit discovery review required");
|
|
51986
|
+
return { path: previous.path, hashMode: "codex-settings-v3", sha256: sha2562 };
|
|
51987
|
+
}
|
|
51881
51988
|
var sha2 = (text2) => createHash10("sha256").update(text2).digest("hex"), EFFORT2, VERBOSITY2, MODEL, CODEX_DISCOVERY_PROJECTION_FIELDS, INFERENCE;
|
|
51882
51989
|
var init_codex_settings_witness = __esm(() => {
|
|
51883
51990
|
init_codex_settings_witness_v1();
|
|
51884
51991
|
init_codex_settings_witness_v1();
|
|
51992
|
+
init_codex_mcp_discovery_projection();
|
|
51885
51993
|
init_claude_settings_witness();
|
|
51886
51994
|
EFFORT2 = new Set(["none", "minimal", "low", "medium", "high", "xhigh"]);
|
|
51887
51995
|
VERBOSITY2 = new Set(["low", "medium", "high"]);
|
|
@@ -52019,7 +52127,7 @@ var init_agent_bridge = __esm(() => {
|
|
|
52019
52127
|
});
|
|
52020
52128
|
|
|
52021
52129
|
// src/lib/agent-codex.ts
|
|
52022
|
-
import { isDeepStrictEqual as
|
|
52130
|
+
import { isDeepStrictEqual as isDeepStrictEqual4 } from "util";
|
|
52023
52131
|
function splitTopLevel(value, delimiter) {
|
|
52024
52132
|
const result2 = [];
|
|
52025
52133
|
let start = 0, square = 0, curly = 0, quote = null, escaped = false;
|
|
@@ -52148,7 +52256,7 @@ function normalizeCodexInlinePathConfig(text2) {
|
|
|
52148
52256
|
const expectedWithoutConfig = structuredClone(before2);
|
|
52149
52257
|
delete expectedWithoutConfig.skills.config;
|
|
52150
52258
|
try {
|
|
52151
|
-
if (
|
|
52259
|
+
if (isDeepStrictEqual4(Bun.TOML.parse(text2.replace(CODEX_SKILL_CONFIG_SECTIONS, "")), expectedWithoutConfig))
|
|
52152
52260
|
return text2;
|
|
52153
52261
|
} catch {}
|
|
52154
52262
|
const matches2 = [];
|
|
@@ -52201,7 +52309,7 @@ function normalizeCodexInlinePathConfig(text2) {
|
|
|
52201
52309
|
try {
|
|
52202
52310
|
const after2 = Bun.TOML.parse(candidate);
|
|
52203
52311
|
const expected = structuredClone(before2);
|
|
52204
|
-
if (
|
|
52312
|
+
if (isDeepStrictEqual4(after2, expected))
|
|
52205
52313
|
matches2.push(candidate);
|
|
52206
52314
|
} catch {}
|
|
52207
52315
|
}
|
|
@@ -52217,11 +52325,11 @@ function assertCodexPathConfigEditable(text2) {
|
|
|
52217
52325
|
delete expected.skills.config;
|
|
52218
52326
|
try {
|
|
52219
52327
|
const withoutSections = Bun.TOML.parse(text2.replace(CODEX_SKILL_CONFIG_SECTIONS, ""));
|
|
52220
|
-
if (
|
|
52328
|
+
if (isDeepStrictEqual4(withoutSections, expected))
|
|
52221
52329
|
return;
|
|
52222
52330
|
const normalized = normalizeCodexInlinePathConfig(text2);
|
|
52223
52331
|
const withoutNormalizedSections = Bun.TOML.parse(normalized.replace(CODEX_SKILL_CONFIG_SECTIONS, ""));
|
|
52224
|
-
if (
|
|
52332
|
+
if (isDeepStrictEqual4(withoutNormalizedSections, expected))
|
|
52225
52333
|
return;
|
|
52226
52334
|
} catch {}
|
|
52227
52335
|
throw codexPathConfigRefusal();
|
|
@@ -52259,7 +52367,7 @@ function disableCodexBundledSkills(text2) {
|
|
|
52259
52367
|
const candidates = new Set;
|
|
52260
52368
|
const consider = (candidate) => {
|
|
52261
52369
|
try {
|
|
52262
|
-
if (
|
|
52370
|
+
if (isDeepStrictEqual4(Bun.TOML.parse(candidate), expected))
|
|
52263
52371
|
candidates.add(candidate);
|
|
52264
52372
|
} catch {}
|
|
52265
52373
|
};
|
|
@@ -52290,7 +52398,7 @@ var init_agent_codex = __esm(() => {
|
|
|
52290
52398
|
|
|
52291
52399
|
// src/lib/agent-integration.ts
|
|
52292
52400
|
import { createHash as createHash12, randomUUID as randomUUID5 } from "crypto";
|
|
52293
|
-
import { isDeepStrictEqual as
|
|
52401
|
+
import { isDeepStrictEqual as isDeepStrictEqual5 } from "util";
|
|
52294
52402
|
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
52403
|
import { dirname as dirname11, join as join21, resolve as resolve11, relative as relative5, isAbsolute as isAbsolute11, sep as sep5 } from "path";
|
|
52296
52404
|
import { homedir as homedir3 } from "os";
|
|
@@ -52500,14 +52608,14 @@ function parseNativeMigrationTargetManifest(input) {
|
|
|
52500
52608
|
}
|
|
52501
52609
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
52502
52610
|
throw new Error("Invalid native migration target manifest");
|
|
52503
|
-
const
|
|
52504
|
-
if (
|
|
52611
|
+
const record3 = value;
|
|
52612
|
+
if (record3.schema !== "hasna.skills-native-migration-targets.v1" || Object.keys(record3).some((key) => !["schema", "targets"].includes(key)))
|
|
52505
52613
|
throw new Error("Unsupported native migration target manifest schema");
|
|
52506
|
-
if (!Array.isArray(
|
|
52614
|
+
if (!Array.isArray(record3.targets) || record3.targets.length === 0 || record3.targets.length > 1000)
|
|
52507
52615
|
throw new Error("Native migration target manifest must contain 1 to 1000 targets");
|
|
52508
52616
|
const targets = [];
|
|
52509
52617
|
const identities = new Set;
|
|
52510
|
-
for (const target of
|
|
52618
|
+
for (const target of record3.targets) {
|
|
52511
52619
|
if (!target || typeof target !== "object" || Array.isArray(target))
|
|
52512
52620
|
throw new Error("Invalid native migration target");
|
|
52513
52621
|
const item = target;
|
|
@@ -53045,6 +53153,8 @@ function atomicWrite2(path, content) {
|
|
|
53045
53153
|
}
|
|
53046
53154
|
}
|
|
53047
53155
|
function planAgentSettingsWitnessUpgrade(options) {
|
|
53156
|
+
if (options.targetCodexVersion !== undefined && (options.agent !== "codex" || ![2, 3].includes(options.targetCodexVersion)))
|
|
53157
|
+
throw new Error("Invalid Codex witness target version");
|
|
53048
53158
|
const home = resolve11(options.home ?? homedir3()), dataDir3 = options.dataDir ?? getDataDirReadOnly();
|
|
53049
53159
|
const snapshot = readManagedSkillPolicySnapshot(dataDir3);
|
|
53050
53160
|
if (!snapshot || sha3(snapshot.text) !== options.expectedPolicySha256)
|
|
@@ -53066,21 +53176,21 @@ function planAgentSettingsWitnessUpgrade(options) {
|
|
|
53066
53176
|
throw new Error("Settings witness upgrade requires a preserved settings preimage");
|
|
53067
53177
|
const replaced = [previous];
|
|
53068
53178
|
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
|
|
53179
|
+
if (previous.hashMode !== undefined && previous.hashMode !== "bytes" && previous.hashMode !== "codex-settings-v1" && !(options.targetCodexVersion === 3 && previous.hashMode === "codex-settings-v2"))
|
|
53180
|
+
throw new Error("Codex settings witness upgrade requires an eligible preserved configuration witness");
|
|
53071
53181
|
const preimage = readCodexSettingsPreimage(options.reviewedPreimage);
|
|
53072
53182
|
for (const source of binding.sources) {
|
|
53073
53183
|
if (source === previous || source.path !== configPath)
|
|
53074
53184
|
continue;
|
|
53075
53185
|
const fields = source.fields;
|
|
53076
|
-
if (source.hashMode !== undefined || source.format !== "toml" || !Array.isArray(fields) || !
|
|
53186
|
+
if (source.hashMode !== undefined || source.format !== "toml" || !Array.isArray(fields) || !isDeepStrictEqual5(fields, [...CODEX_DISCOVERY_PROJECTION_FIELDS]) || typeof source.sha256 !== "string")
|
|
53077
53187
|
throw new Error("Codex settings witness upgrade found an unrecognized configuration witness");
|
|
53078
53188
|
if (projectNativeDiscoveryFields(preimage, "toml", fields, configPath) !== source.sha256)
|
|
53079
53189
|
throw new Error("Reviewed preimage does not explain the Codex discovery projection witness");
|
|
53080
53190
|
replaced.push(source);
|
|
53081
53191
|
}
|
|
53082
53192
|
}
|
|
53083
|
-
const next = options.agent === "claude" ? upgradeClaudeSettingsWitness(previous, options.reviewedPreimage) : upgradeCodexSettingsWitness(previous, options.reviewedPreimage);
|
|
53193
|
+
const next = options.agent === "claude" ? upgradeClaudeSettingsWitness(previous, options.reviewedPreimage) : options.targetCodexVersion === 3 ? upgradeCodexSettingsWitnessV3(previous, options.reviewedPreimage) : upgradeCodexSettingsWitness(previous, options.reviewedPreimage);
|
|
53084
53194
|
const rebound = [];
|
|
53085
53195
|
for (const source of binding.sources) {
|
|
53086
53196
|
if (!replaced.includes(source)) {
|
|
@@ -53117,7 +53227,7 @@ function applyAgentIntegration(plan) {
|
|
|
53117
53227
|
const upgrade = plan.settingsWitnessUpgrade;
|
|
53118
53228
|
if (!plan.managedAgentChecks || !plan.observedPolicy?.before)
|
|
53119
53229
|
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 });
|
|
53230
|
+
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
53231
|
if (JSON.stringify(verified.changes) !== JSON.stringify(plan.changes) || JSON.stringify(verified.settingsWitnessUpgrade) !== JSON.stringify(upgrade))
|
|
53122
53232
|
throw new Error("Settings witness upgrade plan changed");
|
|
53123
53233
|
provenDiscovery = verified.discoveryBefore[0];
|
|
@@ -53653,15 +53763,15 @@ function migrateOwnerLayout(options = {}) {
|
|
|
53653
53763
|
moved.push(name);
|
|
53654
53764
|
}
|
|
53655
53765
|
createLazyDirs(appDir, created);
|
|
53656
|
-
const
|
|
53766
|
+
const record3 = {
|
|
53657
53767
|
version: 1,
|
|
53658
53768
|
migratedAt: new Date().toISOString(),
|
|
53659
53769
|
moved,
|
|
53660
53770
|
note: "installed/ and legacy flat skill dirs moved into skills/; custom/ retained"
|
|
53661
53771
|
};
|
|
53662
|
-
writeFileSync5(layoutMigrationRecordPath(appDir), `${JSON.stringify(
|
|
53772
|
+
writeFileSync5(layoutMigrationRecordPath(appDir), `${JSON.stringify(record3, null, 2)}
|
|
53663
53773
|
`);
|
|
53664
|
-
return { status: "migrated", moved, created, record:
|
|
53774
|
+
return { status: "migrated", moved, created, record: record3 };
|
|
53665
53775
|
}
|
|
53666
53776
|
var LOGS_DIRNAME = "logs", OUTPUTS_DIRNAME = "outputs", LEGACY_CUSTOM_DIRNAME = "custom";
|
|
53667
53777
|
var init_home_migration = __esm(() => {
|
|
@@ -56461,7 +56571,7 @@ var sameStat = (a, b) => ["dev", "ino", "uid", "nlink", "mode", "size", "mtimeNs
|
|
|
56461
56571
|
var init_codex_hook_trust_files = () => {};
|
|
56462
56572
|
|
|
56463
56573
|
// src/lib/codex-hook-trust-layout.ts
|
|
56464
|
-
import { isDeepStrictEqual as
|
|
56574
|
+
import { isDeepStrictEqual as isDeepStrictEqual6 } from "util";
|
|
56465
56575
|
function codexTrustTextWitness(text2, keys2, canonicalize = true) {
|
|
56466
56576
|
const parsed = Bun.TOML.parse(text2), wanted = new Set(keys2);
|
|
56467
56577
|
const headers = [...text2.matchAll(/^[ \t]*(\[[^\r\n]+\])[ \t]*(#[^\r\n]*)?(?:\r?\n|$)/gm)];
|
|
@@ -56526,7 +56636,7 @@ function codexTrustTextWitness(text2, keys2, canonicalize = true) {
|
|
|
56526
56636
|
if (expected.hooks)
|
|
56527
56637
|
delete expected.hooks.state;
|
|
56528
56638
|
try {
|
|
56529
|
-
if (!
|
|
56639
|
+
if (!isDeepStrictEqual6(prune(Bun.TOML.parse(noState)), prune(expected)))
|
|
56530
56640
|
throw fail2();
|
|
56531
56641
|
} catch {
|
|
56532
56642
|
throw fail2();
|
|
@@ -56596,13 +56706,13 @@ var init_codex_hook_trust_layout = () => {};
|
|
|
56596
56706
|
|
|
56597
56707
|
// src/lib/codex-hook-additions-review.ts
|
|
56598
56708
|
import { isAbsolute as isAbsolute16 } from "path";
|
|
56599
|
-
import { isDeepStrictEqual as
|
|
56709
|
+
import { isDeepStrictEqual as isDeepStrictEqual7 } from "util";
|
|
56600
56710
|
function exactKeys2(value, keys2) {
|
|
56601
|
-
need6(value && typeof value === "object" && !Array.isArray(value) &&
|
|
56711
|
+
need6(value && typeof value === "object" && !Array.isArray(value) && isDeepStrictEqual7(Object.keys(value).sort(), [...keys2].sort()), "RECONCILE_ADDITIONS_REVIEW_SCHEMA");
|
|
56602
56712
|
}
|
|
56603
56713
|
function readReviewedAdditionTrustStates(proof, before2, current, journalHooks) {
|
|
56604
56714
|
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 &&
|
|
56715
|
+
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
56716
|
captured.recheck();
|
|
56607
56717
|
unchanged2(before2);
|
|
56608
56718
|
unchanged2(current);
|
|
@@ -56625,7 +56735,7 @@ function reviewNativeHookAdditions(options) {
|
|
|
56625
56735
|
expectedProducer.hooks.state ??= {};
|
|
56626
56736
|
for (const hook of options.journalHooks)
|
|
56627
56737
|
expectedProducer.hooks.state[hook.key] = { ...expectedProducer.hooks.state[hook.key], enabled: true, trusted_hash: hook.currentHash };
|
|
56628
|
-
need6(
|
|
56738
|
+
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
56739
|
need6(Array.isArray(review.additions) && review.additions.length > 0 && review.additions.length <= 20, "RECONCILE_ADDITIONS_REVIEW_SCHEMA");
|
|
56630
56740
|
const expectedHooks = JSON.parse(options.hooksBefore.text), currentHooks = JSON.parse(options.hooksCurrent.text), expectedConfig = structuredClone(producer);
|
|
56631
56741
|
need6(expectedHooks.hooks && typeof expectedHooks.hooks === "object" && !Array.isArray(expectedHooks.hooks), "RECONCILE_ADDITIONS_DECLARATIONS");
|
|
@@ -56654,9 +56764,9 @@ function reviewNativeHookAdditions(options) {
|
|
|
56654
56764
|
expectedHooks.hooks[event] = [...groups, { ...event === "PreToolUse" ? { matcher: hook.matcher } : {}, hooks: [{ type: "command", command: hook.command, timeout: hook.timeoutSec }] }];
|
|
56655
56765
|
expectedConfig.hooks.state[key] = trustState;
|
|
56656
56766
|
}
|
|
56657
|
-
need6(
|
|
56767
|
+
need6(isDeepStrictEqual7(expectedHooks, currentHooks), "RECONCILE_ADDITIONS_DECLARATIONS");
|
|
56658
56768
|
const keys2 = added.map((hook) => hook.key);
|
|
56659
|
-
need6(
|
|
56769
|
+
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
56770
|
const inputs = [reviewFile, producerConfig, producerHooks, options.intent, options.policy, options.configBefore, options.configCurrent, options.hooksBefore, options.hooksCurrent];
|
|
56661
56771
|
const recheck = () => {
|
|
56662
56772
|
for (const input of inputs)
|
|
@@ -56679,7 +56789,7 @@ var init_codex_hook_additions_review = __esm(() => {
|
|
|
56679
56789
|
|
|
56680
56790
|
// src/lib/codex-hook-discovery-recovery.ts
|
|
56681
56791
|
import { createHash as createHash17 } from "crypto";
|
|
56682
|
-
import { isDeepStrictEqual as
|
|
56792
|
+
import { isDeepStrictEqual as isDeepStrictEqual8 } from "util";
|
|
56683
56793
|
function createCodexHookDiscoveryRecovery(binding, before2, current, hooks, additions) {
|
|
56684
56794
|
const journalHooks = hooks.map(({ key, currentHash }) => ({ key, currentHash }));
|
|
56685
56795
|
const additionStates = additions ? readReviewedAdditionTrustStates(additions, before2, current, journalHooks) : [];
|
|
@@ -56693,11 +56803,11 @@ function createCodexHookDiscoveryRecovery(binding, before2, current, hooks, addi
|
|
|
56693
56803
|
need6(binding.agent === "codex" && binding.method === "reviewed" && raw.length === 1 && raw[0].sha256 === before2.sha256 && before2.sha256 !== current.sha256, "RECONCILE_DISCOVERY_CONFIG_WITNESS");
|
|
56694
56804
|
need6(raw[0].format === undefined && raw[0].fields === undefined && raw[0].managedPlugins === undefined, "RECONCILE_DISCOVERY_CONFIG_WITNESS");
|
|
56695
56805
|
const typed = binding.sources.filter((source) => source.path === current.file && source.format === "toml");
|
|
56696
|
-
need6(typed.length === 1 && typed[0].hashMode === undefined &&
|
|
56806
|
+
need6(typed.length === 1 && typed[0].hashMode === undefined && isDeepStrictEqual8(typed[0].fields, fields), "RECONCILE_DISCOVERY_TYPED_WITNESS");
|
|
56697
56807
|
const original = structure2(before2.text), actual = structure2(current.text);
|
|
56698
56808
|
const project = (value) => Object.fromEntries(fields.map((field2) => [field2, value[field2] ?? null]));
|
|
56699
56809
|
const projection = sha4(JSON.stringify(project(original)));
|
|
56700
|
-
need6(typed[0].sha256 === projection && sha4(JSON.stringify(project(actual))) === projection &&
|
|
56810
|
+
need6(typed[0].sha256 === projection && sha4(JSON.stringify(project(actual))) === projection && isDeepStrictEqual8(project(original), project(actual)), "RECONCILE_DISCOVERY_TYPED_WITNESS");
|
|
56701
56811
|
const keys2 = [...journalHooks.map((hook) => hook.key), ...additionStates.map((hook) => hook.key)];
|
|
56702
56812
|
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
56813
|
const expected = structuredClone(original);
|
|
@@ -56707,7 +56817,7 @@ function createCodexHookDiscoveryRecovery(binding, before2, current, hooks, addi
|
|
|
56707
56817
|
expected.hooks.state[hook.key] = { ...expected.hooks.state[hook.key], enabled: true, trusted_hash: hook.currentHash };
|
|
56708
56818
|
for (const { key, state } of additionStates)
|
|
56709
56819
|
expected.hooks.state[key] = { ...state };
|
|
56710
|
-
need6(
|
|
56820
|
+
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
56821
|
unchanged2(before2);
|
|
56712
56822
|
unchanged2(current);
|
|
56713
56823
|
const witness = Object.freeze({ configPath: current.file, beforeSha256: before2.sha256, currentSha256: current.sha256, discoverySha256: sha4(JSON.stringify(binding)), typedProjectionSha256: projection });
|
|
@@ -56742,7 +56852,7 @@ var init_codex_hook_discovery_recovery = __esm(() => {
|
|
|
56742
56852
|
import { createHash as createHash18 } from "crypto";
|
|
56743
56853
|
import { lstatSync as lstatSync21, readFileSync as readFileSync18, readdirSync as readdirSync11, realpathSync as realpathSync7 } from "fs";
|
|
56744
56854
|
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
|
|
56855
|
+
import { isDeepStrictEqual as isDeepStrictEqual9 } from "util";
|
|
56746
56856
|
function parseConfig(text3, path, toml = false) {
|
|
56747
56857
|
try {
|
|
56748
56858
|
const value = toml ? Bun.TOML.parse(text3) : JSON.parse(text3);
|
|
@@ -56781,19 +56891,19 @@ function projectNativeDiscoveryFields(text3, format, fields2, path) {
|
|
|
56781
56891
|
return digest(JSON.stringify(Object.fromEntries(fields2.map((field2) => [field2, object5[field2] ?? null]))));
|
|
56782
56892
|
}
|
|
56783
56893
|
function isSupersededCodexProjection(agent, configPath, source) {
|
|
56784
|
-
return agent === "codex" && source.path === configPath && source.format === "toml" &&
|
|
56894
|
+
return agent === "codex" && source.path === configPath && source.format === "toml" && isDeepStrictEqual9(source.fields, [...CODEX_DISCOVERY_PROJECTION_FIELDS]);
|
|
56785
56895
|
}
|
|
56786
56896
|
function supersedesCodexProjection(sources, configPath) {
|
|
56787
|
-
return sources.some((source) => source.path === configPath && source.hashMode === "codex-settings-v2");
|
|
56897
|
+
return sources.some((source) => source.path === configPath && (source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3"));
|
|
56788
56898
|
}
|
|
56789
56899
|
function projected(source, changes, budget = discoveryByteBudget()) {
|
|
56790
|
-
if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2") {
|
|
56900
|
+
if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3") {
|
|
56791
56901
|
if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
|
|
56792
56902
|
throw new Error("Codex settings witnesses require exact typed metadata");
|
|
56793
|
-
const current = (source.hashMode === "codex-settings-v2" ? captureCodexSettingsV2 : captureCodexSettings)(source.path, budget).sha256;
|
|
56903
|
+
const current = (source.hashMode === "codex-settings-v3" ? captureCodexSettingsV3 : source.hashMode === "codex-settings-v2" ? captureCodexSettingsV2 : captureCodexSettings)(source.path, budget).sha256;
|
|
56794
56904
|
if (current !== source.sha256)
|
|
56795
56905
|
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;
|
|
56906
|
+
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
56907
|
}
|
|
56798
56908
|
if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") {
|
|
56799
56909
|
if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
|
|
@@ -56893,7 +57003,7 @@ function codexInstallationRoots(binding) {
|
|
|
56893
57003
|
});
|
|
56894
57004
|
}
|
|
56895
57005
|
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"))
|
|
57006
|
+
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
57007
|
throw new Error("Codex settings witnesses require explicit reviewed Codex configuration");
|
|
56898
57008
|
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
57009
|
throw new Error("Claude settings witnesses require explicit reviewed Claude configuration");
|
|
@@ -57031,10 +57141,10 @@ function resolveAgentDiscovery(options) {
|
|
|
57031
57141
|
verifyAgentDiscovery(retained);
|
|
57032
57142
|
if (!retained.sources.some((source) => source.path === canonical6(configPath) && source.format === undefined && source.fields === undefined))
|
|
57033
57143
|
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)))
|
|
57144
|
+
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
57145
|
unresolved("retained settings witness names another configuration source");
|
|
57036
57146
|
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) =>
|
|
57147
|
+
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
57148
|
unresolved("retained review is missing current runtime discovery coverage");
|
|
57039
57149
|
return retained;
|
|
57040
57150
|
}
|
|
@@ -57048,7 +57158,7 @@ function resolveAgentDiscovery(options) {
|
|
|
57048
57158
|
if (review.sources.some((source) => source.format !== undefined || source.fields !== undefined))
|
|
57049
57159
|
throw new Error("Explicit discovery reviews require full source-file hashes");
|
|
57050
57160
|
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)))
|
|
57161
|
+
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
57162
|
throw new Error("Semantic settings witnesses must name the configured Claude configuration source");
|
|
57053
57163
|
if (!review.sources.some((source) => source.path === canonical6(configPath)))
|
|
57054
57164
|
throw new Error("Discovery review must include the agent configuration source");
|
|
@@ -59698,14 +59808,14 @@ function readIdentity(env3 = process.env) {
|
|
|
59698
59808
|
const parsed = JSON.parse(readFileSync20(getIdentityFilePath(env3), "utf-8"));
|
|
59699
59809
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
59700
59810
|
return {};
|
|
59701
|
-
const
|
|
59811
|
+
const record3 = parsed;
|
|
59702
59812
|
const selected = resolveSkillsApiOrigin(env3)?.origin;
|
|
59703
|
-
const bound = typeof
|
|
59813
|
+
const bound = typeof record3.apiUrl === "string" ? record3.apiUrl : readCredentialValue(SKILLS_BOUND_API_URL, env3) ?? readStoredApiUrl(env3) ?? defaultFleetGatewayBaseUrl("skills");
|
|
59704
59814
|
if (selected && normalizeSkillsApiOrigin(bound) !== selected)
|
|
59705
59815
|
return {};
|
|
59706
59816
|
const identity5 = {};
|
|
59707
59817
|
for (const field2 of ["email", "orgId", "orgSlug", "userId"]) {
|
|
59708
|
-
const value =
|
|
59818
|
+
const value = record3[field2];
|
|
59709
59819
|
if (typeof value === "string" && value.length > 0)
|
|
59710
59820
|
identity5[field2] = value;
|
|
59711
59821
|
}
|
|
@@ -59842,12 +59952,12 @@ function readStoredCredential(env3 = process.env) {
|
|
|
59842
59952
|
const origin = normalizeSkillsApiOrigin(readCredentialValue(SKILLS_BOUND_API_URL, env3) ?? readStoredApiUrl(env3) ?? defaultFleetGatewayBaseUrl("skills"));
|
|
59843
59953
|
let storedBy = "external";
|
|
59844
59954
|
let urlWrittenByLogin = false;
|
|
59845
|
-
const
|
|
59846
|
-
const recordedFor =
|
|
59847
|
-
if (
|
|
59848
|
-
storedBy =
|
|
59955
|
+
const record3 = apiKey ? readIdentityRecord(env3) : null;
|
|
59956
|
+
const recordedFor = record3 && typeof record3.apiUrl === "string" ? safeOrigin(record3.apiUrl) : null;
|
|
59957
|
+
if (record3 && recordedFor === origin) {
|
|
59958
|
+
storedBy = record3.issuedBy === "sign-in" || record3.issuedBy === "api-key" ? record3.issuedBy : "legacy";
|
|
59849
59959
|
const fileUrl = readStoredApiUrl(env3);
|
|
59850
|
-
urlWrittenByLogin = storedBy !== "legacy" &&
|
|
59960
|
+
urlWrittenByLogin = storedBy !== "legacy" && record3.urlWrittenBy === "login" && fileUrl !== null && safeOrigin(fileUrl) === origin;
|
|
59851
59961
|
}
|
|
59852
59962
|
return { file, apiKey: apiKey ?? null, origin, storedBy, urlWrittenByLogin };
|
|
59853
59963
|
}
|
|
@@ -59877,9 +59987,9 @@ function saveApiUrl(apiUrl, env3 = process.env) {
|
|
|
59877
59987
|
values2[SKILLS_BOUND_API_URL] = normalizeSkillsApiOrigin(readStoredApiUrl(env3) ?? defaultFleetGatewayBaseUrl("skills"));
|
|
59878
59988
|
}
|
|
59879
59989
|
const file = writeCredentialValues(values2, env3);
|
|
59880
|
-
const
|
|
59881
|
-
if (
|
|
59882
|
-
const { urlWrittenBy: _dropped, ...rest2 } =
|
|
59990
|
+
const record3 = readIdentityRecord(env3);
|
|
59991
|
+
if (record3 && "urlWrittenBy" in record3) {
|
|
59992
|
+
const { urlWrittenBy: _dropped, ...rest2 } = record3;
|
|
59883
59993
|
const identityFile = getIdentityFilePath(env3);
|
|
59884
59994
|
writeFileSync10(identityFile, JSON.stringify(rest2, null, 2) + `
|
|
59885
59995
|
`, { mode: 384 });
|
|
@@ -59918,7 +60028,7 @@ function invitationEmailIds(invitationId, challengeId) {
|
|
|
59918
60028
|
}
|
|
59919
60029
|
function invitationEmailInput(action, input) {
|
|
59920
60030
|
const keys2 = ["invitationId", "token", "challengeId", "confirm", ...action === "accept" ? ["code"] : []];
|
|
59921
|
-
if (!
|
|
60031
|
+
if (!record3(input) || Object.keys(input).length !== keys2.length || keys2.some((key) => !Object.hasOwn(input, key)))
|
|
59922
60032
|
throw new InvitationEmailInputError;
|
|
59923
60033
|
const value = { ...input };
|
|
59924
60034
|
const ids = invitationEmailIds(value.invitationId, value.challengeId);
|
|
@@ -59947,12 +60057,12 @@ async function requestInvitationEmail(origin, action, input) {
|
|
|
59947
60057
|
signal: AbortSignal.timeout(15000)
|
|
59948
60058
|
});
|
|
59949
60059
|
const parsed = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(await readBoundedResponse(response, 4096)));
|
|
59950
|
-
if (!response.ok &&
|
|
60060
|
+
if (!response.ok && record3(parsed) && typeof parsed.code === "string" && Object.hasOwn(refusals, parsed.code)) {
|
|
59951
60061
|
const code = parsed.code;
|
|
59952
60062
|
if (response.status === refusals[code][0])
|
|
59953
60063
|
throw new RemoteInvitationEmailError(code);
|
|
59954
60064
|
}
|
|
59955
|
-
if (!
|
|
60065
|
+
if (!record3(parsed))
|
|
59956
60066
|
throw new RemoteInvitationEmailUnconfirmedError(action);
|
|
59957
60067
|
if (action === "challenge" && response.status === 202 && parsed.challengeId === value.challengeId && parsed.expiresIn === 600 && typeof parsed.message === "string" && parsed.message.length <= 256) {
|
|
59958
60068
|
return { challengeId: value.challengeId, message: "If this invitation is eligible, a verification code will arrive. Delivery is not confirmed.", expiresIn: 600 };
|
|
@@ -59971,7 +60081,7 @@ function invitationEmailCustomerError(error) {
|
|
|
59971
60081
|
return { code: error.code, error: error.message };
|
|
59972
60082
|
return { code: "INVITATION_EMAIL_UNAVAILABLE", error: "Unable to prepare this recovery action. Check the explicit server and stable profile. No credential was saved." };
|
|
59973
60083
|
}
|
|
59974
|
-
var InvitationEmailInputError, refusals, RemoteInvitationEmailError, RemoteInvitationEmailUnconfirmedError,
|
|
60084
|
+
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
60085
|
var init_remote_invitation_recovery = __esm(() => {
|
|
59976
60086
|
init_fleet_credentials();
|
|
59977
60087
|
init_remote_files();
|
|
@@ -60018,7 +60128,7 @@ function workspaceExpectedUserId(value) {
|
|
|
60018
60128
|
return value;
|
|
60019
60129
|
}
|
|
60020
60130
|
function workspaceContext(value) {
|
|
60021
|
-
if (!
|
|
60131
|
+
if (!record4(value) || Object.keys(value).sort().join(",") !== "membershipId,userId" || !uuid2(value.userId) || !uuid2(value.membershipId))
|
|
60022
60132
|
throw new WorkspaceContextInputError;
|
|
60023
60133
|
return { userId: value.userId, membershipId: value.membershipId };
|
|
60024
60134
|
}
|
|
@@ -60026,15 +60136,15 @@ function invalid2() {
|
|
|
60026
60136
|
throw new Error(invalidWorkspaceResult);
|
|
60027
60137
|
}
|
|
60028
60138
|
function organization(v) {
|
|
60029
|
-
if (!
|
|
60139
|
+
if (!record4(v) || !uuid2(v.id) || !text3(v.slug) || !text3(v.name))
|
|
60030
60140
|
return invalid2();
|
|
60031
60141
|
return { id: v.id, slug: v.slug, name: v.name };
|
|
60032
60142
|
}
|
|
60033
60143
|
function parseAccountWorkspaces(value) {
|
|
60034
|
-
if (!
|
|
60144
|
+
if (!record4(value) || !Array.isArray(value.workspaces) || !value.workspaces.length || value.workspaces.length > 1000)
|
|
60035
60145
|
return invalid2();
|
|
60036
60146
|
const workspaces = value.workspaces.map((v) => {
|
|
60037
|
-
if (!
|
|
60147
|
+
if (!record4(v) || !uuid2(v.membershipId) || !role(v.role) || typeof v.current !== "boolean")
|
|
60038
60148
|
return invalid2();
|
|
60039
60149
|
return { membershipId: v.membershipId, organization: organization(v.organization), role: v.role, current: v.current };
|
|
60040
60150
|
});
|
|
@@ -60043,10 +60153,10 @@ function parseAccountWorkspaces(value) {
|
|
|
60043
60153
|
return { workspaces };
|
|
60044
60154
|
}
|
|
60045
60155
|
function parseWorkspaceIdentity(value, expectedUserId) {
|
|
60046
|
-
if (!
|
|
60156
|
+
if (!record4(value))
|
|
60047
60157
|
return invalid2();
|
|
60048
60158
|
const user = value.user;
|
|
60049
|
-
if (!
|
|
60159
|
+
if (!record4(user) || !uuid2(user.id) || !uuid2(user.membershipId) || !text3(user.email, 320) || !(user.displayName === null || text3(user.displayName)) || !role(user.role))
|
|
60050
60160
|
return invalid2();
|
|
60051
60161
|
if (user.id !== expectedUserId)
|
|
60052
60162
|
throw new WorkspaceIdentityMismatchError;
|
|
@@ -60064,20 +60174,20 @@ function parseWorkspaceSession(value, expected) {
|
|
|
60064
60174
|
return { token: sessionToken(value.token), ...identity5 };
|
|
60065
60175
|
}
|
|
60066
60176
|
function parseWorkspaceLogin(value, expectedUserId) {
|
|
60067
|
-
const user =
|
|
60068
|
-
if (!
|
|
60177
|
+
const user = record4(value) && value.user;
|
|
60178
|
+
if (!record4(value) || !record4(user) || !uuid2(user.id))
|
|
60069
60179
|
return invalid2();
|
|
60070
60180
|
if (expectedUserId !== undefined && user.id !== expectedUserId)
|
|
60071
60181
|
throw new WorkspaceIdentityMismatchError;
|
|
60072
60182
|
return { token: sessionToken(value.token), userId: user.id };
|
|
60073
60183
|
}
|
|
60074
60184
|
function workspaceSelectionFailure(value, status) {
|
|
60075
|
-
if (!
|
|
60185
|
+
if (!record4(value) || typeof value.code !== "string" || !Object.hasOwn(workspaceSelectionFailures, value.code))
|
|
60076
60186
|
return null;
|
|
60077
60187
|
const code = value.code;
|
|
60078
60188
|
return workspaceSelectionFailures[code][0] === status ? code : null;
|
|
60079
60189
|
}
|
|
60080
|
-
var
|
|
60190
|
+
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
60191
|
var init_remote_workspace_selection = __esm(() => {
|
|
60082
60192
|
WorkspaceContextInputError = class WorkspaceContextInputError extends Error {
|
|
60083
60193
|
constructor() {
|
|
@@ -60108,7 +60218,7 @@ function checkedPublicationDeclaration(value) {
|
|
|
60108
60218
|
return bad();
|
|
60109
60219
|
try {
|
|
60110
60220
|
const manifest = JSON.parse(value.manifestText);
|
|
60111
|
-
if (!
|
|
60221
|
+
if (!record5(manifest) || manifest.version !== value.version || validatePortableManifestContract(manifest, { strict: true }).length || !hash3(manifest.provenance?.content_hash))
|
|
60112
60222
|
return bad();
|
|
60113
60223
|
} catch {
|
|
60114
60224
|
return bad();
|
|
@@ -60166,7 +60276,7 @@ async function boundedJson(url, init, token, mutation, budget = 15000, signal) {
|
|
|
60166
60276
|
return invalid3();
|
|
60167
60277
|
}
|
|
60168
60278
|
if (!response.ok) {
|
|
60169
|
-
const code =
|
|
60279
|
+
const code = record5(body) && typeof body.code === "string" && Object.hasOwn(failures, body.code) ? body.code : null;
|
|
60170
60280
|
if (code && failures[code][0] === response.status)
|
|
60171
60281
|
throw new PrivatePublicationError(code, failures[code][1], mutation && code === "PUBLICATION_UNCERTAIN", response.status);
|
|
60172
60282
|
throw new PrivatePublicationError("PUBLICATION_REQUEST_FAILED", "The publication request was refused. Inspect its status before retrying.", mutation && response.status >= 500, response.status);
|
|
@@ -60221,8 +60331,8 @@ class RemotePrivatePublicationsClient {
|
|
|
60221
60331
|
if (options.timeoutMs !== undefined && (!Number.isSafeInteger(options.timeoutMs) || options.timeoutMs < 1 || options.timeoutMs > 15000))
|
|
60222
60332
|
return bad();
|
|
60223
60333
|
const response = await boundedJson(skillsApiRequestUrl(this.apiOrigin, "/api/v1/capabilities"), {}, this.#token, false, options.timeoutMs, options.signal);
|
|
60224
|
-
const p =
|
|
60225
|
-
if (!
|
|
60334
|
+
const p = record5(response) && response.privatePublishing;
|
|
60335
|
+
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
60336
|
throw new PrivatePublicationError("PUBLICATION_CONTRACT_UNAVAILABLE", "This server does not support the hosted private publication contract.");
|
|
60227
60337
|
return Object.freeze({ ...p });
|
|
60228
60338
|
}
|
|
@@ -60238,7 +60348,7 @@ class RemotePrivatePublicationsClient {
|
|
|
60238
60348
|
async#view(path, method2, skillId, intentId, declaration, options = {}) {
|
|
60239
60349
|
const value = await boundedJson(path, { method: method2, ...method2 === "GET" ? {} : { body: JSON.stringify(declaration ?? {}) } }, this.#token, method2 !== "GET", options.timeoutMs, options.signal);
|
|
60240
60350
|
try {
|
|
60241
|
-
if (!
|
|
60351
|
+
if (!record5(value) || !Object.keys(value).every((k) => k === "upload" || k === "changed") || value.changed !== undefined && typeof value.changed !== "boolean")
|
|
60242
60352
|
return invalid3();
|
|
60243
60353
|
return checkedPublicationView(value.upload, skillId, intentId, declaration);
|
|
60244
60354
|
} catch (error) {
|
|
@@ -60363,7 +60473,7 @@ var PRIVATE_PUBLICATION_MAX_BYTES, failures, PrivatePublicationError, bad = () =
|
|
|
60363
60473
|
throw new PrivatePublicationError("INVALID_PUBLICATION_INPUT", "Invalid publication input or recovery data.");
|
|
60364
60474
|
}, invalid3 = () => {
|
|
60365
60475
|
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),
|
|
60476
|
+
}, 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
60477
|
var init_remote_private_publications = __esm(() => {
|
|
60368
60478
|
init_fleet_credentials();
|
|
60369
60479
|
init_remote_workspace_selection();
|
|
@@ -60406,7 +60516,7 @@ var init_remote_private_publications = __esm(() => {
|
|
|
60406
60516
|
|
|
60407
60517
|
// src/lib/remote-invitations.ts
|
|
60408
60518
|
function invitationFailure(value, status) {
|
|
60409
|
-
if (!
|
|
60519
|
+
if (!record6(value) || typeof value.code !== "string" || !Object.hasOwn(invitationFailures, value.code))
|
|
60410
60520
|
return null;
|
|
60411
60521
|
const code = value.code;
|
|
60412
60522
|
return invitationFailures[code][0] === status ? code : null;
|
|
@@ -60415,7 +60525,7 @@ function invitationId(value) {
|
|
|
60415
60525
|
return uuid3(value) ? value : inputFailure();
|
|
60416
60526
|
}
|
|
60417
60527
|
function invitationInput(action, input) {
|
|
60418
|
-
if (!
|
|
60528
|
+
if (!record6(input))
|
|
60419
60529
|
return inputFailure();
|
|
60420
60530
|
const keys2 = {
|
|
60421
60531
|
list: ["after"],
|
|
@@ -60466,7 +60576,7 @@ function invalid4() {
|
|
|
60466
60576
|
throw new RemoteWorkspaceInvitationReadError;
|
|
60467
60577
|
}
|
|
60468
60578
|
function projection(v, organizationId) {
|
|
60469
|
-
if (!
|
|
60579
|
+
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
60580
|
return invalid4();
|
|
60471
60581
|
return {
|
|
60472
60582
|
id: v.id,
|
|
@@ -60481,7 +60591,7 @@ function projection(v, organizationId) {
|
|
|
60481
60591
|
};
|
|
60482
60592
|
}
|
|
60483
60593
|
function parseInvitationResult(action, value, input, organizationId) {
|
|
60484
|
-
if (!
|
|
60594
|
+
if (!record6(value))
|
|
60485
60595
|
return invalid4();
|
|
60486
60596
|
const request = input;
|
|
60487
60597
|
if (action === "accept") {
|
|
@@ -60512,7 +60622,7 @@ function parseInvitationResult(action, value, input, organizationId) {
|
|
|
60512
60622
|
return invalid4();
|
|
60513
60623
|
return { invitation, changed: value.changed };
|
|
60514
60624
|
}
|
|
60515
|
-
var WorkspaceInvitationInputError, invitationFailures, RemoteWorkspaceInvitationError, RemoteWorkspaceInvitationUnconfirmedError, RemoteWorkspaceInvitationReadError,
|
|
60625
|
+
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
60626
|
throw new WorkspaceInvitationInputError;
|
|
60517
60627
|
};
|
|
60518
60628
|
var init_remote_invitations = __esm(() => {
|
|
@@ -60566,7 +60676,7 @@ var init_remote_invitations = __esm(() => {
|
|
|
60566
60676
|
|
|
60567
60677
|
// src/lib/remote-workspace.ts
|
|
60568
60678
|
function workspaceMembersQuery(options = {}) {
|
|
60569
|
-
if (!
|
|
60679
|
+
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
60680
|
throw new Error("Use a roster limit from 1 to 100 and an unchanged continuation cursor.");
|
|
60571
60681
|
const query = new URLSearchParams;
|
|
60572
60682
|
if (options.limit !== undefined)
|
|
@@ -60582,7 +60692,7 @@ function timestamp2(value) {
|
|
|
60582
60692
|
return Number.isFinite(time) && new Date(time).toISOString().slice(0, 23) === value.slice(0, 23);
|
|
60583
60693
|
}
|
|
60584
60694
|
function parseMember(row, fail3) {
|
|
60585
|
-
if (!
|
|
60695
|
+
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
60696
|
return fail3();
|
|
60587
60697
|
return {
|
|
60588
60698
|
membershipId: row.membershipId,
|
|
@@ -60594,7 +60704,7 @@ function parseMember(row, fail3) {
|
|
|
60594
60704
|
};
|
|
60595
60705
|
}
|
|
60596
60706
|
function mutationInput(membershipId, input, roleChange) {
|
|
60597
|
-
if (typeof membershipId !== "string" || !uuid4(membershipId) || membershipId !== membershipId.toLowerCase() || !
|
|
60707
|
+
if (typeof membershipId !== "string" || !uuid4(membershipId) || membershipId !== membershipId.toLowerCase() || !record7(input) || Object.keys(input).sort().join(",") !== (roleChange ? "expectedRole,role" : "expectedRole"))
|
|
60598
60708
|
throw new WorkspaceMemberInputError;
|
|
60599
60709
|
const expectedRole = input.expectedRole, role3 = roleChange ? input.role : undefined;
|
|
60600
60710
|
if (!isRole(expectedRole) || roleChange && !isRole(role3))
|
|
@@ -60613,7 +60723,7 @@ function parseWorkspaceMemberRoleResult(value, membershipId, role3) {
|
|
|
60613
60723
|
const fail3 = () => {
|
|
60614
60724
|
throw new Error(invalidMemberResult);
|
|
60615
60725
|
};
|
|
60616
|
-
if (!
|
|
60726
|
+
if (!record7(value) || !uuid4(value.organizationId) || typeof value.changed !== "boolean")
|
|
60617
60727
|
return fail3();
|
|
60618
60728
|
const member = parseMember(value.member, fail3);
|
|
60619
60729
|
if (member.membershipId !== membershipId || member.role !== role3)
|
|
@@ -60621,12 +60731,12 @@ function parseWorkspaceMemberRoleResult(value, membershipId, role3) {
|
|
|
60621
60731
|
return { organizationId: value.organizationId, member, changed: value.changed };
|
|
60622
60732
|
}
|
|
60623
60733
|
function parseWorkspaceMemberRemovalResult(value, membershipId) {
|
|
60624
|
-
if (!
|
|
60734
|
+
if (!record7(value) || !uuid4(value.organizationId) || value.membershipId !== membershipId || value.removed !== true || typeof value.alreadyRemoved !== "boolean")
|
|
60625
60735
|
throw new Error(invalidMemberResult);
|
|
60626
60736
|
return { organizationId: value.organizationId, membershipId, removed: true, alreadyRemoved: value.alreadyRemoved };
|
|
60627
60737
|
}
|
|
60628
60738
|
function workspaceMemberFailure(value, status) {
|
|
60629
|
-
if (!
|
|
60739
|
+
if (!record7(value) || typeof value.code !== "string" || !Object.hasOwn(workspaceMemberFailures, value.code))
|
|
60630
60740
|
return null;
|
|
60631
60741
|
const code = value.code;
|
|
60632
60742
|
return workspaceMemberFailures[code][0] === status ? code : null;
|
|
@@ -60635,14 +60745,14 @@ function parseWorkspaceMembersPage(value) {
|
|
|
60635
60745
|
const fail3 = () => {
|
|
60636
60746
|
throw new Error("The server returned an invalid workspace roster.");
|
|
60637
60747
|
};
|
|
60638
|
-
if (!
|
|
60748
|
+
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
60749
|
return fail3();
|
|
60640
60750
|
const members = value.members.map((row) => parseMember(row, fail3));
|
|
60641
60751
|
if (new Set(members.map((row) => row.membershipId)).size !== members.length)
|
|
60642
60752
|
return fail3();
|
|
60643
60753
|
return { organizationId: value.organizationId, members, nextCursor: value.nextCursor };
|
|
60644
60754
|
}
|
|
60645
|
-
var
|
|
60755
|
+
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
60756
|
var init_remote_workspace = __esm(() => {
|
|
60647
60757
|
WorkspaceMemberInputError = class WorkspaceMemberInputError extends Error {
|
|
60648
60758
|
constructor() {
|
|
@@ -75977,8 +76087,8 @@ function rewriteKeyNames(ctx) {
|
|
|
75977
76087
|
bySchema.set(entry.schema, entry);
|
|
75978
76088
|
}
|
|
75979
76089
|
const rewrites = new Map;
|
|
75980
|
-
for (const
|
|
75981
|
-
const seen = ctx.seen.get(
|
|
76090
|
+
for (const record8 of pendingRecords.get(ctx) ?? []) {
|
|
76091
|
+
const seen = ctx.seen.get(record8);
|
|
75982
76092
|
const names = (seen?.def ?? seen?.schema)?.propertyNames;
|
|
75983
76093
|
if (!names || names === true || rewrites.has(names))
|
|
75984
76094
|
continue;
|
|
@@ -77079,7 +77189,7 @@ __export(exports_schemas2, {
|
|
|
77079
77189
|
strictObject: () => strictObject,
|
|
77080
77190
|
set: () => set2,
|
|
77081
77191
|
refine: () => refine,
|
|
77082
|
-
record: () =>
|
|
77192
|
+
record: () => record8,
|
|
77083
77193
|
readonly: () => readonly,
|
|
77084
77194
|
promise: () => promise,
|
|
77085
77195
|
preprocess: () => preprocess,
|
|
@@ -77459,7 +77569,7 @@ function tuple(items, _paramsOrRest, _params) {
|
|
|
77459
77569
|
...exports_util.normalizeParams(params)
|
|
77460
77570
|
});
|
|
77461
77571
|
}
|
|
77462
|
-
function
|
|
77572
|
+
function record8(keyType, valueType, params) {
|
|
77463
77573
|
if (!valueType || !valueType._zod) {
|
|
77464
77574
|
return new ZodRecord({
|
|
77465
77575
|
type: "record",
|
|
@@ -77699,7 +77809,7 @@ function _instanceof(cls, params = {}) {
|
|
|
77699
77809
|
}
|
|
77700
77810
|
function json(params) {
|
|
77701
77811
|
const jsonSchema = lazy(() => {
|
|
77702
|
-
return union2([string2(params), number2(), boolean2(), _null3(), array2(jsonSchema),
|
|
77812
|
+
return union2([string2(params), number2(), boolean2(), _null3(), array2(jsonSchema), record8(string2(), jsonSchema)]);
|
|
77703
77813
|
});
|
|
77704
77814
|
return jsonSchema;
|
|
77705
77815
|
}
|
|
@@ -79518,7 +79628,7 @@ __export(exports_external, {
|
|
|
79518
79628
|
regexes: () => exports_regexes,
|
|
79519
79629
|
regex: () => _regex,
|
|
79520
79630
|
refine: () => refine,
|
|
79521
|
-
record: () =>
|
|
79631
|
+
record: () => record8,
|
|
79522
79632
|
readonly: () => readonly,
|
|
79523
79633
|
property: () => _property,
|
|
79524
79634
|
properties: () => _properties,
|
|
@@ -80131,44 +80241,44 @@ var init_remote_recurring = __esm(() => {
|
|
|
80131
80241
|
|
|
80132
80242
|
// src/lib/remote-run-contract.ts
|
|
80133
80243
|
function normalizeRemoteSkillRunContract(payload, fallbackSkill) {
|
|
80134
|
-
const
|
|
80244
|
+
const record9 = isRecord4(payload) ? payload : {};
|
|
80135
80245
|
return {
|
|
80136
80246
|
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(
|
|
80247
|
+
...pickString(record9, "id"),
|
|
80248
|
+
skill: pickStringValue(record9, "skill") ?? fallbackSkill,
|
|
80249
|
+
...pickString(record9, "requestedSlug"),
|
|
80250
|
+
...pickString(record9, "status"),
|
|
80251
|
+
...pickNumber(record9, "exitCode"),
|
|
80252
|
+
...pickString(record9, "correlationId"),
|
|
80253
|
+
...pickString(record9, "createdAt"),
|
|
80254
|
+
...pickString(record9, "startedAt"),
|
|
80255
|
+
...pickString(record9, "completedAt"),
|
|
80256
|
+
...pickNumber(record9, "durationMs"),
|
|
80257
|
+
...pickString(record9, "outputType"),
|
|
80258
|
+
...hasOwn(record9, "outputPreview") ? { outputPreview: record9.outputPreview } : {},
|
|
80259
|
+
...pickString(record9, "errorCode"),
|
|
80260
|
+
...pickString(record9, "errorMessage"),
|
|
80261
|
+
...pickString(record9, "error"),
|
|
80262
|
+
...pickString(record9, "code"),
|
|
80263
|
+
...hasOwn(record9, "details") ? { details: record9.details } : {}
|
|
80154
80264
|
};
|
|
80155
80265
|
}
|
|
80156
80266
|
function isRecord4(value) {
|
|
80157
80267
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
80158
80268
|
}
|
|
80159
|
-
function hasOwn(
|
|
80160
|
-
return Object.prototype.hasOwnProperty.call(
|
|
80269
|
+
function hasOwn(record9, key) {
|
|
80270
|
+
return Object.prototype.hasOwnProperty.call(record9, key);
|
|
80161
80271
|
}
|
|
80162
|
-
function pickString(
|
|
80163
|
-
const value = pickStringValue(
|
|
80272
|
+
function pickString(record9, key) {
|
|
80273
|
+
const value = pickStringValue(record9, key);
|
|
80164
80274
|
return value === undefined ? {} : { [key]: value };
|
|
80165
80275
|
}
|
|
80166
|
-
function pickStringValue(
|
|
80167
|
-
const value =
|
|
80276
|
+
function pickStringValue(record9, key) {
|
|
80277
|
+
const value = record9[key];
|
|
80168
80278
|
return typeof value === "string" ? value : undefined;
|
|
80169
80279
|
}
|
|
80170
|
-
function pickNumber(
|
|
80171
|
-
const value =
|
|
80280
|
+
function pickNumber(record9, key) {
|
|
80281
|
+
const value = record9[key];
|
|
80172
80282
|
return typeof value === "number" && Number.isFinite(value) ? { [key]: value } : {};
|
|
80173
80283
|
}
|
|
80174
80284
|
var REMOTE_SKILL_RUN_CONTRACT_VERSION = 1;
|
|
@@ -80391,7 +80501,7 @@ var init_remote_quote_errors = __esm(() => {
|
|
|
80391
80501
|
function parseSkillsAccess(value) {
|
|
80392
80502
|
if (value === undefined)
|
|
80393
80503
|
return {};
|
|
80394
|
-
if (!
|
|
80504
|
+
if (!record9(value))
|
|
80395
80505
|
throw new Error("Invalid Skills permission contract");
|
|
80396
80506
|
const result2 = {};
|
|
80397
80507
|
if (value.scopes !== undefined) {
|
|
@@ -80400,7 +80510,7 @@ function parseSkillsAccess(value) {
|
|
|
80400
80510
|
result2.scopes = [...value.scopes];
|
|
80401
80511
|
}
|
|
80402
80512
|
if (value.permissions !== undefined) {
|
|
80403
|
-
if (!
|
|
80513
|
+
if (!record9(value.permissions))
|
|
80404
80514
|
throw new Error("Invalid Skills permission contract");
|
|
80405
80515
|
result2.permissions = {};
|
|
80406
80516
|
for (const name of permissionNames) {
|
|
@@ -80418,7 +80528,7 @@ function assertSkillsPermission(access, permission) {
|
|
|
80418
80528
|
if (access.permissions?.[permission] === false)
|
|
80419
80529
|
throw new RemoteSkillsPermissionError(permission);
|
|
80420
80530
|
}
|
|
80421
|
-
var permissionNames,
|
|
80531
|
+
var permissionNames, record9 = (value) => value !== null && typeof value === "object" && !Array.isArray(value), RemoteSkillsPermissionError;
|
|
80422
80532
|
var init_remote_permissions = __esm(() => {
|
|
80423
80533
|
permissionNames = [
|
|
80424
80534
|
"read",
|
|
@@ -81233,13 +81343,13 @@ class RemoteSkillsClient {
|
|
|
81233
81343
|
return normalizeUpdatedSincePage(await response.json());
|
|
81234
81344
|
}
|
|
81235
81345
|
}
|
|
81236
|
-
function requireOptionalString(
|
|
81237
|
-
if (
|
|
81346
|
+
function requireOptionalString(record10, field2) {
|
|
81347
|
+
if (record10[field2] === undefined)
|
|
81238
81348
|
return;
|
|
81239
|
-
if (typeof
|
|
81349
|
+
if (typeof record10[field2] !== "string") {
|
|
81240
81350
|
throw new Error(`Remote payload did not match the expected contract (${field2} must be a string when present)`);
|
|
81241
81351
|
}
|
|
81242
|
-
return
|
|
81352
|
+
return record10[field2];
|
|
81243
81353
|
}
|
|
81244
81354
|
function isVersionRecord(value) {
|
|
81245
81355
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
@@ -81261,19 +81371,19 @@ function normalizePin(entry) {
|
|
|
81261
81371
|
if (!entry || typeof entry !== "object") {
|
|
81262
81372
|
throw new Error("Remote pin payload did not match the expected contract (expected an object)");
|
|
81263
81373
|
}
|
|
81264
|
-
const
|
|
81265
|
-
const slug2 = typeof
|
|
81374
|
+
const record10 = entry;
|
|
81375
|
+
const slug2 = typeof record10.slug === "string" && record10.slug.trim() ? record10.slug.trim() : undefined;
|
|
81266
81376
|
if (!slug2) {
|
|
81267
81377
|
throw new Error("Remote pin payload did not match the expected contract (missing slug)");
|
|
81268
81378
|
}
|
|
81269
81379
|
let metadata;
|
|
81270
|
-
if (
|
|
81271
|
-
if (!
|
|
81380
|
+
if (record10.metadata !== undefined) {
|
|
81381
|
+
if (!record10.metadata || typeof record10.metadata !== "object" || Array.isArray(record10.metadata)) {
|
|
81272
81382
|
throw new Error("Remote pin payload did not match the expected contract (metadata must be a JSON object when present)");
|
|
81273
81383
|
}
|
|
81274
|
-
metadata =
|
|
81384
|
+
metadata = record10.metadata;
|
|
81275
81385
|
}
|
|
81276
|
-
const pinnedAt = requireOptionalString(
|
|
81386
|
+
const pinnedAt = requireOptionalString(record10, "pinnedAt");
|
|
81277
81387
|
return {
|
|
81278
81388
|
slug: slug2,
|
|
81279
81389
|
...pinnedAt !== undefined ? { pinnedAt } : {},
|
|
@@ -81290,16 +81400,16 @@ function normalizeSkillSummary(entry) {
|
|
|
81290
81400
|
if (!entry || typeof entry !== "object") {
|
|
81291
81401
|
throw new Error("Remote skill payload did not match the expected contract (expected an object)");
|
|
81292
81402
|
}
|
|
81293
|
-
const
|
|
81294
|
-
const slug2 = typeof
|
|
81403
|
+
const record10 = entry;
|
|
81404
|
+
const slug2 = typeof record10.slug === "string" && record10.slug.trim() ? record10.slug.trim() : undefined;
|
|
81295
81405
|
if (!slug2) {
|
|
81296
81406
|
throw new Error("Remote skill payload did not match the expected contract (missing slug)");
|
|
81297
81407
|
}
|
|
81298
81408
|
return {
|
|
81299
81409
|
slug: slug2,
|
|
81300
|
-
...requireOptionalString(
|
|
81301
|
-
...requireOptionalString(
|
|
81302
|
-
...requireOptionalString(
|
|
81410
|
+
...requireOptionalString(record10, "name") !== undefined ? { name: requireOptionalString(record10, "name") } : {},
|
|
81411
|
+
...requireOptionalString(record10, "version") !== undefined ? { version: requireOptionalString(record10, "version") } : {},
|
|
81412
|
+
...requireOptionalString(record10, "updatedAt") !== undefined ? { updatedAt: requireOptionalString(record10, "updatedAt") } : {}
|
|
81303
81413
|
};
|
|
81304
81414
|
}
|
|
81305
81415
|
function normalizeSkillSummaryList(payload) {
|
|
@@ -81356,12 +81466,12 @@ function normalizeUpdatedSincePage(payload) {
|
|
|
81356
81466
|
if (!payload || typeof payload !== "object") {
|
|
81357
81467
|
throw new Error("Updated-since payload did not match the expected contract (expected an object)");
|
|
81358
81468
|
}
|
|
81359
|
-
const
|
|
81360
|
-
if (!Array.isArray(
|
|
81469
|
+
const record10 = payload;
|
|
81470
|
+
if (!Array.isArray(record10.skills)) {
|
|
81361
81471
|
throw new Error("Updated-since payload did not match the expected contract (missing skills array)");
|
|
81362
81472
|
}
|
|
81363
|
-
const skills =
|
|
81364
|
-
const nextCursor =
|
|
81473
|
+
const skills = record10.skills.map(normalizeSkillSummary);
|
|
81474
|
+
const nextCursor = record10.nextCursor === undefined || record10.nextCursor === null ? null : record10.nextCursor;
|
|
81365
81475
|
if (nextCursor !== null && typeof nextCursor !== "string") {
|
|
81366
81476
|
throw new Error("Updated-since payload did not match the expected contract (nextCursor must be a string or absent)");
|
|
81367
81477
|
}
|
|
@@ -81497,10 +81607,10 @@ async function requestAuthApi(instance, path, options) {
|
|
|
81497
81607
|
const text4 = await res.text();
|
|
81498
81608
|
const body = text4 ? parseJsonBody(text4) : {};
|
|
81499
81609
|
if (!res.ok) {
|
|
81500
|
-
const
|
|
81501
|
-
const detail = typeof
|
|
81502
|
-
const error61 = typeof
|
|
81503
|
-
const code = typeof
|
|
81610
|
+
const record10 = isRecord6(body) ? body : {};
|
|
81611
|
+
const detail = typeof record10.detail === "string" ? record10.detail : undefined;
|
|
81612
|
+
const error61 = typeof record10.error === "string" ? record10.error : undefined;
|
|
81613
|
+
const code = typeof record10.code === "string" ? record10.code : undefined;
|
|
81504
81614
|
throw new HostedApiError(detail || error61 || `${res.status} ${res.statusText}`, {
|
|
81505
81615
|
status: res.status,
|
|
81506
81616
|
code,
|
|
@@ -81738,24 +81848,24 @@ function clampIntervalMs(seconds) {
|
|
|
81738
81848
|
return Math.min(MAX_INTERVAL_MS, Math.max(MIN_INTERVAL_MS, Math.round(seconds * 1000)));
|
|
81739
81849
|
}
|
|
81740
81850
|
function parseDeviceAuthorizationStart(body) {
|
|
81741
|
-
const
|
|
81742
|
-
if (typeof
|
|
81743
|
-
throw new Error(typeof
|
|
81851
|
+
const record10 = isRecord7(body) ? body : {};
|
|
81852
|
+
if (typeof record10.error === "string") {
|
|
81853
|
+
throw new Error(typeof record10.detail === "string" ? record10.detail : record10.error);
|
|
81744
81854
|
}
|
|
81745
|
-
const deviceCode = boundedText(
|
|
81746
|
-
const userCode = boundedText(
|
|
81747
|
-
const verificationUri = httpUrl2(
|
|
81855
|
+
const deviceCode = boundedText(record10.deviceCode, 512);
|
|
81856
|
+
const userCode = boundedText(record10.userCode, 64);
|
|
81857
|
+
const verificationUri = httpUrl2(record10.verificationUri);
|
|
81748
81858
|
if (!deviceCode || !userCode || !verificationUri) {
|
|
81749
81859
|
throw new Error("The Skills server returned an incomplete device sign-in (deviceCode, userCode and verificationUri are required)");
|
|
81750
81860
|
}
|
|
81751
|
-
const verificationUriComplete = httpUrl2(
|
|
81861
|
+
const verificationUriComplete = httpUrl2(record10.verificationUriComplete);
|
|
81752
81862
|
return {
|
|
81753
81863
|
deviceCode,
|
|
81754
81864
|
userCode,
|
|
81755
81865
|
verificationUri,
|
|
81756
81866
|
...verificationUriComplete ? { verificationUriComplete } : {},
|
|
81757
|
-
expiresIn: positiveNumber(
|
|
81758
|
-
interval: positiveNumber(
|
|
81867
|
+
expiresIn: positiveNumber(record10.expiresIn, DEFAULT_EXPIRES_IN_SECONDS),
|
|
81868
|
+
interval: positiveNumber(record10.interval, DEFAULT_INTERVAL_SECONDS)
|
|
81759
81869
|
};
|
|
81760
81870
|
}
|
|
81761
81871
|
async function startDeviceAuthorization(origin, client2 = SKILLS_CLI_DEVICE_CLIENT) {
|
|
@@ -81833,9 +81943,9 @@ async function pollDeviceAuthorization(input2) {
|
|
|
81833
81943
|
throw error61;
|
|
81834
81944
|
}
|
|
81835
81945
|
}
|
|
81836
|
-
const
|
|
81837
|
-
const code = typeof
|
|
81838
|
-
if (code === "authorization_pending" || code === undefined &&
|
|
81946
|
+
const record10 = isRecord7(body) ? body : {};
|
|
81947
|
+
const code = typeof record10.error === "string" ? record10.error : undefined;
|
|
81948
|
+
if (code === "authorization_pending" || code === undefined && record10.status === "pending") {
|
|
81839
81949
|
await wait();
|
|
81840
81950
|
continue;
|
|
81841
81951
|
}
|
|
@@ -81851,8 +81961,8 @@ async function pollDeviceAuthorization(input2) {
|
|
|
81851
81961
|
if (code === "access_denied")
|
|
81852
81962
|
return { status: "denied" };
|
|
81853
81963
|
if (code)
|
|
81854
|
-
throw new Error(typeof
|
|
81855
|
-
return { status: "authorized", result:
|
|
81964
|
+
throw new Error(typeof record10.detail === "string" ? record10.detail : code);
|
|
81965
|
+
return { status: "authorized", result: record10 };
|
|
81856
81966
|
}
|
|
81857
81967
|
}
|
|
81858
81968
|
function pendingDeviceSignInStem(env3) {
|
|
@@ -82138,10 +82248,10 @@ async function readSignedInAccount(env3 = process.env) {
|
|
|
82138
82248
|
const body = await new RemoteSkillsAuthClient(connection.apiOrigin).request("/api/auth/whoami", {
|
|
82139
82249
|
headers: { Authorization: `Bearer ${connection.apiKey}` }
|
|
82140
82250
|
});
|
|
82141
|
-
const
|
|
82142
|
-
const data = isRecord7(
|
|
82143
|
-
const user = isRecord7(
|
|
82144
|
-
const organization2 = isRecord7(
|
|
82251
|
+
const record10 = isRecord7(body) ? body : {};
|
|
82252
|
+
const data = isRecord7(record10.data) ? record10.data : {};
|
|
82253
|
+
const user = isRecord7(record10.user) ? record10.user : isRecord7(data.user) ? data.user : {};
|
|
82254
|
+
const organization2 = isRecord7(record10.organization) ? record10.organization : isRecord7(data.organization) ? data.organization : {};
|
|
82145
82255
|
const email4 = boundedText(user.email, 320);
|
|
82146
82256
|
const org = boundedText(organization2.slug, 200) ?? boundedText(organization2.name, 200);
|
|
82147
82257
|
return { ...base2, ...email4 ? { email: email4 } : {}, ...org ? { organization: org } : {} };
|
|
@@ -82941,16 +83051,16 @@ function installBundleAtomically(name, entries, options = {}, marker = {}) {
|
|
|
82941
83051
|
}
|
|
82942
83052
|
return { path: target, created };
|
|
82943
83053
|
}
|
|
82944
|
-
function writePullMarker(dir,
|
|
83054
|
+
function writePullMarker(dir, record10) {
|
|
82945
83055
|
const marker = {
|
|
82946
83056
|
managedBy: "@hasna/skills",
|
|
82947
|
-
skill:
|
|
82948
|
-
source:
|
|
82949
|
-
...
|
|
82950
|
-
...
|
|
82951
|
-
...
|
|
82952
|
-
...
|
|
82953
|
-
...
|
|
83057
|
+
skill: record10.skill,
|
|
83058
|
+
source: record10.source ?? "pull",
|
|
83059
|
+
...record10.version ? { version: record10.version } : {},
|
|
83060
|
+
...record10.contentHash ? { contentHash: record10.contentHash } : {},
|
|
83061
|
+
...record10.sourceCommit ? { sourceCommit: record10.sourceCommit } : {},
|
|
83062
|
+
...record10.signature ? { signature: record10.signature } : {},
|
|
83063
|
+
...record10.revisionId ? { revisionId: record10.revisionId } : {},
|
|
82954
83064
|
syncedAt: new Date().toISOString()
|
|
82955
83065
|
};
|
|
82956
83066
|
writeFileSync12(join38(dir, PULL_MARKER_FILE), `${JSON.stringify(marker, null, 2)}
|
|
@@ -82965,19 +83075,19 @@ async function safeMeta(client2, slug2) {
|
|
|
82965
83075
|
}
|
|
82966
83076
|
if (!raw || typeof raw !== "object")
|
|
82967
83077
|
return null;
|
|
82968
|
-
const
|
|
82969
|
-
const kind =
|
|
82970
|
-
const tags = Array.isArray(
|
|
83078
|
+
const record10 = raw;
|
|
83079
|
+
const kind = record10.kind === "instruction" || record10.kind === "executable" ? record10.kind : undefined;
|
|
83080
|
+
const tags = Array.isArray(record10.tags) ? record10.tags.filter((tag) => typeof tag === "string" && tag.trim().length > 0) : undefined;
|
|
82971
83081
|
return {
|
|
82972
|
-
...str(
|
|
82973
|
-
...str(
|
|
82974
|
-
...str(
|
|
83082
|
+
...str(record10.displayName) ? { displayName: str(record10.displayName) } : {},
|
|
83083
|
+
...str(record10.description) ? { description: str(record10.description) } : {},
|
|
83084
|
+
...str(record10.category) ? { category: str(record10.category) } : {},
|
|
82975
83085
|
...tags && tags.length ? { tags } : {},
|
|
82976
|
-
...str(
|
|
83086
|
+
...str(record10.version) ? { version: str(record10.version) } : {},
|
|
82977
83087
|
...kind ? { kind } : {},
|
|
82978
|
-
...REVISION_ID_PATTERN.test(str(
|
|
82979
|
-
...typeof
|
|
82980
|
-
...str(
|
|
83088
|
+
...REVISION_ID_PATTERN.test(str(record10.revisionId) ?? "") ? { revisionId: str(record10.revisionId) } : {},
|
|
83089
|
+
...typeof record10.skillMd === "string" && record10.skillMd.length > 0 ? { skillMd: record10.skillMd } : {},
|
|
83090
|
+
...str(record10.publishedSource) ? { publishedSource: str(record10.publishedSource) } : {}
|
|
82981
83091
|
};
|
|
82982
83092
|
}
|
|
82983
83093
|
function pickCorpusOptions(options) {
|
|
@@ -82986,8 +83096,8 @@ function pickCorpusOptions(options) {
|
|
|
82986
83096
|
function extractSlug(entry) {
|
|
82987
83097
|
if (!entry || typeof entry !== "object")
|
|
82988
83098
|
return;
|
|
82989
|
-
const
|
|
82990
|
-
return str(
|
|
83099
|
+
const record10 = entry;
|
|
83100
|
+
return str(record10.slug) ?? str(record10.name);
|
|
82991
83101
|
}
|
|
82992
83102
|
function dedupe(values2) {
|
|
82993
83103
|
return [...new Set(values2)];
|
|
@@ -83138,7 +83248,7 @@ var init_skill_context = __esm(() => {
|
|
|
83138
83248
|
|
|
83139
83249
|
// src/lib/session-reconciliation.ts
|
|
83140
83250
|
import { createHash as createHash24 } from "crypto";
|
|
83141
|
-
import { isDeepStrictEqual as
|
|
83251
|
+
import { isDeepStrictEqual as isDeepStrictEqual10 } from "util";
|
|
83142
83252
|
function exactTimestamp(value) {
|
|
83143
83253
|
const parsed = value === undefined ? Number.NaN : Date.parse(value);
|
|
83144
83254
|
if (!Number.isFinite(parsed) || new Date(parsed).toISOString() !== value) {
|
|
@@ -83195,7 +83305,7 @@ async function reconcileSkillSessionIfSafe(sessionId, profileId, options = {}) {
|
|
|
83195
83305
|
for (const key of old.loaded) {
|
|
83196
83306
|
const previous = oldByKey.get(key);
|
|
83197
83307
|
const current = targetBySlug.get(previous.slug);
|
|
83198
|
-
if (!current || !
|
|
83308
|
+
if (!current || !isDeepStrictEqual10({ ...previous, profileRevision: target.profileRevision }, current)) {
|
|
83199
83309
|
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
83310
|
}
|
|
83201
83311
|
}
|
|
@@ -85348,8 +85458,8 @@ function writeRollbackRecord(mode, entries, appDir = getDataDir()) {
|
|
|
85348
85458
|
const dir = join41(appDir, ROLLBACK_DIRNAME);
|
|
85349
85459
|
mkdirSync14(dir, { recursive: true });
|
|
85350
85460
|
const file2 = join41(dir, `${mode}-${Date.now()}.json`);
|
|
85351
|
-
const
|
|
85352
|
-
writeFileSync14(file2, `${JSON.stringify(
|
|
85461
|
+
const record10 = { version: 1, mode, timestamp: new Date().toISOString(), entries };
|
|
85462
|
+
writeFileSync14(file2, `${JSON.stringify(record10, null, 2)}
|
|
85353
85463
|
`);
|
|
85354
85464
|
return file2;
|
|
85355
85465
|
}
|
|
@@ -87549,7 +87659,7 @@ function selectedSecretBindingsTemplate(scope, names, createClient2 = createSecr
|
|
|
87549
87659
|
function refuse3(code, message) {
|
|
87550
87660
|
throw new SkillSelectionError(code, message);
|
|
87551
87661
|
}
|
|
87552
|
-
function
|
|
87662
|
+
function record10(value) {
|
|
87553
87663
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
87554
87664
|
}
|
|
87555
87665
|
function exactKeys3(value, keys2) {
|
|
@@ -87592,7 +87702,7 @@ function readSelectedSecretBindings(path) {
|
|
|
87592
87702
|
}
|
|
87593
87703
|
}
|
|
87594
87704
|
function validateSelectedSecretBindings(value, scope, names) {
|
|
87595
|
-
if (!
|
|
87705
|
+
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
87706
|
return refuse3("INVALID_SECRET_BINDINGS", "Secret bindings do not match the hasna.skills-secret-bindings.v1 contract.");
|
|
87597
87707
|
}
|
|
87598
87708
|
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 +87905,7 @@ var init_execution_grants = __esm(() => {
|
|
|
87795
87905
|
});
|
|
87796
87906
|
|
|
87797
87907
|
// src/lib/execution-grant-client.ts
|
|
87798
|
-
import { isDeepStrictEqual as
|
|
87908
|
+
import { isDeepStrictEqual as isDeepStrictEqual11 } from "util";
|
|
87799
87909
|
function id(value) {
|
|
87800
87910
|
if (!grantIdentifier(value))
|
|
87801
87911
|
throw new Error("Invalid execution grant profile or revision identifier.");
|
|
@@ -87847,7 +87957,7 @@ async function saveExecutionGrantPolicy(profileId, grants, revision) {
|
|
|
87847
87957
|
headers: revision === undefined ? { "If-None-Match": "*" } : { "If-Match": `"${revision}"` },
|
|
87848
87958
|
body: JSON.stringify({ grants: snapshot2 })
|
|
87849
87959
|
}));
|
|
87850
|
-
if (policy.profileId !== profileId || policy.previousRevision !== (revision ?? null) || !
|
|
87960
|
+
if (policy.profileId !== profileId || policy.previousRevision !== (revision ?? null) || !isDeepStrictEqual11(policy.grants, snapshot2)) {
|
|
87851
87961
|
throw new Error("The API did not preserve the reviewed execution grant policy; read it before retrying.");
|
|
87852
87962
|
}
|
|
87853
87963
|
return policy;
|
|
@@ -87858,7 +87968,7 @@ async function resolveExecutionGrant(input2) {
|
|
|
87858
87968
|
if (!grantRecord(value) || Object.keys(value).length !== 3 || !grantIdentifier(value.policyRevision) || !grantIdentifier(value.grantId) || !grantRecord(value.bindings)) {
|
|
87859
87969
|
throw new SkillSelectionError("INVALID_EXECUTION_GRANT", "The Skills API returned an invalid execution grant.");
|
|
87860
87970
|
}
|
|
87861
|
-
if (!
|
|
87971
|
+
if (!isDeepStrictEqual11(value.bindings.selection, snapshot2.selection) || !isDeepStrictEqual11(value.bindings.consumer, snapshot2.consumer)) {
|
|
87862
87972
|
throw new SkillSelectionError("EXECUTION_GRANT_SCOPE_MISMATCH", "The Skills API returned a grant for a different selection or consumer.");
|
|
87863
87973
|
}
|
|
87864
87974
|
return value;
|
|
@@ -92235,7 +92345,7 @@ function createSkillRun(params, targetDir = process.cwd()) {
|
|
|
92235
92345
|
mkdirSync16(logsDir, { recursive: true });
|
|
92236
92346
|
mkdirSync16(exportDir, { recursive: true });
|
|
92237
92347
|
mkdirSync16(join46(root2, "tmp"), { recursive: true });
|
|
92238
|
-
const
|
|
92348
|
+
const record11 = {
|
|
92239
92349
|
id: id2,
|
|
92240
92350
|
skill: skillName,
|
|
92241
92351
|
status: params.status ?? "running",
|
|
@@ -92253,10 +92363,10 @@ function createSkillRun(params, targetDir = process.cwd()) {
|
|
|
92253
92363
|
logsDir: toProjectRelative(targetDir, logsDir)
|
|
92254
92364
|
}
|
|
92255
92365
|
};
|
|
92256
|
-
const context = { targetDir, runDir, exportDir, logsDir, record:
|
|
92366
|
+
const context = { targetDir, runDir, exportDir, logsDir, record: record11 };
|
|
92257
92367
|
writeRunRecord(context);
|
|
92258
92368
|
writeArtifactsManifest(context, []);
|
|
92259
|
-
appendRunEvent(context, "created", { status:
|
|
92369
|
+
appendRunEvent(context, "created", { status: record11.status });
|
|
92260
92370
|
return context;
|
|
92261
92371
|
}
|
|
92262
92372
|
function completeSkillRun(context, patch) {
|
|
@@ -92306,9 +92416,9 @@ function listSkillRuns(targetDir = process.cwd(), limit = 50) {
|
|
|
92306
92416
|
if (!statSync16(dayDir).isDirectory())
|
|
92307
92417
|
continue;
|
|
92308
92418
|
for (const runId2 of readdirSync18(dayDir).sort().reverse()) {
|
|
92309
|
-
const
|
|
92310
|
-
if (
|
|
92311
|
-
records.push(
|
|
92419
|
+
const record11 = readRunRecord(join46(dayDir, runId2));
|
|
92420
|
+
if (record11)
|
|
92421
|
+
records.push(record11);
|
|
92312
92422
|
if (records.length >= limit)
|
|
92313
92423
|
return records;
|
|
92314
92424
|
}
|
|
@@ -92320,9 +92430,9 @@ function findSkillRun(runId2, targetDir = process.cwd()) {
|
|
|
92320
92430
|
if (!existsSync27(runsRoot))
|
|
92321
92431
|
return null;
|
|
92322
92432
|
for (const day of readdirSync18(runsRoot)) {
|
|
92323
|
-
const
|
|
92324
|
-
if (
|
|
92325
|
-
return
|
|
92433
|
+
const record11 = readRunRecord(join46(runsRoot, day, runId2));
|
|
92434
|
+
if (record11)
|
|
92435
|
+
return record11;
|
|
92326
92436
|
}
|
|
92327
92437
|
return null;
|
|
92328
92438
|
}
|
|
@@ -92549,7 +92659,7 @@ var init_types2 = __esm(() => {
|
|
|
92549
92659
|
});
|
|
92550
92660
|
FormElicitationCapabilitySchema = intersection2(object5({
|
|
92551
92661
|
applyDefaults: boolean2().optional()
|
|
92552
|
-
}),
|
|
92662
|
+
}), record8(string2(), unknown()));
|
|
92553
92663
|
ElicitationCapabilitySchema = preprocess((value) => {
|
|
92554
92664
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
92555
92665
|
if (Object.keys(value).length === 0) {
|
|
@@ -92560,7 +92670,7 @@ var init_types2 = __esm(() => {
|
|
|
92560
92670
|
}, intersection2(object5({
|
|
92561
92671
|
form: FormElicitationCapabilitySchema.optional(),
|
|
92562
92672
|
url: AssertObjectSchema.optional()
|
|
92563
|
-
}),
|
|
92673
|
+
}), record8(string2(), unknown()).optional()));
|
|
92564
92674
|
ClientTasksCapabilitySchema = looseObject({
|
|
92565
92675
|
list: AssertObjectSchema.optional(),
|
|
92566
92676
|
cancel: AssertObjectSchema.optional(),
|
|
@@ -92583,7 +92693,7 @@ var init_types2 = __esm(() => {
|
|
|
92583
92693
|
}).optional()
|
|
92584
92694
|
});
|
|
92585
92695
|
ClientCapabilitiesSchema = object5({
|
|
92586
|
-
experimental:
|
|
92696
|
+
experimental: record8(string2(), AssertObjectSchema).optional(),
|
|
92587
92697
|
sampling: object5({
|
|
92588
92698
|
context: AssertObjectSchema.optional(),
|
|
92589
92699
|
tools: AssertObjectSchema.optional()
|
|
@@ -92593,7 +92703,7 @@ var init_types2 = __esm(() => {
|
|
|
92593
92703
|
listChanged: boolean2().optional()
|
|
92594
92704
|
}).optional(),
|
|
92595
92705
|
tasks: ClientTasksCapabilitySchema.optional(),
|
|
92596
|
-
extensions:
|
|
92706
|
+
extensions: record8(string2(), AssertObjectSchema).optional()
|
|
92597
92707
|
});
|
|
92598
92708
|
InitializeRequestParamsSchema = BaseRequestParamsSchema.extend({
|
|
92599
92709
|
protocolVersion: string2(),
|
|
@@ -92605,7 +92715,7 @@ var init_types2 = __esm(() => {
|
|
|
92605
92715
|
params: InitializeRequestParamsSchema
|
|
92606
92716
|
});
|
|
92607
92717
|
ServerCapabilitiesSchema = object5({
|
|
92608
|
-
experimental:
|
|
92718
|
+
experimental: record8(string2(), AssertObjectSchema).optional(),
|
|
92609
92719
|
logging: AssertObjectSchema.optional(),
|
|
92610
92720
|
completions: AssertObjectSchema.optional(),
|
|
92611
92721
|
prompts: object5({
|
|
@@ -92619,7 +92729,7 @@ var init_types2 = __esm(() => {
|
|
|
92619
92729
|
listChanged: boolean2().optional()
|
|
92620
92730
|
}).optional(),
|
|
92621
92731
|
tasks: ServerTasksCapabilitySchema.optional(),
|
|
92622
|
-
extensions:
|
|
92732
|
+
extensions: record8(string2(), AssertObjectSchema).optional()
|
|
92623
92733
|
});
|
|
92624
92734
|
InitializeResultSchema = ResultSchema.extend({
|
|
92625
92735
|
protocolVersion: string2(),
|
|
@@ -92706,7 +92816,7 @@ var init_types2 = __esm(() => {
|
|
|
92706
92816
|
ResourceContentsSchema = object5({
|
|
92707
92817
|
uri: string2(),
|
|
92708
92818
|
mimeType: optional(string2()),
|
|
92709
|
-
_meta:
|
|
92819
|
+
_meta: record8(string2(), unknown()).optional()
|
|
92710
92820
|
});
|
|
92711
92821
|
TextResourceContentsSchema = ResourceContentsSchema.extend({
|
|
92712
92822
|
text: string2()
|
|
@@ -92811,7 +92921,7 @@ var init_types2 = __esm(() => {
|
|
|
92811
92921
|
});
|
|
92812
92922
|
GetPromptRequestParamsSchema = BaseRequestParamsSchema.extend({
|
|
92813
92923
|
name: string2(),
|
|
92814
|
-
arguments:
|
|
92924
|
+
arguments: record8(string2(), string2()).optional()
|
|
92815
92925
|
});
|
|
92816
92926
|
GetPromptRequestSchema = RequestSchema.extend({
|
|
92817
92927
|
method: literal("prompts/get"),
|
|
@@ -92821,34 +92931,34 @@ var init_types2 = __esm(() => {
|
|
|
92821
92931
|
type: literal("text"),
|
|
92822
92932
|
text: string2(),
|
|
92823
92933
|
annotations: AnnotationsSchema.optional(),
|
|
92824
|
-
_meta:
|
|
92934
|
+
_meta: record8(string2(), unknown()).optional()
|
|
92825
92935
|
});
|
|
92826
92936
|
ImageContentSchema = object5({
|
|
92827
92937
|
type: literal("image"),
|
|
92828
92938
|
data: Base64Schema,
|
|
92829
92939
|
mimeType: string2(),
|
|
92830
92940
|
annotations: AnnotationsSchema.optional(),
|
|
92831
|
-
_meta:
|
|
92941
|
+
_meta: record8(string2(), unknown()).optional()
|
|
92832
92942
|
});
|
|
92833
92943
|
AudioContentSchema = object5({
|
|
92834
92944
|
type: literal("audio"),
|
|
92835
92945
|
data: Base64Schema,
|
|
92836
92946
|
mimeType: string2(),
|
|
92837
92947
|
annotations: AnnotationsSchema.optional(),
|
|
92838
|
-
_meta:
|
|
92948
|
+
_meta: record8(string2(), unknown()).optional()
|
|
92839
92949
|
});
|
|
92840
92950
|
ToolUseContentSchema = object5({
|
|
92841
92951
|
type: literal("tool_use"),
|
|
92842
92952
|
name: string2(),
|
|
92843
92953
|
id: string2(),
|
|
92844
|
-
input:
|
|
92845
|
-
_meta:
|
|
92954
|
+
input: record8(string2(), unknown()),
|
|
92955
|
+
_meta: record8(string2(), unknown()).optional()
|
|
92846
92956
|
});
|
|
92847
92957
|
EmbeddedResourceSchema = object5({
|
|
92848
92958
|
type: literal("resource"),
|
|
92849
92959
|
resource: union2([TextResourceContentsSchema, BlobResourceContentsSchema]),
|
|
92850
92960
|
annotations: AnnotationsSchema.optional(),
|
|
92851
|
-
_meta:
|
|
92961
|
+
_meta: record8(string2(), unknown()).optional()
|
|
92852
92962
|
});
|
|
92853
92963
|
ResourceLinkSchema = ResourceSchema.extend({
|
|
92854
92964
|
type: literal("resource_link")
|
|
@@ -92888,17 +92998,17 @@ var init_types2 = __esm(() => {
|
|
|
92888
92998
|
description: string2().optional(),
|
|
92889
92999
|
inputSchema: object5({
|
|
92890
93000
|
type: literal("object"),
|
|
92891
|
-
properties:
|
|
93001
|
+
properties: record8(string2(), AssertObjectSchema).optional(),
|
|
92892
93002
|
required: array2(string2()).optional()
|
|
92893
93003
|
}).catchall(unknown()),
|
|
92894
93004
|
outputSchema: object5({
|
|
92895
93005
|
type: literal("object"),
|
|
92896
|
-
properties:
|
|
93006
|
+
properties: record8(string2(), AssertObjectSchema).optional(),
|
|
92897
93007
|
required: array2(string2()).optional()
|
|
92898
93008
|
}).catchall(unknown()).optional(),
|
|
92899
93009
|
annotations: ToolAnnotationsSchema.optional(),
|
|
92900
93010
|
execution: ToolExecutionSchema.optional(),
|
|
92901
|
-
_meta:
|
|
93011
|
+
_meta: record8(string2(), unknown()).optional()
|
|
92902
93012
|
});
|
|
92903
93013
|
ListToolsRequestSchema = PaginatedRequestSchema.extend({
|
|
92904
93014
|
method: literal("tools/list")
|
|
@@ -92908,7 +93018,7 @@ var init_types2 = __esm(() => {
|
|
|
92908
93018
|
});
|
|
92909
93019
|
CallToolResultSchema = ResultSchema.extend({
|
|
92910
93020
|
content: array2(ContentBlockSchema).default([]),
|
|
92911
|
-
structuredContent:
|
|
93021
|
+
structuredContent: record8(string2(), unknown()).optional(),
|
|
92912
93022
|
isError: boolean2().optional()
|
|
92913
93023
|
});
|
|
92914
93024
|
CompatibilityCallToolResultSchema = CallToolResultSchema.or(ResultSchema.extend({
|
|
@@ -92916,7 +93026,7 @@ var init_types2 = __esm(() => {
|
|
|
92916
93026
|
}));
|
|
92917
93027
|
CallToolRequestParamsSchema = TaskAugmentedRequestParamsSchema.extend({
|
|
92918
93028
|
name: string2(),
|
|
92919
|
-
arguments:
|
|
93029
|
+
arguments: record8(string2(), unknown()).optional()
|
|
92920
93030
|
});
|
|
92921
93031
|
CallToolRequestSchema = RequestSchema.extend({
|
|
92922
93032
|
method: literal("tools/call"),
|
|
@@ -92965,7 +93075,7 @@ var init_types2 = __esm(() => {
|
|
|
92965
93075
|
content: array2(ContentBlockSchema).default([]),
|
|
92966
93076
|
structuredContent: object5({}).loose().optional(),
|
|
92967
93077
|
isError: boolean2().optional(),
|
|
92968
|
-
_meta:
|
|
93078
|
+
_meta: record8(string2(), unknown()).optional()
|
|
92969
93079
|
});
|
|
92970
93080
|
SamplingContentSchema = discriminatedUnion("type", [TextContentSchema, ImageContentSchema, AudioContentSchema]);
|
|
92971
93081
|
SamplingMessageContentBlockSchema = discriminatedUnion("type", [
|
|
@@ -92978,7 +93088,7 @@ var init_types2 = __esm(() => {
|
|
|
92978
93088
|
SamplingMessageSchema = object5({
|
|
92979
93089
|
role: RoleSchema,
|
|
92980
93090
|
content: union2([SamplingMessageContentBlockSchema, array2(SamplingMessageContentBlockSchema)]),
|
|
92981
|
-
_meta:
|
|
93091
|
+
_meta: record8(string2(), unknown()).optional()
|
|
92982
93092
|
});
|
|
92983
93093
|
CreateMessageRequestParamsSchema = TaskAugmentedRequestParamsSchema.extend({
|
|
92984
93094
|
messages: array2(SamplingMessageSchema),
|
|
@@ -93091,7 +93201,7 @@ var init_types2 = __esm(() => {
|
|
|
93091
93201
|
message: string2(),
|
|
93092
93202
|
requestedSchema: object5({
|
|
93093
93203
|
type: literal("object"),
|
|
93094
|
-
properties:
|
|
93204
|
+
properties: record8(string2(), PrimitiveSchemaDefinitionSchema),
|
|
93095
93205
|
required: array2(string2()).optional()
|
|
93096
93206
|
})
|
|
93097
93207
|
});
|
|
@@ -93115,7 +93225,7 @@ var init_types2 = __esm(() => {
|
|
|
93115
93225
|
});
|
|
93116
93226
|
ElicitResultSchema = ResultSchema.extend({
|
|
93117
93227
|
action: _enum2(["accept", "decline", "cancel"]),
|
|
93118
|
-
content: preprocess((val) => val === null ? undefined : val,
|
|
93228
|
+
content: preprocess((val) => val === null ? undefined : val, record8(string2(), union2([string2(), number2(), boolean2(), array2(string2())])).optional())
|
|
93119
93229
|
});
|
|
93120
93230
|
ResourceTemplateReferenceSchema = object5({
|
|
93121
93231
|
type: literal("ref/resource"),
|
|
@@ -93132,7 +93242,7 @@ var init_types2 = __esm(() => {
|
|
|
93132
93242
|
value: string2()
|
|
93133
93243
|
}),
|
|
93134
93244
|
context: object5({
|
|
93135
|
-
arguments:
|
|
93245
|
+
arguments: record8(string2(), string2()).optional()
|
|
93136
93246
|
}).optional()
|
|
93137
93247
|
});
|
|
93138
93248
|
CompleteRequestSchema = RequestSchema.extend({
|
|
@@ -93149,7 +93259,7 @@ var init_types2 = __esm(() => {
|
|
|
93149
93259
|
RootSchema = object5({
|
|
93150
93260
|
uri: string2().startsWith("file://"),
|
|
93151
93261
|
name: string2().optional(),
|
|
93152
|
-
_meta:
|
|
93262
|
+
_meta: record8(string2(), unknown()).optional()
|
|
93153
93263
|
});
|
|
93154
93264
|
ListRootsRequestSchema = RequestSchema.extend({
|
|
93155
93265
|
method: literal("roots/list"),
|
|
@@ -112311,7 +112421,7 @@ var init_create_sync_config = __esm(() => {
|
|
|
112311
112421
|
});
|
|
112312
112422
|
|
|
112313
112423
|
// src/lib/codex-native-config.ts
|
|
112314
|
-
import { isDeepStrictEqual as
|
|
112424
|
+
import { isDeepStrictEqual as isDeepStrictEqual12 } from "util";
|
|
112315
112425
|
function isRecord8(value) {
|
|
112316
112426
|
if (!value || typeof value !== "object")
|
|
112317
112427
|
return false;
|
|
@@ -112333,7 +112443,7 @@ function decimalIdentity(text4) {
|
|
|
112333
112443
|
return `${match[1]}${coefficient}e${exponent}`;
|
|
112334
112444
|
}
|
|
112335
112445
|
function codexNativeConfigEqual(native, expected) {
|
|
112336
|
-
if (
|
|
112446
|
+
if (isDeepStrictEqual12(native, expected))
|
|
112337
112447
|
return true;
|
|
112338
112448
|
if (typeof expected === "number") {
|
|
112339
112449
|
if (!Number.isFinite(expected) || !isRecord8(native))
|
|
@@ -112359,7 +112469,7 @@ var init_codex_native_config = () => {};
|
|
|
112359
112469
|
// src/lib/codex-hook-trust-identity.ts
|
|
112360
112470
|
import { realpathSync as realpathSync16 } from "fs";
|
|
112361
112471
|
import { dirname as dirname33, isAbsolute as isAbsolute27, join as join59 } from "path";
|
|
112362
|
-
import { isDeepStrictEqual as
|
|
112472
|
+
import { isDeepStrictEqual as isDeepStrictEqual13 } from "util";
|
|
112363
112473
|
function inspectRecordedSkillsCli(command, expected) {
|
|
112364
112474
|
need6(isAbsolute27(command) && !command.includes("\x00"), "RECONCILE_RECORDED_COMMAND_REQUIRED");
|
|
112365
112475
|
const resolved = realpathSync16(command);
|
|
@@ -112369,7 +112479,7 @@ function inspectRecordedSkillsCli(command, expected) {
|
|
|
112369
112479
|
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
112480
|
need6((cli.stat.mode & 0o100n) !== 0n, "SKILLS_COMMAND_NOT_EXECUTABLE");
|
|
112371
112481
|
const receipt = { path: resolved, version: pkg.version, sha256: cli.sha256, manifestSha256: manifest.sha256 };
|
|
112372
|
-
need6(
|
|
112482
|
+
need6(isDeepStrictEqual13(receipt, expected), "RECONCILE_SKILLS_BINDING_CHANGED");
|
|
112373
112483
|
return { receipt, recheck() {
|
|
112374
112484
|
need6(realpathSync16(command) === resolved, "SKILLS_COMMAND_CHANGED");
|
|
112375
112485
|
unchanged2(cli);
|
|
@@ -112405,19 +112515,19 @@ var init_codex_hook_trust_identity = __esm(() => {
|
|
|
112405
112515
|
});
|
|
112406
112516
|
|
|
112407
112517
|
// src/lib/codex-hook-policy-recovery.ts
|
|
112408
|
-
import { isDeepStrictEqual as
|
|
112518
|
+
import { isDeepStrictEqual as isDeepStrictEqual14 } from "util";
|
|
112409
112519
|
function reviewedClaudeDiscoveryChange(beforeText, currentText, options) {
|
|
112410
112520
|
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
112521
|
need6(options.reviewedPlanDigest === undefined || /^[a-f0-9]{64}$/.test(options.reviewedPlanDigest), "RECONCILE_RECOVERY_PLAN_CHANGED");
|
|
112412
112522
|
const before2 = parseManagedSkillPolicy(beforeText), current = parseManagedSkillPolicy(currentText);
|
|
112413
112523
|
const oldDiscovery = before2.bridge?.discovery?.claude, newDiscovery = current.bridge?.discovery?.claude;
|
|
112414
112524
|
need6(oldDiscovery?.agent === "claude" && newDiscovery?.agent === "claude" && oldDiscovery.method === "reviewed" && newDiscovery.method === "reviewed", "RECONCILE_POLICY_CHANGED");
|
|
112415
|
-
const changes = ["roots", "sources"].filter((key) => !
|
|
112525
|
+
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
112526
|
need6(changes.length > 0, "RECONCILE_POLICY_CHANGED");
|
|
112417
112527
|
const compared = structuredClone(current);
|
|
112418
112528
|
compared.bridge.discovery.claude.roots = oldDiscovery.roots;
|
|
112419
112529
|
compared.bridge.discovery.claude.sources = oldDiscovery.sources;
|
|
112420
|
-
need6(
|
|
112530
|
+
need6(isDeepStrictEqual14(before2, compared), "RECONCILE_POLICY_CHANGED");
|
|
112421
112531
|
verifyAgentDiscovery(newDiscovery);
|
|
112422
112532
|
return { reason: options.reason, changes };
|
|
112423
112533
|
}
|
|
@@ -112433,7 +112543,7 @@ import { createHash as createHash31, randomUUID as randomUUID11 } from "crypto";
|
|
|
112433
112543
|
import { execFileSync } from "child_process";
|
|
112434
112544
|
import { dirname as dirname34, isAbsolute as isAbsolute28, join as join60, resolve as resolve25 } from "path";
|
|
112435
112545
|
import { homedir as homedir12 } from "os";
|
|
112436
|
-
import { isDeepStrictEqual as
|
|
112546
|
+
import { isDeepStrictEqual as isDeepStrictEqual15 } from "util";
|
|
112437
112547
|
function verifyReleaseArtifact(proof, skillsCli) {
|
|
112438
112548
|
need6(isAbsolute28(proof.packageTarPath) && !proof.packageTarPath.includes("\x00"), "RECONCILE_RELEASE_PROVENANCE_PATH");
|
|
112439
112549
|
const tarPath = realpathSync17(proof.packageTarPath);
|
|
@@ -112475,7 +112585,7 @@ async function reconcileCodexNativeHooks(options, connect = connectCodexHookRpc)
|
|
|
112475
112585
|
const configSha256 = intent.configSha256 ?? configBefore.sha256, configVersion = intent.configVersion ?? intent.expectedVersion;
|
|
112476
112586
|
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
112587
|
need6(makePlanDigest(digestInput) === intent.planDigest, "RECONCILE_PLAN_CHANGED");
|
|
112478
|
-
need6(
|
|
112588
|
+
need6(isDeepStrictEqual15(intent.hooks, admitted.filter((hook) => !hook.enabled || hook.trustStatus !== "trusted")), "RECONCILE_INTENT_HOOKS_CHANGED");
|
|
112479
112589
|
need6(configBefore.sha256 === (intent.beforeSha256 ?? intent.configSha256) && hooksBefore.sha256 === intent.hooksSha256 && policyBefore.sha256 === intent.policySha256, "RECONCILE_JOURNAL_CHANGED");
|
|
112480
112590
|
const policyCurrent = snapshot(join60(dataDir3, "agent-policy.json"), true);
|
|
112481
112591
|
const { claudeDiscoveryRecovery: claudeRecovery, nativeHookAdditionsRecovery: additionsRecovery } = options;
|
|
@@ -112488,7 +112598,7 @@ async function reconcileCodexNativeHooks(options, connect = connectCodexHookRpc)
|
|
|
112488
112598
|
if (policyCurrent.sha256 !== policyBefore.sha256 && !claudeRecovery) {
|
|
112489
112599
|
need6(options.supersedeBinding === true, "RECONCILE_POLICY_CHANGED");
|
|
112490
112600
|
const oldPolicy = JSON.parse(policyBefore.text), currentPolicy = JSON.parse(policyCurrent.text);
|
|
112491
|
-
need6(
|
|
112601
|
+
need6(isDeepStrictEqual15(withoutCodexCommand(oldPolicy), withoutCodexCommand(currentPolicy)), "RECONCILE_POLICY_CHANGED");
|
|
112492
112602
|
supersededBinding = true;
|
|
112493
112603
|
}
|
|
112494
112604
|
if (supersededBinding || recovery) {
|
|
@@ -112524,7 +112634,7 @@ async function reconcileCodexNativeHooks(options, connect = connectCodexHookRpc)
|
|
|
112524
112634
|
need6(state?.enabled === true && typeof state.trusted_hash === "string" && /^sha256:[a-f0-9]{64}$/.test(state.trusted_hash), "RECONCILE_CONFIG_DRIFT");
|
|
112525
112635
|
}
|
|
112526
112636
|
} else
|
|
112527
|
-
need6(
|
|
112637
|
+
need6(isDeepStrictEqual15(expectedConfig, current), "RECONCILE_CONFIG_DRIFT");
|
|
112528
112638
|
const configDiscoveryRecovery = recovery && binding.discovery?.codex ? createCodexHookDiscoveryRecovery(binding.discovery.codex, configBefore, currentConfig, intent.hooks, additions?.trustProof) : undefined;
|
|
112529
112639
|
assertManagedAgentBridge("codex", { home, dataDir: dataDir3, projectDir: home, codexDiscoveryRecovery: configDiscoveryRecovery });
|
|
112530
112640
|
const recoveryCli = recovery ? bindSkillsCli("skills", options.reviewedSkillsCli) : undefined;
|
|
@@ -112533,14 +112643,14 @@ async function reconcileCodexNativeHooks(options, connect = connectCodexHookRpc)
|
|
|
112533
112643
|
const skillsCli = recovery ? inspectRecordedSkillsCli(binding.commands.codex, intent.skillsCli) : bindSkillsCli(binding.commands.codex, options.reviewedSkillsCli);
|
|
112534
112644
|
if (supersededBinding)
|
|
112535
112645
|
verifyReleaseArtifact(options.releaseProof, skillsCli);
|
|
112536
|
-
const skillsBindingChanged = !
|
|
112646
|
+
const skillsBindingChanged = !isDeepStrictEqual15(skillsCli.receipt, intent.skillsCli);
|
|
112537
112647
|
need6(!skillsBindingChanged || supersededBinding, "RECONCILE_SKILLS_BINDING_CHANGED");
|
|
112538
112648
|
if (!additions && hooksCurrent.sha256 !== intent.hooksSha256 && hooksCurrent.sha256 !== hooksBefore.sha256) {
|
|
112539
112649
|
need6(supersededBinding, "RECONCILE_HOOKS_CHANGED");
|
|
112540
112650
|
const currentDeclarations = JSON.parse(hooksCurrent.text).hooks;
|
|
112541
112651
|
for (const [event, [nativeEvent]] of Object.entries(eventNames)) {
|
|
112542
112652
|
const command = renderAgentHookCommand(binding.commands.codex, "codex", binding.profiles.codex, event);
|
|
112543
|
-
need6(
|
|
112653
|
+
need6(isDeepStrictEqual15(currentDeclarations?.[event], [{ hooks: [{ type: "command", command, timeout: 15 }] }]), "RECONCILE_BINDING_HOOK_CHANGED");
|
|
112544
112654
|
}
|
|
112545
112655
|
}
|
|
112546
112656
|
rpc = await connect({ command: options.codexCommand ?? "codex", home, codexHome });
|
|
@@ -112563,9 +112673,9 @@ async function reconcileCodexNativeHooks(options, connect = connectCodexHookRpc)
|
|
|
112563
112673
|
delete identity5.command;
|
|
112564
112674
|
return identity5;
|
|
112565
112675
|
};
|
|
112566
|
-
need6(
|
|
112676
|
+
need6(isDeepStrictEqual15(stable(actual), stable(expected)), "RECONCILE_NATIVE_IDENTITY_CHANGED");
|
|
112567
112677
|
if (!plannedKeys.has(expected.key))
|
|
112568
|
-
need6(
|
|
112678
|
+
need6(isDeepStrictEqual15(actual, expected), "RECONCILE_UNRELATED_HOOK_CHANGED");
|
|
112569
112679
|
}
|
|
112570
112680
|
for (const wanted of intent.hooks) {
|
|
112571
112681
|
const matches2 = nativeHooks.filter((h2) => h2.key === wanted.key || h2.key === wanted.key.replace(join60(home, ".codex/hooks.json"), hooksPath));
|
|
@@ -112584,7 +112694,7 @@ async function reconcileCodexNativeHooks(options, connect = connectCodexHookRpc)
|
|
|
112584
112694
|
const layers = config2?.layers?.filter((layer) => layer.name?.type === "user" && layer.name.file === nativeConfigPath && !layer.name.profile);
|
|
112585
112695
|
need6(layers?.length === 1 && !layers[0].disabledReason && codexNativeConfigEqual(layers[0].config, current), "RECONCILE_NATIVE_CONFIG_MISMATCH");
|
|
112586
112696
|
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 ||
|
|
112697
|
+
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
112698
|
const finalConfig = await rpc.request("config/read", { includeLayers: true, cwd: home });
|
|
112589
112699
|
const finalLayers = finalConfig?.layers?.filter((layer) => layer.name?.type === "user" && layer.name.file === nativeConfigPath && !layer.name.profile);
|
|
112590
112700
|
need6(finalLayers?.length === 1 && !finalLayers[0].disabledReason && codexNativeConfigEqual(finalLayers[0].config, current), "RECONCILE_NATIVE_CONFIG_CHANGED");
|
|
@@ -112645,7 +112755,7 @@ async function enrollCodexNativeHooks(options = {}, connect = connectCodexHookRp
|
|
|
112645
112755
|
const groups = declarations[event];
|
|
112646
112756
|
need6(Array.isArray(groups), "DECLARATION_CHANGED");
|
|
112647
112757
|
const matches2 = groups.flatMap((group, gi) => (group.hooks ?? []).flatMap((entry, hi) => entry.command === command ? [{ group, entry, gi, hi }] : []));
|
|
112648
|
-
need6(matches2.length === 1 &&
|
|
112758
|
+
need6(matches2.length === 1 && isDeepStrictEqual15(matches2[0].group, { hooks: [{ type: "command", command, timeout: 15 }] }), "DECLARATION_CHANGED");
|
|
112649
112759
|
expected.push({ event: nativeEvent, key: `${join60(home, ".codex/hooks.json")}:${label}:${matches2[0].gi}:${matches2[0].hi}`, command });
|
|
112650
112760
|
}
|
|
112651
112761
|
codexTrustTextWitness(configFile.text, expected.map((h) => h.key));
|
|
@@ -112711,7 +112821,7 @@ async function enrollCodexNativeHooks(options = {}, connect = connectCodexHookRp
|
|
|
112711
112821
|
save(join60(journal, "hooks.before.json"), hooksFile.bytes);
|
|
112712
112822
|
save(join60(journal, "policy.before.json"), policyFile.bytes);
|
|
112713
112823
|
save(join60(journal, "intent.json"), json2({ ...digestInput, planDigest, hooks: planned, nativeHooks: discovered.map(safeNativeHook) }));
|
|
112714
|
-
need6(
|
|
112824
|
+
need6(isDeepStrictEqual15(admit(await list2()), admitted), "NATIVE_DISCOVERY_CHANGED");
|
|
112715
112825
|
checkInputs();
|
|
112716
112826
|
let result2;
|
|
112717
112827
|
try {
|
|
@@ -112725,7 +112835,7 @@ async function enrollCodexNativeHooks(options = {}, connect = connectCodexHookRp
|
|
|
112725
112835
|
expectedConfig.hooks.state ??= {};
|
|
112726
112836
|
for (const h of planned)
|
|
112727
112837
|
expectedConfig.hooks.state[h.key] = { ...expectedConfig.hooks.state[h.key], enabled: true, trusted_hash: h.currentHash };
|
|
112728
|
-
need6(
|
|
112838
|
+
need6(isDeepStrictEqual15(structure3(after2.text), expectedConfig) && codexTrustTextWitness(after2.text, keys3) === preservationText, "PRESERVATION_FAILED");
|
|
112729
112839
|
const savedConfig = snapshot(join60(journal, "config.before.toml"), true);
|
|
112730
112840
|
need6(savedConfig.sha256 === configFile.sha256, "JOURNAL_CHANGED");
|
|
112731
112841
|
const discoveryTransition = binding.discovery?.codex ? createCodexHookDiscoveryRecovery(binding.discovery.codex, savedConfig, after2, planned) : undefined;
|
|
@@ -112733,8 +112843,8 @@ async function enrollCodexNativeHooks(options = {}, connect = connectCodexHookRp
|
|
|
112733
112843
|
unchanged2(hooksFile);
|
|
112734
112844
|
assertManagedAgentBridge("codex", { home, dataDir: dataDir3, projectDir: home, codexDiscoveryRecovery: discoveryTransition });
|
|
112735
112845
|
const current = await list2(), confirmed = admit(current);
|
|
112736
|
-
need6(confirmed.every((h) => h.enabled && h.trustStatus === "trusted") &&
|
|
112737
|
-
need6(
|
|
112846
|
+
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");
|
|
112847
|
+
need6(isDeepStrictEqual15(current.filter((h) => !keys3.includes(h.key)), discovered.filter((h) => !keys3.includes(h.key))), "UNRELATED_HOOK_CHANGED");
|
|
112738
112848
|
unchanged2(after2);
|
|
112739
112849
|
unchanged2(savedConfig);
|
|
112740
112850
|
unchanged2(hooksFile);
|
|
@@ -113004,17 +113114,19 @@ function registerAgentIntegration(parent) {
|
|
|
113004
113114
|
process.exitCode = 1;
|
|
113005
113115
|
}
|
|
113006
113116
|
});
|
|
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;
|
|
113117
|
+
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) => {
|
|
113118
|
+
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
113119
|
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");
|
|
113120
|
+
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
113121
|
await writeCliOutput(JSON.stringify(capture2(options.path), null, 2));
|
|
113012
113122
|
});
|
|
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) => {
|
|
113123
|
+
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
113124
|
try {
|
|
113015
113125
|
if (!["claude", "codex"].includes(options.agent))
|
|
113016
113126
|
throw new Error("Settings witness rebind accepts claude or codex");
|
|
113017
|
-
|
|
113127
|
+
if (options.codexWitnessVersion !== undefined && !["2", "3"].includes(options.codexWitnessVersion))
|
|
113128
|
+
throw new Error("Codex witness version accepts 2 or 3");
|
|
113129
|
+
const plan = planAgentSettingsWitnessUpgrade({ ...options.codexWitnessVersion !== undefined ? { targetCodexVersion: Number(options.codexWitnessVersion) } : {}, agent: options.agent, reviewedPreimage: options.reviewedPreimage, expectedPolicySha256: options.expectedPolicySha256, expectedSettingsSha256: options.expectedSettingsSha256 });
|
|
113018
113130
|
const result2 = options.apply ? applyAgentIntegration(plan) : { changed: [], backups: [] };
|
|
113019
113131
|
const receipt = { applied: options.apply, settingsWitnessUpgrade: plan.settingsWitnessUpgrade, ...result2 };
|
|
113020
113132
|
await writeCliOutput(options.json ? JSON.stringify(receipt) : `Settings witness ${options.apply ? "upgraded" : "planned"} for ${options.agent}. Native configuration was not changed.`);
|
|
@@ -115013,21 +115125,21 @@ async function readPublishRevision(client2, slug2) {
|
|
|
115013
115125
|
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
115126
|
}
|
|
115015
115127
|
const body = lookup.body;
|
|
115016
|
-
const
|
|
115017
|
-
const nestedError =
|
|
115018
|
-
const code2 = typeof
|
|
115128
|
+
const record12 = body !== null && typeof body === "object" && !Array.isArray(body) ? body : undefined;
|
|
115129
|
+
const nestedError = record12?.error;
|
|
115130
|
+
const code2 = typeof record12?.code === "string" ? record12.code : nestedError !== null && typeof nestedError === "object" && !Array.isArray(nestedError) ? nestedError.code : undefined;
|
|
115019
115131
|
if (lookup.status === 404 && code2 === "SKILL_NOT_FOUND")
|
|
115020
115132
|
return;
|
|
115021
115133
|
if (lookup.status < 200 || lookup.status >= 300) {
|
|
115022
115134
|
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
115135
|
}
|
|
115024
|
-
const revision =
|
|
115025
|
-
if (
|
|
115026
|
-
if (
|
|
115136
|
+
const revision = record12?.revisionId;
|
|
115137
|
+
if (record12?.publicationState === "catalogue-only") {
|
|
115138
|
+
if (record12.name === slug2 && (record12.slug === undefined || record12.slug === slug2) && revision === null)
|
|
115027
115139
|
return;
|
|
115028
115140
|
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
115141
|
}
|
|
115030
|
-
if (
|
|
115142
|
+
if (record12?.slug !== slug2 || typeof revision !== "string" || revision.length === 0 || revision !== revision.trim() || !/^[\x21-\x7e]+$/.test(revision)) {
|
|
115031
115143
|
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
115144
|
}
|
|
115033
115145
|
return revision;
|
|
@@ -116709,14 +116821,14 @@ function resolveCorpusRootReadOnly(options) {
|
|
|
116709
116821
|
}
|
|
116710
116822
|
return { root: join65(appDir, INSTALLED_SKILLS_DIRNAME), migrationPending: true };
|
|
116711
116823
|
}
|
|
116712
|
-
function remoteRowToSkill(
|
|
116713
|
-
const slug2 = typeof
|
|
116824
|
+
function remoteRowToSkill(record12) {
|
|
116825
|
+
const slug2 = typeof record12.slug === "string" ? record12.slug : typeof record12.name === "string" ? record12.name : undefined;
|
|
116714
116826
|
if (!slug2)
|
|
116715
116827
|
return;
|
|
116716
116828
|
return {
|
|
116717
116829
|
slug: slug2,
|
|
116718
|
-
version: typeof
|
|
116719
|
-
sha256: typeof
|
|
116830
|
+
version: typeof record12.version === "string" ? record12.version : undefined,
|
|
116831
|
+
sha256: typeof record12.bundleSha256 === "string" && record12.bundleSha256 ? record12.bundleSha256 : undefined
|
|
116720
116832
|
};
|
|
116721
116833
|
}
|
|
116722
116834
|
function recheckLocalSide(plannedLocal, localDir, ops = {
|