@hasna/skills 0.10.25 → 0.10.27

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