@hasna/skills 0.10.25 → 0.10.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -0
- package/bin/index.js +437 -327
- package/bin/mcp.js +263 -117
- package/bin/migrate.js +1 -1
- package/bin/server.js +1 -1
- package/bin/worker.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +326 -219
- 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 +423 -318
- 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.27",
|
|
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,23 @@ 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"] : 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 (version === 3 && key !== "model_verbosity") {
|
|
39005
|
+
need3(typeof value === "string" && value.length <= 128 && !/[\x00-\x1f\x7f]/.test(value));
|
|
39006
|
+
if (key !== "service_tier")
|
|
39007
|
+
need3(value.length > 0);
|
|
39008
|
+
} else
|
|
38926
39009
|
need3(typeof value === "string" && (key === "model_reasoning_effort" ? EFFORT2.has(value) : VERBOSITY2.has(value)));
|
|
38927
39010
|
delete target[key];
|
|
38928
39011
|
}
|
|
38929
39012
|
}
|
|
38930
|
-
function settingsDigest2(text) {
|
|
39013
|
+
function settingsDigest2(text, version = 2) {
|
|
38931
39014
|
let config;
|
|
38932
39015
|
try {
|
|
38933
39016
|
config = Bun.TOML.parse(text);
|
|
@@ -38935,8 +39018,9 @@ function settingsDigest2(text) {
|
|
|
38935
39018
|
throw new Error("Invalid Codex settings witness");
|
|
38936
39019
|
}
|
|
38937
39020
|
need3(isRecord(config));
|
|
38938
|
-
|
|
38939
|
-
|
|
39021
|
+
const projected = version === 3 ? projectRegularCodexMcp(config, text) : { config, numericSource: text };
|
|
39022
|
+
normalize2(projected.config, version);
|
|
39023
|
+
return sha2(`hasna.skills.codex-settings.v${version}\x00${JSON.stringify([canonical3(projected.config), numericTokens2(projected.numericSource)])}`);
|
|
38940
39024
|
}
|
|
38941
39025
|
function hashCodexSettingsReplacementV2(text, budget = { remaining: 256 * 1024 * 1024 }) {
|
|
38942
39026
|
need3(Buffer.byteLength(text) <= 1024 * 1024 && budget.remaining >= Buffer.byteLength(text));
|
|
@@ -38960,6 +39044,25 @@ function upgradeCodexSettingsWitness(previous, reviewedSettingsPath) {
|
|
|
38960
39044
|
throw new Error("Codex non-preference settings changed; explicit discovery review required");
|
|
38961
39045
|
return { path: previous.path, hashMode: "codex-settings-v2", sha256: sha2562 };
|
|
38962
39046
|
}
|
|
39047
|
+
function hashCodexSettingsReplacementV3(text, budget = { remaining: 256 * 1024 * 1024 }) {
|
|
39048
|
+
need3(Buffer.byteLength(text) <= 1024 * 1024 && budget.remaining >= Buffer.byteLength(text));
|
|
39049
|
+
budget.remaining -= Buffer.byteLength(text);
|
|
39050
|
+
return settingsDigest2(text, 3);
|
|
39051
|
+
}
|
|
39052
|
+
function captureCodexSettingsV3(path, budget = { remaining: 256 * 1024 * 1024 }) {
|
|
39053
|
+
return { path, hashMode: "codex-settings-v3", sha256: settingsDigest2(readNativeSettingsWitnessFile(path, budget, "config.toml"), 3) };
|
|
39054
|
+
}
|
|
39055
|
+
function upgradeCodexSettingsWitnessV3(previous, reviewedSettingsPath) {
|
|
39056
|
+
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));
|
|
39057
|
+
const budget = { remaining: 2 * 1024 * 1024 };
|
|
39058
|
+
const before = readNativeSettingsWitnessFile(reviewedSettingsPath, budget, "config.toml"), current = readNativeSettingsWitnessFile(previous.path, budget, "config.toml");
|
|
39059
|
+
const original = previous.hashMode === "codex-settings-v2" ? settingsDigest2(before) : previous.hashMode === "codex-settings-v1" ? hashCodexSettingsReplacement(before) : sha2(before);
|
|
39060
|
+
need3(original === previous.sha256);
|
|
39061
|
+
const sha2562 = settingsDigest2(current, 3);
|
|
39062
|
+
if (settingsDigest2(before, 3) !== sha2562)
|
|
39063
|
+
throw new Error("Codex settings outside the reviewed V3 contract changed; explicit discovery review required");
|
|
39064
|
+
return { path: previous.path, hashMode: "codex-settings-v3", sha256: sha2562 };
|
|
39065
|
+
}
|
|
38963
39066
|
|
|
38964
39067
|
// src/lib/native-discovery-roots.ts
|
|
38965
39068
|
var NATIVE_SKILL_ROOTS = [
|
|
@@ -38982,7 +39085,7 @@ var NATIVE_SKILL_ROOTS = [
|
|
|
38982
39085
|
|
|
38983
39086
|
// src/lib/agent-integration.ts
|
|
38984
39087
|
import { createHash as createHash18, randomUUID as randomUUID3 } from "crypto";
|
|
38985
|
-
import { isDeepStrictEqual as
|
|
39088
|
+
import { isDeepStrictEqual as isDeepStrictEqual6 } from "util";
|
|
38986
39089
|
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
39090
|
import { dirname as dirname15, join as join22, resolve as resolve15, relative as relative4, isAbsolute as isAbsolute17, sep as sep5 } from "path";
|
|
38988
39091
|
import { homedir as homedir3 } from "os";
|
|
@@ -39005,7 +39108,7 @@ function array(value, maximum) {
|
|
|
39005
39108
|
requireBound(Array.isArray(value) && value.length <= maximum);
|
|
39006
39109
|
return value;
|
|
39007
39110
|
}
|
|
39008
|
-
function
|
|
39111
|
+
function record3(value, maximum) {
|
|
39009
39112
|
requireBound(object3(value) && Object.keys(value).length <= maximum);
|
|
39010
39113
|
return value;
|
|
39011
39114
|
}
|
|
@@ -39015,13 +39118,13 @@ function text(value, maximum = AGENT_POLICY_LIMITS.pathCharacters) {
|
|
|
39015
39118
|
function assertAgentPolicyCollections(policy) {
|
|
39016
39119
|
if (policy.bridge === undefined)
|
|
39017
39120
|
return;
|
|
39018
|
-
const bridge =
|
|
39121
|
+
const bridge = record3(policy.bridge, 64);
|
|
39019
39122
|
if (bridge.agents !== undefined)
|
|
39020
39123
|
for (const agent of array(bridge.agents, AGENT_POLICY_LIMITS.agents))
|
|
39021
39124
|
text(agent, 128);
|
|
39022
39125
|
for (const key of ["commands", "profiles", "supervisors"])
|
|
39023
39126
|
if (bridge[key] !== undefined) {
|
|
39024
|
-
const entries =
|
|
39127
|
+
const entries = record3(bridge[key], AGENT_POLICY_LIMITS.agents);
|
|
39025
39128
|
for (const [agent, value] of Object.entries(entries)) {
|
|
39026
39129
|
text(agent, 128);
|
|
39027
39130
|
if (key === "supervisors") {
|
|
@@ -39074,12 +39177,12 @@ function assertAgentPolicyCollections(policy) {
|
|
|
39074
39177
|
}
|
|
39075
39178
|
if (bridge.discovery === undefined)
|
|
39076
39179
|
return;
|
|
39077
|
-
for (const [agent, value] of Object.entries(
|
|
39180
|
+
for (const [agent, value] of Object.entries(record3(bridge.discovery, AGENT_POLICY_LIMITS.agents))) {
|
|
39078
39181
|
text(agent, 128);
|
|
39079
39182
|
requireBound(object3(value));
|
|
39080
39183
|
text(value.agent, 128);
|
|
39081
39184
|
if (value.codexInstallationInputs !== undefined) {
|
|
39082
|
-
const proof =
|
|
39185
|
+
const proof = record3(value.codexInstallationInputs, 4), inputs = array(proof.plugins, 4096), ids = new Set;
|
|
39083
39186
|
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
39187
|
for (const input of inputs) {
|
|
39085
39188
|
requireBound(object3(input) && Object.keys(input).every((key) => ["pluginId", "namespace", "pluginParent", "sourceRoot", "sourceSha256"].includes(key)));
|
|
@@ -39104,8 +39207,8 @@ function assertAgentPolicyCollections(policy) {
|
|
|
39104
39207
|
text(source.path);
|
|
39105
39208
|
requireBound(source.sha256 === null || typeof source.sha256 === "string" && /^[a-f0-9]{64}$/.test(source.sha256));
|
|
39106
39209
|
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")
|
|
39210
|
+
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));
|
|
39211
|
+
if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3")
|
|
39109
39212
|
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
39213
|
if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3")
|
|
39111
39214
|
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 +39368,7 @@ function isOwnedCliBridge(path, expectedPaths) {
|
|
|
39265
39368
|
import { createHash as createHash17 } from "crypto";
|
|
39266
39369
|
import { lstatSync as lstatSync18, readFileSync as readFileSync13, readdirSync as readdirSync7, realpathSync as realpathSync6 } from "fs";
|
|
39267
39370
|
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
|
|
39371
|
+
import { isDeepStrictEqual as isDeepStrictEqual4 } from "util";
|
|
39269
39372
|
|
|
39270
39373
|
// node_modules/yaml/dist/index.js
|
|
39271
39374
|
var composer = require_composer();
|
|
@@ -39683,7 +39786,7 @@ function trace(path) {
|
|
|
39683
39786
|
canonical4(path);
|
|
39684
39787
|
const rows = [], paths = [];
|
|
39685
39788
|
let metadataBytes = 0, steps = 0, links = 0, cursor = parse3(path).root, pending = path.slice(cursor.length).split(sep3);
|
|
39686
|
-
function
|
|
39789
|
+
function record4(path2, row) {
|
|
39687
39790
|
const value = { path: path2, ...row };
|
|
39688
39791
|
metadataBytes += Buffer.byteLength(JSON.stringify(value));
|
|
39689
39792
|
if (metadataBytes > AGENT_POLICY_LIMITS.discoveryPathSourceMetadataBytes)
|
|
@@ -39695,7 +39798,7 @@ function trace(path) {
|
|
|
39695
39798
|
const stat = lstatSync12(cursor, { bigint: true });
|
|
39696
39799
|
if (!stat.isDirectory())
|
|
39697
39800
|
throw new Error("Unsupported discovery path root");
|
|
39698
|
-
|
|
39801
|
+
record4(cursor, { type: "directory", ...identity3(stat) });
|
|
39699
39802
|
}
|
|
39700
39803
|
root();
|
|
39701
39804
|
while (pending.length) {
|
|
@@ -39713,7 +39816,7 @@ function trace(path) {
|
|
|
39713
39816
|
throw new Error("Discovery resolved path length limit exceeded");
|
|
39714
39817
|
const stat = lstatSync12(candidate, { bigint: true, throwIfNoEntry: false });
|
|
39715
39818
|
if (!stat) {
|
|
39716
|
-
|
|
39819
|
+
record4(candidate, { type: "missing", remaining: pending });
|
|
39717
39820
|
return { rows, paths, file: null, missing: candidate, metadataBytes };
|
|
39718
39821
|
}
|
|
39719
39822
|
if (stat.isSymbolicLink()) {
|
|
@@ -39724,7 +39827,7 @@ function trace(path) {
|
|
|
39724
39827
|
throw new Error("Unsupported non-UTF8 discovery link target");
|
|
39725
39828
|
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
39829
|
throw new Error("Discovery link changed during read");
|
|
39727
|
-
|
|
39830
|
+
record4(candidate, { type: "link", target, ...identity3(stat, true) });
|
|
39728
39831
|
if (isAbsolute10(target)) {
|
|
39729
39832
|
cursor = parse3(target).root;
|
|
39730
39833
|
root();
|
|
@@ -39736,7 +39839,7 @@ function trace(path) {
|
|
|
39736
39839
|
continue;
|
|
39737
39840
|
}
|
|
39738
39841
|
if (stat.isDirectory()) {
|
|
39739
|
-
|
|
39842
|
+
record4(candidate, { type: "directory", ...identity3(stat) });
|
|
39740
39843
|
cursor = candidate;
|
|
39741
39844
|
continue;
|
|
39742
39845
|
}
|
|
@@ -39744,7 +39847,7 @@ function trace(path) {
|
|
|
39744
39847
|
throw new Error("Unsupported discovery path input");
|
|
39745
39848
|
if (stat.size > BigInt(AGENT_POLICY_LIMITS.discoveryRawSourceBytes))
|
|
39746
39849
|
throw new Error("Unsupported or oversized raw discovery input");
|
|
39747
|
-
|
|
39850
|
+
record4(candidate, { type: "file", ...identity3(stat, true) });
|
|
39748
39851
|
return { rows, paths, file: candidate, missing: null, metadataBytes };
|
|
39749
39852
|
}
|
|
39750
39853
|
throw new Error("Unsupported directory discovery path input");
|
|
@@ -41615,19 +41718,19 @@ function projectNativeDiscoveryFields(text2, format, fields2, path) {
|
|
|
41615
41718
|
return digest2(JSON.stringify(Object.fromEntries(fields2.map((field2) => [field2, object5[field2] ?? null]))));
|
|
41616
41719
|
}
|
|
41617
41720
|
function isSupersededCodexProjection(agent, configPath, source) {
|
|
41618
|
-
return agent === "codex" && source.path === configPath && source.format === "toml" &&
|
|
41721
|
+
return agent === "codex" && source.path === configPath && source.format === "toml" && isDeepStrictEqual4(source.fields, [...CODEX_DISCOVERY_PROJECTION_FIELDS]);
|
|
41619
41722
|
}
|
|
41620
41723
|
function supersedesCodexProjection(sources, configPath) {
|
|
41621
|
-
return sources.some((source) => source.path === configPath && source.hashMode === "codex-settings-v2");
|
|
41724
|
+
return sources.some((source) => source.path === configPath && (source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3"));
|
|
41622
41725
|
}
|
|
41623
41726
|
function projected(source, changes, budget = discoveryByteBudget()) {
|
|
41624
|
-
if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2") {
|
|
41727
|
+
if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3") {
|
|
41625
41728
|
if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
|
|
41626
41729
|
throw new Error("Codex settings witnesses require exact typed metadata");
|
|
41627
|
-
const current = (source.hashMode === "codex-settings-v2" ? captureCodexSettingsV2 : captureCodexSettings)(source.path, budget).sha256;
|
|
41730
|
+
const current = (source.hashMode === "codex-settings-v3" ? captureCodexSettingsV3 : source.hashMode === "codex-settings-v2" ? captureCodexSettingsV2 : captureCodexSettings)(source.path, budget).sha256;
|
|
41628
41731
|
if (current !== source.sha256)
|
|
41629
41732
|
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;
|
|
41733
|
+
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
41734
|
}
|
|
41632
41735
|
if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") {
|
|
41633
41736
|
if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
|
|
@@ -41727,7 +41830,7 @@ function codexInstallationRoots(binding) {
|
|
|
41727
41830
|
});
|
|
41728
41831
|
}
|
|
41729
41832
|
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"))
|
|
41833
|
+
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
41834
|
throw new Error("Codex settings witnesses require explicit reviewed Codex configuration");
|
|
41732
41835
|
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
41836
|
throw new Error("Claude settings witnesses require explicit reviewed Claude configuration");
|
|
@@ -41877,10 +41980,10 @@ function resolveAgentDiscovery(options) {
|
|
|
41877
41980
|
verifyAgentDiscovery(retained);
|
|
41878
41981
|
if (!retained.sources.some((source) => source.path === canonical6(configPath) && source.format === undefined && source.fields === undefined))
|
|
41879
41982
|
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)))
|
|
41983
|
+
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
41984
|
unresolved("retained settings witness names another configuration source");
|
|
41882
41985
|
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) =>
|
|
41986
|
+
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
41987
|
unresolved("retained review is missing current runtime discovery coverage");
|
|
41885
41988
|
return retained;
|
|
41886
41989
|
}
|
|
@@ -41894,7 +41997,7 @@ function resolveAgentDiscovery(options) {
|
|
|
41894
41997
|
if (review.sources.some((source) => source.format !== undefined || source.fields !== undefined))
|
|
41895
41998
|
throw new Error("Explicit discovery reviews require full source-file hashes");
|
|
41896
41999
|
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)))
|
|
42000
|
+
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
42001
|
throw new Error("Semantic settings witnesses must name the configured Claude configuration source");
|
|
41899
42002
|
if (!review.sources.some((source) => source.path === canonical6(configPath)))
|
|
41900
42003
|
throw new Error("Discovery review must include the agent configuration source");
|
|
@@ -42078,7 +42181,7 @@ export default async ({ directory }) => {
|
|
|
42078
42181
|
}
|
|
42079
42182
|
|
|
42080
42183
|
// src/lib/agent-codex.ts
|
|
42081
|
-
import { isDeepStrictEqual as
|
|
42184
|
+
import { isDeepStrictEqual as isDeepStrictEqual5 } from "util";
|
|
42082
42185
|
var CODEX_SKILL_CONFIG_SECTIONS = /^\[\[skills\.config\]\][^\n]*(?:\n(?!\s*\[)[^\n]*)*/gm;
|
|
42083
42186
|
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
42187
|
function splitTopLevel(value, delimiter) {
|
|
@@ -42209,7 +42312,7 @@ function normalizeCodexInlinePathConfig(text2) {
|
|
|
42209
42312
|
const expectedWithoutConfig = structuredClone(before);
|
|
42210
42313
|
delete expectedWithoutConfig.skills.config;
|
|
42211
42314
|
try {
|
|
42212
|
-
if (
|
|
42315
|
+
if (isDeepStrictEqual5(Bun.TOML.parse(text2.replace(CODEX_SKILL_CONFIG_SECTIONS, "")), expectedWithoutConfig))
|
|
42213
42316
|
return text2;
|
|
42214
42317
|
} catch {}
|
|
42215
42318
|
const matches = [];
|
|
@@ -42262,7 +42365,7 @@ function normalizeCodexInlinePathConfig(text2) {
|
|
|
42262
42365
|
try {
|
|
42263
42366
|
const after = Bun.TOML.parse(candidate2);
|
|
42264
42367
|
const expected = structuredClone(before);
|
|
42265
|
-
if (
|
|
42368
|
+
if (isDeepStrictEqual5(after, expected))
|
|
42266
42369
|
matches.push(candidate2);
|
|
42267
42370
|
} catch {}
|
|
42268
42371
|
}
|
|
@@ -42278,11 +42381,11 @@ function assertCodexPathConfigEditable(text2) {
|
|
|
42278
42381
|
delete expected.skills.config;
|
|
42279
42382
|
try {
|
|
42280
42383
|
const withoutSections = Bun.TOML.parse(text2.replace(CODEX_SKILL_CONFIG_SECTIONS, ""));
|
|
42281
|
-
if (
|
|
42384
|
+
if (isDeepStrictEqual5(withoutSections, expected))
|
|
42282
42385
|
return;
|
|
42283
42386
|
const normalized = normalizeCodexInlinePathConfig(text2);
|
|
42284
42387
|
const withoutNormalizedSections = Bun.TOML.parse(normalized.replace(CODEX_SKILL_CONFIG_SECTIONS, ""));
|
|
42285
|
-
if (
|
|
42388
|
+
if (isDeepStrictEqual5(withoutNormalizedSections, expected))
|
|
42286
42389
|
return;
|
|
42287
42390
|
} catch {}
|
|
42288
42391
|
throw codexPathConfigRefusal();
|
|
@@ -42320,7 +42423,7 @@ function disableCodexBundledSkills(text2) {
|
|
|
42320
42423
|
const candidates = new Set;
|
|
42321
42424
|
const consider = (candidate2) => {
|
|
42322
42425
|
try {
|
|
42323
|
-
if (
|
|
42426
|
+
if (isDeepStrictEqual5(Bun.TOML.parse(candidate2), expected))
|
|
42324
42427
|
candidates.add(candidate2);
|
|
42325
42428
|
} catch {}
|
|
42326
42429
|
};
|
|
@@ -42650,7 +42753,7 @@ function inventoryNativeSkills(home = homedir3(), options = {}) {
|
|
|
42650
42753
|
admit(path);
|
|
42651
42754
|
const scan = { complete: true, hasSkills: false, entries: 1 };
|
|
42652
42755
|
assertSafePath(path);
|
|
42653
|
-
if (configuredRoot && agent === "codex" && installationInputs.
|
|
42756
|
+
if (configuredRoot && agent === "codex" && installationInputs.some((root2) => path === root2 || path.startsWith(`${root2}${sep5}`)))
|
|
42654
42757
|
return scan;
|
|
42655
42758
|
if (!existsSync6(path))
|
|
42656
42759
|
return scan;
|
|
@@ -43131,6 +43234,8 @@ function atomicWrite2(path, content) {
|
|
|
43131
43234
|
}
|
|
43132
43235
|
}
|
|
43133
43236
|
function planAgentSettingsWitnessUpgrade(options) {
|
|
43237
|
+
if (options.targetCodexVersion !== undefined && (options.agent !== "codex" || ![2, 3].includes(options.targetCodexVersion)))
|
|
43238
|
+
throw new Error("Invalid Codex witness target version");
|
|
43134
43239
|
const home = resolve15(options.home ?? homedir3()), dataDir2 = options.dataDir ?? getDataDirReadOnly();
|
|
43135
43240
|
const snapshot2 = readManagedSkillPolicySnapshot(dataDir2);
|
|
43136
43241
|
if (!snapshot2 || sha4(snapshot2.text) !== options.expectedPolicySha256)
|
|
@@ -43152,21 +43257,21 @@ function planAgentSettingsWitnessUpgrade(options) {
|
|
|
43152
43257
|
throw new Error("Settings witness upgrade requires a preserved settings preimage");
|
|
43153
43258
|
const replaced = [previous];
|
|
43154
43259
|
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
|
|
43260
|
+
if (previous.hashMode !== undefined && previous.hashMode !== "bytes" && previous.hashMode !== "codex-settings-v1" && !(options.targetCodexVersion === 3 && previous.hashMode === "codex-settings-v2"))
|
|
43261
|
+
throw new Error("Codex settings witness upgrade requires an eligible preserved configuration witness");
|
|
43157
43262
|
const preimage = readCodexSettingsPreimage(options.reviewedPreimage);
|
|
43158
43263
|
for (const source of binding.sources) {
|
|
43159
43264
|
if (source === previous || source.path !== configPath)
|
|
43160
43265
|
continue;
|
|
43161
43266
|
const fields2 = source.fields;
|
|
43162
|
-
if (source.hashMode !== undefined || source.format !== "toml" || !Array.isArray(fields2) || !
|
|
43267
|
+
if (source.hashMode !== undefined || source.format !== "toml" || !Array.isArray(fields2) || !isDeepStrictEqual6(fields2, [...CODEX_DISCOVERY_PROJECTION_FIELDS]) || typeof source.sha256 !== "string")
|
|
43163
43268
|
throw new Error("Codex settings witness upgrade found an unrecognized configuration witness");
|
|
43164
43269
|
if (projectNativeDiscoveryFields(preimage, "toml", fields2, configPath) !== source.sha256)
|
|
43165
43270
|
throw new Error("Reviewed preimage does not explain the Codex discovery projection witness");
|
|
43166
43271
|
replaced.push(source);
|
|
43167
43272
|
}
|
|
43168
43273
|
}
|
|
43169
|
-
const next = options.agent === "claude" ? upgradeClaudeSettingsWitness(previous, options.reviewedPreimage) : upgradeCodexSettingsWitness(previous, options.reviewedPreimage);
|
|
43274
|
+
const next = options.agent === "claude" ? upgradeClaudeSettingsWitness(previous, options.reviewedPreimage) : options.targetCodexVersion === 3 ? upgradeCodexSettingsWitnessV3(previous, options.reviewedPreimage) : upgradeCodexSettingsWitness(previous, options.reviewedPreimage);
|
|
43170
43275
|
const rebound = [];
|
|
43171
43276
|
for (const source of binding.sources) {
|
|
43172
43277
|
if (!replaced.includes(source)) {
|
|
@@ -43203,7 +43308,7 @@ function applyAgentIntegration(plan) {
|
|
|
43203
43308
|
const upgrade = plan.settingsWitnessUpgrade;
|
|
43204
43309
|
if (!plan.managedAgentChecks || !plan.observedPolicy?.before)
|
|
43205
43310
|
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 });
|
|
43311
|
+
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
43312
|
if (JSON.stringify(verified.changes) !== JSON.stringify(plan.changes) || JSON.stringify(verified.settingsWitnessUpgrade) !== JSON.stringify(upgrade))
|
|
43208
43313
|
throw new Error("Settings witness upgrade plan changed");
|
|
43209
43314
|
provenDiscovery = verified.discoveryBefore[0];
|
|
@@ -43624,22 +43729,22 @@ function canonicalizeManifest(raw) {
|
|
|
43624
43729
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
43625
43730
|
return normalizeLineEndings(raw);
|
|
43626
43731
|
}
|
|
43627
|
-
const
|
|
43628
|
-
delete
|
|
43629
|
-
if (
|
|
43630
|
-
delete
|
|
43732
|
+
const record4 = parsed;
|
|
43733
|
+
delete record4.content_hash;
|
|
43734
|
+
if (record4.provenance && typeof record4.provenance === "object" && !Array.isArray(record4.provenance)) {
|
|
43735
|
+
delete record4.provenance.content_hash;
|
|
43631
43736
|
}
|
|
43632
|
-
return `${JSON.stringify(sortObjectKeys(
|
|
43737
|
+
return `${JSON.stringify(sortObjectKeys(record4), null, 2)}
|
|
43633
43738
|
`;
|
|
43634
43739
|
}
|
|
43635
43740
|
function sortObjectKeys(value) {
|
|
43636
43741
|
if (Array.isArray(value))
|
|
43637
43742
|
return value.map((item) => sortObjectKeys(item));
|
|
43638
43743
|
if (typeof value === "object" && value !== null) {
|
|
43639
|
-
const
|
|
43744
|
+
const record4 = value;
|
|
43640
43745
|
const sorted = Object.create(null);
|
|
43641
|
-
for (const key of Object.keys(
|
|
43642
|
-
sorted[key] = sortObjectKeys(
|
|
43746
|
+
for (const key of Object.keys(record4).sort())
|
|
43747
|
+
sorted[key] = sortObjectKeys(record4[key]);
|
|
43643
43748
|
return sorted;
|
|
43644
43749
|
}
|
|
43645
43750
|
return value;
|
|
@@ -43778,10 +43883,10 @@ function contentRecord(value, allowed) {
|
|
|
43778
43883
|
return result;
|
|
43779
43884
|
}
|
|
43780
43885
|
function contentOptions(options) {
|
|
43781
|
-
const
|
|
43886
|
+
const record4 = contentRecord(options, ["limits", "signal"]);
|
|
43782
43887
|
const limits = { ...CONTENT_HASH_LIMITS };
|
|
43783
|
-
if (
|
|
43784
|
-
const supplied = contentRecord(
|
|
43888
|
+
if (record4.limits !== undefined) {
|
|
43889
|
+
const supplied = contentRecord(record4.limits, Object.keys(limits));
|
|
43785
43890
|
for (const key of Object.keys(supplied)) {
|
|
43786
43891
|
const value = supplied[key];
|
|
43787
43892
|
if (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0 || value > limits[key])
|
|
@@ -43789,9 +43894,9 @@ function contentOptions(options) {
|
|
|
43789
43894
|
limits[key] = value;
|
|
43790
43895
|
}
|
|
43791
43896
|
}
|
|
43792
|
-
if (
|
|
43897
|
+
if (record4.signal !== undefined && !(record4.signal instanceof AbortSignal))
|
|
43793
43898
|
invalidContent("Invalid content hash signal");
|
|
43794
|
-
return { limits, signal:
|
|
43899
|
+
return { limits, signal: record4.signal };
|
|
43795
43900
|
}
|
|
43796
43901
|
var typedArrayPrototype = Object.getPrototypeOf(Uint8Array.prototype);
|
|
43797
43902
|
var byteLengthOf = Object.getOwnPropertyDescriptor(typedArrayPrototype, "byteLength").get;
|
|
@@ -46996,44 +47101,44 @@ async function subprocess(command, cwd, env, input, timeoutMs) {
|
|
|
46996
47101
|
// src/lib/remote-run-contract.ts
|
|
46997
47102
|
var REMOTE_SKILL_RUN_CONTRACT_VERSION = 1;
|
|
46998
47103
|
function normalizeRemoteSkillRunContract(payload, fallbackSkill) {
|
|
46999
|
-
const
|
|
47104
|
+
const record4 = isRecord4(payload) ? payload : {};
|
|
47000
47105
|
return {
|
|
47001
47106
|
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(
|
|
47107
|
+
...pickString(record4, "id"),
|
|
47108
|
+
skill: pickStringValue(record4, "skill") ?? fallbackSkill,
|
|
47109
|
+
...pickString(record4, "requestedSlug"),
|
|
47110
|
+
...pickString(record4, "status"),
|
|
47111
|
+
...pickNumber(record4, "exitCode"),
|
|
47112
|
+
...pickString(record4, "correlationId"),
|
|
47113
|
+
...pickString(record4, "createdAt"),
|
|
47114
|
+
...pickString(record4, "startedAt"),
|
|
47115
|
+
...pickString(record4, "completedAt"),
|
|
47116
|
+
...pickNumber(record4, "durationMs"),
|
|
47117
|
+
...pickString(record4, "outputType"),
|
|
47118
|
+
...hasOwn(record4, "outputPreview") ? { outputPreview: record4.outputPreview } : {},
|
|
47119
|
+
...pickString(record4, "errorCode"),
|
|
47120
|
+
...pickString(record4, "errorMessage"),
|
|
47121
|
+
...pickString(record4, "error"),
|
|
47122
|
+
...pickString(record4, "code"),
|
|
47123
|
+
...hasOwn(record4, "details") ? { details: record4.details } : {}
|
|
47019
47124
|
};
|
|
47020
47125
|
}
|
|
47021
47126
|
function isRecord4(value) {
|
|
47022
47127
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
47023
47128
|
}
|
|
47024
|
-
function hasOwn(
|
|
47025
|
-
return Object.prototype.hasOwnProperty.call(
|
|
47129
|
+
function hasOwn(record4, key) {
|
|
47130
|
+
return Object.prototype.hasOwnProperty.call(record4, key);
|
|
47026
47131
|
}
|
|
47027
|
-
function pickString(
|
|
47028
|
-
const value = pickStringValue(
|
|
47132
|
+
function pickString(record4, key) {
|
|
47133
|
+
const value = pickStringValue(record4, key);
|
|
47029
47134
|
return value === undefined ? {} : { [key]: value };
|
|
47030
47135
|
}
|
|
47031
|
-
function pickStringValue(
|
|
47032
|
-
const value =
|
|
47136
|
+
function pickStringValue(record4, key) {
|
|
47137
|
+
const value = record4[key];
|
|
47033
47138
|
return typeof value === "string" ? value : undefined;
|
|
47034
47139
|
}
|
|
47035
|
-
function pickNumber(
|
|
47036
|
-
const value =
|
|
47140
|
+
function pickNumber(record4, key) {
|
|
47141
|
+
const value = record4[key];
|
|
47037
47142
|
return typeof value === "number" && Number.isFinite(value) ? { [key]: value } : {};
|
|
47038
47143
|
}
|
|
47039
47144
|
|
|
@@ -57653,8 +57758,8 @@ function revisionIdOf(content) {
|
|
|
57653
57758
|
const canonical6 = JSON.stringify(canonicalContent);
|
|
57654
57759
|
return createHash24("sha256").update(canonical6).digest("hex");
|
|
57655
57760
|
}
|
|
57656
|
-
function revisionIdOfRecord(
|
|
57657
|
-
return revisionIdOf(
|
|
57761
|
+
function revisionIdOfRecord(record4) {
|
|
57762
|
+
return revisionIdOf(record4);
|
|
57658
57763
|
}
|
|
57659
57764
|
|
|
57660
57765
|
// src/server/sqlite-store.ts
|
|
@@ -57696,11 +57801,11 @@ class SqliteSkillsStore {
|
|
|
57696
57801
|
backfillLegacyRevisions() {
|
|
57697
57802
|
const rows = this.all("SELECT * FROM skills_registry WHERE revision_id = ''", []);
|
|
57698
57803
|
for (const row of rows) {
|
|
57699
|
-
const
|
|
57804
|
+
const record4 = rowToSkill(row);
|
|
57700
57805
|
this.db.run("UPDATE skills_registry SET revision_id = ? WHERE org_id = ? AND slug = ?", [
|
|
57701
|
-
revisionIdOfRecord(
|
|
57702
|
-
|
|
57703
|
-
|
|
57806
|
+
revisionIdOfRecord(record4),
|
|
57807
|
+
record4.orgId,
|
|
57808
|
+
record4.slug
|
|
57704
57809
|
]);
|
|
57705
57810
|
}
|
|
57706
57811
|
}
|
|
@@ -58250,12 +58355,12 @@ class SqliteSkillsStore {
|
|
|
58250
58355
|
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
58356
|
const purged = [];
|
|
58252
58357
|
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(
|
|
58358
|
+
const record4 = rowToSkill(row);
|
|
58359
|
+
this.db.run("DELETE FROM skills_registry WHERE org_id = ? AND slug = ?", [principal.orgId, record4.slug]);
|
|
58360
|
+
this.db.run("DELETE FROM skills_tags WHERE org_id = ? AND slug = ?", [principal.orgId, record4.slug]);
|
|
58361
|
+
if (record4.bundleSha256)
|
|
58362
|
+
this.collectOrphanBundle(principal.orgId, record4.bundleSha256);
|
|
58363
|
+
purged.push(record4);
|
|
58259
58364
|
}
|
|
58260
58365
|
return purged;
|
|
58261
58366
|
})();
|
|
@@ -58772,35 +58877,35 @@ function skillLifecyclePatch(body) {
|
|
|
58772
58877
|
throw new SkillRequestError(400, "INVALID_LIFECYCLE", "replacementSlug must be a valid skill slug");
|
|
58773
58878
|
return { lifecycle: body.lifecycle, ...body.reason ? { reason: body.reason } : {}, ...body.replacementSlug ? { replacementSlug: body.replacementSlug } : {} };
|
|
58774
58879
|
}
|
|
58775
|
-
function publishedSkillMeta(
|
|
58880
|
+
function publishedSkillMeta(record4) {
|
|
58776
58881
|
return {
|
|
58777
|
-
name:
|
|
58778
|
-
displayName:
|
|
58779
|
-
description:
|
|
58780
|
-
category:
|
|
58781
|
-
tags:
|
|
58782
|
-
...
|
|
58783
|
-
kind:
|
|
58882
|
+
name: record4.slug,
|
|
58883
|
+
displayName: record4.displayName,
|
|
58884
|
+
description: record4.description,
|
|
58885
|
+
category: record4.category,
|
|
58886
|
+
tags: record4.tags,
|
|
58887
|
+
...record4.version ? { version: record4.version } : {},
|
|
58888
|
+
kind: record4.kind,
|
|
58784
58889
|
source: "remote",
|
|
58785
58890
|
availability: { status: "available" }
|
|
58786
58891
|
};
|
|
58787
58892
|
}
|
|
58788
|
-
function publishedPayload(
|
|
58893
|
+
function publishedPayload(record4, opts = {}) {
|
|
58789
58894
|
return {
|
|
58790
|
-
...publishedSkillMeta(
|
|
58791
|
-
slug:
|
|
58792
|
-
publishedSource:
|
|
58895
|
+
...publishedSkillMeta(record4),
|
|
58896
|
+
slug: record4.slug,
|
|
58897
|
+
publishedSource: record4.source,
|
|
58793
58898
|
...opts.alreadyPublished ? { alreadyPublished: true } : {},
|
|
58794
|
-
...
|
|
58795
|
-
...
|
|
58796
|
-
publishedAt:
|
|
58797
|
-
updatedAt:
|
|
58798
|
-
revisionId:
|
|
58799
|
-
revisionNumber:
|
|
58800
|
-
lifecycle:
|
|
58801
|
-
...
|
|
58802
|
-
...
|
|
58803
|
-
...
|
|
58899
|
+
...record4.skillMd ? { skillMd: record4.skillMd } : {},
|
|
58900
|
+
...record4.bundleSha256 ? { bundleSha256: record4.bundleSha256, bundleByteSize: record4.bundleByteSize } : {},
|
|
58901
|
+
publishedAt: record4.createdAt,
|
|
58902
|
+
updatedAt: record4.updatedAt,
|
|
58903
|
+
revisionId: record4.revisionId,
|
|
58904
|
+
revisionNumber: record4.revisionNumber,
|
|
58905
|
+
lifecycle: record4.lifecycle,
|
|
58906
|
+
...record4.archivedAt ? { archivedAt: record4.archivedAt } : {},
|
|
58907
|
+
...record4.archiveReason ? { archiveReason: record4.archiveReason } : {},
|
|
58908
|
+
...record4.replacementSlug ? { replacementSlug: record4.replacementSlug } : {}
|
|
58804
58909
|
};
|
|
58805
58910
|
}
|
|
58806
58911
|
function revisionEtag(revisionId) {
|
|
@@ -58819,10 +58924,10 @@ function parseIfMatch(value) {
|
|
|
58819
58924
|
}
|
|
58820
58925
|
return unquoted;
|
|
58821
58926
|
}
|
|
58822
|
-
async function tombstoneStatus(store, artifactStorage, principal,
|
|
58823
|
-
if (!
|
|
58927
|
+
async function tombstoneStatus(store, artifactStorage, principal, record4) {
|
|
58928
|
+
if (!record4.tombstonedAt)
|
|
58824
58929
|
return "live";
|
|
58825
|
-
if (
|
|
58930
|
+
if (record4.tombstonePurgeAfter && record4.tombstonePurgeAfter <= new Date().toISOString()) {
|
|
58826
58931
|
const purged = await store.purgeExpiredTombstones(principal);
|
|
58827
58932
|
for (const removed of purged) {
|
|
58828
58933
|
if (removed.bundleSha256)
|
|
@@ -58831,33 +58936,33 @@ async function tombstoneStatus(store, artifactStorage, principal, record3) {
|
|
|
58831
58936
|
return "purged";
|
|
58832
58937
|
}
|
|
58833
58938
|
return {
|
|
58834
|
-
slug:
|
|
58939
|
+
slug: record4.slug,
|
|
58835
58940
|
deleted: true,
|
|
58836
58941
|
code: "TOMBSTONED",
|
|
58837
|
-
tombstonedAt:
|
|
58838
|
-
tombstonePurgeAfter:
|
|
58839
|
-
revisionId:
|
|
58942
|
+
tombstonedAt: record4.tombstonedAt,
|
|
58943
|
+
tombstonePurgeAfter: record4.tombstonePurgeAfter,
|
|
58944
|
+
revisionId: record4.revisionId
|
|
58840
58945
|
};
|
|
58841
58946
|
}
|
|
58842
58947
|
async function listMergedSkills(store, principal) {
|
|
58843
|
-
return (await store.listSkills(principal)).filter((
|
|
58948
|
+
return (await store.listSkills(principal)).filter((record4) => record4.lifecycle === "active").sort((a3, b3) => a3.slug.localeCompare(b3.slug)).map((record4) => publishedPayload(record4));
|
|
58844
58949
|
}
|
|
58845
58950
|
async function resolvePublishedSkill(store, artifactStorage, principal, slug) {
|
|
58846
|
-
const
|
|
58847
|
-
if (!
|
|
58951
|
+
const record4 = await store.getSkill(principal, slug);
|
|
58952
|
+
if (!record4)
|
|
58848
58953
|
return { kind: "absent" };
|
|
58849
|
-
const status = await tombstoneStatus(store, artifactStorage, principal,
|
|
58954
|
+
const status = await tombstoneStatus(store, artifactStorage, principal, record4);
|
|
58850
58955
|
if (status === "purged")
|
|
58851
58956
|
return { kind: "absent" };
|
|
58852
58957
|
if (status !== "live")
|
|
58853
58958
|
return { kind: "tombstone", payload: status };
|
|
58854
|
-
return { kind: "published", record:
|
|
58959
|
+
return { kind: "published", record: record4 };
|
|
58855
58960
|
}
|
|
58856
58961
|
async function listOrgTags(store, principal) {
|
|
58857
58962
|
return [...new Set((await store.listTags(principal)).filter((tag) => tag.trim()))].sort();
|
|
58858
58963
|
}
|
|
58859
58964
|
async function listMergedSkillsByTag(store, principal, tag) {
|
|
58860
|
-
return (await store.listSkillsByTag(principal, tag)).filter((
|
|
58965
|
+
return (await store.listSkillsByTag(principal, tag)).filter((record4) => record4.lifecycle === "active").sort((a3, b3) => a3.slug.localeCompare(b3.slug)).map((record4) => publishedPayload(record4));
|
|
58861
58966
|
}
|
|
58862
58967
|
function skillSummary(skill) {
|
|
58863
58968
|
return {
|
|
@@ -58998,16 +59103,16 @@ async function storePublishedSkill(store, artifactStorage, principal, parsed, ex
|
|
|
58998
59103
|
};
|
|
58999
59104
|
}
|
|
59000
59105
|
}
|
|
59001
|
-
let
|
|
59106
|
+
let record4;
|
|
59002
59107
|
try {
|
|
59003
|
-
|
|
59108
|
+
record4 = await store.publishSkill(input);
|
|
59004
59109
|
} catch (error) {
|
|
59005
59110
|
if (input.bundle?.sha256) {
|
|
59006
59111
|
await discardCollectedObject(store, artifactStorage, principal, input.bundle.sha256);
|
|
59007
59112
|
}
|
|
59008
59113
|
throw error;
|
|
59009
59114
|
}
|
|
59010
|
-
if (superseded && superseded !==
|
|
59115
|
+
if (superseded && superseded !== record4.bundleSha256) {
|
|
59011
59116
|
await discardCollectedObject(store, artifactStorage, principal, superseded);
|
|
59012
59117
|
}
|
|
59013
59118
|
if (writeVersionObjects && versionManifest && parsed.bundleBytes && input.bundle) {
|
|
@@ -59017,7 +59122,7 @@ async function storePublishedSkill(store, artifactStorage, principal, parsed, ex
|
|
|
59017
59122
|
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
59123
|
}
|
|
59019
59124
|
}
|
|
59020
|
-
return { record:
|
|
59125
|
+
return { record: record4, alreadyPublished: existingVersion !== null };
|
|
59021
59126
|
}
|
|
59022
59127
|
async function deletePublishedSkill(store, artifactStorage, principal, slug, tombstoneWindowMs) {
|
|
59023
59128
|
return store.deleteSkill(principal, slug, tombstoneWindowMs);
|
|
@@ -59028,23 +59133,23 @@ async function discardCollectedObject(store, artifactStorage, principal, sha2562
|
|
|
59028
59133
|
await artifactStorage.deleteBundle(principal.orgId, sha2562);
|
|
59029
59134
|
}
|
|
59030
59135
|
async function readPublishedBundle(store, artifactStorage, principal, slug) {
|
|
59031
|
-
const
|
|
59032
|
-
if (!
|
|
59136
|
+
const record4 = await store.getSkill(principal, slug);
|
|
59137
|
+
if (!record4)
|
|
59033
59138
|
throw new SkillRequestError(404, "SKILL_NOT_FOUND", "skill not found");
|
|
59034
|
-
if (!
|
|
59139
|
+
if (!record4.bundleSha256)
|
|
59035
59140
|
throw new SkillRequestError(404, "BUNDLE_NOT_FOUND", `skill '${slug}' was published without a bundle`);
|
|
59036
|
-
const bundle2 = await store.getSkillBundle(principal,
|
|
59141
|
+
const bundle2 = await store.getSkillBundle(principal, record4.bundleSha256);
|
|
59037
59142
|
if (!bundle2)
|
|
59038
|
-
throw new SkillRequestError(404, "BUNDLE_NOT_FOUND", `no stored bundle for digest ${
|
|
59143
|
+
throw new SkillRequestError(404, "BUNDLE_NOT_FOUND", `no stored bundle for digest ${record4.bundleSha256}`);
|
|
59039
59144
|
const bytes = await artifactStorage.readBundle(bundle2);
|
|
59040
59145
|
if (!bytes) {
|
|
59041
59146
|
throw new SkillRequestError(503, "BUNDLE_BACKEND_UNAVAILABLE", "bundle storage backend unavailable");
|
|
59042
59147
|
}
|
|
59043
59148
|
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 ${
|
|
59149
|
+
if (actual !== record4.bundleSha256) {
|
|
59150
|
+
throw new SkillRequestError(500, "BUNDLE_DIGEST_DRIFT", `stored bundle for '${slug}' hashes to ${actual} but was published as ${record4.bundleSha256}`);
|
|
59046
59151
|
}
|
|
59047
|
-
return { record:
|
|
59152
|
+
return { record: record4, bytes };
|
|
59048
59153
|
}
|
|
59049
59154
|
function assertPublishableSlug(slug) {
|
|
59050
59155
|
if (slug.length > MAX_SLUG_LENGTH || !SLUG_PATTERN.test(slug)) {
|
|
@@ -59153,14 +59258,14 @@ function skillVersionPayload(version2, currentSha) {
|
|
|
59153
59258
|
}
|
|
59154
59259
|
async function listSkillVersionsPayload(store, principal, slug) {
|
|
59155
59260
|
assertPublishableSlug(slug);
|
|
59156
|
-
const
|
|
59261
|
+
const record4 = await store.getSkill(principal, slug);
|
|
59157
59262
|
const versions = await store.listSkillVersions(principal, slug);
|
|
59158
|
-
if (!
|
|
59263
|
+
if (!record4 && !versions.length)
|
|
59159
59264
|
throw new SkillRequestError(404, "SKILL_NOT_FOUND", "skill not found");
|
|
59160
|
-
const currentSha =
|
|
59265
|
+
const currentSha = record4?.bundleSha256;
|
|
59161
59266
|
return {
|
|
59162
59267
|
slug,
|
|
59163
|
-
...
|
|
59268
|
+
...record4?.version ? { currentVersion: record4.version } : {},
|
|
59164
59269
|
...currentSha ? { currentBundleSha256: currentSha } : {},
|
|
59165
59270
|
versions: versions.map((version2) => skillVersionPayload(version2, currentSha))
|
|
59166
59271
|
};
|
|
@@ -59612,10 +59717,10 @@ function sortKeys(value) {
|
|
|
59612
59717
|
if (Array.isArray(value))
|
|
59613
59718
|
return value.map(sortKeys);
|
|
59614
59719
|
if (value !== null && typeof value === "object") {
|
|
59615
|
-
const
|
|
59720
|
+
const record4 = value;
|
|
59616
59721
|
const sorted = Object.create(null);
|
|
59617
|
-
for (const key of Object.keys(
|
|
59618
|
-
sorted[key] = sortKeys(
|
|
59722
|
+
for (const key of Object.keys(record4).sort()) {
|
|
59723
|
+
sorted[key] = sortKeys(record4[key]);
|
|
59619
59724
|
}
|
|
59620
59725
|
return sorted;
|
|
59621
59726
|
}
|
|
@@ -60539,14 +60644,14 @@ function createRunStateMachine(store) {
|
|
|
60539
60644
|
const next2 = await store.setRunStatus(runId3, to);
|
|
60540
60645
|
if (!next2)
|
|
60541
60646
|
return { ok: false, reason: "NO_SUCH_RUN" };
|
|
60542
|
-
const
|
|
60647
|
+
const record4 = {
|
|
60543
60648
|
runId: runId3,
|
|
60544
60649
|
attemptId,
|
|
60545
60650
|
from,
|
|
60546
60651
|
to,
|
|
60547
60652
|
at: new Date().toISOString()
|
|
60548
60653
|
};
|
|
60549
|
-
await store.recordTransition(
|
|
60654
|
+
await store.recordTransition(record4);
|
|
60550
60655
|
return { ok: true };
|
|
60551
60656
|
}
|
|
60552
60657
|
return {
|
|
@@ -65265,7 +65370,7 @@ class MemorySkillsStore {
|
|
|
65265
65370
|
}
|
|
65266
65371
|
const carriedBundle = !input.bundle && previous?.bundleSha256 ? { bundleSha256: previous.bundleSha256, ...previous.bundleByteSize === undefined ? {} : { bundleByteSize: previous.bundleByteSize } } : {};
|
|
65267
65372
|
const carriedSkillMd = typeof input.skillMd === "string" ? input.skillMd : previous?.skillMd;
|
|
65268
|
-
const
|
|
65373
|
+
const record4 = {
|
|
65269
65374
|
orgId: input.principal.orgId,
|
|
65270
65375
|
slug: input.slug,
|
|
65271
65376
|
displayName: input.displayName,
|
|
@@ -65287,7 +65392,7 @@ class MemorySkillsStore {
|
|
|
65287
65392
|
...previous?.archiveReason ? { archiveReason: previous.archiveReason } : {},
|
|
65288
65393
|
...previous?.replacementSlug ? { replacementSlug: previous.replacementSlug } : {}
|
|
65289
65394
|
};
|
|
65290
|
-
this.skills.set(key,
|
|
65395
|
+
this.skills.set(key, record4);
|
|
65291
65396
|
if (input.version && versionSha && !this.versions.has(versionKey(input.principal.orgId, input.slug, input.version))) {
|
|
65292
65397
|
this.versions.set(versionKey(input.principal.orgId, input.slug, input.version), {
|
|
65293
65398
|
orgId: input.principal.orgId,
|
|
@@ -65305,7 +65410,7 @@ class MemorySkillsStore {
|
|
|
65305
65410
|
if (previous?.bundleSha256 && input.bundle && previous.bundleSha256 !== input.bundle.sha256) {
|
|
65306
65411
|
this.collectOrphanBundle(input.principal.orgId, previous.bundleSha256);
|
|
65307
65412
|
}
|
|
65308
|
-
return
|
|
65413
|
+
return record4;
|
|
65309
65414
|
}
|
|
65310
65415
|
async listSkillVersions(principal, slug) {
|
|
65311
65416
|
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 +65620,8 @@ class PostgresSkillsStore {
|
|
|
65515
65620
|
async backfillLegacyRevisions() {
|
|
65516
65621
|
const rows = await this.sql`SELECT * FROM skills_registry WHERE revision_id = ${""}`;
|
|
65517
65622
|
for (const row of rows) {
|
|
65518
|
-
const
|
|
65519
|
-
await this.sql`UPDATE skills_registry SET revision_id = ${revisionIdOfRecord(
|
|
65623
|
+
const record4 = rowToSkill(row);
|
|
65624
|
+
await this.sql`UPDATE skills_registry SET revision_id = ${revisionIdOfRecord(record4)} WHERE org_id = ${record4.orgId} AND slug = ${record4.slug}`;
|
|
65520
65625
|
}
|
|
65521
65626
|
}
|
|
65522
65627
|
async close() {
|
|
@@ -66105,23 +66210,23 @@ class PostgresSkillsStore {
|
|
|
66105
66210
|
return [];
|
|
66106
66211
|
const purged = [];
|
|
66107
66212
|
for (const row of expiredRows) {
|
|
66108
|
-
const
|
|
66213
|
+
const record4 = rowToSkill(row);
|
|
66109
66214
|
await tx`
|
|
66110
|
-
DELETE FROM skills_registry WHERE org_id = ${principal.orgId} AND slug = ${
|
|
66215
|
+
DELETE FROM skills_registry WHERE org_id = ${principal.orgId} AND slug = ${record4.slug} AND tombstone_purge_after <= now()
|
|
66111
66216
|
`;
|
|
66112
|
-
await tx`DELETE FROM skills_tags WHERE org_id = ${principal.orgId} AND slug = ${
|
|
66217
|
+
await tx`DELETE FROM skills_tags WHERE org_id = ${principal.orgId} AND slug = ${record4.slug}`;
|
|
66113
66218
|
await tx`
|
|
66114
|
-
DELETE FROM skills_registry WHERE org_id = ${principal.orgId} AND slug = ${
|
|
66219
|
+
DELETE FROM skills_registry WHERE org_id = ${principal.orgId} AND slug = ${record4.slug} AND tombstone_purge_after <= now()
|
|
66115
66220
|
`;
|
|
66116
|
-
if (
|
|
66221
|
+
if (record4.bundleSha256) {
|
|
66117
66222
|
await tx`
|
|
66118
66223
|
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 = ${
|
|
66224
|
+
WHERE org_id = ${principal.orgId} AND sha256 = ${record4.bundleSha256}
|
|
66225
|
+
AND NOT EXISTS (SELECT 1 FROM skills_registry WHERE org_id = ${principal.orgId} AND bundle_sha256 = ${record4.bundleSha256})
|
|
66226
|
+
AND NOT EXISTS (SELECT 1 FROM skills_versions WHERE org_id = ${principal.orgId} AND bundle_sha256 = ${record4.bundleSha256})
|
|
66122
66227
|
`;
|
|
66123
66228
|
}
|
|
66124
|
-
purged.push(
|
|
66229
|
+
purged.push(record4);
|
|
66125
66230
|
}
|
|
66126
66231
|
return purged;
|
|
66127
66232
|
});
|
|
@@ -66420,8 +66525,8 @@ async function handleApiV1(store, governanceStore, principal, request2, parts, c
|
|
|
66420
66525
|
if (request2.method === "POST" && !id2) {
|
|
66421
66526
|
const expectedRevisionId = parseIfMatch(request2.headers.get("if-match"));
|
|
66422
66527
|
const parsed = await parsePublishRequest(request2, config);
|
|
66423
|
-
const { record:
|
|
66424
|
-
return json4(publishedPayload(
|
|
66528
|
+
const { record: record4, alreadyPublished } = await storePublishedSkill(store, artifactStorage, principal, parsed, expectedRevisionId);
|
|
66529
|
+
return json4(publishedPayload(record4, { alreadyPublished }), { status: 201, headers: { ETag: revisionEtag(record4.revisionId) } });
|
|
66425
66530
|
}
|
|
66426
66531
|
if (request2.method === "GET" && id2 && subresource === "skill.md") {
|
|
66427
66532
|
const resolved = await resolvePublishedSkill(store, artifactStorage, principal, id2);
|
|
@@ -66469,15 +66574,15 @@ async function handleApiV1(store, governanceStore, principal, request2, parts, c
|
|
|
66469
66574
|
if (resolved.kind === "absent") {
|
|
66470
66575
|
return json4({ error: "skill not found", code: "SKILL_NOT_FOUND" }, { status: 404 });
|
|
66471
66576
|
}
|
|
66472
|
-
const { record:
|
|
66577
|
+
const { record: record4, bytes } = await readPublishedBundle(store, artifactStorage, principal, id2);
|
|
66473
66578
|
const headers = {
|
|
66474
66579
|
"Content-Type": "application/gzip",
|
|
66475
66580
|
"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(
|
|
66581
|
+
"Content-Disposition": `attachment; filename="${record4.slug}.tar.gz"`,
|
|
66582
|
+
"X-Skill-Bundle-Sha256": record4.bundleSha256 ?? "",
|
|
66583
|
+
"X-Skill-Revision-Id": record4.revisionId,
|
|
66584
|
+
"X-Skill-Revision-Number": String(record4.revisionNumber),
|
|
66585
|
+
ETag: revisionEtag(record4.revisionId),
|
|
66481
66586
|
"Cache-Control": "no-store"
|
|
66482
66587
|
};
|
|
66483
66588
|
if (config.bundleSigningKey) {
|
|
@@ -66715,7 +66820,7 @@ var bundledRegistry = {
|
|
|
66715
66820
|
isValidSlug: isValidSkillSlug
|
|
66716
66821
|
};
|
|
66717
66822
|
var currentVersionService = {
|
|
66718
|
-
resolveVersion: (
|
|
66823
|
+
resolveVersion: (record4) => record4.version
|
|
66719
66824
|
};
|
|
66720
66825
|
// node_modules/zod/v3/external.js
|
|
66721
66826
|
var exports_external = {};
|
|
@@ -71113,7 +71218,7 @@ __export(exports_external2, {
|
|
|
71113
71218
|
regexes: () => exports_regexes,
|
|
71114
71219
|
regex: () => _regex,
|
|
71115
71220
|
refine: () => refine,
|
|
71116
|
-
record: () =>
|
|
71221
|
+
record: () => record4,
|
|
71117
71222
|
readonly: () => readonly,
|
|
71118
71223
|
property: () => _property,
|
|
71119
71224
|
properties: () => _properties,
|
|
@@ -86887,8 +86992,8 @@ function rewriteKeyNames(ctx) {
|
|
|
86887
86992
|
bySchema.set(entry.schema, entry);
|
|
86888
86993
|
}
|
|
86889
86994
|
const rewrites = new Map;
|
|
86890
|
-
for (const
|
|
86891
|
-
const seen = ctx.seen.get(
|
|
86995
|
+
for (const record4 of pendingRecords.get(ctx) ?? []) {
|
|
86996
|
+
const seen = ctx.seen.get(record4);
|
|
86892
86997
|
const names = (seen?.def ?? seen?.schema)?.propertyNames;
|
|
86893
86998
|
if (!names || names === true || rewrites.has(names))
|
|
86894
86999
|
continue;
|
|
@@ -87215,7 +87320,7 @@ __export(exports_schemas2, {
|
|
|
87215
87320
|
strictObject: () => strictObject,
|
|
87216
87321
|
set: () => set,
|
|
87217
87322
|
refine: () => refine,
|
|
87218
|
-
record: () =>
|
|
87323
|
+
record: () => record4,
|
|
87219
87324
|
readonly: () => readonly,
|
|
87220
87325
|
promise: () => promise,
|
|
87221
87326
|
preprocess: () => preprocess,
|
|
@@ -88385,7 +88490,7 @@ var ZodRecord2 = /* @__PURE__ */ $constructor("ZodRecord", (inst, def) => {
|
|
|
88385
88490
|
inst.keyType = def.keyType;
|
|
88386
88491
|
inst.valueType = def.valueType;
|
|
88387
88492
|
});
|
|
88388
|
-
function
|
|
88493
|
+
function record4(keyType, valueType, params) {
|
|
88389
88494
|
if (!valueType || !valueType._zod) {
|
|
88390
88495
|
return new ZodRecord2({
|
|
88391
88496
|
type: "record",
|
|
@@ -88851,7 +88956,7 @@ var stringbool = (...args) => _stringbool({
|
|
|
88851
88956
|
}, ...args);
|
|
88852
88957
|
function json5(params) {
|
|
88853
88958
|
const jsonSchema = lazy(() => {
|
|
88854
|
-
return union([string2(params), number2(), boolean2(), _null3(), array2(jsonSchema),
|
|
88959
|
+
return union([string2(params), number2(), boolean2(), _null3(), array2(jsonSchema), record4(string2(), jsonSchema)]);
|
|
88855
88960
|
});
|
|
88856
88961
|
return jsonSchema;
|
|
88857
88962
|
}
|
|
@@ -90074,12 +90179,12 @@ class RemoteWorkspaceInvitationReadError extends Error {
|
|
|
90074
90179
|
}
|
|
90075
90180
|
}
|
|
90076
90181
|
function invitationFailure(value, status) {
|
|
90077
|
-
if (!
|
|
90182
|
+
if (!record5(value) || typeof value.code !== "string" || !Object.hasOwn(invitationFailures, value.code))
|
|
90078
90183
|
return null;
|
|
90079
90184
|
const code = value.code;
|
|
90080
90185
|
return invitationFailures[code][0] === status ? code : null;
|
|
90081
90186
|
}
|
|
90082
|
-
var
|
|
90187
|
+
var record5 = (v2) => !!v2 && typeof v2 === "object" && !Array.isArray(v2);
|
|
90083
90188
|
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
90189
|
var role = (v2) => typeof v2 === "string" && ["owner", "admin", "member", "viewer"].includes(v2);
|
|
90085
90190
|
var email3 = (v2) => typeof v2 === "string" && v2.length <= 254 && !/[\p{Cc}\p{Cs}\u2028\u2029\s]/u.test(v2) && /^[^@]+@[^@]+\.[^@]+$/.test(v2);
|
|
@@ -90088,7 +90193,7 @@ var inputFailure = () => {
|
|
|
90088
90193
|
throw new WorkspaceInvitationInputError;
|
|
90089
90194
|
};
|
|
90090
90195
|
function invitationInput(action, input2) {
|
|
90091
|
-
if (!
|
|
90196
|
+
if (!record5(input2))
|
|
90092
90197
|
return inputFailure();
|
|
90093
90198
|
const keys3 = {
|
|
90094
90199
|
list: ["after"],
|
|
@@ -90139,7 +90244,7 @@ function invalid5() {
|
|
|
90139
90244
|
throw new RemoteWorkspaceInvitationReadError;
|
|
90140
90245
|
}
|
|
90141
90246
|
function projection(v2, organizationId) {
|
|
90142
|
-
if (!
|
|
90247
|
+
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
90248
|
return invalid5();
|
|
90144
90249
|
return {
|
|
90145
90250
|
id: v2.id,
|
|
@@ -90154,7 +90259,7 @@ function projection(v2, organizationId) {
|
|
|
90154
90259
|
};
|
|
90155
90260
|
}
|
|
90156
90261
|
function parseInvitationResult(action, value, input2, organizationId) {
|
|
90157
|
-
if (!
|
|
90262
|
+
if (!record5(value))
|
|
90158
90263
|
return invalid5();
|
|
90159
90264
|
const request2 = input2;
|
|
90160
90265
|
if (action === "accept") {
|
|
@@ -90187,7 +90292,7 @@ function parseInvitationResult(action, value, input2, organizationId) {
|
|
|
90187
90292
|
}
|
|
90188
90293
|
|
|
90189
90294
|
// src/lib/remote-workspace-selection.ts
|
|
90190
|
-
var
|
|
90295
|
+
var record6 = (v2) => !!v2 && typeof v2 === "object" && !Array.isArray(v2);
|
|
90191
90296
|
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
90297
|
var text2 = (v2, max = 1024) => typeof v2 === "string" && !!v2.trim() && v2.length <= max && !/[\p{Cc}\p{Cs}\u2028\u2029]/u.test(v2);
|
|
90193
90298
|
var role2 = (v2) => typeof v2 === "string" && ["owner", "admin", "member", "viewer"].includes(v2);
|
|
@@ -90212,7 +90317,7 @@ function workspaceExpectedUserId(value) {
|
|
|
90212
90317
|
return value;
|
|
90213
90318
|
}
|
|
90214
90319
|
function workspaceContext(value) {
|
|
90215
|
-
if (!
|
|
90320
|
+
if (!record6(value) || Object.keys(value).sort().join(",") !== "membershipId,userId" || !uuid8(value.userId) || !uuid8(value.membershipId))
|
|
90216
90321
|
throw new WorkspaceContextInputError;
|
|
90217
90322
|
return { userId: value.userId, membershipId: value.membershipId };
|
|
90218
90323
|
}
|
|
@@ -90220,15 +90325,15 @@ function invalid6() {
|
|
|
90220
90325
|
throw new Error(invalidWorkspaceResult);
|
|
90221
90326
|
}
|
|
90222
90327
|
function organization(v2) {
|
|
90223
|
-
if (!
|
|
90328
|
+
if (!record6(v2) || !uuid8(v2.id) || !text2(v2.slug) || !text2(v2.name))
|
|
90224
90329
|
return invalid6();
|
|
90225
90330
|
return { id: v2.id, slug: v2.slug, name: v2.name };
|
|
90226
90331
|
}
|
|
90227
90332
|
function parseAccountWorkspaces(value) {
|
|
90228
|
-
if (!
|
|
90333
|
+
if (!record6(value) || !Array.isArray(value.workspaces) || !value.workspaces.length || value.workspaces.length > 1000)
|
|
90229
90334
|
return invalid6();
|
|
90230
90335
|
const workspaces = value.workspaces.map((v2) => {
|
|
90231
|
-
if (!
|
|
90336
|
+
if (!record6(v2) || !uuid8(v2.membershipId) || !role2(v2.role) || typeof v2.current !== "boolean")
|
|
90232
90337
|
return invalid6();
|
|
90233
90338
|
return { membershipId: v2.membershipId, organization: organization(v2.organization), role: v2.role, current: v2.current };
|
|
90234
90339
|
});
|
|
@@ -90237,10 +90342,10 @@ function parseAccountWorkspaces(value) {
|
|
|
90237
90342
|
return { workspaces };
|
|
90238
90343
|
}
|
|
90239
90344
|
function parseWorkspaceIdentity(value, expectedUserId) {
|
|
90240
|
-
if (!
|
|
90345
|
+
if (!record6(value))
|
|
90241
90346
|
return invalid6();
|
|
90242
90347
|
const user = value.user;
|
|
90243
|
-
if (!
|
|
90348
|
+
if (!record6(user) || !uuid8(user.id) || !uuid8(user.membershipId) || !text2(user.email, 320) || !(user.displayName === null || text2(user.displayName)) || !role2(user.role))
|
|
90244
90349
|
return invalid6();
|
|
90245
90350
|
if (user.id !== expectedUserId)
|
|
90246
90351
|
throw new WorkspaceIdentityMismatchError;
|
|
@@ -90258,8 +90363,8 @@ function parseWorkspaceSession(value, expected) {
|
|
|
90258
90363
|
return { token: sessionToken(value.token), ...identity4 };
|
|
90259
90364
|
}
|
|
90260
90365
|
function parseWorkspaceLogin(value, expectedUserId) {
|
|
90261
|
-
const user =
|
|
90262
|
-
if (!
|
|
90366
|
+
const user = record6(value) && value.user;
|
|
90367
|
+
if (!record6(value) || !record6(user) || !uuid8(user.id))
|
|
90263
90368
|
return invalid6();
|
|
90264
90369
|
if (expectedUserId !== undefined && user.id !== expectedUserId)
|
|
90265
90370
|
throw new WorkspaceIdentityMismatchError;
|
|
@@ -90274,18 +90379,18 @@ var workspaceSelectionFailures = {
|
|
|
90274
90379
|
WORKSPACE_BUSY: [503, "Workspace is busy. Refresh before retrying."]
|
|
90275
90380
|
};
|
|
90276
90381
|
function workspaceSelectionFailure(value, status) {
|
|
90277
|
-
if (!
|
|
90382
|
+
if (!record6(value) || typeof value.code !== "string" || !Object.hasOwn(workspaceSelectionFailures, value.code))
|
|
90278
90383
|
return null;
|
|
90279
90384
|
const code = value.code;
|
|
90280
90385
|
return workspaceSelectionFailures[code][0] === status ? code : null;
|
|
90281
90386
|
}
|
|
90282
90387
|
|
|
90283
90388
|
// src/lib/remote-workspace.ts
|
|
90284
|
-
var
|
|
90389
|
+
var record7 = (value) => !!value && typeof value === "object" && !Array.isArray(value);
|
|
90285
90390
|
var cursor = (value) => typeof value === "string" && /^[A-Za-z0-9_-]{1,512}$/.test(value);
|
|
90286
90391
|
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
90392
|
function workspaceMembersQuery(options = {}) {
|
|
90288
|
-
if (!
|
|
90393
|
+
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
90394
|
throw new Error("Use a roster limit from 1 to 100 and an unchanged continuation cursor.");
|
|
90290
90395
|
const query = new URLSearchParams;
|
|
90291
90396
|
if (options.limit !== undefined)
|
|
@@ -90301,7 +90406,7 @@ function timestamp2(value) {
|
|
|
90301
90406
|
return Number.isFinite(time4) && new Date(time4).toISOString().slice(0, 23) === value.slice(0, 23);
|
|
90302
90407
|
}
|
|
90303
90408
|
function parseMember(row, fail) {
|
|
90304
|
-
if (!
|
|
90409
|
+
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
90410
|
return fail();
|
|
90306
90411
|
return {
|
|
90307
90412
|
membershipId: row.membershipId,
|
|
@@ -90321,7 +90426,7 @@ class WorkspaceMemberInputError extends Error {
|
|
|
90321
90426
|
}
|
|
90322
90427
|
}
|
|
90323
90428
|
function mutationInput(membershipId, input2, roleChange) {
|
|
90324
|
-
if (typeof membershipId !== "string" || !uuid10(membershipId) || membershipId !== membershipId.toLowerCase() || !
|
|
90429
|
+
if (typeof membershipId !== "string" || !uuid10(membershipId) || membershipId !== membershipId.toLowerCase() || !record7(input2) || Object.keys(input2).sort().join(",") !== (roleChange ? "expectedRole,role" : "expectedRole"))
|
|
90325
90430
|
throw new WorkspaceMemberInputError;
|
|
90326
90431
|
const expectedRole = input2.expectedRole, role3 = roleChange ? input2.role : undefined;
|
|
90327
90432
|
if (!isRole(expectedRole) || roleChange && !isRole(role3))
|
|
@@ -90341,7 +90446,7 @@ function parseWorkspaceMemberRoleResult(value, membershipId, role3) {
|
|
|
90341
90446
|
const fail = () => {
|
|
90342
90447
|
throw new Error(invalidMemberResult);
|
|
90343
90448
|
};
|
|
90344
|
-
if (!
|
|
90449
|
+
if (!record7(value) || !uuid10(value.organizationId) || typeof value.changed !== "boolean")
|
|
90345
90450
|
return fail();
|
|
90346
90451
|
const member = parseMember(value.member, fail);
|
|
90347
90452
|
if (member.membershipId !== membershipId || member.role !== role3)
|
|
@@ -90349,7 +90454,7 @@ function parseWorkspaceMemberRoleResult(value, membershipId, role3) {
|
|
|
90349
90454
|
return { organizationId: value.organizationId, member, changed: value.changed };
|
|
90350
90455
|
}
|
|
90351
90456
|
function parseWorkspaceMemberRemovalResult(value, membershipId) {
|
|
90352
|
-
if (!
|
|
90457
|
+
if (!record7(value) || !uuid10(value.organizationId) || value.membershipId !== membershipId || value.removed !== true || typeof value.alreadyRemoved !== "boolean")
|
|
90353
90458
|
throw new Error(invalidMemberResult);
|
|
90354
90459
|
return { organizationId: value.organizationId, membershipId, removed: true, alreadyRemoved: value.alreadyRemoved };
|
|
90355
90460
|
}
|
|
@@ -90366,7 +90471,7 @@ var workspaceMemberFailures = {
|
|
|
90366
90471
|
MEMBERSHIP_BUSY: [503, "Membership is busy. Refresh the roster before another action."]
|
|
90367
90472
|
};
|
|
90368
90473
|
function workspaceMemberFailure(value, status) {
|
|
90369
|
-
if (!
|
|
90474
|
+
if (!record7(value) || typeof value.code !== "string" || !Object.hasOwn(workspaceMemberFailures, value.code))
|
|
90370
90475
|
return null;
|
|
90371
90476
|
const code = value.code;
|
|
90372
90477
|
return workspaceMemberFailures[code][0] === status ? code : null;
|
|
@@ -90375,7 +90480,7 @@ function parseWorkspaceMembersPage(value) {
|
|
|
90375
90480
|
const fail = () => {
|
|
90376
90481
|
throw new Error("The server returned an invalid workspace roster.");
|
|
90377
90482
|
};
|
|
90378
|
-
if (!
|
|
90483
|
+
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
90484
|
return fail();
|
|
90380
90485
|
const members2 = value.members.map((row) => parseMember(row, fail));
|
|
90381
90486
|
if (new Set(members2.map((row) => row.membershipId)).size !== members2.length)
|
|
@@ -90664,11 +90769,11 @@ var permissionNames = [
|
|
|
90664
90769
|
"executionGrantsWrite",
|
|
90665
90770
|
"executionGrantsResolve"
|
|
90666
90771
|
];
|
|
90667
|
-
var
|
|
90772
|
+
var record8 = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
90668
90773
|
function parseSkillsAccess(value) {
|
|
90669
90774
|
if (value === undefined)
|
|
90670
90775
|
return {};
|
|
90671
|
-
if (!
|
|
90776
|
+
if (!record8(value))
|
|
90672
90777
|
throw new Error("Invalid Skills permission contract");
|
|
90673
90778
|
const result = {};
|
|
90674
90779
|
if (value.scopes !== undefined) {
|
|
@@ -90677,7 +90782,7 @@ function parseSkillsAccess(value) {
|
|
|
90677
90782
|
result.scopes = [...value.scopes];
|
|
90678
90783
|
}
|
|
90679
90784
|
if (value.permissions !== undefined) {
|
|
90680
|
-
if (!
|
|
90785
|
+
if (!record8(value.permissions))
|
|
90681
90786
|
throw new Error("Invalid Skills permission contract");
|
|
90682
90787
|
result.permissions = {};
|
|
90683
90788
|
for (const name of permissionNames) {
|
|
@@ -91574,13 +91679,13 @@ class RemoteSkillsClient {
|
|
|
91574
91679
|
return normalizeUpdatedSincePage(await response.json());
|
|
91575
91680
|
}
|
|
91576
91681
|
}
|
|
91577
|
-
function requireOptionalString(
|
|
91578
|
-
if (
|
|
91682
|
+
function requireOptionalString(record9, field2) {
|
|
91683
|
+
if (record9[field2] === undefined)
|
|
91579
91684
|
return;
|
|
91580
|
-
if (typeof
|
|
91685
|
+
if (typeof record9[field2] !== "string") {
|
|
91581
91686
|
throw new Error(`Remote payload did not match the expected contract (${field2} must be a string when present)`);
|
|
91582
91687
|
}
|
|
91583
|
-
return
|
|
91688
|
+
return record9[field2];
|
|
91584
91689
|
}
|
|
91585
91690
|
var INVALID_SKILL_VERSION_RESPONSE = "Remote skill version payload did not match the expected contract.";
|
|
91586
91691
|
function isVersionRecord(value) {
|
|
@@ -91603,19 +91708,19 @@ function normalizePin(entry) {
|
|
|
91603
91708
|
if (!entry || typeof entry !== "object") {
|
|
91604
91709
|
throw new Error("Remote pin payload did not match the expected contract (expected an object)");
|
|
91605
91710
|
}
|
|
91606
|
-
const
|
|
91607
|
-
const slug2 = typeof
|
|
91711
|
+
const record9 = entry;
|
|
91712
|
+
const slug2 = typeof record9.slug === "string" && record9.slug.trim() ? record9.slug.trim() : undefined;
|
|
91608
91713
|
if (!slug2) {
|
|
91609
91714
|
throw new Error("Remote pin payload did not match the expected contract (missing slug)");
|
|
91610
91715
|
}
|
|
91611
91716
|
let metadata;
|
|
91612
|
-
if (
|
|
91613
|
-
if (!
|
|
91717
|
+
if (record9.metadata !== undefined) {
|
|
91718
|
+
if (!record9.metadata || typeof record9.metadata !== "object" || Array.isArray(record9.metadata)) {
|
|
91614
91719
|
throw new Error("Remote pin payload did not match the expected contract (metadata must be a JSON object when present)");
|
|
91615
91720
|
}
|
|
91616
|
-
metadata =
|
|
91721
|
+
metadata = record9.metadata;
|
|
91617
91722
|
}
|
|
91618
|
-
const pinnedAt = requireOptionalString(
|
|
91723
|
+
const pinnedAt = requireOptionalString(record9, "pinnedAt");
|
|
91619
91724
|
return {
|
|
91620
91725
|
slug: slug2,
|
|
91621
91726
|
...pinnedAt !== undefined ? { pinnedAt } : {},
|
|
@@ -91632,16 +91737,16 @@ function normalizeSkillSummary(entry) {
|
|
|
91632
91737
|
if (!entry || typeof entry !== "object") {
|
|
91633
91738
|
throw new Error("Remote skill payload did not match the expected contract (expected an object)");
|
|
91634
91739
|
}
|
|
91635
|
-
const
|
|
91636
|
-
const slug2 = typeof
|
|
91740
|
+
const record9 = entry;
|
|
91741
|
+
const slug2 = typeof record9.slug === "string" && record9.slug.trim() ? record9.slug.trim() : undefined;
|
|
91637
91742
|
if (!slug2) {
|
|
91638
91743
|
throw new Error("Remote skill payload did not match the expected contract (missing slug)");
|
|
91639
91744
|
}
|
|
91640
91745
|
return {
|
|
91641
91746
|
slug: slug2,
|
|
91642
|
-
...requireOptionalString(
|
|
91643
|
-
...requireOptionalString(
|
|
91644
|
-
...requireOptionalString(
|
|
91747
|
+
...requireOptionalString(record9, "name") !== undefined ? { name: requireOptionalString(record9, "name") } : {},
|
|
91748
|
+
...requireOptionalString(record9, "version") !== undefined ? { version: requireOptionalString(record9, "version") } : {},
|
|
91749
|
+
...requireOptionalString(record9, "updatedAt") !== undefined ? { updatedAt: requireOptionalString(record9, "updatedAt") } : {}
|
|
91645
91750
|
};
|
|
91646
91751
|
}
|
|
91647
91752
|
function normalizeSkillSummaryList(payload) {
|
|
@@ -91698,12 +91803,12 @@ function normalizeUpdatedSincePage(payload) {
|
|
|
91698
91803
|
if (!payload || typeof payload !== "object") {
|
|
91699
91804
|
throw new Error("Updated-since payload did not match the expected contract (expected an object)");
|
|
91700
91805
|
}
|
|
91701
|
-
const
|
|
91702
|
-
if (!Array.isArray(
|
|
91806
|
+
const record9 = payload;
|
|
91807
|
+
if (!Array.isArray(record9.skills)) {
|
|
91703
91808
|
throw new Error("Updated-since payload did not match the expected contract (missing skills array)");
|
|
91704
91809
|
}
|
|
91705
|
-
const skills =
|
|
91706
|
-
const nextCursor =
|
|
91810
|
+
const skills = record9.skills.map(normalizeSkillSummary);
|
|
91811
|
+
const nextCursor = record9.nextCursor === undefined || record9.nextCursor === null ? null : record9.nextCursor;
|
|
91707
91812
|
if (nextCursor !== null && typeof nextCursor !== "string") {
|
|
91708
91813
|
throw new Error("Updated-since payload did not match the expected contract (nextCursor must be a string or absent)");
|
|
91709
91814
|
}
|
|
@@ -91750,7 +91855,7 @@ class RemoteInvitationEmailUnconfirmedError extends Error {
|
|
|
91750
91855
|
this.name = "RemoteInvitationEmailUnconfirmedError";
|
|
91751
91856
|
}
|
|
91752
91857
|
}
|
|
91753
|
-
var
|
|
91858
|
+
var record9 = (v2) => !!v2 && typeof v2 === "object" && !Array.isArray(v2);
|
|
91754
91859
|
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
91860
|
function invitationEmailIds(invitationId, challengeId) {
|
|
91756
91861
|
if (!uuid11(invitationId) || !uuid11(challengeId))
|
|
@@ -91759,7 +91864,7 @@ function invitationEmailIds(invitationId, challengeId) {
|
|
|
91759
91864
|
}
|
|
91760
91865
|
function invitationEmailInput(action, input2) {
|
|
91761
91866
|
const keys3 = ["invitationId", "token", "challengeId", "confirm", ...action === "accept" ? ["code"] : []];
|
|
91762
|
-
if (!
|
|
91867
|
+
if (!record9(input2) || Object.keys(input2).length !== keys3.length || keys3.some((key) => !Object.hasOwn(input2, key)))
|
|
91763
91868
|
throw new InvitationEmailInputError;
|
|
91764
91869
|
const value = { ...input2 };
|
|
91765
91870
|
const ids = invitationEmailIds(value.invitationId, value.challengeId);
|
|
@@ -91788,12 +91893,12 @@ async function requestInvitationEmail(origin, action, input2) {
|
|
|
91788
91893
|
signal: AbortSignal.timeout(15000)
|
|
91789
91894
|
});
|
|
91790
91895
|
const parsed = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(await readBoundedResponse(response, 4096)));
|
|
91791
|
-
if (!response.ok &&
|
|
91896
|
+
if (!response.ok && record9(parsed) && typeof parsed.code === "string" && Object.hasOwn(refusals, parsed.code)) {
|
|
91792
91897
|
const code = parsed.code;
|
|
91793
91898
|
if (response.status === refusals[code][0])
|
|
91794
91899
|
throw new RemoteInvitationEmailError(code);
|
|
91795
91900
|
}
|
|
91796
|
-
if (!
|
|
91901
|
+
if (!record9(parsed))
|
|
91797
91902
|
throw new RemoteInvitationEmailUnconfirmedError(action);
|
|
91798
91903
|
if (action === "challenge" && response.status === 202 && parsed.challengeId === value.challengeId && parsed.expiresIn === 600 && typeof parsed.message === "string" && parsed.message.length <= 256) {
|
|
91799
91904
|
return { challengeId: value.challengeId, message: "If this invitation is eligible, a verification code will arrive. Delivery is not confirmed.", expiresIn: 600 };
|
|
@@ -91853,8 +91958,8 @@ var invalid7 = () => {
|
|
|
91853
91958
|
};
|
|
91854
91959
|
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
91960
|
var hash4 = (v2) => typeof v2 === "string" && /^[a-f0-9]{64}$/.test(v2);
|
|
91856
|
-
var
|
|
91857
|
-
var exact = (v2, keys3) =>
|
|
91961
|
+
var record10 = (v2) => !!v2 && typeof v2 === "object" && !Array.isArray(v2);
|
|
91962
|
+
var exact = (v2, keys3) => record10(v2) && Object.keys(v2).sort().join(",") === keys3.sort().join(",");
|
|
91858
91963
|
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
91964
|
var publicationSha256 = (bytes) => createHash33("sha256").update(bytes).digest("hex");
|
|
91860
91965
|
function checkedPublicationDeclaration(value) {
|
|
@@ -91862,7 +91967,7 @@ function checkedPublicationDeclaration(value) {
|
|
|
91862
91967
|
return bad();
|
|
91863
91968
|
try {
|
|
91864
91969
|
const manifest = JSON.parse(value.manifestText);
|
|
91865
|
-
if (!
|
|
91970
|
+
if (!record10(manifest) || manifest.version !== value.version || validatePortableManifestContract(manifest, { strict: true }).length || !hash4(manifest.provenance?.content_hash))
|
|
91866
91971
|
return bad();
|
|
91867
91972
|
} catch {
|
|
91868
91973
|
return bad();
|
|
@@ -91920,7 +92025,7 @@ async function boundedJson(url2, init, token, mutation, budget2 = 15000, signal)
|
|
|
91920
92025
|
return invalid7();
|
|
91921
92026
|
}
|
|
91922
92027
|
if (!response.ok) {
|
|
91923
|
-
const code =
|
|
92028
|
+
const code = record10(body4) && typeof body4.code === "string" && Object.hasOwn(failures2, body4.code) ? body4.code : null;
|
|
91924
92029
|
if (code && failures2[code][0] === response.status)
|
|
91925
92030
|
throw new PrivatePublicationError(code, failures2[code][1], mutation && code === "PUBLICATION_UNCERTAIN", response.status);
|
|
91926
92031
|
throw new PrivatePublicationError("PUBLICATION_REQUEST_FAILED", "The publication request was refused. Inspect its status before retrying.", mutation && response.status >= 500, response.status);
|
|
@@ -91975,8 +92080,8 @@ class RemotePrivatePublicationsClient {
|
|
|
91975
92080
|
if (options.timeoutMs !== undefined && (!Number.isSafeInteger(options.timeoutMs) || options.timeoutMs < 1 || options.timeoutMs > 15000))
|
|
91976
92081
|
return bad();
|
|
91977
92082
|
const response = await boundedJson(skillsApiRequestUrl(this.apiOrigin, "/api/v1/capabilities"), {}, this.#token, false, options.timeoutMs, options.signal);
|
|
91978
|
-
const p2 =
|
|
91979
|
-
if (!
|
|
92083
|
+
const p2 = record10(response) && response.privatePublishing;
|
|
92084
|
+
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
92085
|
throw new PrivatePublicationError("PUBLICATION_CONTRACT_UNAVAILABLE", "This server does not support the hosted private publication contract.");
|
|
91981
92086
|
return Object.freeze({ ...p2 });
|
|
91982
92087
|
}
|
|
@@ -91992,7 +92097,7 @@ class RemotePrivatePublicationsClient {
|
|
|
91992
92097
|
async#view(path2, method, skillId, intentId, declaration, options = {}) {
|
|
91993
92098
|
const value = await boundedJson(path2, { method, ...method === "GET" ? {} : { body: JSON.stringify(declaration ?? {}) } }, this.#token, method !== "GET", options.timeoutMs, options.signal);
|
|
91994
92099
|
try {
|
|
91995
|
-
if (!
|
|
92100
|
+
if (!record10(value) || !Object.keys(value).every((k4) => k4 === "upload" || k4 === "changed") || value.changed !== undefined && typeof value.changed !== "boolean")
|
|
91996
92101
|
return invalid7();
|
|
91997
92102
|
return checkedPublicationView(value.upload, skillId, intentId, declaration);
|
|
91998
92103
|
} catch (error61) {
|
|
@@ -92155,10 +92260,10 @@ async function requestAuthApi(instance, path2, options) {
|
|
|
92155
92260
|
const text3 = await res.text();
|
|
92156
92261
|
const body4 = text3 ? parseJsonBody(text3) : {};
|
|
92157
92262
|
if (!res.ok) {
|
|
92158
|
-
const
|
|
92159
|
-
const detail = typeof
|
|
92160
|
-
const error61 = typeof
|
|
92161
|
-
const code = typeof
|
|
92263
|
+
const record11 = isRecord7(body4) ? body4 : {};
|
|
92264
|
+
const detail = typeof record11.detail === "string" ? record11.detail : undefined;
|
|
92265
|
+
const error61 = typeof record11.error === "string" ? record11.error : undefined;
|
|
92266
|
+
const code = typeof record11.code === "string" ? record11.code : undefined;
|
|
92162
92267
|
throw new HostedApiError(detail || error61 || `${res.status} ${res.statusText}`, {
|
|
92163
92268
|
status: res.status,
|
|
92164
92269
|
code,
|
|
@@ -92592,7 +92697,7 @@ var requestIdPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]
|
|
|
92592
92697
|
function validId(value) {
|
|
92593
92698
|
return typeof value === "string" && requestIdPattern.test(value);
|
|
92594
92699
|
}
|
|
92595
|
-
function
|
|
92700
|
+
function record11(value) {
|
|
92596
92701
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
92597
92702
|
}
|
|
92598
92703
|
function exact2(value, names) {
|
|
@@ -92679,7 +92784,7 @@ function snapshot2(value, maximum) {
|
|
|
92679
92784
|
function requestSnapshot(input2) {
|
|
92680
92785
|
try {
|
|
92681
92786
|
const owned = snapshot2(input2, SKILL_OPERATION_LIMITS.requestBytes), value = owned.value;
|
|
92682
|
-
if (!
|
|
92787
|
+
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
92788
|
throw Error();
|
|
92684
92789
|
return { ...owned, value };
|
|
92685
92790
|
} catch {
|
|
@@ -92689,7 +92794,7 @@ function requestSnapshot(input2) {
|
|
|
92689
92794
|
function resultSnapshot(input2, requestId) {
|
|
92690
92795
|
try {
|
|
92691
92796
|
const value = snapshot2(input2, SKILL_OPERATION_LIMITS.resultBytes).value;
|
|
92692
|
-
if (!
|
|
92797
|
+
if (!record11(value) || value.contractVersion !== 1 || value.requestId !== requestId)
|
|
92693
92798
|
throw Error();
|
|
92694
92799
|
const fields2 = ["contractVersion", "requestId", "status"];
|
|
92695
92800
|
if (value.status === "succeeded")
|