@hasna/skills 0.10.26 → 0.10.28

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