@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/dist/sdk/index.js
CHANGED
|
@@ -22023,18 +22023,18 @@ var require_protocols2 = __commonJS((exports) => {
|
|
|
22023
22023
|
}
|
|
22024
22024
|
return value;
|
|
22025
22025
|
}
|
|
22026
|
-
_readStruct(ns,
|
|
22026
|
+
_readStruct(ns, record4) {
|
|
22027
22027
|
const union = ns.isUnionSchema();
|
|
22028
22028
|
const out = {};
|
|
22029
22029
|
let nameMap;
|
|
22030
|
-
const hasType = typeof
|
|
22030
|
+
const hasType = typeof record4.__type === "string";
|
|
22031
22031
|
const { jsonName } = this.settings;
|
|
22032
22032
|
if (jsonName && hasType) {
|
|
22033
22033
|
nameMap = {};
|
|
22034
22034
|
}
|
|
22035
22035
|
let unionSerde;
|
|
22036
22036
|
if (union) {
|
|
22037
|
-
unionSerde = new UnionSerde(
|
|
22037
|
+
unionSerde = new UnionSerde(record4, out);
|
|
22038
22038
|
}
|
|
22039
22039
|
for (const [memberName, memberSchema] of ns.structIterator()) {
|
|
22040
22040
|
let fromKey = memberName;
|
|
@@ -22047,15 +22047,15 @@ var require_protocols2 = __commonJS((exports) => {
|
|
|
22047
22047
|
if (union) {
|
|
22048
22048
|
unionSerde.mark(fromKey);
|
|
22049
22049
|
}
|
|
22050
|
-
if (
|
|
22051
|
-
out[memberName] = this._read(memberSchema,
|
|
22050
|
+
if (record4[fromKey] != null) {
|
|
22051
|
+
out[memberName] = this._read(memberSchema, record4[fromKey]);
|
|
22052
22052
|
}
|
|
22053
22053
|
}
|
|
22054
22054
|
if (union) {
|
|
22055
22055
|
unionSerde.writeUnknown();
|
|
22056
22056
|
} else if (hasType) {
|
|
22057
|
-
for (const k in
|
|
22058
|
-
const v =
|
|
22057
|
+
for (const k in record4) {
|
|
22058
|
+
const v = record4[k];
|
|
22059
22059
|
const t2 = jsonName ? nameMap[k] ?? k : k;
|
|
22060
22060
|
if (!(t2 in out)) {
|
|
22061
22061
|
out[t2] = v;
|
|
@@ -22911,7 +22911,7 @@ var require_protocols2 = __commonJS((exports) => {
|
|
|
22911
22911
|
const ns = NormalizedSchema.of(schema);
|
|
22912
22912
|
if (isObject) {
|
|
22913
22913
|
if (ns.isStructSchema()) {
|
|
22914
|
-
const
|
|
22914
|
+
const record4 = value;
|
|
22915
22915
|
const union = ns.isUnionSchema();
|
|
22916
22916
|
const out = {};
|
|
22917
22917
|
let nameMap = undefined;
|
|
@@ -22921,7 +22921,7 @@ var require_protocols2 = __commonJS((exports) => {
|
|
|
22921
22921
|
}
|
|
22922
22922
|
let unionSerde;
|
|
22923
22923
|
if (union) {
|
|
22924
|
-
unionSerde = new UnionSerde(
|
|
22924
|
+
unionSerde = new UnionSerde(record4, out);
|
|
22925
22925
|
}
|
|
22926
22926
|
for (const [memberName, memberSchema] of ns.structIterator()) {
|
|
22927
22927
|
let fromKey = memberName;
|
|
@@ -22932,15 +22932,15 @@ var require_protocols2 = __commonJS((exports) => {
|
|
|
22932
22932
|
if (union) {
|
|
22933
22933
|
unionSerde.mark(fromKey);
|
|
22934
22934
|
}
|
|
22935
|
-
if (
|
|
22936
|
-
out[memberName] = this._read(memberSchema,
|
|
22935
|
+
if (record4[fromKey] != null) {
|
|
22936
|
+
out[memberName] = this._read(memberSchema, record4[fromKey]);
|
|
22937
22937
|
}
|
|
22938
22938
|
}
|
|
22939
22939
|
if (union) {
|
|
22940
22940
|
unionSerde.writeUnknown();
|
|
22941
|
-
} else if (typeof
|
|
22942
|
-
for (const k in
|
|
22943
|
-
const v =
|
|
22941
|
+
} else if (typeof record4.__type === "string") {
|
|
22942
|
+
for (const k in record4) {
|
|
22943
|
+
const v = record4[k];
|
|
22944
22944
|
const t2 = jsonName ? nameMap[k] ?? k : k;
|
|
22945
22945
|
if (!(t2 in out)) {
|
|
22946
22946
|
out[t2] = v;
|
|
@@ -23124,7 +23124,7 @@ var require_protocols2 = __commonJS((exports) => {
|
|
|
23124
23124
|
const ns = NormalizedSchema.of(schema);
|
|
23125
23125
|
if (isObject) {
|
|
23126
23126
|
if (ns.isStructSchema()) {
|
|
23127
|
-
const
|
|
23127
|
+
const record4 = value;
|
|
23128
23128
|
const out = {};
|
|
23129
23129
|
const { jsonName } = this.settings;
|
|
23130
23130
|
let nameMap = undefined;
|
|
@@ -23133,7 +23133,7 @@ var require_protocols2 = __commonJS((exports) => {
|
|
|
23133
23133
|
}
|
|
23134
23134
|
let outCount = 0;
|
|
23135
23135
|
for (const [memberName, memberSchema] of ns.structIterator()) {
|
|
23136
|
-
const serializableValue = this._write(memberSchema,
|
|
23136
|
+
const serializableValue = this._write(memberSchema, record4[memberName], ns);
|
|
23137
23137
|
if (serializableValue !== undefined) {
|
|
23138
23138
|
let targetKey = memberName;
|
|
23139
23139
|
if (jsonName) {
|
|
@@ -23145,7 +23145,7 @@ var require_protocols2 = __commonJS((exports) => {
|
|
|
23145
23145
|
}
|
|
23146
23146
|
}
|
|
23147
23147
|
if (ns.isUnionSchema() && outCount === 0) {
|
|
23148
|
-
const { $unknown } =
|
|
23148
|
+
const { $unknown } = record4;
|
|
23149
23149
|
if (Array.isArray($unknown)) {
|
|
23150
23150
|
const [k, v] = $unknown;
|
|
23151
23151
|
if (k === "__proto__") {
|
|
@@ -23153,9 +23153,9 @@ var require_protocols2 = __commonJS((exports) => {
|
|
|
23153
23153
|
}
|
|
23154
23154
|
out[k] = this._write(15, v);
|
|
23155
23155
|
}
|
|
23156
|
-
} else if (typeof
|
|
23157
|
-
for (const k in
|
|
23158
|
-
const v =
|
|
23156
|
+
} else if (typeof record4.__type === "string") {
|
|
23157
|
+
for (const k in record4) {
|
|
23158
|
+
const v = record4[k];
|
|
23159
23159
|
const targetKey = jsonName ? nameMap[k] ?? k : k;
|
|
23160
23160
|
if (!(targetKey in out)) {
|
|
23161
23161
|
out[targetKey] = this._write(15, v);
|
|
@@ -32373,7 +32373,7 @@ var init_event_sink = __esm(() => {
|
|
|
32373
32373
|
// package.json
|
|
32374
32374
|
var package_default = {
|
|
32375
32375
|
name: "@hasna/skills",
|
|
32376
|
-
version: "0.10.
|
|
32376
|
+
version: "0.10.28",
|
|
32377
32377
|
description: "Skills library for AI coding agents",
|
|
32378
32378
|
type: "module",
|
|
32379
32379
|
bin: {
|
|
@@ -37694,6 +37694,72 @@ import {
|
|
|
37694
37694
|
import { homedir as homedir5 } from "os";
|
|
37695
37695
|
import { basename as basename11, dirname as dirname19, join as join27 } from "path";
|
|
37696
37696
|
|
|
37697
|
+
// src/lib/codex-local-mcp-controls.ts
|
|
37698
|
+
function isCodexLocalStdioMcpServer(name, server) {
|
|
37699
|
+
const identifier3 = (value) => typeof value === "string" && /^[A-Za-z0-9_-]{1,64}$/.test(value);
|
|
37700
|
+
const refuse2 = () => {
|
|
37701
|
+
throw new Error("Unsupported Codex local stdio MCP controls");
|
|
37702
|
+
};
|
|
37703
|
+
const object2 = (v) => Boolean(v && typeof v === "object" && !Array.isArray(v) && !(v instanceof Date));
|
|
37704
|
+
const textField = (v, empty = false) => typeof v === "string" && (empty || Boolean(v.trim())) && Buffer.byteLength(v) <= 16384 && !/[\x00-\x1f\x7f]/.test(v);
|
|
37705
|
+
const envName = (v) => typeof v === "string" && /^[A-Za-z_][A-Za-z0-9_]{0,255}$/.test(v);
|
|
37706
|
+
const optional = (v, valid) => v === undefined || v === null || valid(v);
|
|
37707
|
+
const stringList = (v) => Array.isArray(v) && v.length <= 256 && v.every((item) => textField(item));
|
|
37708
|
+
const approval = (v) => ["auto", "prompt", "writes", "approve"].includes(v);
|
|
37709
|
+
const duration = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0;
|
|
37710
|
+
const positiveInteger = (v) => Number.isSafeInteger(v) && v > 0;
|
|
37711
|
+
const fields = [
|
|
37712
|
+
"command",
|
|
37713
|
+
"args",
|
|
37714
|
+
"cwd",
|
|
37715
|
+
"env",
|
|
37716
|
+
"env_vars",
|
|
37717
|
+
"enabled",
|
|
37718
|
+
"required",
|
|
37719
|
+
"environment_id",
|
|
37720
|
+
"startup_readiness",
|
|
37721
|
+
"supports_parallel_tool_calls",
|
|
37722
|
+
"tool_input_schema_max_bytes",
|
|
37723
|
+
"startup_timeout_sec",
|
|
37724
|
+
"startup_timeout_ms",
|
|
37725
|
+
"tool_timeout_sec",
|
|
37726
|
+
"default_tools_approval_mode",
|
|
37727
|
+
"enabled_tools",
|
|
37728
|
+
"disabled_tools",
|
|
37729
|
+
"omit_tools_from",
|
|
37730
|
+
"tools",
|
|
37731
|
+
"name"
|
|
37732
|
+
];
|
|
37733
|
+
try {
|
|
37734
|
+
if (!identifier3(name) || !object2(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) => object2(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))
|
|
37735
|
+
refuse2();
|
|
37736
|
+
if (server.env_vars !== undefined && server.env_vars !== null) {
|
|
37737
|
+
if (!Array.isArray(server.env_vars) || server.env_vars.length > 256)
|
|
37738
|
+
refuse2();
|
|
37739
|
+
const names = server.env_vars.map((entry) => {
|
|
37740
|
+
if (envName(entry))
|
|
37741
|
+
return entry;
|
|
37742
|
+
if (!object2(entry) || !Object.keys(entry).every((key) => ["name", "source"].includes(key)) || !envName(entry.name) || !optional(entry.source, (v) => v === "local"))
|
|
37743
|
+
refuse2();
|
|
37744
|
+
return entry.name;
|
|
37745
|
+
});
|
|
37746
|
+
if (new Set(names).size !== names.length)
|
|
37747
|
+
refuse2();
|
|
37748
|
+
}
|
|
37749
|
+
if (server.tools !== undefined && server.tools !== null) {
|
|
37750
|
+
if (!object2(server.tools) || Object.keys(server.tools).length > 256)
|
|
37751
|
+
refuse2();
|
|
37752
|
+
for (const [tool, config] of Object.entries(server.tools)) {
|
|
37753
|
+
if (!textField(tool) || !object2(config) || !Object.keys(config).every((key) => ["approval_mode", "output_token_limit"].includes(key)) || !optional(config.approval_mode, approval) || !optional(config.output_token_limit, positiveInteger))
|
|
37754
|
+
refuse2();
|
|
37755
|
+
}
|
|
37756
|
+
}
|
|
37757
|
+
return true;
|
|
37758
|
+
} catch {
|
|
37759
|
+
return false;
|
|
37760
|
+
}
|
|
37761
|
+
}
|
|
37762
|
+
|
|
37697
37763
|
// src/lib/claude-settings-witness.ts
|
|
37698
37764
|
import { createHash as createHash5 } from "crypto";
|
|
37699
37765
|
import { closeSync as closeSync9, constants as constants5, fstatSync as fstatSync9, lstatSync as lstatSync5, openSync as openSync9, readSync as readSync4 } from "fs";
|
|
@@ -38375,65 +38441,14 @@ function mcpControls(path, read) {
|
|
|
38375
38441
|
refuse3();
|
|
38376
38442
|
}
|
|
38377
38443
|
const object3 = (v) => Boolean(v && typeof v === "object" && !Array.isArray(v));
|
|
38378
|
-
const textField = (v, empty = false) => typeof v === "string" && (empty || Boolean(v.trim())) && Buffer.byteLength(v) <= 16384 && !/[\x00-\x1f\x7f]/.test(v);
|
|
38379
|
-
const envName = (v) => typeof v === "string" && /^[A-Za-z_][A-Za-z0-9_]{0,255}$/.test(v);
|
|
38380
|
-
const optional = (v, valid) => v === undefined || v === null || valid(v);
|
|
38381
|
-
const stringList = (v) => Array.isArray(v) && v.length <= 256 && v.every((item) => textField(item));
|
|
38382
|
-
const approval = (v) => ["auto", "prompt", "writes", "approve"].includes(v);
|
|
38383
|
-
const duration = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0;
|
|
38384
|
-
const positiveInteger = (v) => Number.isSafeInteger(v) && v > 0;
|
|
38385
|
-
const fields = [
|
|
38386
|
-
"command",
|
|
38387
|
-
"args",
|
|
38388
|
-
"cwd",
|
|
38389
|
-
"env",
|
|
38390
|
-
"env_vars",
|
|
38391
|
-
"enabled",
|
|
38392
|
-
"required",
|
|
38393
|
-
"environment_id",
|
|
38394
|
-
"startup_readiness",
|
|
38395
|
-
"supports_parallel_tool_calls",
|
|
38396
|
-
"tool_input_schema_max_bytes",
|
|
38397
|
-
"startup_timeout_sec",
|
|
38398
|
-
"startup_timeout_ms",
|
|
38399
|
-
"tool_timeout_sec",
|
|
38400
|
-
"default_tools_approval_mode",
|
|
38401
|
-
"enabled_tools",
|
|
38402
|
-
"disabled_tools",
|
|
38403
|
-
"omit_tools_from",
|
|
38404
|
-
"tools",
|
|
38405
|
-
"name"
|
|
38406
|
-
];
|
|
38407
38444
|
if (!object3(value) || Object.keys(value).length !== 1 || !object3(value.mcpServers))
|
|
38408
38445
|
refuse3();
|
|
38409
38446
|
const servers = Object.entries(value.mcpServers);
|
|
38410
38447
|
if (!servers.length || servers.length > 256)
|
|
38411
38448
|
refuse3();
|
|
38412
|
-
for (const [name, server] of servers)
|
|
38413
|
-
if (!
|
|
38449
|
+
for (const [name, server] of servers)
|
|
38450
|
+
if (!isCodexLocalStdioMcpServer(name, server))
|
|
38414
38451
|
refuse3();
|
|
38415
|
-
if (server.env_vars !== undefined && server.env_vars !== null) {
|
|
38416
|
-
if (!Array.isArray(server.env_vars) || server.env_vars.length > 256)
|
|
38417
|
-
refuse3();
|
|
38418
|
-
const names = server.env_vars.map((entry) => {
|
|
38419
|
-
if (envName(entry))
|
|
38420
|
-
return entry;
|
|
38421
|
-
if (!object3(entry) || !Object.keys(entry).every((key) => ["name", "source"].includes(key)) || !envName(entry.name) || !optional(entry.source, (v) => v === "local"))
|
|
38422
|
-
refuse3();
|
|
38423
|
-
return entry.name;
|
|
38424
|
-
});
|
|
38425
|
-
if (new Set(names).size !== names.length)
|
|
38426
|
-
refuse3();
|
|
38427
|
-
}
|
|
38428
|
-
if (server.tools !== undefined && server.tools !== null) {
|
|
38429
|
-
if (!object3(server.tools) || Object.keys(server.tools).length > 256)
|
|
38430
|
-
refuse3();
|
|
38431
|
-
for (const [tool, config] of Object.entries(server.tools)) {
|
|
38432
|
-
if (!textField(tool) || !object3(config) || !Object.keys(config).every((key) => ["approval_mode", "output_token_limit"].includes(key)) || !optional(config.approval_mode, approval) || !optional(config.output_token_limit, positiveInteger))
|
|
38433
|
-
refuse3();
|
|
38434
|
-
}
|
|
38435
|
-
}
|
|
38436
|
-
}
|
|
38437
38452
|
return sha2562;
|
|
38438
38453
|
}
|
|
38439
38454
|
function rootControls(root, read) {
|
|
@@ -38803,6 +38818,69 @@ function captureCodexSettings(path, budget = { remaining: 256 * 1024 * 1024 }) {
|
|
|
38803
38818
|
const text = readNativeSettingsWitnessFile(path, budget, "config.toml");
|
|
38804
38819
|
return { path, hashMode: "codex-settings-v1", sha256: hashCodexSettingsReplacement(text) };
|
|
38805
38820
|
}
|
|
38821
|
+
// src/lib/codex-mcp-discovery-projection.ts
|
|
38822
|
+
import { isDeepStrictEqual as isDeepStrictEqual3 } from "util";
|
|
38823
|
+
function record2(value) {
|
|
38824
|
+
return !!value && typeof value === "object" && !Array.isArray(value) && !(value instanceof Date);
|
|
38825
|
+
}
|
|
38826
|
+
function localStdio(name, row) {
|
|
38827
|
+
return name !== "codex_apps" && name !== "_codex_apps" && isCodexLocalStdioMcpServer(name, row);
|
|
38828
|
+
}
|
|
38829
|
+
function stripEmptyParent(config) {
|
|
38830
|
+
if (record2(config.mcp_servers) && !Object.keys(config.mcp_servers).length)
|
|
38831
|
+
delete config.mcp_servers;
|
|
38832
|
+
return config;
|
|
38833
|
+
}
|
|
38834
|
+
function projectRegularCodexMcp(config, source) {
|
|
38835
|
+
const unchanged2 = { config, numericSource: source };
|
|
38836
|
+
if (!record2(config.mcp_servers))
|
|
38837
|
+
return unchanged2;
|
|
38838
|
+
const candidates = Object.entries(config.mcp_servers).filter(([name, row]) => localStdio(name, row)).map(([name]) => name);
|
|
38839
|
+
if (!candidates.length)
|
|
38840
|
+
return unchanged2;
|
|
38841
|
+
const headers = [];
|
|
38842
|
+
let attempts = 0;
|
|
38843
|
+
for (const match of source.matchAll(/^[ \t]*\[{1,2}[^\r\n]*\]{1,2}[ \t]*(?:#[^\r\n]*)?(?:\r?\n|$)/gm)) {
|
|
38844
|
+
if (++attempts > 256)
|
|
38845
|
+
return unchanged2;
|
|
38846
|
+
try {
|
|
38847
|
+
Bun.TOML.parse(source.slice(0, match.index));
|
|
38848
|
+
} catch {
|
|
38849
|
+
continue;
|
|
38850
|
+
}
|
|
38851
|
+
let header;
|
|
38852
|
+
try {
|
|
38853
|
+
header = Bun.TOML.parse(match[0]);
|
|
38854
|
+
} catch {
|
|
38855
|
+
return unchanged2;
|
|
38856
|
+
}
|
|
38857
|
+
const path = [];
|
|
38858
|
+
while (record2(header) && Object.keys(header).length === 1) {
|
|
38859
|
+
const key = Object.keys(header)[0];
|
|
38860
|
+
path.push(key);
|
|
38861
|
+
header = header[key];
|
|
38862
|
+
}
|
|
38863
|
+
headers.push({ start: match.index, path });
|
|
38864
|
+
}
|
|
38865
|
+
const names = candidates.filter((name) => headers.filter((header) => header.path.length === 2 && header.path[0] === "mcp_servers" && header.path[1] === name).length === 1);
|
|
38866
|
+
if (!names.length)
|
|
38867
|
+
return unchanged2;
|
|
38868
|
+
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]));
|
|
38869
|
+
let numericSource = source;
|
|
38870
|
+
for (const range of selected.reverse())
|
|
38871
|
+
numericSource = numericSource.slice(0, range.start) + numericSource.slice(range.end);
|
|
38872
|
+
const expected = structuredClone(config);
|
|
38873
|
+
for (const name of names)
|
|
38874
|
+
delete expected.mcp_servers[name];
|
|
38875
|
+
stripEmptyParent(expected);
|
|
38876
|
+
try {
|
|
38877
|
+
if (!isDeepStrictEqual3(stripEmptyParent(Bun.TOML.parse(numericSource)), expected))
|
|
38878
|
+
return unchanged2;
|
|
38879
|
+
} catch {
|
|
38880
|
+
return unchanged2;
|
|
38881
|
+
}
|
|
38882
|
+
return { config: expected, numericSource };
|
|
38883
|
+
}
|
|
38806
38884
|
|
|
38807
38885
|
// src/lib/codex-settings-witness.ts
|
|
38808
38886
|
import { createHash as createHash7 } from "crypto";
|
|
@@ -38882,7 +38960,7 @@ function canonical3(value, depth = 0, budget = { remaining: 65536 }) {
|
|
|
38882
38960
|
need3(isRecord(value));
|
|
38883
38961
|
return ["object", Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, child]) => [key, canonical3(child, depth + 1, budget)])];
|
|
38884
38962
|
}
|
|
38885
|
-
function normalize2(config) {
|
|
38963
|
+
function normalize2(config, version = 2) {
|
|
38886
38964
|
if (isRecord(config.hooks)) {
|
|
38887
38965
|
delete config.hooks.state;
|
|
38888
38966
|
if (!Object.keys(config.hooks).length)
|
|
@@ -38900,11 +38978,11 @@ function normalize2(config) {
|
|
|
38900
38978
|
if (!Object.keys(skills).length)
|
|
38901
38979
|
delete config.skills;
|
|
38902
38980
|
}
|
|
38903
|
-
inference(config);
|
|
38981
|
+
inference(config, version);
|
|
38904
38982
|
if (isRecord(config.profiles)) {
|
|
38905
38983
|
for (const profile of Object.values(config.profiles))
|
|
38906
38984
|
if (isRecord(profile))
|
|
38907
|
-
inference(profile);
|
|
38985
|
+
inference(profile, version);
|
|
38908
38986
|
}
|
|
38909
38987
|
}
|
|
38910
38988
|
function disablesOneSkill(entry) {
|
|
@@ -38916,18 +38994,25 @@ function disablesOneSkill(entry) {
|
|
|
38916
38994
|
const selector = ["path", "name"].filter((key) => Object.hasOwn(entry, key));
|
|
38917
38995
|
return selector.length === 1 && typeof entry[selector[0]] === "string" && entry[selector[0]].length > 0;
|
|
38918
38996
|
}
|
|
38919
|
-
function inference(target) {
|
|
38920
|
-
|
|
38997
|
+
function inference(target, version) {
|
|
38998
|
+
const keys2 = version === 3 ? [...INFERENCE, "service_tier", "plan_mode_reasoning_effort", "personality"] : INFERENCE;
|
|
38999
|
+
for (const key of keys2)
|
|
38921
39000
|
if (Object.hasOwn(target, key)) {
|
|
38922
39001
|
const value = target[key];
|
|
38923
39002
|
if (key === "model")
|
|
38924
39003
|
need3(typeof value === "string" && MODEL.test(value));
|
|
38925
|
-
else
|
|
39004
|
+
else if (key === "personality")
|
|
39005
|
+
need3(typeof value === "string" && ["none", "friendly", "pragmatic"].includes(value));
|
|
39006
|
+
else if (version === 3 && key !== "model_verbosity") {
|
|
39007
|
+
need3(typeof value === "string" && value.length <= 128 && !/[\x00-\x1f\x7f]/.test(value));
|
|
39008
|
+
if (key !== "service_tier")
|
|
39009
|
+
need3(value.length > 0);
|
|
39010
|
+
} else
|
|
38926
39011
|
need3(typeof value === "string" && (key === "model_reasoning_effort" ? EFFORT2.has(value) : VERBOSITY2.has(value)));
|
|
38927
39012
|
delete target[key];
|
|
38928
39013
|
}
|
|
38929
39014
|
}
|
|
38930
|
-
function settingsDigest2(text) {
|
|
39015
|
+
function settingsDigest2(text, version = 2) {
|
|
38931
39016
|
let config;
|
|
38932
39017
|
try {
|
|
38933
39018
|
config = Bun.TOML.parse(text);
|
|
@@ -38935,8 +39020,9 @@ function settingsDigest2(text) {
|
|
|
38935
39020
|
throw new Error("Invalid Codex settings witness");
|
|
38936
39021
|
}
|
|
38937
39022
|
need3(isRecord(config));
|
|
38938
|
-
|
|
38939
|
-
|
|
39023
|
+
const projected = version === 3 ? projectRegularCodexMcp(config, text) : { config, numericSource: text };
|
|
39024
|
+
normalize2(projected.config, version);
|
|
39025
|
+
return sha2(`hasna.skills.codex-settings.v${version}\x00${JSON.stringify([canonical3(projected.config), numericTokens2(projected.numericSource)])}`);
|
|
38940
39026
|
}
|
|
38941
39027
|
function hashCodexSettingsReplacementV2(text, budget = { remaining: 256 * 1024 * 1024 }) {
|
|
38942
39028
|
need3(Buffer.byteLength(text) <= 1024 * 1024 && budget.remaining >= Buffer.byteLength(text));
|
|
@@ -38960,6 +39046,25 @@ function upgradeCodexSettingsWitness(previous, reviewedSettingsPath) {
|
|
|
38960
39046
|
throw new Error("Codex non-preference settings changed; explicit discovery review required");
|
|
38961
39047
|
return { path: previous.path, hashMode: "codex-settings-v2", sha256: sha2562 };
|
|
38962
39048
|
}
|
|
39049
|
+
function hashCodexSettingsReplacementV3(text, budget = { remaining: 256 * 1024 * 1024 }) {
|
|
39050
|
+
need3(Buffer.byteLength(text) <= 1024 * 1024 && budget.remaining >= Buffer.byteLength(text));
|
|
39051
|
+
budget.remaining -= Buffer.byteLength(text);
|
|
39052
|
+
return settingsDigest2(text, 3);
|
|
39053
|
+
}
|
|
39054
|
+
function captureCodexSettingsV3(path, budget = { remaining: 256 * 1024 * 1024 }) {
|
|
39055
|
+
return { path, hashMode: "codex-settings-v3", sha256: settingsDigest2(readNativeSettingsWitnessFile(path, budget, "config.toml"), 3) };
|
|
39056
|
+
}
|
|
39057
|
+
function upgradeCodexSettingsWitnessV3(previous, reviewedSettingsPath) {
|
|
39058
|
+
need3(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));
|
|
39059
|
+
const budget = { remaining: 2 * 1024 * 1024 };
|
|
39060
|
+
const before = readNativeSettingsWitnessFile(reviewedSettingsPath, budget, "config.toml"), current = readNativeSettingsWitnessFile(previous.path, budget, "config.toml");
|
|
39061
|
+
const original = previous.hashMode === "codex-settings-v2" ? settingsDigest2(before) : previous.hashMode === "codex-settings-v1" ? hashCodexSettingsReplacement(before) : sha2(before);
|
|
39062
|
+
need3(original === previous.sha256);
|
|
39063
|
+
const sha2562 = settingsDigest2(current, 3);
|
|
39064
|
+
if (settingsDigest2(before, 3) !== sha2562)
|
|
39065
|
+
throw new Error("Codex settings outside the reviewed V3 contract changed; explicit discovery review required");
|
|
39066
|
+
return { path: previous.path, hashMode: "codex-settings-v3", sha256: sha2562 };
|
|
39067
|
+
}
|
|
38963
39068
|
|
|
38964
39069
|
// src/lib/native-discovery-roots.ts
|
|
38965
39070
|
var NATIVE_SKILL_ROOTS = [
|
|
@@ -38982,7 +39087,7 @@ var NATIVE_SKILL_ROOTS = [
|
|
|
38982
39087
|
|
|
38983
39088
|
// src/lib/agent-integration.ts
|
|
38984
39089
|
import { createHash as createHash18, randomUUID as randomUUID3 } from "crypto";
|
|
38985
|
-
import { isDeepStrictEqual as
|
|
39090
|
+
import { isDeepStrictEqual as isDeepStrictEqual6 } from "util";
|
|
38986
39091
|
import { existsSync as existsSync6, lstatSync as lstatSync19, statSync as statSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync14, readdirSync as readdirSync8, opendirSync as opendirSync5, readlinkSync as readlinkSync4, realpathSync as realpathSync7, renameSync as renameSync3, rmdirSync as rmdirSync3, writeFileSync as writeFileSync4, unlinkSync as unlinkSync4, chmodSync, openSync as openSync16, closeSync as closeSync16, fsyncSync as fsyncSync4, fstatSync as fstatSync16, readSync as readSync11, constants as constants12, linkSync as linkSync2 } from "fs";
|
|
38987
39092
|
import { dirname as dirname15, join as join22, resolve as resolve15, relative as relative4, isAbsolute as isAbsolute17, sep as sep5 } from "path";
|
|
38988
39093
|
import { homedir as homedir3 } from "os";
|
|
@@ -39005,7 +39110,7 @@ function array(value, maximum) {
|
|
|
39005
39110
|
requireBound(Array.isArray(value) && value.length <= maximum);
|
|
39006
39111
|
return value;
|
|
39007
39112
|
}
|
|
39008
|
-
function
|
|
39113
|
+
function record3(value, maximum) {
|
|
39009
39114
|
requireBound(object3(value) && Object.keys(value).length <= maximum);
|
|
39010
39115
|
return value;
|
|
39011
39116
|
}
|
|
@@ -39015,13 +39120,13 @@ function text(value, maximum = AGENT_POLICY_LIMITS.pathCharacters) {
|
|
|
39015
39120
|
function assertAgentPolicyCollections(policy) {
|
|
39016
39121
|
if (policy.bridge === undefined)
|
|
39017
39122
|
return;
|
|
39018
|
-
const bridge =
|
|
39123
|
+
const bridge = record3(policy.bridge, 64);
|
|
39019
39124
|
if (bridge.agents !== undefined)
|
|
39020
39125
|
for (const agent of array(bridge.agents, AGENT_POLICY_LIMITS.agents))
|
|
39021
39126
|
text(agent, 128);
|
|
39022
39127
|
for (const key of ["commands", "profiles", "supervisors"])
|
|
39023
39128
|
if (bridge[key] !== undefined) {
|
|
39024
|
-
const entries =
|
|
39129
|
+
const entries = record3(bridge[key], AGENT_POLICY_LIMITS.agents);
|
|
39025
39130
|
for (const [agent, value] of Object.entries(entries)) {
|
|
39026
39131
|
text(agent, 128);
|
|
39027
39132
|
if (key === "supervisors") {
|
|
@@ -39074,12 +39179,12 @@ function assertAgentPolicyCollections(policy) {
|
|
|
39074
39179
|
}
|
|
39075
39180
|
if (bridge.discovery === undefined)
|
|
39076
39181
|
return;
|
|
39077
|
-
for (const [agent, value] of Object.entries(
|
|
39182
|
+
for (const [agent, value] of Object.entries(record3(bridge.discovery, AGENT_POLICY_LIMITS.agents))) {
|
|
39078
39183
|
text(agent, 128);
|
|
39079
39184
|
requireBound(object3(value));
|
|
39080
39185
|
text(value.agent, 128);
|
|
39081
39186
|
if (value.codexInstallationInputs !== undefined) {
|
|
39082
|
-
const proof =
|
|
39187
|
+
const proof = record3(value.codexInstallationInputs, 4), inputs = array(proof.plugins, 4096), ids = new Set;
|
|
39083
39188
|
requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && proof.version === "codex-cli 0.160.0" && typeof proof.catalogSha256 === "string" && /^[a-f0-9]{64}$/.test(proof.catalogSha256) && inputs.length > 0 && object3(bridge.codexPluginSkillReview) && bridge.codexPluginSkillReview.version === proof.version && bridge.codexPluginSkillReview.catalogSha256 === proof.catalogSha256);
|
|
39084
39189
|
for (const input of inputs) {
|
|
39085
39190
|
requireBound(object3(input) && Object.keys(input).every((key) => ["pluginId", "namespace", "pluginParent", "sourceRoot", "sourceSha256"].includes(key)));
|
|
@@ -39104,8 +39209,8 @@ function assertAgentPolicyCollections(policy) {
|
|
|
39104
39209
|
text(source.path);
|
|
39105
39210
|
requireBound(source.sha256 === null || typeof source.sha256 === "string" && /^[a-f0-9]{64}$/.test(source.sha256));
|
|
39106
39211
|
if (source.hashMode !== undefined)
|
|
39107
|
-
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));
|
|
39108
|
-
if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2")
|
|
39212
|
+
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));
|
|
39213
|
+
if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3")
|
|
39109
39214
|
requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute6(source.path) && resolve5(source.path) === source.path && basename4(source.path) === "config.toml");
|
|
39110
39215
|
if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3")
|
|
39111
39216
|
requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute6(source.path) && resolve5(source.path) === source.path && basename4(source.path) === "settings.json");
|
|
@@ -39265,7 +39370,7 @@ function isOwnedCliBridge(path, expectedPaths) {
|
|
|
39265
39370
|
import { createHash as createHash17 } from "crypto";
|
|
39266
39371
|
import { lstatSync as lstatSync18, readFileSync as readFileSync13, readdirSync as readdirSync7, realpathSync as realpathSync6 } from "fs";
|
|
39267
39372
|
import { basename as basename7, dirname as dirname14, isAbsolute as isAbsolute16, join as join21, resolve as resolve14, sep as sep4 } from "path";
|
|
39268
|
-
import { isDeepStrictEqual as
|
|
39373
|
+
import { isDeepStrictEqual as isDeepStrictEqual4 } from "util";
|
|
39269
39374
|
|
|
39270
39375
|
// node_modules/yaml/dist/index.js
|
|
39271
39376
|
var composer = require_composer();
|
|
@@ -39683,7 +39788,7 @@ function trace(path) {
|
|
|
39683
39788
|
canonical4(path);
|
|
39684
39789
|
const rows = [], paths = [];
|
|
39685
39790
|
let metadataBytes = 0, steps = 0, links = 0, cursor = parse3(path).root, pending = path.slice(cursor.length).split(sep3);
|
|
39686
|
-
function
|
|
39791
|
+
function record4(path2, row) {
|
|
39687
39792
|
const value = { path: path2, ...row };
|
|
39688
39793
|
metadataBytes += Buffer.byteLength(JSON.stringify(value));
|
|
39689
39794
|
if (metadataBytes > AGENT_POLICY_LIMITS.discoveryPathSourceMetadataBytes)
|
|
@@ -39695,7 +39800,7 @@ function trace(path) {
|
|
|
39695
39800
|
const stat = lstatSync12(cursor, { bigint: true });
|
|
39696
39801
|
if (!stat.isDirectory())
|
|
39697
39802
|
throw new Error("Unsupported discovery path root");
|
|
39698
|
-
|
|
39803
|
+
record4(cursor, { type: "directory", ...identity3(stat) });
|
|
39699
39804
|
}
|
|
39700
39805
|
root();
|
|
39701
39806
|
while (pending.length) {
|
|
@@ -39713,7 +39818,7 @@ function trace(path) {
|
|
|
39713
39818
|
throw new Error("Discovery resolved path length limit exceeded");
|
|
39714
39819
|
const stat = lstatSync12(candidate, { bigint: true, throwIfNoEntry: false });
|
|
39715
39820
|
if (!stat) {
|
|
39716
|
-
|
|
39821
|
+
record4(candidate, { type: "missing", remaining: pending });
|
|
39717
39822
|
return { rows, paths, file: null, missing: candidate, metadataBytes };
|
|
39718
39823
|
}
|
|
39719
39824
|
if (stat.isSymbolicLink()) {
|
|
@@ -39724,7 +39829,7 @@ function trace(path) {
|
|
|
39724
39829
|
throw new Error("Unsupported non-UTF8 discovery link target");
|
|
39725
39830
|
if (!target || target.includes("\x00") || Buffer.byteLength(target) > AGENT_POLICY_LIMITS.pathCharacters || !after.isSymbolicLink() || JSON.stringify(identity3(stat, true)) !== JSON.stringify(identity3(after, true)))
|
|
39726
39831
|
throw new Error("Discovery link changed during read");
|
|
39727
|
-
|
|
39832
|
+
record4(candidate, { type: "link", target, ...identity3(stat, true) });
|
|
39728
39833
|
if (isAbsolute10(target)) {
|
|
39729
39834
|
cursor = parse3(target).root;
|
|
39730
39835
|
root();
|
|
@@ -39736,7 +39841,7 @@ function trace(path) {
|
|
|
39736
39841
|
continue;
|
|
39737
39842
|
}
|
|
39738
39843
|
if (stat.isDirectory()) {
|
|
39739
|
-
|
|
39844
|
+
record4(candidate, { type: "directory", ...identity3(stat) });
|
|
39740
39845
|
cursor = candidate;
|
|
39741
39846
|
continue;
|
|
39742
39847
|
}
|
|
@@ -39744,7 +39849,7 @@ function trace(path) {
|
|
|
39744
39849
|
throw new Error("Unsupported discovery path input");
|
|
39745
39850
|
if (stat.size > BigInt(AGENT_POLICY_LIMITS.discoveryRawSourceBytes))
|
|
39746
39851
|
throw new Error("Unsupported or oversized raw discovery input");
|
|
39747
|
-
|
|
39852
|
+
record4(candidate, { type: "file", ...identity3(stat, true) });
|
|
39748
39853
|
return { rows, paths, file: candidate, missing: null, metadataBytes };
|
|
39749
39854
|
}
|
|
39750
39855
|
throw new Error("Unsupported directory discovery path input");
|
|
@@ -41615,19 +41720,19 @@ function projectNativeDiscoveryFields(text2, format, fields2, path) {
|
|
|
41615
41720
|
return digest2(JSON.stringify(Object.fromEntries(fields2.map((field2) => [field2, object5[field2] ?? null]))));
|
|
41616
41721
|
}
|
|
41617
41722
|
function isSupersededCodexProjection(agent, configPath, source) {
|
|
41618
|
-
return agent === "codex" && source.path === configPath && source.format === "toml" &&
|
|
41723
|
+
return agent === "codex" && source.path === configPath && source.format === "toml" && isDeepStrictEqual4(source.fields, [...CODEX_DISCOVERY_PROJECTION_FIELDS]);
|
|
41619
41724
|
}
|
|
41620
41725
|
function supersedesCodexProjection(sources, configPath) {
|
|
41621
|
-
return sources.some((source) => source.path === configPath && source.hashMode === "codex-settings-v2");
|
|
41726
|
+
return sources.some((source) => source.path === configPath && (source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3"));
|
|
41622
41727
|
}
|
|
41623
41728
|
function projected(source, changes, budget = discoveryByteBudget()) {
|
|
41624
|
-
if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2") {
|
|
41729
|
+
if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3") {
|
|
41625
41730
|
if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
|
|
41626
41731
|
throw new Error("Codex settings witnesses require exact typed metadata");
|
|
41627
|
-
const current = (source.hashMode === "codex-settings-v2" ? captureCodexSettingsV2 : captureCodexSettings)(source.path, budget).sha256;
|
|
41732
|
+
const current = (source.hashMode === "codex-settings-v3" ? captureCodexSettingsV3 : source.hashMode === "codex-settings-v2" ? captureCodexSettingsV2 : captureCodexSettings)(source.path, budget).sha256;
|
|
41628
41733
|
if (current !== source.sha256)
|
|
41629
41734
|
throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
|
|
41630
|
-
return changes?.has(source.path) ? (source.hashMode === "codex-settings-v2" ? hashCodexSettingsReplacementV2 : hashCodexSettingsReplacement)(changes.get(source.path), budget) : current;
|
|
41735
|
+
return changes?.has(source.path) ? (source.hashMode === "codex-settings-v3" ? hashCodexSettingsReplacementV3 : source.hashMode === "codex-settings-v2" ? hashCodexSettingsReplacementV2 : hashCodexSettingsReplacement)(changes.get(source.path), budget) : current;
|
|
41631
41736
|
}
|
|
41632
41737
|
if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") {
|
|
41633
41738
|
if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
|
|
@@ -41727,7 +41832,7 @@ function codexInstallationRoots(binding) {
|
|
|
41727
41832
|
});
|
|
41728
41833
|
}
|
|
41729
41834
|
function assertMarketplaceBinding(binding, source) {
|
|
41730
|
-
if ((source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2") && (binding.agent !== "codex" || binding.method !== "reviewed" || basename7(source.path) !== "config.toml"))
|
|
41835
|
+
if ((source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3") && (binding.agent !== "codex" || binding.method !== "reviewed" || basename7(source.path) !== "config.toml"))
|
|
41731
41836
|
throw new Error("Codex settings witnesses require explicit reviewed Codex configuration");
|
|
41732
41837
|
if ((source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") && (binding.agent !== "claude" || binding.method !== "reviewed" || basename7(source.path) !== "settings.json"))
|
|
41733
41838
|
throw new Error("Claude settings witnesses require explicit reviewed Claude configuration");
|
|
@@ -41877,10 +41982,10 @@ function resolveAgentDiscovery(options) {
|
|
|
41877
41982
|
verifyAgentDiscovery(retained);
|
|
41878
41983
|
if (!retained.sources.some((source) => source.path === canonical6(configPath) && source.format === undefined && source.fields === undefined))
|
|
41879
41984
|
unresolved("retained review is missing the full agent configuration source");
|
|
41880
|
-
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)))
|
|
41985
|
+
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)))
|
|
41881
41986
|
unresolved("retained settings witness names another configuration source");
|
|
41882
41987
|
const covered = supersedesCodexProjection(retained.sources, canonical6(configPath)) ? sources.filter((source) => !isSupersededCodexProjection(agent, canonical6(configPath), source)) : sources;
|
|
41883
|
-
if (covered.some((source) => !retained.sources.some((saved) =>
|
|
41988
|
+
if (covered.some((source) => !retained.sources.some((saved) => isDeepStrictEqual4(saved, source))) || [...roots].some((root2) => !retained.roots.includes(root2)) || agent === "gemini" && JSON.stringify(retained.builtinNames) !== JSON.stringify(builtinNames))
|
|
41884
41989
|
unresolved("retained review is missing current runtime discovery coverage");
|
|
41885
41990
|
return retained;
|
|
41886
41991
|
}
|
|
@@ -41894,7 +41999,7 @@ function resolveAgentDiscovery(options) {
|
|
|
41894
41999
|
if (review.sources.some((source) => source.format !== undefined || source.fields !== undefined))
|
|
41895
42000
|
throw new Error("Explicit discovery reviews require full source-file hashes");
|
|
41896
42001
|
verifyAgentDiscovery(supplied);
|
|
41897
|
-
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)))
|
|
42002
|
+
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)))
|
|
41898
42003
|
throw new Error("Semantic settings witnesses must name the configured Claude configuration source");
|
|
41899
42004
|
if (!review.sources.some((source) => source.path === canonical6(configPath)))
|
|
41900
42005
|
throw new Error("Discovery review must include the agent configuration source");
|
|
@@ -42078,7 +42183,7 @@ export default async ({ directory }) => {
|
|
|
42078
42183
|
}
|
|
42079
42184
|
|
|
42080
42185
|
// src/lib/agent-codex.ts
|
|
42081
|
-
import { isDeepStrictEqual as
|
|
42186
|
+
import { isDeepStrictEqual as isDeepStrictEqual5 } from "util";
|
|
42082
42187
|
var CODEX_SKILL_CONFIG_SECTIONS = /^\[\[skills\.config\]\][^\n]*(?:\n(?!\s*\[)[^\n]*)*/gm;
|
|
42083
42188
|
var codexPathConfigRefusal = () => new Error("Codex skill path controls require ordinary [[skills.config]] TOML tables or a native single-line inline array; preserve and review unsupported inline, dotted, or malformed definitions before running skills hook install");
|
|
42084
42189
|
function splitTopLevel(value, delimiter) {
|
|
@@ -42209,7 +42314,7 @@ function normalizeCodexInlinePathConfig(text2) {
|
|
|
42209
42314
|
const expectedWithoutConfig = structuredClone(before);
|
|
42210
42315
|
delete expectedWithoutConfig.skills.config;
|
|
42211
42316
|
try {
|
|
42212
|
-
if (
|
|
42317
|
+
if (isDeepStrictEqual5(Bun.TOML.parse(text2.replace(CODEX_SKILL_CONFIG_SECTIONS, "")), expectedWithoutConfig))
|
|
42213
42318
|
return text2;
|
|
42214
42319
|
} catch {}
|
|
42215
42320
|
const matches = [];
|
|
@@ -42262,7 +42367,7 @@ function normalizeCodexInlinePathConfig(text2) {
|
|
|
42262
42367
|
try {
|
|
42263
42368
|
const after = Bun.TOML.parse(candidate2);
|
|
42264
42369
|
const expected = structuredClone(before);
|
|
42265
|
-
if (
|
|
42370
|
+
if (isDeepStrictEqual5(after, expected))
|
|
42266
42371
|
matches.push(candidate2);
|
|
42267
42372
|
} catch {}
|
|
42268
42373
|
}
|
|
@@ -42278,11 +42383,11 @@ function assertCodexPathConfigEditable(text2) {
|
|
|
42278
42383
|
delete expected.skills.config;
|
|
42279
42384
|
try {
|
|
42280
42385
|
const withoutSections = Bun.TOML.parse(text2.replace(CODEX_SKILL_CONFIG_SECTIONS, ""));
|
|
42281
|
-
if (
|
|
42386
|
+
if (isDeepStrictEqual5(withoutSections, expected))
|
|
42282
42387
|
return;
|
|
42283
42388
|
const normalized = normalizeCodexInlinePathConfig(text2);
|
|
42284
42389
|
const withoutNormalizedSections = Bun.TOML.parse(normalized.replace(CODEX_SKILL_CONFIG_SECTIONS, ""));
|
|
42285
|
-
if (
|
|
42390
|
+
if (isDeepStrictEqual5(withoutNormalizedSections, expected))
|
|
42286
42391
|
return;
|
|
42287
42392
|
} catch {}
|
|
42288
42393
|
throw codexPathConfigRefusal();
|
|
@@ -42320,7 +42425,7 @@ function disableCodexBundledSkills(text2) {
|
|
|
42320
42425
|
const candidates = new Set;
|
|
42321
42426
|
const consider = (candidate2) => {
|
|
42322
42427
|
try {
|
|
42323
|
-
if (
|
|
42428
|
+
if (isDeepStrictEqual5(Bun.TOML.parse(candidate2), expected))
|
|
42324
42429
|
candidates.add(candidate2);
|
|
42325
42430
|
} catch {}
|
|
42326
42431
|
};
|
|
@@ -43131,6 +43236,8 @@ function atomicWrite2(path, content) {
|
|
|
43131
43236
|
}
|
|
43132
43237
|
}
|
|
43133
43238
|
function planAgentSettingsWitnessUpgrade(options) {
|
|
43239
|
+
if (options.targetCodexVersion !== undefined && (options.agent !== "codex" || ![2, 3].includes(options.targetCodexVersion)))
|
|
43240
|
+
throw new Error("Invalid Codex witness target version");
|
|
43134
43241
|
const home = resolve15(options.home ?? homedir3()), dataDir2 = options.dataDir ?? getDataDirReadOnly();
|
|
43135
43242
|
const snapshot2 = readManagedSkillPolicySnapshot(dataDir2);
|
|
43136
43243
|
if (!snapshot2 || sha4(snapshot2.text) !== options.expectedPolicySha256)
|
|
@@ -43152,21 +43259,21 @@ function planAgentSettingsWitnessUpgrade(options) {
|
|
|
43152
43259
|
throw new Error("Settings witness upgrade requires a preserved settings preimage");
|
|
43153
43260
|
const replaced = [previous];
|
|
43154
43261
|
if (options.agent === "codex") {
|
|
43155
|
-
if (previous.hashMode !== undefined && previous.hashMode !== "bytes" && previous.hashMode !== "codex-settings-v1")
|
|
43156
|
-
throw new Error("Codex settings witness upgrade requires
|
|
43262
|
+
if (previous.hashMode !== undefined && previous.hashMode !== "bytes" && previous.hashMode !== "codex-settings-v1" && !(options.targetCodexVersion === 3 && previous.hashMode === "codex-settings-v2"))
|
|
43263
|
+
throw new Error("Codex settings witness upgrade requires an eligible preserved configuration witness");
|
|
43157
43264
|
const preimage = readCodexSettingsPreimage(options.reviewedPreimage);
|
|
43158
43265
|
for (const source of binding.sources) {
|
|
43159
43266
|
if (source === previous || source.path !== configPath)
|
|
43160
43267
|
continue;
|
|
43161
43268
|
const fields2 = source.fields;
|
|
43162
|
-
if (source.hashMode !== undefined || source.format !== "toml" || !Array.isArray(fields2) || !
|
|
43269
|
+
if (source.hashMode !== undefined || source.format !== "toml" || !Array.isArray(fields2) || !isDeepStrictEqual6(fields2, [...CODEX_DISCOVERY_PROJECTION_FIELDS]) || typeof source.sha256 !== "string")
|
|
43163
43270
|
throw new Error("Codex settings witness upgrade found an unrecognized configuration witness");
|
|
43164
43271
|
if (projectNativeDiscoveryFields(preimage, "toml", fields2, configPath) !== source.sha256)
|
|
43165
43272
|
throw new Error("Reviewed preimage does not explain the Codex discovery projection witness");
|
|
43166
43273
|
replaced.push(source);
|
|
43167
43274
|
}
|
|
43168
43275
|
}
|
|
43169
|
-
const next = options.agent === "claude" ? upgradeClaudeSettingsWitness(previous, options.reviewedPreimage) : upgradeCodexSettingsWitness(previous, options.reviewedPreimage);
|
|
43276
|
+
const next = options.agent === "claude" ? upgradeClaudeSettingsWitness(previous, options.reviewedPreimage) : options.targetCodexVersion === 3 ? upgradeCodexSettingsWitnessV3(previous, options.reviewedPreimage) : upgradeCodexSettingsWitness(previous, options.reviewedPreimage);
|
|
43170
43277
|
const rebound = [];
|
|
43171
43278
|
for (const source of binding.sources) {
|
|
43172
43279
|
if (!replaced.includes(source)) {
|
|
@@ -43203,7 +43310,7 @@ function applyAgentIntegration(plan) {
|
|
|
43203
43310
|
const upgrade = plan.settingsWitnessUpgrade;
|
|
43204
43311
|
if (!plan.managedAgentChecks || !plan.observedPolicy?.before)
|
|
43205
43312
|
throw new Error("Invalid settings witness upgrade plan");
|
|
43206
|
-
const verified = planAgentSettingsWitnessUpgrade({ agent: upgrade.agent, reviewedPreimage: upgrade.reviewedPreimage, home: plan.managedAgentChecks.home, dataDir: plan.dataDir, expectedPolicySha256: sha4(plan.observedPolicy.before), expectedSettingsSha256: upgrade.currentSettingsSha256 });
|
|
43313
|
+
const verified = planAgentSettingsWitnessUpgrade({ agent: upgrade.agent, ...upgrade.agent === "codex" ? { targetCodexVersion: upgrade.toHashMode === "codex-settings-v3" ? 3 : 2 } : {}, reviewedPreimage: upgrade.reviewedPreimage, home: plan.managedAgentChecks.home, dataDir: plan.dataDir, expectedPolicySha256: sha4(plan.observedPolicy.before), expectedSettingsSha256: upgrade.currentSettingsSha256 });
|
|
43207
43314
|
if (JSON.stringify(verified.changes) !== JSON.stringify(plan.changes) || JSON.stringify(verified.settingsWitnessUpgrade) !== JSON.stringify(upgrade))
|
|
43208
43315
|
throw new Error("Settings witness upgrade plan changed");
|
|
43209
43316
|
provenDiscovery = verified.discoveryBefore[0];
|
|
@@ -43624,22 +43731,22 @@ function canonicalizeManifest(raw) {
|
|
|
43624
43731
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
43625
43732
|
return normalizeLineEndings(raw);
|
|
43626
43733
|
}
|
|
43627
|
-
const
|
|
43628
|
-
delete
|
|
43629
|
-
if (
|
|
43630
|
-
delete
|
|
43734
|
+
const record4 = parsed;
|
|
43735
|
+
delete record4.content_hash;
|
|
43736
|
+
if (record4.provenance && typeof record4.provenance === "object" && !Array.isArray(record4.provenance)) {
|
|
43737
|
+
delete record4.provenance.content_hash;
|
|
43631
43738
|
}
|
|
43632
|
-
return `${JSON.stringify(sortObjectKeys(
|
|
43739
|
+
return `${JSON.stringify(sortObjectKeys(record4), null, 2)}
|
|
43633
43740
|
`;
|
|
43634
43741
|
}
|
|
43635
43742
|
function sortObjectKeys(value) {
|
|
43636
43743
|
if (Array.isArray(value))
|
|
43637
43744
|
return value.map((item) => sortObjectKeys(item));
|
|
43638
43745
|
if (typeof value === "object" && value !== null) {
|
|
43639
|
-
const
|
|
43746
|
+
const record4 = value;
|
|
43640
43747
|
const sorted = Object.create(null);
|
|
43641
|
-
for (const key of Object.keys(
|
|
43642
|
-
sorted[key] = sortObjectKeys(
|
|
43748
|
+
for (const key of Object.keys(record4).sort())
|
|
43749
|
+
sorted[key] = sortObjectKeys(record4[key]);
|
|
43643
43750
|
return sorted;
|
|
43644
43751
|
}
|
|
43645
43752
|
return value;
|
|
@@ -43778,10 +43885,10 @@ function contentRecord(value, allowed) {
|
|
|
43778
43885
|
return result;
|
|
43779
43886
|
}
|
|
43780
43887
|
function contentOptions(options) {
|
|
43781
|
-
const
|
|
43888
|
+
const record4 = contentRecord(options, ["limits", "signal"]);
|
|
43782
43889
|
const limits = { ...CONTENT_HASH_LIMITS };
|
|
43783
|
-
if (
|
|
43784
|
-
const supplied = contentRecord(
|
|
43890
|
+
if (record4.limits !== undefined) {
|
|
43891
|
+
const supplied = contentRecord(record4.limits, Object.keys(limits));
|
|
43785
43892
|
for (const key of Object.keys(supplied)) {
|
|
43786
43893
|
const value = supplied[key];
|
|
43787
43894
|
if (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0 || value > limits[key])
|
|
@@ -43789,9 +43896,9 @@ function contentOptions(options) {
|
|
|
43789
43896
|
limits[key] = value;
|
|
43790
43897
|
}
|
|
43791
43898
|
}
|
|
43792
|
-
if (
|
|
43899
|
+
if (record4.signal !== undefined && !(record4.signal instanceof AbortSignal))
|
|
43793
43900
|
invalidContent("Invalid content hash signal");
|
|
43794
|
-
return { limits, signal:
|
|
43901
|
+
return { limits, signal: record4.signal };
|
|
43795
43902
|
}
|
|
43796
43903
|
var typedArrayPrototype = Object.getPrototypeOf(Uint8Array.prototype);
|
|
43797
43904
|
var byteLengthOf = Object.getOwnPropertyDescriptor(typedArrayPrototype, "byteLength").get;
|
|
@@ -46996,44 +47103,44 @@ async function subprocess(command, cwd, env, input, timeoutMs) {
|
|
|
46996
47103
|
// src/lib/remote-run-contract.ts
|
|
46997
47104
|
var REMOTE_SKILL_RUN_CONTRACT_VERSION = 1;
|
|
46998
47105
|
function normalizeRemoteSkillRunContract(payload, fallbackSkill) {
|
|
46999
|
-
const
|
|
47106
|
+
const record4 = isRecord4(payload) ? payload : {};
|
|
47000
47107
|
return {
|
|
47001
47108
|
contractVersion: REMOTE_SKILL_RUN_CONTRACT_VERSION,
|
|
47002
|
-
...pickString(
|
|
47003
|
-
skill: pickStringValue(
|
|
47004
|
-
...pickString(
|
|
47005
|
-
...pickString(
|
|
47006
|
-
...pickNumber(
|
|
47007
|
-
...pickString(
|
|
47008
|
-
...pickString(
|
|
47009
|
-
...pickString(
|
|
47010
|
-
...pickString(
|
|
47011
|
-
...pickNumber(
|
|
47012
|
-
...pickString(
|
|
47013
|
-
...hasOwn(
|
|
47014
|
-
...pickString(
|
|
47015
|
-
...pickString(
|
|
47016
|
-
...pickString(
|
|
47017
|
-
...pickString(
|
|
47018
|
-
...hasOwn(
|
|
47109
|
+
...pickString(record4, "id"),
|
|
47110
|
+
skill: pickStringValue(record4, "skill") ?? fallbackSkill,
|
|
47111
|
+
...pickString(record4, "requestedSlug"),
|
|
47112
|
+
...pickString(record4, "status"),
|
|
47113
|
+
...pickNumber(record4, "exitCode"),
|
|
47114
|
+
...pickString(record4, "correlationId"),
|
|
47115
|
+
...pickString(record4, "createdAt"),
|
|
47116
|
+
...pickString(record4, "startedAt"),
|
|
47117
|
+
...pickString(record4, "completedAt"),
|
|
47118
|
+
...pickNumber(record4, "durationMs"),
|
|
47119
|
+
...pickString(record4, "outputType"),
|
|
47120
|
+
...hasOwn(record4, "outputPreview") ? { outputPreview: record4.outputPreview } : {},
|
|
47121
|
+
...pickString(record4, "errorCode"),
|
|
47122
|
+
...pickString(record4, "errorMessage"),
|
|
47123
|
+
...pickString(record4, "error"),
|
|
47124
|
+
...pickString(record4, "code"),
|
|
47125
|
+
...hasOwn(record4, "details") ? { details: record4.details } : {}
|
|
47019
47126
|
};
|
|
47020
47127
|
}
|
|
47021
47128
|
function isRecord4(value) {
|
|
47022
47129
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
47023
47130
|
}
|
|
47024
|
-
function hasOwn(
|
|
47025
|
-
return Object.prototype.hasOwnProperty.call(
|
|
47131
|
+
function hasOwn(record4, key) {
|
|
47132
|
+
return Object.prototype.hasOwnProperty.call(record4, key);
|
|
47026
47133
|
}
|
|
47027
|
-
function pickString(
|
|
47028
|
-
const value = pickStringValue(
|
|
47134
|
+
function pickString(record4, key) {
|
|
47135
|
+
const value = pickStringValue(record4, key);
|
|
47029
47136
|
return value === undefined ? {} : { [key]: value };
|
|
47030
47137
|
}
|
|
47031
|
-
function pickStringValue(
|
|
47032
|
-
const value =
|
|
47138
|
+
function pickStringValue(record4, key) {
|
|
47139
|
+
const value = record4[key];
|
|
47033
47140
|
return typeof value === "string" ? value : undefined;
|
|
47034
47141
|
}
|
|
47035
|
-
function pickNumber(
|
|
47036
|
-
const value =
|
|
47142
|
+
function pickNumber(record4, key) {
|
|
47143
|
+
const value = record4[key];
|
|
47037
47144
|
return typeof value === "number" && Number.isFinite(value) ? { [key]: value } : {};
|
|
47038
47145
|
}
|
|
47039
47146
|
|
|
@@ -57653,8 +57760,8 @@ function revisionIdOf(content) {
|
|
|
57653
57760
|
const canonical6 = JSON.stringify(canonicalContent);
|
|
57654
57761
|
return createHash24("sha256").update(canonical6).digest("hex");
|
|
57655
57762
|
}
|
|
57656
|
-
function revisionIdOfRecord(
|
|
57657
|
-
return revisionIdOf(
|
|
57763
|
+
function revisionIdOfRecord(record4) {
|
|
57764
|
+
return revisionIdOf(record4);
|
|
57658
57765
|
}
|
|
57659
57766
|
|
|
57660
57767
|
// src/server/sqlite-store.ts
|
|
@@ -57696,11 +57803,11 @@ class SqliteSkillsStore {
|
|
|
57696
57803
|
backfillLegacyRevisions() {
|
|
57697
57804
|
const rows = this.all("SELECT * FROM skills_registry WHERE revision_id = ''", []);
|
|
57698
57805
|
for (const row of rows) {
|
|
57699
|
-
const
|
|
57806
|
+
const record4 = rowToSkill(row);
|
|
57700
57807
|
this.db.run("UPDATE skills_registry SET revision_id = ? WHERE org_id = ? AND slug = ?", [
|
|
57701
|
-
revisionIdOfRecord(
|
|
57702
|
-
|
|
57703
|
-
|
|
57808
|
+
revisionIdOfRecord(record4),
|
|
57809
|
+
record4.orgId,
|
|
57810
|
+
record4.slug
|
|
57704
57811
|
]);
|
|
57705
57812
|
}
|
|
57706
57813
|
}
|
|
@@ -58250,12 +58357,12 @@ class SqliteSkillsStore {
|
|
|
58250
58357
|
const expired = this.all("SELECT * FROM skills_registry WHERE org_id = ? AND tombstoned_at IS NOT NULL AND tombstone_purge_after <= ?", [principal.orgId, now]);
|
|
58251
58358
|
const purged = [];
|
|
58252
58359
|
for (const row of expired) {
|
|
58253
|
-
const
|
|
58254
|
-
this.db.run("DELETE FROM skills_registry WHERE org_id = ? AND slug = ?", [principal.orgId,
|
|
58255
|
-
this.db.run("DELETE FROM skills_tags WHERE org_id = ? AND slug = ?", [principal.orgId,
|
|
58256
|
-
if (
|
|
58257
|
-
this.collectOrphanBundle(principal.orgId,
|
|
58258
|
-
purged.push(
|
|
58360
|
+
const record4 = rowToSkill(row);
|
|
58361
|
+
this.db.run("DELETE FROM skills_registry WHERE org_id = ? AND slug = ?", [principal.orgId, record4.slug]);
|
|
58362
|
+
this.db.run("DELETE FROM skills_tags WHERE org_id = ? AND slug = ?", [principal.orgId, record4.slug]);
|
|
58363
|
+
if (record4.bundleSha256)
|
|
58364
|
+
this.collectOrphanBundle(principal.orgId, record4.bundleSha256);
|
|
58365
|
+
purged.push(record4);
|
|
58259
58366
|
}
|
|
58260
58367
|
return purged;
|
|
58261
58368
|
})();
|
|
@@ -58772,35 +58879,35 @@ function skillLifecyclePatch(body) {
|
|
|
58772
58879
|
throw new SkillRequestError(400, "INVALID_LIFECYCLE", "replacementSlug must be a valid skill slug");
|
|
58773
58880
|
return { lifecycle: body.lifecycle, ...body.reason ? { reason: body.reason } : {}, ...body.replacementSlug ? { replacementSlug: body.replacementSlug } : {} };
|
|
58774
58881
|
}
|
|
58775
|
-
function publishedSkillMeta(
|
|
58882
|
+
function publishedSkillMeta(record4) {
|
|
58776
58883
|
return {
|
|
58777
|
-
name:
|
|
58778
|
-
displayName:
|
|
58779
|
-
description:
|
|
58780
|
-
category:
|
|
58781
|
-
tags:
|
|
58782
|
-
...
|
|
58783
|
-
kind:
|
|
58884
|
+
name: record4.slug,
|
|
58885
|
+
displayName: record4.displayName,
|
|
58886
|
+
description: record4.description,
|
|
58887
|
+
category: record4.category,
|
|
58888
|
+
tags: record4.tags,
|
|
58889
|
+
...record4.version ? { version: record4.version } : {},
|
|
58890
|
+
kind: record4.kind,
|
|
58784
58891
|
source: "remote",
|
|
58785
58892
|
availability: { status: "available" }
|
|
58786
58893
|
};
|
|
58787
58894
|
}
|
|
58788
|
-
function publishedPayload(
|
|
58895
|
+
function publishedPayload(record4, opts = {}) {
|
|
58789
58896
|
return {
|
|
58790
|
-
...publishedSkillMeta(
|
|
58791
|
-
slug:
|
|
58792
|
-
publishedSource:
|
|
58897
|
+
...publishedSkillMeta(record4),
|
|
58898
|
+
slug: record4.slug,
|
|
58899
|
+
publishedSource: record4.source,
|
|
58793
58900
|
...opts.alreadyPublished ? { alreadyPublished: true } : {},
|
|
58794
|
-
...
|
|
58795
|
-
...
|
|
58796
|
-
publishedAt:
|
|
58797
|
-
updatedAt:
|
|
58798
|
-
revisionId:
|
|
58799
|
-
revisionNumber:
|
|
58800
|
-
lifecycle:
|
|
58801
|
-
...
|
|
58802
|
-
...
|
|
58803
|
-
...
|
|
58901
|
+
...record4.skillMd ? { skillMd: record4.skillMd } : {},
|
|
58902
|
+
...record4.bundleSha256 ? { bundleSha256: record4.bundleSha256, bundleByteSize: record4.bundleByteSize } : {},
|
|
58903
|
+
publishedAt: record4.createdAt,
|
|
58904
|
+
updatedAt: record4.updatedAt,
|
|
58905
|
+
revisionId: record4.revisionId,
|
|
58906
|
+
revisionNumber: record4.revisionNumber,
|
|
58907
|
+
lifecycle: record4.lifecycle,
|
|
58908
|
+
...record4.archivedAt ? { archivedAt: record4.archivedAt } : {},
|
|
58909
|
+
...record4.archiveReason ? { archiveReason: record4.archiveReason } : {},
|
|
58910
|
+
...record4.replacementSlug ? { replacementSlug: record4.replacementSlug } : {}
|
|
58804
58911
|
};
|
|
58805
58912
|
}
|
|
58806
58913
|
function revisionEtag(revisionId) {
|
|
@@ -58819,10 +58926,10 @@ function parseIfMatch(value) {
|
|
|
58819
58926
|
}
|
|
58820
58927
|
return unquoted;
|
|
58821
58928
|
}
|
|
58822
|
-
async function tombstoneStatus(store, artifactStorage, principal,
|
|
58823
|
-
if (!
|
|
58929
|
+
async function tombstoneStatus(store, artifactStorage, principal, record4) {
|
|
58930
|
+
if (!record4.tombstonedAt)
|
|
58824
58931
|
return "live";
|
|
58825
|
-
if (
|
|
58932
|
+
if (record4.tombstonePurgeAfter && record4.tombstonePurgeAfter <= new Date().toISOString()) {
|
|
58826
58933
|
const purged = await store.purgeExpiredTombstones(principal);
|
|
58827
58934
|
for (const removed of purged) {
|
|
58828
58935
|
if (removed.bundleSha256)
|
|
@@ -58831,33 +58938,33 @@ async function tombstoneStatus(store, artifactStorage, principal, record3) {
|
|
|
58831
58938
|
return "purged";
|
|
58832
58939
|
}
|
|
58833
58940
|
return {
|
|
58834
|
-
slug:
|
|
58941
|
+
slug: record4.slug,
|
|
58835
58942
|
deleted: true,
|
|
58836
58943
|
code: "TOMBSTONED",
|
|
58837
|
-
tombstonedAt:
|
|
58838
|
-
tombstonePurgeAfter:
|
|
58839
|
-
revisionId:
|
|
58944
|
+
tombstonedAt: record4.tombstonedAt,
|
|
58945
|
+
tombstonePurgeAfter: record4.tombstonePurgeAfter,
|
|
58946
|
+
revisionId: record4.revisionId
|
|
58840
58947
|
};
|
|
58841
58948
|
}
|
|
58842
58949
|
async function listMergedSkills(store, principal) {
|
|
58843
|
-
return (await store.listSkills(principal)).filter((
|
|
58950
|
+
return (await store.listSkills(principal)).filter((record4) => record4.lifecycle === "active").sort((a3, b3) => a3.slug.localeCompare(b3.slug)).map((record4) => publishedPayload(record4));
|
|
58844
58951
|
}
|
|
58845
58952
|
async function resolvePublishedSkill(store, artifactStorage, principal, slug) {
|
|
58846
|
-
const
|
|
58847
|
-
if (!
|
|
58953
|
+
const record4 = await store.getSkill(principal, slug);
|
|
58954
|
+
if (!record4)
|
|
58848
58955
|
return { kind: "absent" };
|
|
58849
|
-
const status = await tombstoneStatus(store, artifactStorage, principal,
|
|
58956
|
+
const status = await tombstoneStatus(store, artifactStorage, principal, record4);
|
|
58850
58957
|
if (status === "purged")
|
|
58851
58958
|
return { kind: "absent" };
|
|
58852
58959
|
if (status !== "live")
|
|
58853
58960
|
return { kind: "tombstone", payload: status };
|
|
58854
|
-
return { kind: "published", record:
|
|
58961
|
+
return { kind: "published", record: record4 };
|
|
58855
58962
|
}
|
|
58856
58963
|
async function listOrgTags(store, principal) {
|
|
58857
58964
|
return [...new Set((await store.listTags(principal)).filter((tag) => tag.trim()))].sort();
|
|
58858
58965
|
}
|
|
58859
58966
|
async function listMergedSkillsByTag(store, principal, tag) {
|
|
58860
|
-
return (await store.listSkillsByTag(principal, tag)).filter((
|
|
58967
|
+
return (await store.listSkillsByTag(principal, tag)).filter((record4) => record4.lifecycle === "active").sort((a3, b3) => a3.slug.localeCompare(b3.slug)).map((record4) => publishedPayload(record4));
|
|
58861
58968
|
}
|
|
58862
58969
|
function skillSummary(skill) {
|
|
58863
58970
|
return {
|
|
@@ -58998,16 +59105,16 @@ async function storePublishedSkill(store, artifactStorage, principal, parsed, ex
|
|
|
58998
59105
|
};
|
|
58999
59106
|
}
|
|
59000
59107
|
}
|
|
59001
|
-
let
|
|
59108
|
+
let record4;
|
|
59002
59109
|
try {
|
|
59003
|
-
|
|
59110
|
+
record4 = await store.publishSkill(input);
|
|
59004
59111
|
} catch (error) {
|
|
59005
59112
|
if (input.bundle?.sha256) {
|
|
59006
59113
|
await discardCollectedObject(store, artifactStorage, principal, input.bundle.sha256);
|
|
59007
59114
|
}
|
|
59008
59115
|
throw error;
|
|
59009
59116
|
}
|
|
59010
|
-
if (superseded && superseded !==
|
|
59117
|
+
if (superseded && superseded !== record4.bundleSha256) {
|
|
59011
59118
|
await discardCollectedObject(store, artifactStorage, principal, superseded);
|
|
59012
59119
|
}
|
|
59013
59120
|
if (writeVersionObjects && versionManifest && parsed.bundleBytes && input.bundle) {
|
|
@@ -59017,7 +59124,7 @@ async function storePublishedSkill(store, artifactStorage, principal, parsed, ex
|
|
|
59017
59124
|
throw new SkillRequestError(502, "VERSION_OBJECTS_WRITE_FAILED", `'${input.slug}@${input.version}' was recorded but its version-addressed objects could not be written: ${error.message}. Re-run the same push to write them.`);
|
|
59018
59125
|
}
|
|
59019
59126
|
}
|
|
59020
|
-
return { record:
|
|
59127
|
+
return { record: record4, alreadyPublished: existingVersion !== null };
|
|
59021
59128
|
}
|
|
59022
59129
|
async function deletePublishedSkill(store, artifactStorage, principal, slug, tombstoneWindowMs) {
|
|
59023
59130
|
return store.deleteSkill(principal, slug, tombstoneWindowMs);
|
|
@@ -59028,23 +59135,23 @@ async function discardCollectedObject(store, artifactStorage, principal, sha2562
|
|
|
59028
59135
|
await artifactStorage.deleteBundle(principal.orgId, sha2562);
|
|
59029
59136
|
}
|
|
59030
59137
|
async function readPublishedBundle(store, artifactStorage, principal, slug) {
|
|
59031
|
-
const
|
|
59032
|
-
if (!
|
|
59138
|
+
const record4 = await store.getSkill(principal, slug);
|
|
59139
|
+
if (!record4)
|
|
59033
59140
|
throw new SkillRequestError(404, "SKILL_NOT_FOUND", "skill not found");
|
|
59034
|
-
if (!
|
|
59141
|
+
if (!record4.bundleSha256)
|
|
59035
59142
|
throw new SkillRequestError(404, "BUNDLE_NOT_FOUND", `skill '${slug}' was published without a bundle`);
|
|
59036
|
-
const bundle2 = await store.getSkillBundle(principal,
|
|
59143
|
+
const bundle2 = await store.getSkillBundle(principal, record4.bundleSha256);
|
|
59037
59144
|
if (!bundle2)
|
|
59038
|
-
throw new SkillRequestError(404, "BUNDLE_NOT_FOUND", `no stored bundle for digest ${
|
|
59145
|
+
throw new SkillRequestError(404, "BUNDLE_NOT_FOUND", `no stored bundle for digest ${record4.bundleSha256}`);
|
|
59039
59146
|
const bytes = await artifactStorage.readBundle(bundle2);
|
|
59040
59147
|
if (!bytes) {
|
|
59041
59148
|
throw new SkillRequestError(503, "BUNDLE_BACKEND_UNAVAILABLE", "bundle storage backend unavailable");
|
|
59042
59149
|
}
|
|
59043
59150
|
const actual = createHash25("sha256").update(bytes).digest("hex");
|
|
59044
|
-
if (actual !==
|
|
59045
|
-
throw new SkillRequestError(500, "BUNDLE_DIGEST_DRIFT", `stored bundle for '${slug}' hashes to ${actual} but was published as ${
|
|
59151
|
+
if (actual !== record4.bundleSha256) {
|
|
59152
|
+
throw new SkillRequestError(500, "BUNDLE_DIGEST_DRIFT", `stored bundle for '${slug}' hashes to ${actual} but was published as ${record4.bundleSha256}`);
|
|
59046
59153
|
}
|
|
59047
|
-
return { record:
|
|
59154
|
+
return { record: record4, bytes };
|
|
59048
59155
|
}
|
|
59049
59156
|
function assertPublishableSlug(slug) {
|
|
59050
59157
|
if (slug.length > MAX_SLUG_LENGTH || !SLUG_PATTERN.test(slug)) {
|
|
@@ -59153,14 +59260,14 @@ function skillVersionPayload(version2, currentSha) {
|
|
|
59153
59260
|
}
|
|
59154
59261
|
async function listSkillVersionsPayload(store, principal, slug) {
|
|
59155
59262
|
assertPublishableSlug(slug);
|
|
59156
|
-
const
|
|
59263
|
+
const record4 = await store.getSkill(principal, slug);
|
|
59157
59264
|
const versions = await store.listSkillVersions(principal, slug);
|
|
59158
|
-
if (!
|
|
59265
|
+
if (!record4 && !versions.length)
|
|
59159
59266
|
throw new SkillRequestError(404, "SKILL_NOT_FOUND", "skill not found");
|
|
59160
|
-
const currentSha =
|
|
59267
|
+
const currentSha = record4?.bundleSha256;
|
|
59161
59268
|
return {
|
|
59162
59269
|
slug,
|
|
59163
|
-
...
|
|
59270
|
+
...record4?.version ? { currentVersion: record4.version } : {},
|
|
59164
59271
|
...currentSha ? { currentBundleSha256: currentSha } : {},
|
|
59165
59272
|
versions: versions.map((version2) => skillVersionPayload(version2, currentSha))
|
|
59166
59273
|
};
|
|
@@ -59612,10 +59719,10 @@ function sortKeys(value) {
|
|
|
59612
59719
|
if (Array.isArray(value))
|
|
59613
59720
|
return value.map(sortKeys);
|
|
59614
59721
|
if (value !== null && typeof value === "object") {
|
|
59615
|
-
const
|
|
59722
|
+
const record4 = value;
|
|
59616
59723
|
const sorted = Object.create(null);
|
|
59617
|
-
for (const key of Object.keys(
|
|
59618
|
-
sorted[key] = sortKeys(
|
|
59724
|
+
for (const key of Object.keys(record4).sort()) {
|
|
59725
|
+
sorted[key] = sortKeys(record4[key]);
|
|
59619
59726
|
}
|
|
59620
59727
|
return sorted;
|
|
59621
59728
|
}
|
|
@@ -60539,14 +60646,14 @@ function createRunStateMachine(store) {
|
|
|
60539
60646
|
const next2 = await store.setRunStatus(runId3, to);
|
|
60540
60647
|
if (!next2)
|
|
60541
60648
|
return { ok: false, reason: "NO_SUCH_RUN" };
|
|
60542
|
-
const
|
|
60649
|
+
const record4 = {
|
|
60543
60650
|
runId: runId3,
|
|
60544
60651
|
attemptId,
|
|
60545
60652
|
from,
|
|
60546
60653
|
to,
|
|
60547
60654
|
at: new Date().toISOString()
|
|
60548
60655
|
};
|
|
60549
|
-
await store.recordTransition(
|
|
60656
|
+
await store.recordTransition(record4);
|
|
60550
60657
|
return { ok: true };
|
|
60551
60658
|
}
|
|
60552
60659
|
return {
|
|
@@ -65265,7 +65372,7 @@ class MemorySkillsStore {
|
|
|
65265
65372
|
}
|
|
65266
65373
|
const carriedBundle = !input.bundle && previous?.bundleSha256 ? { bundleSha256: previous.bundleSha256, ...previous.bundleByteSize === undefined ? {} : { bundleByteSize: previous.bundleByteSize } } : {};
|
|
65267
65374
|
const carriedSkillMd = typeof input.skillMd === "string" ? input.skillMd : previous?.skillMd;
|
|
65268
|
-
const
|
|
65375
|
+
const record4 = {
|
|
65269
65376
|
orgId: input.principal.orgId,
|
|
65270
65377
|
slug: input.slug,
|
|
65271
65378
|
displayName: input.displayName,
|
|
@@ -65287,7 +65394,7 @@ class MemorySkillsStore {
|
|
|
65287
65394
|
...previous?.archiveReason ? { archiveReason: previous.archiveReason } : {},
|
|
65288
65395
|
...previous?.replacementSlug ? { replacementSlug: previous.replacementSlug } : {}
|
|
65289
65396
|
};
|
|
65290
|
-
this.skills.set(key,
|
|
65397
|
+
this.skills.set(key, record4);
|
|
65291
65398
|
if (input.version && versionSha && !this.versions.has(versionKey(input.principal.orgId, input.slug, input.version))) {
|
|
65292
65399
|
this.versions.set(versionKey(input.principal.orgId, input.slug, input.version), {
|
|
65293
65400
|
orgId: input.principal.orgId,
|
|
@@ -65305,7 +65412,7 @@ class MemorySkillsStore {
|
|
|
65305
65412
|
if (previous?.bundleSha256 && input.bundle && previous.bundleSha256 !== input.bundle.sha256) {
|
|
65306
65413
|
this.collectOrphanBundle(input.principal.orgId, previous.bundleSha256);
|
|
65307
65414
|
}
|
|
65308
|
-
return
|
|
65415
|
+
return record4;
|
|
65309
65416
|
}
|
|
65310
65417
|
async listSkillVersions(principal, slug) {
|
|
65311
65418
|
return Array.from(this.versions.values()).filter((v2) => v2.orgId === principal.orgId && v2.slug === slug).sort((a4, b4) => b4.createdAt.localeCompare(a4.createdAt) || b4.version.localeCompare(a4.version));
|
|
@@ -65515,8 +65622,8 @@ class PostgresSkillsStore {
|
|
|
65515
65622
|
async backfillLegacyRevisions() {
|
|
65516
65623
|
const rows = await this.sql`SELECT * FROM skills_registry WHERE revision_id = ${""}`;
|
|
65517
65624
|
for (const row of rows) {
|
|
65518
|
-
const
|
|
65519
|
-
await this.sql`UPDATE skills_registry SET revision_id = ${revisionIdOfRecord(
|
|
65625
|
+
const record4 = rowToSkill(row);
|
|
65626
|
+
await this.sql`UPDATE skills_registry SET revision_id = ${revisionIdOfRecord(record4)} WHERE org_id = ${record4.orgId} AND slug = ${record4.slug}`;
|
|
65520
65627
|
}
|
|
65521
65628
|
}
|
|
65522
65629
|
async close() {
|
|
@@ -66105,23 +66212,23 @@ class PostgresSkillsStore {
|
|
|
66105
66212
|
return [];
|
|
66106
66213
|
const purged = [];
|
|
66107
66214
|
for (const row of expiredRows) {
|
|
66108
|
-
const
|
|
66215
|
+
const record4 = rowToSkill(row);
|
|
66109
66216
|
await tx`
|
|
66110
|
-
DELETE FROM skills_registry WHERE org_id = ${principal.orgId} AND slug = ${
|
|
66217
|
+
DELETE FROM skills_registry WHERE org_id = ${principal.orgId} AND slug = ${record4.slug} AND tombstone_purge_after <= now()
|
|
66111
66218
|
`;
|
|
66112
|
-
await tx`DELETE FROM skills_tags WHERE org_id = ${principal.orgId} AND slug = ${
|
|
66219
|
+
await tx`DELETE FROM skills_tags WHERE org_id = ${principal.orgId} AND slug = ${record4.slug}`;
|
|
66113
66220
|
await tx`
|
|
66114
|
-
DELETE FROM skills_registry WHERE org_id = ${principal.orgId} AND slug = ${
|
|
66221
|
+
DELETE FROM skills_registry WHERE org_id = ${principal.orgId} AND slug = ${record4.slug} AND tombstone_purge_after <= now()
|
|
66115
66222
|
`;
|
|
66116
|
-
if (
|
|
66223
|
+
if (record4.bundleSha256) {
|
|
66117
66224
|
await tx`
|
|
66118
66225
|
DELETE FROM skills_bundles
|
|
66119
|
-
WHERE org_id = ${principal.orgId} AND sha256 = ${
|
|
66120
|
-
AND NOT EXISTS (SELECT 1 FROM skills_registry WHERE org_id = ${principal.orgId} AND bundle_sha256 = ${
|
|
66121
|
-
AND NOT EXISTS (SELECT 1 FROM skills_versions WHERE org_id = ${principal.orgId} AND bundle_sha256 = ${
|
|
66226
|
+
WHERE org_id = ${principal.orgId} AND sha256 = ${record4.bundleSha256}
|
|
66227
|
+
AND NOT EXISTS (SELECT 1 FROM skills_registry WHERE org_id = ${principal.orgId} AND bundle_sha256 = ${record4.bundleSha256})
|
|
66228
|
+
AND NOT EXISTS (SELECT 1 FROM skills_versions WHERE org_id = ${principal.orgId} AND bundle_sha256 = ${record4.bundleSha256})
|
|
66122
66229
|
`;
|
|
66123
66230
|
}
|
|
66124
|
-
purged.push(
|
|
66231
|
+
purged.push(record4);
|
|
66125
66232
|
}
|
|
66126
66233
|
return purged;
|
|
66127
66234
|
});
|
|
@@ -66420,8 +66527,8 @@ async function handleApiV1(store, governanceStore, principal, request2, parts, c
|
|
|
66420
66527
|
if (request2.method === "POST" && !id2) {
|
|
66421
66528
|
const expectedRevisionId = parseIfMatch(request2.headers.get("if-match"));
|
|
66422
66529
|
const parsed = await parsePublishRequest(request2, config);
|
|
66423
|
-
const { record:
|
|
66424
|
-
return json4(publishedPayload(
|
|
66530
|
+
const { record: record4, alreadyPublished } = await storePublishedSkill(store, artifactStorage, principal, parsed, expectedRevisionId);
|
|
66531
|
+
return json4(publishedPayload(record4, { alreadyPublished }), { status: 201, headers: { ETag: revisionEtag(record4.revisionId) } });
|
|
66425
66532
|
}
|
|
66426
66533
|
if (request2.method === "GET" && id2 && subresource === "skill.md") {
|
|
66427
66534
|
const resolved = await resolvePublishedSkill(store, artifactStorage, principal, id2);
|
|
@@ -66469,15 +66576,15 @@ async function handleApiV1(store, governanceStore, principal, request2, parts, c
|
|
|
66469
66576
|
if (resolved.kind === "absent") {
|
|
66470
66577
|
return json4({ error: "skill not found", code: "SKILL_NOT_FOUND" }, { status: 404 });
|
|
66471
66578
|
}
|
|
66472
|
-
const { record:
|
|
66579
|
+
const { record: record4, bytes } = await readPublishedBundle(store, artifactStorage, principal, id2);
|
|
66473
66580
|
const headers = {
|
|
66474
66581
|
"Content-Type": "application/gzip",
|
|
66475
66582
|
"Content-Length": String(bytes.byteLength),
|
|
66476
|
-
"Content-Disposition": `attachment; filename="${
|
|
66477
|
-
"X-Skill-Bundle-Sha256":
|
|
66478
|
-
"X-Skill-Revision-Id":
|
|
66479
|
-
"X-Skill-Revision-Number": String(
|
|
66480
|
-
ETag: revisionEtag(
|
|
66583
|
+
"Content-Disposition": `attachment; filename="${record4.slug}.tar.gz"`,
|
|
66584
|
+
"X-Skill-Bundle-Sha256": record4.bundleSha256 ?? "",
|
|
66585
|
+
"X-Skill-Revision-Id": record4.revisionId,
|
|
66586
|
+
"X-Skill-Revision-Number": String(record4.revisionNumber),
|
|
66587
|
+
ETag: revisionEtag(record4.revisionId),
|
|
66481
66588
|
"Cache-Control": "no-store"
|
|
66482
66589
|
};
|
|
66483
66590
|
if (config.bundleSigningKey) {
|
|
@@ -66715,7 +66822,7 @@ var bundledRegistry = {
|
|
|
66715
66822
|
isValidSlug: isValidSkillSlug
|
|
66716
66823
|
};
|
|
66717
66824
|
var currentVersionService = {
|
|
66718
|
-
resolveVersion: (
|
|
66825
|
+
resolveVersion: (record4) => record4.version
|
|
66719
66826
|
};
|
|
66720
66827
|
// node_modules/zod/v3/external.js
|
|
66721
66828
|
var exports_external = {};
|
|
@@ -71113,7 +71220,7 @@ __export(exports_external2, {
|
|
|
71113
71220
|
regexes: () => exports_regexes,
|
|
71114
71221
|
regex: () => _regex,
|
|
71115
71222
|
refine: () => refine,
|
|
71116
|
-
record: () =>
|
|
71223
|
+
record: () => record4,
|
|
71117
71224
|
readonly: () => readonly,
|
|
71118
71225
|
property: () => _property,
|
|
71119
71226
|
properties: () => _properties,
|
|
@@ -86887,8 +86994,8 @@ function rewriteKeyNames(ctx) {
|
|
|
86887
86994
|
bySchema.set(entry.schema, entry);
|
|
86888
86995
|
}
|
|
86889
86996
|
const rewrites = new Map;
|
|
86890
|
-
for (const
|
|
86891
|
-
const seen = ctx.seen.get(
|
|
86997
|
+
for (const record4 of pendingRecords.get(ctx) ?? []) {
|
|
86998
|
+
const seen = ctx.seen.get(record4);
|
|
86892
86999
|
const names = (seen?.def ?? seen?.schema)?.propertyNames;
|
|
86893
87000
|
if (!names || names === true || rewrites.has(names))
|
|
86894
87001
|
continue;
|
|
@@ -87215,7 +87322,7 @@ __export(exports_schemas2, {
|
|
|
87215
87322
|
strictObject: () => strictObject,
|
|
87216
87323
|
set: () => set,
|
|
87217
87324
|
refine: () => refine,
|
|
87218
|
-
record: () =>
|
|
87325
|
+
record: () => record4,
|
|
87219
87326
|
readonly: () => readonly,
|
|
87220
87327
|
promise: () => promise,
|
|
87221
87328
|
preprocess: () => preprocess,
|
|
@@ -88385,7 +88492,7 @@ var ZodRecord2 = /* @__PURE__ */ $constructor("ZodRecord", (inst, def) => {
|
|
|
88385
88492
|
inst.keyType = def.keyType;
|
|
88386
88493
|
inst.valueType = def.valueType;
|
|
88387
88494
|
});
|
|
88388
|
-
function
|
|
88495
|
+
function record4(keyType, valueType, params) {
|
|
88389
88496
|
if (!valueType || !valueType._zod) {
|
|
88390
88497
|
return new ZodRecord2({
|
|
88391
88498
|
type: "record",
|
|
@@ -88851,7 +88958,7 @@ var stringbool = (...args) => _stringbool({
|
|
|
88851
88958
|
}, ...args);
|
|
88852
88959
|
function json5(params) {
|
|
88853
88960
|
const jsonSchema = lazy(() => {
|
|
88854
|
-
return union([string2(params), number2(), boolean2(), _null3(), array2(jsonSchema),
|
|
88961
|
+
return union([string2(params), number2(), boolean2(), _null3(), array2(jsonSchema), record4(string2(), jsonSchema)]);
|
|
88855
88962
|
});
|
|
88856
88963
|
return jsonSchema;
|
|
88857
88964
|
}
|
|
@@ -90074,12 +90181,12 @@ class RemoteWorkspaceInvitationReadError extends Error {
|
|
|
90074
90181
|
}
|
|
90075
90182
|
}
|
|
90076
90183
|
function invitationFailure(value, status) {
|
|
90077
|
-
if (!
|
|
90184
|
+
if (!record5(value) || typeof value.code !== "string" || !Object.hasOwn(invitationFailures, value.code))
|
|
90078
90185
|
return null;
|
|
90079
90186
|
const code = value.code;
|
|
90080
90187
|
return invitationFailures[code][0] === status ? code : null;
|
|
90081
90188
|
}
|
|
90082
|
-
var
|
|
90189
|
+
var record5 = (v2) => !!v2 && typeof v2 === "object" && !Array.isArray(v2);
|
|
90083
90190
|
var uuid5 = (v2) => typeof v2 === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v2);
|
|
90084
90191
|
var role = (v2) => typeof v2 === "string" && ["owner", "admin", "member", "viewer"].includes(v2);
|
|
90085
90192
|
var email3 = (v2) => typeof v2 === "string" && v2.length <= 254 && !/[\p{Cc}\p{Cs}\u2028\u2029\s]/u.test(v2) && /^[^@]+@[^@]+\.[^@]+$/.test(v2);
|
|
@@ -90088,7 +90195,7 @@ var inputFailure = () => {
|
|
|
90088
90195
|
throw new WorkspaceInvitationInputError;
|
|
90089
90196
|
};
|
|
90090
90197
|
function invitationInput(action, input2) {
|
|
90091
|
-
if (!
|
|
90198
|
+
if (!record5(input2))
|
|
90092
90199
|
return inputFailure();
|
|
90093
90200
|
const keys3 = {
|
|
90094
90201
|
list: ["after"],
|
|
@@ -90139,7 +90246,7 @@ function invalid5() {
|
|
|
90139
90246
|
throw new RemoteWorkspaceInvitationReadError;
|
|
90140
90247
|
}
|
|
90141
90248
|
function projection(v2, organizationId) {
|
|
90142
|
-
if (!
|
|
90249
|
+
if (!record5(v2) || !uuid5(v2.id) || v2.organizationId !== organizationId || !email3(v2.email) || v2.email !== v2.email.trim().toLowerCase() || !role(v2.role) || !Number.isInteger(v2.generation) || Number(v2.generation) < 1 || Number(v2.generation) > 10 || typeof v2.status !== "string" || !["pending", "expired", "accepted", "revoked"].includes(v2.status) || !timestamp(v2.expiresAt) || !timestamp(v2.createdAt) || !record5(v2.delivery) || typeof v2.delivery.state !== "string" || !["queued", "sending", "uncertain", "provider_accepted", "failed", "cancelled"].includes(v2.delivery.state) || !Number.isInteger(v2.delivery.attempts) || Number(v2.delivery.attempts) < 0 || Number(v2.delivery.attempts) > 5)
|
|
90143
90250
|
return invalid5();
|
|
90144
90251
|
return {
|
|
90145
90252
|
id: v2.id,
|
|
@@ -90154,7 +90261,7 @@ function projection(v2, organizationId) {
|
|
|
90154
90261
|
};
|
|
90155
90262
|
}
|
|
90156
90263
|
function parseInvitationResult(action, value, input2, organizationId) {
|
|
90157
|
-
if (!
|
|
90264
|
+
if (!record5(value))
|
|
90158
90265
|
return invalid5();
|
|
90159
90266
|
const request2 = input2;
|
|
90160
90267
|
if (action === "accept") {
|
|
@@ -90187,7 +90294,7 @@ function parseInvitationResult(action, value, input2, organizationId) {
|
|
|
90187
90294
|
}
|
|
90188
90295
|
|
|
90189
90296
|
// src/lib/remote-workspace-selection.ts
|
|
90190
|
-
var
|
|
90297
|
+
var record6 = (v2) => !!v2 && typeof v2 === "object" && !Array.isArray(v2);
|
|
90191
90298
|
var uuid8 = (v2) => typeof v2 === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v2);
|
|
90192
90299
|
var text2 = (v2, max = 1024) => typeof v2 === "string" && !!v2.trim() && v2.length <= max && !/[\p{Cc}\p{Cs}\u2028\u2029]/u.test(v2);
|
|
90193
90300
|
var role2 = (v2) => typeof v2 === "string" && ["owner", "admin", "member", "viewer"].includes(v2);
|
|
@@ -90212,7 +90319,7 @@ function workspaceExpectedUserId(value) {
|
|
|
90212
90319
|
return value;
|
|
90213
90320
|
}
|
|
90214
90321
|
function workspaceContext(value) {
|
|
90215
|
-
if (!
|
|
90322
|
+
if (!record6(value) || Object.keys(value).sort().join(",") !== "membershipId,userId" || !uuid8(value.userId) || !uuid8(value.membershipId))
|
|
90216
90323
|
throw new WorkspaceContextInputError;
|
|
90217
90324
|
return { userId: value.userId, membershipId: value.membershipId };
|
|
90218
90325
|
}
|
|
@@ -90220,15 +90327,15 @@ function invalid6() {
|
|
|
90220
90327
|
throw new Error(invalidWorkspaceResult);
|
|
90221
90328
|
}
|
|
90222
90329
|
function organization(v2) {
|
|
90223
|
-
if (!
|
|
90330
|
+
if (!record6(v2) || !uuid8(v2.id) || !text2(v2.slug) || !text2(v2.name))
|
|
90224
90331
|
return invalid6();
|
|
90225
90332
|
return { id: v2.id, slug: v2.slug, name: v2.name };
|
|
90226
90333
|
}
|
|
90227
90334
|
function parseAccountWorkspaces(value) {
|
|
90228
|
-
if (!
|
|
90335
|
+
if (!record6(value) || !Array.isArray(value.workspaces) || !value.workspaces.length || value.workspaces.length > 1000)
|
|
90229
90336
|
return invalid6();
|
|
90230
90337
|
const workspaces = value.workspaces.map((v2) => {
|
|
90231
|
-
if (!
|
|
90338
|
+
if (!record6(v2) || !uuid8(v2.membershipId) || !role2(v2.role) || typeof v2.current !== "boolean")
|
|
90232
90339
|
return invalid6();
|
|
90233
90340
|
return { membershipId: v2.membershipId, organization: organization(v2.organization), role: v2.role, current: v2.current };
|
|
90234
90341
|
});
|
|
@@ -90237,10 +90344,10 @@ function parseAccountWorkspaces(value) {
|
|
|
90237
90344
|
return { workspaces };
|
|
90238
90345
|
}
|
|
90239
90346
|
function parseWorkspaceIdentity(value, expectedUserId) {
|
|
90240
|
-
if (!
|
|
90347
|
+
if (!record6(value))
|
|
90241
90348
|
return invalid6();
|
|
90242
90349
|
const user = value.user;
|
|
90243
|
-
if (!
|
|
90350
|
+
if (!record6(user) || !uuid8(user.id) || !uuid8(user.membershipId) || !text2(user.email, 320) || !(user.displayName === null || text2(user.displayName)) || !role2(user.role))
|
|
90244
90351
|
return invalid6();
|
|
90245
90352
|
if (user.id !== expectedUserId)
|
|
90246
90353
|
throw new WorkspaceIdentityMismatchError;
|
|
@@ -90258,8 +90365,8 @@ function parseWorkspaceSession(value, expected) {
|
|
|
90258
90365
|
return { token: sessionToken(value.token), ...identity4 };
|
|
90259
90366
|
}
|
|
90260
90367
|
function parseWorkspaceLogin(value, expectedUserId) {
|
|
90261
|
-
const user =
|
|
90262
|
-
if (!
|
|
90368
|
+
const user = record6(value) && value.user;
|
|
90369
|
+
if (!record6(value) || !record6(user) || !uuid8(user.id))
|
|
90263
90370
|
return invalid6();
|
|
90264
90371
|
if (expectedUserId !== undefined && user.id !== expectedUserId)
|
|
90265
90372
|
throw new WorkspaceIdentityMismatchError;
|
|
@@ -90274,18 +90381,18 @@ var workspaceSelectionFailures = {
|
|
|
90274
90381
|
WORKSPACE_BUSY: [503, "Workspace is busy. Refresh before retrying."]
|
|
90275
90382
|
};
|
|
90276
90383
|
function workspaceSelectionFailure(value, status) {
|
|
90277
|
-
if (!
|
|
90384
|
+
if (!record6(value) || typeof value.code !== "string" || !Object.hasOwn(workspaceSelectionFailures, value.code))
|
|
90278
90385
|
return null;
|
|
90279
90386
|
const code = value.code;
|
|
90280
90387
|
return workspaceSelectionFailures[code][0] === status ? code : null;
|
|
90281
90388
|
}
|
|
90282
90389
|
|
|
90283
90390
|
// src/lib/remote-workspace.ts
|
|
90284
|
-
var
|
|
90391
|
+
var record7 = (value) => !!value && typeof value === "object" && !Array.isArray(value);
|
|
90285
90392
|
var cursor = (value) => typeof value === "string" && /^[A-Za-z0-9_-]{1,512}$/.test(value);
|
|
90286
90393
|
var uuid10 = (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);
|
|
90287
90394
|
function workspaceMembersQuery(options = {}) {
|
|
90288
|
-
if (!
|
|
90395
|
+
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))
|
|
90289
90396
|
throw new Error("Use a roster limit from 1 to 100 and an unchanged continuation cursor.");
|
|
90290
90397
|
const query = new URLSearchParams;
|
|
90291
90398
|
if (options.limit !== undefined)
|
|
@@ -90301,7 +90408,7 @@ function timestamp2(value) {
|
|
|
90301
90408
|
return Number.isFinite(time4) && new Date(time4).toISOString().slice(0, 23) === value.slice(0, 23);
|
|
90302
90409
|
}
|
|
90303
90410
|
function parseMember(row, fail) {
|
|
90304
|
-
if (!
|
|
90411
|
+
if (!record7(row) || !uuid10(row.membershipId) || !uuid10(row.userId) || typeof row.email !== "string" || !row.email || !(row.displayName === null || typeof row.displayName === "string") || !isRole(row.role) || !timestamp2(row.createdAt))
|
|
90305
90412
|
return fail();
|
|
90306
90413
|
return {
|
|
90307
90414
|
membershipId: row.membershipId,
|
|
@@ -90321,7 +90428,7 @@ class WorkspaceMemberInputError extends Error {
|
|
|
90321
90428
|
}
|
|
90322
90429
|
}
|
|
90323
90430
|
function mutationInput(membershipId, input2, roleChange) {
|
|
90324
|
-
if (typeof membershipId !== "string" || !uuid10(membershipId) || membershipId !== membershipId.toLowerCase() || !
|
|
90431
|
+
if (typeof membershipId !== "string" || !uuid10(membershipId) || membershipId !== membershipId.toLowerCase() || !record7(input2) || Object.keys(input2).sort().join(",") !== (roleChange ? "expectedRole,role" : "expectedRole"))
|
|
90325
90432
|
throw new WorkspaceMemberInputError;
|
|
90326
90433
|
const expectedRole = input2.expectedRole, role3 = roleChange ? input2.role : undefined;
|
|
90327
90434
|
if (!isRole(expectedRole) || roleChange && !isRole(role3))
|
|
@@ -90341,7 +90448,7 @@ function parseWorkspaceMemberRoleResult(value, membershipId, role3) {
|
|
|
90341
90448
|
const fail = () => {
|
|
90342
90449
|
throw new Error(invalidMemberResult);
|
|
90343
90450
|
};
|
|
90344
|
-
if (!
|
|
90451
|
+
if (!record7(value) || !uuid10(value.organizationId) || typeof value.changed !== "boolean")
|
|
90345
90452
|
return fail();
|
|
90346
90453
|
const member = parseMember(value.member, fail);
|
|
90347
90454
|
if (member.membershipId !== membershipId || member.role !== role3)
|
|
@@ -90349,7 +90456,7 @@ function parseWorkspaceMemberRoleResult(value, membershipId, role3) {
|
|
|
90349
90456
|
return { organizationId: value.organizationId, member, changed: value.changed };
|
|
90350
90457
|
}
|
|
90351
90458
|
function parseWorkspaceMemberRemovalResult(value, membershipId) {
|
|
90352
|
-
if (!
|
|
90459
|
+
if (!record7(value) || !uuid10(value.organizationId) || value.membershipId !== membershipId || value.removed !== true || typeof value.alreadyRemoved !== "boolean")
|
|
90353
90460
|
throw new Error(invalidMemberResult);
|
|
90354
90461
|
return { organizationId: value.organizationId, membershipId, removed: true, alreadyRemoved: value.alreadyRemoved };
|
|
90355
90462
|
}
|
|
@@ -90366,7 +90473,7 @@ var workspaceMemberFailures = {
|
|
|
90366
90473
|
MEMBERSHIP_BUSY: [503, "Membership is busy. Refresh the roster before another action."]
|
|
90367
90474
|
};
|
|
90368
90475
|
function workspaceMemberFailure(value, status) {
|
|
90369
|
-
if (!
|
|
90476
|
+
if (!record7(value) || typeof value.code !== "string" || !Object.hasOwn(workspaceMemberFailures, value.code))
|
|
90370
90477
|
return null;
|
|
90371
90478
|
const code = value.code;
|
|
90372
90479
|
return workspaceMemberFailures[code][0] === status ? code : null;
|
|
@@ -90375,7 +90482,7 @@ function parseWorkspaceMembersPage(value) {
|
|
|
90375
90482
|
const fail = () => {
|
|
90376
90483
|
throw new Error("The server returned an invalid workspace roster.");
|
|
90377
90484
|
};
|
|
90378
|
-
if (!
|
|
90485
|
+
if (!record7(value) || !uuid10(value.organizationId) || !Array.isArray(value.members) || value.members.length > 100 || !(value.nextCursor === null || cursor(value.nextCursor)) || !value.members.length && value.nextCursor !== null)
|
|
90379
90486
|
return fail();
|
|
90380
90487
|
const members2 = value.members.map((row) => parseMember(row, fail));
|
|
90381
90488
|
if (new Set(members2.map((row) => row.membershipId)).size !== members2.length)
|
|
@@ -90664,11 +90771,11 @@ var permissionNames = [
|
|
|
90664
90771
|
"executionGrantsWrite",
|
|
90665
90772
|
"executionGrantsResolve"
|
|
90666
90773
|
];
|
|
90667
|
-
var
|
|
90774
|
+
var record8 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
90668
90775
|
function parseSkillsAccess(value) {
|
|
90669
90776
|
if (value === undefined)
|
|
90670
90777
|
return {};
|
|
90671
|
-
if (!
|
|
90778
|
+
if (!record8(value))
|
|
90672
90779
|
throw new Error("Invalid Skills permission contract");
|
|
90673
90780
|
const result = {};
|
|
90674
90781
|
if (value.scopes !== undefined) {
|
|
@@ -90677,7 +90784,7 @@ function parseSkillsAccess(value) {
|
|
|
90677
90784
|
result.scopes = [...value.scopes];
|
|
90678
90785
|
}
|
|
90679
90786
|
if (value.permissions !== undefined) {
|
|
90680
|
-
if (!
|
|
90787
|
+
if (!record8(value.permissions))
|
|
90681
90788
|
throw new Error("Invalid Skills permission contract");
|
|
90682
90789
|
result.permissions = {};
|
|
90683
90790
|
for (const name of permissionNames) {
|
|
@@ -91574,13 +91681,13 @@ class RemoteSkillsClient {
|
|
|
91574
91681
|
return normalizeUpdatedSincePage(await response.json());
|
|
91575
91682
|
}
|
|
91576
91683
|
}
|
|
91577
|
-
function requireOptionalString(
|
|
91578
|
-
if (
|
|
91684
|
+
function requireOptionalString(record9, field2) {
|
|
91685
|
+
if (record9[field2] === undefined)
|
|
91579
91686
|
return;
|
|
91580
|
-
if (typeof
|
|
91687
|
+
if (typeof record9[field2] !== "string") {
|
|
91581
91688
|
throw new Error(`Remote payload did not match the expected contract (${field2} must be a string when present)`);
|
|
91582
91689
|
}
|
|
91583
|
-
return
|
|
91690
|
+
return record9[field2];
|
|
91584
91691
|
}
|
|
91585
91692
|
var INVALID_SKILL_VERSION_RESPONSE = "Remote skill version payload did not match the expected contract.";
|
|
91586
91693
|
function isVersionRecord(value) {
|
|
@@ -91603,19 +91710,19 @@ function normalizePin(entry) {
|
|
|
91603
91710
|
if (!entry || typeof entry !== "object") {
|
|
91604
91711
|
throw new Error("Remote pin payload did not match the expected contract (expected an object)");
|
|
91605
91712
|
}
|
|
91606
|
-
const
|
|
91607
|
-
const slug2 = typeof
|
|
91713
|
+
const record9 = entry;
|
|
91714
|
+
const slug2 = typeof record9.slug === "string" && record9.slug.trim() ? record9.slug.trim() : undefined;
|
|
91608
91715
|
if (!slug2) {
|
|
91609
91716
|
throw new Error("Remote pin payload did not match the expected contract (missing slug)");
|
|
91610
91717
|
}
|
|
91611
91718
|
let metadata;
|
|
91612
|
-
if (
|
|
91613
|
-
if (!
|
|
91719
|
+
if (record9.metadata !== undefined) {
|
|
91720
|
+
if (!record9.metadata || typeof record9.metadata !== "object" || Array.isArray(record9.metadata)) {
|
|
91614
91721
|
throw new Error("Remote pin payload did not match the expected contract (metadata must be a JSON object when present)");
|
|
91615
91722
|
}
|
|
91616
|
-
metadata =
|
|
91723
|
+
metadata = record9.metadata;
|
|
91617
91724
|
}
|
|
91618
|
-
const pinnedAt = requireOptionalString(
|
|
91725
|
+
const pinnedAt = requireOptionalString(record9, "pinnedAt");
|
|
91619
91726
|
return {
|
|
91620
91727
|
slug: slug2,
|
|
91621
91728
|
...pinnedAt !== undefined ? { pinnedAt } : {},
|
|
@@ -91632,16 +91739,16 @@ function normalizeSkillSummary(entry) {
|
|
|
91632
91739
|
if (!entry || typeof entry !== "object") {
|
|
91633
91740
|
throw new Error("Remote skill payload did not match the expected contract (expected an object)");
|
|
91634
91741
|
}
|
|
91635
|
-
const
|
|
91636
|
-
const slug2 = typeof
|
|
91742
|
+
const record9 = entry;
|
|
91743
|
+
const slug2 = typeof record9.slug === "string" && record9.slug.trim() ? record9.slug.trim() : undefined;
|
|
91637
91744
|
if (!slug2) {
|
|
91638
91745
|
throw new Error("Remote skill payload did not match the expected contract (missing slug)");
|
|
91639
91746
|
}
|
|
91640
91747
|
return {
|
|
91641
91748
|
slug: slug2,
|
|
91642
|
-
...requireOptionalString(
|
|
91643
|
-
...requireOptionalString(
|
|
91644
|
-
...requireOptionalString(
|
|
91749
|
+
...requireOptionalString(record9, "name") !== undefined ? { name: requireOptionalString(record9, "name") } : {},
|
|
91750
|
+
...requireOptionalString(record9, "version") !== undefined ? { version: requireOptionalString(record9, "version") } : {},
|
|
91751
|
+
...requireOptionalString(record9, "updatedAt") !== undefined ? { updatedAt: requireOptionalString(record9, "updatedAt") } : {}
|
|
91645
91752
|
};
|
|
91646
91753
|
}
|
|
91647
91754
|
function normalizeSkillSummaryList(payload) {
|
|
@@ -91698,12 +91805,12 @@ function normalizeUpdatedSincePage(payload) {
|
|
|
91698
91805
|
if (!payload || typeof payload !== "object") {
|
|
91699
91806
|
throw new Error("Updated-since payload did not match the expected contract (expected an object)");
|
|
91700
91807
|
}
|
|
91701
|
-
const
|
|
91702
|
-
if (!Array.isArray(
|
|
91808
|
+
const record9 = payload;
|
|
91809
|
+
if (!Array.isArray(record9.skills)) {
|
|
91703
91810
|
throw new Error("Updated-since payload did not match the expected contract (missing skills array)");
|
|
91704
91811
|
}
|
|
91705
|
-
const skills =
|
|
91706
|
-
const nextCursor =
|
|
91812
|
+
const skills = record9.skills.map(normalizeSkillSummary);
|
|
91813
|
+
const nextCursor = record9.nextCursor === undefined || record9.nextCursor === null ? null : record9.nextCursor;
|
|
91707
91814
|
if (nextCursor !== null && typeof nextCursor !== "string") {
|
|
91708
91815
|
throw new Error("Updated-since payload did not match the expected contract (nextCursor must be a string or absent)");
|
|
91709
91816
|
}
|
|
@@ -91750,7 +91857,7 @@ class RemoteInvitationEmailUnconfirmedError extends Error {
|
|
|
91750
91857
|
this.name = "RemoteInvitationEmailUnconfirmedError";
|
|
91751
91858
|
}
|
|
91752
91859
|
}
|
|
91753
|
-
var
|
|
91860
|
+
var record9 = (v2) => !!v2 && typeof v2 === "object" && !Array.isArray(v2);
|
|
91754
91861
|
var uuid11 = (v2) => typeof v2 === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v2);
|
|
91755
91862
|
function invitationEmailIds(invitationId, challengeId) {
|
|
91756
91863
|
if (!uuid11(invitationId) || !uuid11(challengeId))
|
|
@@ -91759,7 +91866,7 @@ function invitationEmailIds(invitationId, challengeId) {
|
|
|
91759
91866
|
}
|
|
91760
91867
|
function invitationEmailInput(action, input2) {
|
|
91761
91868
|
const keys3 = ["invitationId", "token", "challengeId", "confirm", ...action === "accept" ? ["code"] : []];
|
|
91762
|
-
if (!
|
|
91869
|
+
if (!record9(input2) || Object.keys(input2).length !== keys3.length || keys3.some((key) => !Object.hasOwn(input2, key)))
|
|
91763
91870
|
throw new InvitationEmailInputError;
|
|
91764
91871
|
const value = { ...input2 };
|
|
91765
91872
|
const ids = invitationEmailIds(value.invitationId, value.challengeId);
|
|
@@ -91788,12 +91895,12 @@ async function requestInvitationEmail(origin, action, input2) {
|
|
|
91788
91895
|
signal: AbortSignal.timeout(15000)
|
|
91789
91896
|
});
|
|
91790
91897
|
const parsed = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(await readBoundedResponse(response, 4096)));
|
|
91791
|
-
if (!response.ok &&
|
|
91898
|
+
if (!response.ok && record9(parsed) && typeof parsed.code === "string" && Object.hasOwn(refusals, parsed.code)) {
|
|
91792
91899
|
const code = parsed.code;
|
|
91793
91900
|
if (response.status === refusals[code][0])
|
|
91794
91901
|
throw new RemoteInvitationEmailError(code);
|
|
91795
91902
|
}
|
|
91796
|
-
if (!
|
|
91903
|
+
if (!record9(parsed))
|
|
91797
91904
|
throw new RemoteInvitationEmailUnconfirmedError(action);
|
|
91798
91905
|
if (action === "challenge" && response.status === 202 && parsed.challengeId === value.challengeId && parsed.expiresIn === 600 && typeof parsed.message === "string" && parsed.message.length <= 256) {
|
|
91799
91906
|
return { challengeId: value.challengeId, message: "If this invitation is eligible, a verification code will arrive. Delivery is not confirmed.", expiresIn: 600 };
|
|
@@ -91853,8 +91960,8 @@ var invalid7 = () => {
|
|
|
91853
91960
|
};
|
|
91854
91961
|
var publicationUuid = (v2) => typeof v2 === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v2);
|
|
91855
91962
|
var hash4 = (v2) => typeof v2 === "string" && /^[a-f0-9]{64}$/.test(v2);
|
|
91856
|
-
var
|
|
91857
|
-
var exact = (v2, keys3) =>
|
|
91963
|
+
var record10 = (v2) => !!v2 && typeof v2 === "object" && !Array.isArray(v2);
|
|
91964
|
+
var exact = (v2, keys3) => record10(v2) && Object.keys(v2).sort().join(",") === keys3.sort().join(",");
|
|
91858
91965
|
var date5 = (v2) => typeof v2 === "string" && /^\d{4}-\d\d-\d\dT[0-9:.]+(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(v2) && Number.isFinite(Date.parse(v2));
|
|
91859
91966
|
var publicationSha256 = (bytes) => createHash33("sha256").update(bytes).digest("hex");
|
|
91860
91967
|
function checkedPublicationDeclaration(value) {
|
|
@@ -91862,7 +91969,7 @@ function checkedPublicationDeclaration(value) {
|
|
|
91862
91969
|
return bad();
|
|
91863
91970
|
try {
|
|
91864
91971
|
const manifest = JSON.parse(value.manifestText);
|
|
91865
|
-
if (!
|
|
91972
|
+
if (!record10(manifest) || manifest.version !== value.version || validatePortableManifestContract(manifest, { strict: true }).length || !hash4(manifest.provenance?.content_hash))
|
|
91866
91973
|
return bad();
|
|
91867
91974
|
} catch {
|
|
91868
91975
|
return bad();
|
|
@@ -91920,7 +92027,7 @@ async function boundedJson(url2, init, token, mutation, budget2 = 15000, signal)
|
|
|
91920
92027
|
return invalid7();
|
|
91921
92028
|
}
|
|
91922
92029
|
if (!response.ok) {
|
|
91923
|
-
const code =
|
|
92030
|
+
const code = record10(body4) && typeof body4.code === "string" && Object.hasOwn(failures2, body4.code) ? body4.code : null;
|
|
91924
92031
|
if (code && failures2[code][0] === response.status)
|
|
91925
92032
|
throw new PrivatePublicationError(code, failures2[code][1], mutation && code === "PUBLICATION_UNCERTAIN", response.status);
|
|
91926
92033
|
throw new PrivatePublicationError("PUBLICATION_REQUEST_FAILED", "The publication request was refused. Inspect its status before retrying.", mutation && response.status >= 500, response.status);
|
|
@@ -91975,8 +92082,8 @@ class RemotePrivatePublicationsClient {
|
|
|
91975
92082
|
if (options.timeoutMs !== undefined && (!Number.isSafeInteger(options.timeoutMs) || options.timeoutMs < 1 || options.timeoutMs > 15000))
|
|
91976
92083
|
return bad();
|
|
91977
92084
|
const response = await boundedJson(skillsApiRequestUrl(this.apiOrigin, "/api/v1/capabilities"), {}, this.#token, false, options.timeoutMs, options.signal);
|
|
91978
|
-
const p2 =
|
|
91979
|
-
if (!
|
|
92085
|
+
const p2 = record10(response) && response.privatePublishing;
|
|
92086
|
+
if (!record10(response) || response.contractVersion !== 1 || response.apiVersion !== 1 || !exact(p2, ["contractVersion", "enabled", "authentication", "maxArchiveBytes", "uploadMaxTtlSeconds", "executionEnabled"]) || p2.contractVersion !== 1 || typeof p2.enabled !== "boolean" || p2.authentication !== "interactive-session" || p2.maxArchiveBytes !== PRIVATE_PUBLICATION_MAX_BYTES || p2.uploadMaxTtlSeconds !== 300 || typeof p2.executionEnabled !== "boolean")
|
|
91980
92087
|
throw new PrivatePublicationError("PUBLICATION_CONTRACT_UNAVAILABLE", "This server does not support the hosted private publication contract.");
|
|
91981
92088
|
return Object.freeze({ ...p2 });
|
|
91982
92089
|
}
|
|
@@ -91992,7 +92099,7 @@ class RemotePrivatePublicationsClient {
|
|
|
91992
92099
|
async#view(path2, method, skillId, intentId, declaration, options = {}) {
|
|
91993
92100
|
const value = await boundedJson(path2, { method, ...method === "GET" ? {} : { body: JSON.stringify(declaration ?? {}) } }, this.#token, method !== "GET", options.timeoutMs, options.signal);
|
|
91994
92101
|
try {
|
|
91995
|
-
if (!
|
|
92102
|
+
if (!record10(value) || !Object.keys(value).every((k4) => k4 === "upload" || k4 === "changed") || value.changed !== undefined && typeof value.changed !== "boolean")
|
|
91996
92103
|
return invalid7();
|
|
91997
92104
|
return checkedPublicationView(value.upload, skillId, intentId, declaration);
|
|
91998
92105
|
} catch (error61) {
|
|
@@ -92155,10 +92262,10 @@ async function requestAuthApi(instance, path2, options) {
|
|
|
92155
92262
|
const text3 = await res.text();
|
|
92156
92263
|
const body4 = text3 ? parseJsonBody(text3) : {};
|
|
92157
92264
|
if (!res.ok) {
|
|
92158
|
-
const
|
|
92159
|
-
const detail = typeof
|
|
92160
|
-
const error61 = typeof
|
|
92161
|
-
const code = typeof
|
|
92265
|
+
const record11 = isRecord7(body4) ? body4 : {};
|
|
92266
|
+
const detail = typeof record11.detail === "string" ? record11.detail : undefined;
|
|
92267
|
+
const error61 = typeof record11.error === "string" ? record11.error : undefined;
|
|
92268
|
+
const code = typeof record11.code === "string" ? record11.code : undefined;
|
|
92162
92269
|
throw new HostedApiError(detail || error61 || `${res.status} ${res.statusText}`, {
|
|
92163
92270
|
status: res.status,
|
|
92164
92271
|
code,
|
|
@@ -92592,7 +92699,7 @@ var requestIdPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]
|
|
|
92592
92699
|
function validId(value) {
|
|
92593
92700
|
return typeof value === "string" && requestIdPattern.test(value);
|
|
92594
92701
|
}
|
|
92595
|
-
function
|
|
92702
|
+
function record11(value) {
|
|
92596
92703
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
92597
92704
|
}
|
|
92598
92705
|
function exact2(value, names) {
|
|
@@ -92679,7 +92786,7 @@ function snapshot2(value, maximum) {
|
|
|
92679
92786
|
function requestSnapshot(input2) {
|
|
92680
92787
|
try {
|
|
92681
92788
|
const owned = snapshot2(input2, SKILL_OPERATION_LIMITS.requestBytes), value = owned.value;
|
|
92682
|
-
if (!
|
|
92789
|
+
if (!record11(value) || !exact2(value, ["contractVersion", "requestId", "operation", "input"]) || value.contractVersion !== 1 || !validId(value.requestId) || typeof value.operation !== "string" || value.operation.length > 128 || !/^[a-z][a-z0-9]*(?:[.-][a-z0-9]+)*$/.test(value.operation) || !record11(value.input))
|
|
92683
92790
|
throw Error();
|
|
92684
92791
|
return { ...owned, value };
|
|
92685
92792
|
} catch {
|
|
@@ -92689,7 +92796,7 @@ function requestSnapshot(input2) {
|
|
|
92689
92796
|
function resultSnapshot(input2, requestId) {
|
|
92690
92797
|
try {
|
|
92691
92798
|
const value = snapshot2(input2, SKILL_OPERATION_LIMITS.resultBytes).value;
|
|
92692
|
-
if (!
|
|
92799
|
+
if (!record11(value) || value.contractVersion !== 1 || value.requestId !== requestId)
|
|
92693
92800
|
throw Error();
|
|
92694
92801
|
const fields2 = ["contractVersion", "requestId", "status"];
|
|
92695
92802
|
if (value.status === "succeeded")
|