@hasna/skills 0.10.26 → 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/bin/mcp.js CHANGED
@@ -20019,7 +20019,7 @@ var package_default;
20019
20019
  var init_package = __esm(() => {
20020
20020
  package_default = {
20021
20021
  name: "@hasna/skills",
20022
- version: "0.10.26",
20022
+ version: "0.10.27",
20023
20023
  description: "Skills library for AI coding agents",
20024
20024
  type: "module",
20025
20025
  bin: {
@@ -38316,8 +38316,8 @@ function assertAgentPolicyCollections(policy) {
38316
38316
  text(source.path);
38317
38317
  requireBound(source.sha256 === null || typeof source.sha256 === "string" && /^[a-f0-9]{64}$/.test(source.sha256));
38318
38318
  if (source.hashMode !== undefined)
38319
- 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));
38320
- if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2")
38319
+ 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));
38320
+ if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3")
38321
38321
  requireBound(agent === "codex" && value.agent === "codex" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute3(source.path) && resolve2(source.path) === source.path && basename3(source.path) === "config.toml");
38322
38322
  if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3")
38323
38323
  requireBound(agent === "claude" && value.agent === "claude" && value.method === "reviewed" && !/[\x00-\x1f\x7f]/.test(source.path) && isAbsolute3(source.path) && resolve2(source.path) === source.path && basename3(source.path) === "settings.json");
@@ -47237,6 +47237,72 @@ async function prepareSkillDependencies(skillPath, env, timeoutMs = DEFAULT_PREP
47237
47237
  var DEPENDENCY_PREPARATION_MARKER = ".skills-dependency-preparation", RECOVERY = "Skill dependency preparation is incomplete. Confirm no installer is running, successfully run bun install --no-save in the skill directory, then remove only .skills-dependency-preparation. See docs/skill-standard.md#recovering-interrupted-dependency-preparation.", DEFAULT_PREPARATION_TIMEOUT_MS = 60000;
47238
47238
  var init_dependency_preparation = () => {};
47239
47239
 
47240
+ // src/lib/codex-local-mcp-controls.ts
47241
+ function isCodexLocalStdioMcpServer(name, server) {
47242
+ const identifier2 = (value) => typeof value === "string" && /^[A-Za-z0-9_-]{1,64}$/.test(value);
47243
+ const refuse = () => {
47244
+ throw new Error("Unsupported Codex local stdio MCP controls");
47245
+ };
47246
+ const object7 = (v) => Boolean(v && typeof v === "object" && !Array.isArray(v) && !(v instanceof Date));
47247
+ const textField = (v, empty = false) => typeof v === "string" && (empty || Boolean(v.trim())) && Buffer.byteLength(v) <= 16384 && !/[\x00-\x1f\x7f]/.test(v);
47248
+ const envName = (v) => typeof v === "string" && /^[A-Za-z_][A-Za-z0-9_]{0,255}$/.test(v);
47249
+ const optional3 = (v, valid) => v === undefined || v === null || valid(v);
47250
+ const stringList = (v) => Array.isArray(v) && v.length <= 256 && v.every((item) => textField(item));
47251
+ const approval = (v) => ["auto", "prompt", "writes", "approve"].includes(v);
47252
+ const duration3 = (v) => typeof v === "number" && Number.isFinite(v) && v >= 0;
47253
+ const positiveInteger = (v) => Number.isSafeInteger(v) && v > 0;
47254
+ const fields = [
47255
+ "command",
47256
+ "args",
47257
+ "cwd",
47258
+ "env",
47259
+ "env_vars",
47260
+ "enabled",
47261
+ "required",
47262
+ "environment_id",
47263
+ "startup_readiness",
47264
+ "supports_parallel_tool_calls",
47265
+ "tool_input_schema_max_bytes",
47266
+ "startup_timeout_sec",
47267
+ "startup_timeout_ms",
47268
+ "tool_timeout_sec",
47269
+ "default_tools_approval_mode",
47270
+ "enabled_tools",
47271
+ "disabled_tools",
47272
+ "omit_tools_from",
47273
+ "tools",
47274
+ "name"
47275
+ ];
47276
+ try {
47277
+ if (!identifier2(name) || !object7(server) || !Object.keys(server).every((key) => fields.includes(key)) || !textField(server.command) || !optional3(server.args, (v) => Array.isArray(v) && v.length <= 256 && v.every((arg) => textField(arg, true))) || !optional3(server.cwd, textField) || !optional3(server.env, (v) => object7(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) => optional3(server[key], (v) => typeof v === "boolean")) || !optional3(server.environment_id, (v) => v === "local") || !optional3(server.startup_readiness, (v) => ["connection", "catalog"].includes(v)) || !optional3(server.tool_input_schema_max_bytes, positiveInteger) || !["startup_timeout_sec", "tool_timeout_sec"].every((key) => optional3(server[key], duration3)) || !optional3(server.startup_timeout_ms, (v) => Number.isSafeInteger(v) && v >= 0) || !optional3(server.default_tools_approval_mode, approval) || !["enabled_tools", "disabled_tools"].every((key) => optional3(server[key], stringList)) || !optional3(server.omit_tools_from, (v) => Array.isArray(v) && v.length <= 256 && v.every((item) => ["code_mode", "deferred", "direct"].includes(item))) || !optional3(server.name, textField))
47278
+ refuse();
47279
+ if (server.env_vars !== undefined && server.env_vars !== null) {
47280
+ if (!Array.isArray(server.env_vars) || server.env_vars.length > 256)
47281
+ refuse();
47282
+ const names = server.env_vars.map((entry) => {
47283
+ if (envName(entry))
47284
+ return entry;
47285
+ if (!object7(entry) || !Object.keys(entry).every((key) => ["name", "source"].includes(key)) || !envName(entry.name) || !optional3(entry.source, (v) => v === "local"))
47286
+ refuse();
47287
+ return entry.name;
47288
+ });
47289
+ if (new Set(names).size !== names.length)
47290
+ refuse();
47291
+ }
47292
+ if (server.tools !== undefined && server.tools !== null) {
47293
+ if (!object7(server.tools) || Object.keys(server.tools).length > 256)
47294
+ refuse();
47295
+ for (const [tool, config2] of Object.entries(server.tools)) {
47296
+ if (!textField(tool) || !object7(config2) || !Object.keys(config2).every((key) => ["approval_mode", "output_token_limit"].includes(key)) || !optional3(config2.approval_mode, approval) || !optional3(config2.output_token_limit, positiveInteger))
47297
+ refuse();
47298
+ }
47299
+ }
47300
+ return true;
47301
+ } catch {
47302
+ return false;
47303
+ }
47304
+ }
47305
+
47240
47306
  // src/lib/claude-settings-witness.ts
47241
47307
  import { createHash as createHash8 } from "crypto";
47242
47308
  import { closeSync as closeSync8, constants as constants5, fstatSync as fstatSync8, lstatSync as lstatSync10, openSync as openSync8, readSync as readSync4 } from "fs";
@@ -47688,6 +47754,71 @@ var init_codex_settings_witness_v1 = __esm(() => {
47688
47754
  VERBOSITY = new Set(["low", "medium", "high"]);
47689
47755
  });
47690
47756
 
47757
+ // src/lib/codex-mcp-discovery-projection.ts
47758
+ import { isDeepStrictEqual as isDeepStrictEqual2 } from "util";
47759
+ function record4(value) {
47760
+ return !!value && typeof value === "object" && !Array.isArray(value) && !(value instanceof Date);
47761
+ }
47762
+ function localStdio(name, row) {
47763
+ return name !== "codex_apps" && name !== "_codex_apps" && isCodexLocalStdioMcpServer(name, row);
47764
+ }
47765
+ function stripEmptyParent(config2) {
47766
+ if (record4(config2.mcp_servers) && !Object.keys(config2.mcp_servers).length)
47767
+ delete config2.mcp_servers;
47768
+ return config2;
47769
+ }
47770
+ function projectRegularCodexMcp(config2, source) {
47771
+ const unchanged2 = { config: config2, numericSource: source };
47772
+ if (!record4(config2.mcp_servers))
47773
+ return unchanged2;
47774
+ const candidates = Object.entries(config2.mcp_servers).filter(([name, row]) => localStdio(name, row)).map(([name]) => name);
47775
+ if (!candidates.length)
47776
+ return unchanged2;
47777
+ const headers = [];
47778
+ let attempts = 0;
47779
+ for (const match of source.matchAll(/^[ \t]*\[{1,2}[^\r\n]*\]{1,2}[ \t]*(?:#[^\r\n]*)?(?:\r?\n|$)/gm)) {
47780
+ if (++attempts > 256)
47781
+ return unchanged2;
47782
+ try {
47783
+ Bun.TOML.parse(source.slice(0, match.index));
47784
+ } catch {
47785
+ continue;
47786
+ }
47787
+ let header;
47788
+ try {
47789
+ header = Bun.TOML.parse(match[0]);
47790
+ } catch {
47791
+ return unchanged2;
47792
+ }
47793
+ const path = [];
47794
+ while (record4(header) && Object.keys(header).length === 1) {
47795
+ const key = Object.keys(header)[0];
47796
+ path.push(key);
47797
+ header = header[key];
47798
+ }
47799
+ headers.push({ start: match.index, path });
47800
+ }
47801
+ const names = candidates.filter((name) => headers.filter((header) => header.path.length === 2 && header.path[0] === "mcp_servers" && header.path[1] === name).length === 1);
47802
+ if (!names.length)
47803
+ return unchanged2;
47804
+ 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]));
47805
+ let numericSource = source;
47806
+ for (const range of selected.reverse())
47807
+ numericSource = numericSource.slice(0, range.start) + numericSource.slice(range.end);
47808
+ const expected = structuredClone(config2);
47809
+ for (const name of names)
47810
+ delete expected.mcp_servers[name];
47811
+ stripEmptyParent(expected);
47812
+ try {
47813
+ if (!isDeepStrictEqual2(stripEmptyParent(Bun.TOML.parse(numericSource)), expected))
47814
+ return unchanged2;
47815
+ } catch {
47816
+ return unchanged2;
47817
+ }
47818
+ return { config: expected, numericSource };
47819
+ }
47820
+ var init_codex_mcp_discovery_projection = () => {};
47821
+
47691
47822
  // src/lib/codex-settings-witness.ts
47692
47823
  import { createHash as createHash10 } from "crypto";
47693
47824
  function need4(value) {
@@ -47760,7 +47891,7 @@ function canonical4(value, depth = 0, budget = { remaining: 65536 }) {
47760
47891
  need4(isRecord3(value));
47761
47892
  return ["object", Object.entries(value).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([key, child]) => [key, canonical4(child, depth + 1, budget)])];
47762
47893
  }
47763
- function normalize2(config2) {
47894
+ function normalize2(config2, version2 = 2) {
47764
47895
  if (isRecord3(config2.hooks)) {
47765
47896
  delete config2.hooks.state;
47766
47897
  if (!Object.keys(config2.hooks).length)
@@ -47778,11 +47909,11 @@ function normalize2(config2) {
47778
47909
  if (!Object.keys(skills).length)
47779
47910
  delete config2.skills;
47780
47911
  }
47781
- inference(config2);
47912
+ inference(config2, version2);
47782
47913
  if (isRecord3(config2.profiles)) {
47783
47914
  for (const profile of Object.values(config2.profiles))
47784
47915
  if (isRecord3(profile))
47785
- inference(profile);
47916
+ inference(profile, version2);
47786
47917
  }
47787
47918
  }
47788
47919
  function disablesOneSkill(entry) {
@@ -47794,18 +47925,23 @@ function disablesOneSkill(entry) {
47794
47925
  const selector = ["path", "name"].filter((key) => Object.hasOwn(entry, key));
47795
47926
  return selector.length === 1 && typeof entry[selector[0]] === "string" && entry[selector[0]].length > 0;
47796
47927
  }
47797
- function inference(target) {
47798
- for (const key of INFERENCE)
47928
+ function inference(target, version2) {
47929
+ const keys = version2 === 3 ? [...INFERENCE, "service_tier", "plan_mode_reasoning_effort"] : INFERENCE;
47930
+ for (const key of keys)
47799
47931
  if (Object.hasOwn(target, key)) {
47800
47932
  const value = target[key];
47801
47933
  if (key === "model")
47802
47934
  need4(typeof value === "string" && MODEL.test(value));
47803
- else
47935
+ else if (version2 === 3 && key !== "model_verbosity") {
47936
+ need4(typeof value === "string" && value.length <= 128 && !/[\x00-\x1f\x7f]/.test(value));
47937
+ if (key !== "service_tier")
47938
+ need4(value.length > 0);
47939
+ } else
47804
47940
  need4(typeof value === "string" && (key === "model_reasoning_effort" ? EFFORT2.has(value) : VERBOSITY2.has(value)));
47805
47941
  delete target[key];
47806
47942
  }
47807
47943
  }
47808
- function settingsDigest2(text2) {
47944
+ function settingsDigest2(text2, version2 = 2) {
47809
47945
  let config2;
47810
47946
  try {
47811
47947
  config2 = Bun.TOML.parse(text2);
@@ -47813,8 +47949,9 @@ function settingsDigest2(text2) {
47813
47949
  throw new Error("Invalid Codex settings witness");
47814
47950
  }
47815
47951
  need4(isRecord3(config2));
47816
- normalize2(config2);
47817
- return sha2(`hasna.skills.codex-settings.v2\x00${JSON.stringify([canonical4(config2), numericTokens2(text2)])}`);
47952
+ const projected = version2 === 3 ? projectRegularCodexMcp(config2, text2) : { config: config2, numericSource: text2 };
47953
+ normalize2(projected.config, version2);
47954
+ return sha2(`hasna.skills.codex-settings.v${version2}\x00${JSON.stringify([canonical4(projected.config), numericTokens2(projected.numericSource)])}`);
47818
47955
  }
47819
47956
  function hashCodexSettingsReplacementV2(text2, budget = { remaining: 256 * 1024 * 1024 }) {
47820
47957
  need4(Buffer.byteLength(text2) <= 1024 * 1024 && budget.remaining >= Buffer.byteLength(text2));
@@ -47825,10 +47962,19 @@ function captureCodexSettingsV2(path, budget = { remaining: 256 * 1024 * 1024 })
47825
47962
  const text2 = readNativeSettingsWitnessFile(path, budget, "config.toml");
47826
47963
  return { path, hashMode: "codex-settings-v2", sha256: settingsDigest2(text2) };
47827
47964
  }
47965
+ function hashCodexSettingsReplacementV3(text2, budget = { remaining: 256 * 1024 * 1024 }) {
47966
+ need4(Buffer.byteLength(text2) <= 1024 * 1024 && budget.remaining >= Buffer.byteLength(text2));
47967
+ budget.remaining -= Buffer.byteLength(text2);
47968
+ return settingsDigest2(text2, 3);
47969
+ }
47970
+ function captureCodexSettingsV3(path, budget = { remaining: 256 * 1024 * 1024 }) {
47971
+ return { path, hashMode: "codex-settings-v3", sha256: settingsDigest2(readNativeSettingsWitnessFile(path, budget, "config.toml"), 3) };
47972
+ }
47828
47973
  var sha2 = (text2) => createHash10("sha256").update(text2).digest("hex"), EFFORT2, VERBOSITY2, MODEL, CODEX_DISCOVERY_PROJECTION_FIELDS, INFERENCE;
47829
47974
  var init_codex_settings_witness = __esm(() => {
47830
47975
  init_codex_settings_witness_v1();
47831
47976
  init_codex_settings_witness_v1();
47977
+ init_codex_mcp_discovery_projection();
47832
47978
  init_claude_settings_witness();
47833
47979
  EFFORT2 = new Set(["none", "minimal", "low", "medium", "high", "xhigh"]);
47834
47980
  VERBOSITY2 = new Set(["low", "medium", "high"]);
@@ -49585,7 +49731,7 @@ var init_codex_hook_discovery_recovery = __esm(() => {
49585
49731
  import { createHash as createHash16 } from "crypto";
49586
49732
  import { lstatSync as lstatSync17, readFileSync as readFileSync15, readdirSync as readdirSync7, realpathSync as realpathSync4 } from "fs";
49587
49733
  import { basename as basename8, dirname as dirname15, isAbsolute as isAbsolute13, join as join24, resolve as resolve14, sep as sep5 } from "path";
49588
- import { isDeepStrictEqual as isDeepStrictEqual2 } from "util";
49734
+ import { isDeepStrictEqual as isDeepStrictEqual3 } from "util";
49589
49735
  function parseConfig(text2, path, toml = false) {
49590
49736
  try {
49591
49737
  const value = toml ? Bun.TOML.parse(text2) : JSON.parse(text2);
@@ -49624,19 +49770,19 @@ function projectNativeDiscoveryFields(text2, format, fields2, path) {
49624
49770
  return digest(JSON.stringify(Object.fromEntries(fields2.map((field2) => [field2, object7[field2] ?? null]))));
49625
49771
  }
49626
49772
  function isSupersededCodexProjection(agent, configPath, source) {
49627
- return agent === "codex" && source.path === configPath && source.format === "toml" && isDeepStrictEqual2(source.fields, [...CODEX_DISCOVERY_PROJECTION_FIELDS]);
49773
+ return agent === "codex" && source.path === configPath && source.format === "toml" && isDeepStrictEqual3(source.fields, [...CODEX_DISCOVERY_PROJECTION_FIELDS]);
49628
49774
  }
49629
49775
  function supersedesCodexProjection(sources, configPath) {
49630
- return sources.some((source) => source.path === configPath && source.hashMode === "codex-settings-v2");
49776
+ return sources.some((source) => source.path === configPath && (source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3"));
49631
49777
  }
49632
49778
  function projected(source, changes, budget = discoveryByteBudget()) {
49633
- if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2") {
49779
+ if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3") {
49634
49780
  if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
49635
49781
  throw new Error("Codex settings witnesses require exact typed metadata");
49636
- const current = (source.hashMode === "codex-settings-v2" ? captureCodexSettingsV2 : captureCodexSettings)(source.path, budget).sha256;
49782
+ const current = (source.hashMode === "codex-settings-v3" ? captureCodexSettingsV3 : source.hashMode === "codex-settings-v2" ? captureCodexSettingsV2 : captureCodexSettings)(source.path, budget).sha256;
49637
49783
  if (current !== source.sha256)
49638
49784
  throw new Error(`Native discovery input changed; run skills hook install with a fresh discovery review: ${source.path}`);
49639
- return changes?.has(source.path) ? (source.hashMode === "codex-settings-v2" ? hashCodexSettingsReplacementV2 : hashCodexSettingsReplacement)(changes.get(source.path), budget) : current;
49785
+ return changes?.has(source.path) ? (source.hashMode === "codex-settings-v3" ? hashCodexSettingsReplacementV3 : source.hashMode === "codex-settings-v2" ? hashCodexSettingsReplacementV2 : hashCodexSettingsReplacement)(changes.get(source.path), budget) : current;
49640
49786
  }
49641
49787
  if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") {
49642
49788
  if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
@@ -49736,7 +49882,7 @@ function codexInstallationRoots(binding) {
49736
49882
  });
49737
49883
  }
49738
49884
  function assertMarketplaceBinding(binding, source) {
49739
- if ((source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2") && (binding.agent !== "codex" || binding.method !== "reviewed" || basename8(source.path) !== "config.toml"))
49885
+ if ((source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3") && (binding.agent !== "codex" || binding.method !== "reviewed" || basename8(source.path) !== "config.toml"))
49740
49886
  throw new Error("Codex settings witnesses require explicit reviewed Codex configuration");
49741
49887
  if ((source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") && (binding.agent !== "claude" || binding.method !== "reviewed" || basename8(source.path) !== "settings.json"))
49742
49888
  throw new Error("Claude settings witnesses require explicit reviewed Claude configuration");
@@ -49819,10 +49965,10 @@ function resolveAgentDiscovery(options) {
49819
49965
  verifyAgentDiscovery(retained);
49820
49966
  if (!retained.sources.some((source) => source.path === canonical6(configPath) && source.format === undefined && source.fields === undefined))
49821
49967
  unresolved("retained review is missing the full agent configuration source");
49822
- 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)))
49968
+ 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)))
49823
49969
  unresolved("retained settings witness names another configuration source");
49824
49970
  const covered = supersedesCodexProjection(retained.sources, canonical6(configPath)) ? sources.filter((source) => !isSupersededCodexProjection(agent, canonical6(configPath), source)) : sources;
49825
- if (covered.some((source) => !retained.sources.some((saved) => isDeepStrictEqual2(saved, source))) || [...roots].some((root) => !retained.roots.includes(root)) || agent === "gemini" && JSON.stringify(retained.builtinNames) !== JSON.stringify(builtinNames))
49971
+ if (covered.some((source) => !retained.sources.some((saved) => isDeepStrictEqual3(saved, source))) || [...roots].some((root) => !retained.roots.includes(root)) || agent === "gemini" && JSON.stringify(retained.builtinNames) !== JSON.stringify(builtinNames))
49826
49972
  unresolved("retained review is missing current runtime discovery coverage");
49827
49973
  return retained;
49828
49974
  }
@@ -49836,7 +49982,7 @@ function resolveAgentDiscovery(options) {
49836
49982
  if (review.sources.some((source) => source.format !== undefined || source.fields !== undefined))
49837
49983
  throw new Error("Explicit discovery reviews require full source-file hashes");
49838
49984
  verifyAgentDiscovery(supplied);
49839
- 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)))
49985
+ 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)))
49840
49986
  throw new Error("Semantic settings witnesses must name the configured Claude configuration source");
49841
49987
  if (!review.sources.some((source) => source.path === canonical6(configPath)))
49842
49988
  throw new Error("Discovery review must include the agent configuration source");
@@ -51410,13 +51556,13 @@ var init_remote_recurring = __esm(() => {
51410
51556
 
51411
51557
  // src/lib/remote-invitations.ts
51412
51558
  function invitationFailure(value, status) {
51413
- if (!record4(value) || typeof value.code !== "string" || !Object.hasOwn(invitationFailures, value.code))
51559
+ if (!record5(value) || typeof value.code !== "string" || !Object.hasOwn(invitationFailures, value.code))
51414
51560
  return null;
51415
51561
  const code = value.code;
51416
51562
  return invitationFailures[code][0] === status ? code : null;
51417
51563
  }
51418
51564
  function invitationInput(action, input2) {
51419
- if (!record4(input2))
51565
+ if (!record5(input2))
51420
51566
  return inputFailure();
51421
51567
  const keys = {
51422
51568
  list: ["after"],
@@ -51467,7 +51613,7 @@ function invalid2() {
51467
51613
  throw new RemoteWorkspaceInvitationReadError;
51468
51614
  }
51469
51615
  function projection(v, organizationId) {
51470
- if (!record4(v) || !uuid5(v.id) || v.organizationId !== organizationId || !email3(v.email) || v.email !== v.email.trim().toLowerCase() || !role(v.role) || !Number.isInteger(v.generation) || Number(v.generation) < 1 || Number(v.generation) > 10 || typeof v.status !== "string" || !["pending", "expired", "accepted", "revoked"].includes(v.status) || !timestamp(v.expiresAt) || !timestamp(v.createdAt) || !record4(v.delivery) || typeof v.delivery.state !== "string" || !["queued", "sending", "uncertain", "provider_accepted", "failed", "cancelled"].includes(v.delivery.state) || !Number.isInteger(v.delivery.attempts) || Number(v.delivery.attempts) < 0 || Number(v.delivery.attempts) > 5)
51616
+ if (!record5(v) || !uuid5(v.id) || v.organizationId !== organizationId || !email3(v.email) || v.email !== v.email.trim().toLowerCase() || !role(v.role) || !Number.isInteger(v.generation) || Number(v.generation) < 1 || Number(v.generation) > 10 || typeof v.status !== "string" || !["pending", "expired", "accepted", "revoked"].includes(v.status) || !timestamp(v.expiresAt) || !timestamp(v.createdAt) || !record5(v.delivery) || typeof v.delivery.state !== "string" || !["queued", "sending", "uncertain", "provider_accepted", "failed", "cancelled"].includes(v.delivery.state) || !Number.isInteger(v.delivery.attempts) || Number(v.delivery.attempts) < 0 || Number(v.delivery.attempts) > 5)
51471
51617
  return invalid2();
51472
51618
  return {
51473
51619
  id: v.id,
@@ -51482,7 +51628,7 @@ function projection(v, organizationId) {
51482
51628
  };
51483
51629
  }
51484
51630
  function parseInvitationResult(action, value, input2, organizationId) {
51485
- if (!record4(value))
51631
+ if (!record5(value))
51486
51632
  return invalid2();
51487
51633
  const request = input2;
51488
51634
  if (action === "accept") {
@@ -51513,7 +51659,7 @@ function parseInvitationResult(action, value, input2, organizationId) {
51513
51659
  return invalid2();
51514
51660
  return { invitation, changed: value.changed };
51515
51661
  }
51516
- var WorkspaceInvitationInputError, invitationFailures, RemoteWorkspaceInvitationError, RemoteWorkspaceInvitationUnconfirmedError, RemoteWorkspaceInvitationReadError, record4 = (v) => !!v && typeof v === "object" && !Array.isArray(v), uuid5 = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), role = (v) => typeof v === "string" && ["owner", "admin", "member", "viewer"].includes(v), email3 = (v) => typeof v === "string" && v.length <= 254 && !/[\p{Cc}\p{Cs}\u2028\u2029\s]/u.test(v) && /^[^@]+@[^@]+\.[^@]+$/.test(v), timestamp = (v) => typeof v === "string" && v.length <= 40 && /^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(?:\.\d{1,6})?(?:Z|[+-]\d\d:\d\d)$/.test(v) && Number.isFinite(Date.parse(v)), inputFailure = () => {
51662
+ var WorkspaceInvitationInputError, invitationFailures, RemoteWorkspaceInvitationError, RemoteWorkspaceInvitationUnconfirmedError, RemoteWorkspaceInvitationReadError, record5 = (v) => !!v && typeof v === "object" && !Array.isArray(v), uuid5 = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), role = (v) => typeof v === "string" && ["owner", "admin", "member", "viewer"].includes(v), email3 = (v) => typeof v === "string" && v.length <= 254 && !/[\p{Cc}\p{Cs}\u2028\u2029\s]/u.test(v) && /^[^@]+@[^@]+\.[^@]+$/.test(v), timestamp = (v) => typeof v === "string" && v.length <= 40 && /^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d(?:\.\d{1,6})?(?:Z|[+-]\d\d:\d\d)$/.test(v) && Number.isFinite(Date.parse(v)), inputFailure = () => {
51517
51663
  throw new WorkspaceInvitationInputError;
51518
51664
  };
51519
51665
  var init_remote_invitations = __esm(() => {
@@ -51572,7 +51718,7 @@ function workspaceExpectedUserId(value) {
51572
51718
  return value;
51573
51719
  }
51574
51720
  function workspaceContext(value) {
51575
- if (!record5(value) || Object.keys(value).sort().join(",") !== "membershipId,userId" || !uuid8(value.userId) || !uuid8(value.membershipId))
51721
+ if (!record6(value) || Object.keys(value).sort().join(",") !== "membershipId,userId" || !uuid8(value.userId) || !uuid8(value.membershipId))
51576
51722
  throw new WorkspaceContextInputError;
51577
51723
  return { userId: value.userId, membershipId: value.membershipId };
51578
51724
  }
@@ -51580,15 +51726,15 @@ function invalid3() {
51580
51726
  throw new Error(invalidWorkspaceResult);
51581
51727
  }
51582
51728
  function organization(v) {
51583
- if (!record5(v) || !uuid8(v.id) || !text2(v.slug) || !text2(v.name))
51729
+ if (!record6(v) || !uuid8(v.id) || !text2(v.slug) || !text2(v.name))
51584
51730
  return invalid3();
51585
51731
  return { id: v.id, slug: v.slug, name: v.name };
51586
51732
  }
51587
51733
  function parseAccountWorkspaces(value) {
51588
- if (!record5(value) || !Array.isArray(value.workspaces) || !value.workspaces.length || value.workspaces.length > 1000)
51734
+ if (!record6(value) || !Array.isArray(value.workspaces) || !value.workspaces.length || value.workspaces.length > 1000)
51589
51735
  return invalid3();
51590
51736
  const workspaces = value.workspaces.map((v) => {
51591
- if (!record5(v) || !uuid8(v.membershipId) || !role2(v.role) || typeof v.current !== "boolean")
51737
+ if (!record6(v) || !uuid8(v.membershipId) || !role2(v.role) || typeof v.current !== "boolean")
51592
51738
  return invalid3();
51593
51739
  return { membershipId: v.membershipId, organization: organization(v.organization), role: v.role, current: v.current };
51594
51740
  });
@@ -51597,10 +51743,10 @@ function parseAccountWorkspaces(value) {
51597
51743
  return { workspaces };
51598
51744
  }
51599
51745
  function parseWorkspaceIdentity(value, expectedUserId) {
51600
- if (!record5(value))
51746
+ if (!record6(value))
51601
51747
  return invalid3();
51602
51748
  const user = value.user;
51603
- if (!record5(user) || !uuid8(user.id) || !uuid8(user.membershipId) || !text2(user.email, 320) || !(user.displayName === null || text2(user.displayName)) || !role2(user.role))
51749
+ if (!record6(user) || !uuid8(user.id) || !uuid8(user.membershipId) || !text2(user.email, 320) || !(user.displayName === null || text2(user.displayName)) || !role2(user.role))
51604
51750
  return invalid3();
51605
51751
  if (user.id !== expectedUserId)
51606
51752
  throw new WorkspaceIdentityMismatchError;
@@ -51618,20 +51764,20 @@ function parseWorkspaceSession(value, expected) {
51618
51764
  return { token: sessionToken(value.token), ...identity3 };
51619
51765
  }
51620
51766
  function parseWorkspaceLogin(value, expectedUserId) {
51621
- const user = record5(value) && value.user;
51622
- if (!record5(value) || !record5(user) || !uuid8(user.id))
51767
+ const user = record6(value) && value.user;
51768
+ if (!record6(value) || !record6(user) || !uuid8(user.id))
51623
51769
  return invalid3();
51624
51770
  if (expectedUserId !== undefined && user.id !== expectedUserId)
51625
51771
  throw new WorkspaceIdentityMismatchError;
51626
51772
  return { token: sessionToken(value.token), userId: user.id };
51627
51773
  }
51628
51774
  function workspaceSelectionFailure(value, status) {
51629
- if (!record5(value) || typeof value.code !== "string" || !Object.hasOwn(workspaceSelectionFailures, value.code))
51775
+ if (!record6(value) || typeof value.code !== "string" || !Object.hasOwn(workspaceSelectionFailures, value.code))
51630
51776
  return null;
51631
51777
  const code = value.code;
51632
51778
  return workspaceSelectionFailures[code][0] === status ? code : null;
51633
51779
  }
51634
- var record5 = (v) => !!v && typeof v === "object" && !Array.isArray(v), uuid8 = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), text2 = (v, max = 1024) => typeof v === "string" && !!v.trim() && v.length <= max && !/[\p{Cc}\p{Cs}\u2028\u2029]/u.test(v), role2 = (v) => typeof v === "string" && ["owner", "admin", "member", "viewer"].includes(v), invalidWorkspaceResult = "The server returned an invalid workspace selection result.", WorkspaceContextInputError, WorkspaceIdentityMismatchError, workspaceSelectionFailures;
51780
+ var record6 = (v) => !!v && typeof v === "object" && !Array.isArray(v), uuid8 = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), text2 = (v, max = 1024) => typeof v === "string" && !!v.trim() && v.length <= max && !/[\p{Cc}\p{Cs}\u2028\u2029]/u.test(v), role2 = (v) => typeof v === "string" && ["owner", "admin", "member", "viewer"].includes(v), invalidWorkspaceResult = "The server returned an invalid workspace selection result.", WorkspaceContextInputError, WorkspaceIdentityMismatchError, workspaceSelectionFailures;
51635
51781
  var init_remote_workspace_selection = __esm(() => {
51636
51782
  WorkspaceContextInputError = class WorkspaceContextInputError extends Error {
51637
51783
  constructor() {
@@ -51657,7 +51803,7 @@ var init_remote_workspace_selection = __esm(() => {
51657
51803
 
51658
51804
  // src/lib/remote-workspace.ts
51659
51805
  function workspaceMembersQuery(options = {}) {
51660
- 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))
51806
+ 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))
51661
51807
  throw new Error("Use a roster limit from 1 to 100 and an unchanged continuation cursor.");
51662
51808
  const query = new URLSearchParams;
51663
51809
  if (options.limit !== undefined)
@@ -51673,7 +51819,7 @@ function timestamp2(value) {
51673
51819
  return Number.isFinite(time3) && new Date(time3).toISOString().slice(0, 23) === value.slice(0, 23);
51674
51820
  }
51675
51821
  function parseMember(row, fail) {
51676
- 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))
51822
+ 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))
51677
51823
  return fail();
51678
51824
  return {
51679
51825
  membershipId: row.membershipId,
@@ -51685,7 +51831,7 @@ function parseMember(row, fail) {
51685
51831
  };
51686
51832
  }
51687
51833
  function mutationInput(membershipId, input2, roleChange) {
51688
- if (typeof membershipId !== "string" || !uuid10(membershipId) || membershipId !== membershipId.toLowerCase() || !record6(input2) || Object.keys(input2).sort().join(",") !== (roleChange ? "expectedRole,role" : "expectedRole"))
51834
+ if (typeof membershipId !== "string" || !uuid10(membershipId) || membershipId !== membershipId.toLowerCase() || !record7(input2) || Object.keys(input2).sort().join(",") !== (roleChange ? "expectedRole,role" : "expectedRole"))
51689
51835
  throw new WorkspaceMemberInputError;
51690
51836
  const expectedRole = input2.expectedRole, role3 = roleChange ? input2.role : undefined;
51691
51837
  if (!isRole(expectedRole) || roleChange && !isRole(role3))
@@ -51704,7 +51850,7 @@ function parseWorkspaceMemberRoleResult(value, membershipId, role3) {
51704
51850
  const fail = () => {
51705
51851
  throw new Error(invalidMemberResult);
51706
51852
  };
51707
- if (!record6(value) || !uuid10(value.organizationId) || typeof value.changed !== "boolean")
51853
+ if (!record7(value) || !uuid10(value.organizationId) || typeof value.changed !== "boolean")
51708
51854
  return fail();
51709
51855
  const member = parseMember(value.member, fail);
51710
51856
  if (member.membershipId !== membershipId || member.role !== role3)
@@ -51712,12 +51858,12 @@ function parseWorkspaceMemberRoleResult(value, membershipId, role3) {
51712
51858
  return { organizationId: value.organizationId, member, changed: value.changed };
51713
51859
  }
51714
51860
  function parseWorkspaceMemberRemovalResult(value, membershipId) {
51715
- if (!record6(value) || !uuid10(value.organizationId) || value.membershipId !== membershipId || value.removed !== true || typeof value.alreadyRemoved !== "boolean")
51861
+ if (!record7(value) || !uuid10(value.organizationId) || value.membershipId !== membershipId || value.removed !== true || typeof value.alreadyRemoved !== "boolean")
51716
51862
  throw new Error(invalidMemberResult);
51717
51863
  return { organizationId: value.organizationId, membershipId, removed: true, alreadyRemoved: value.alreadyRemoved };
51718
51864
  }
51719
51865
  function workspaceMemberFailure(value, status) {
51720
- if (!record6(value) || typeof value.code !== "string" || !Object.hasOwn(workspaceMemberFailures, value.code))
51866
+ if (!record7(value) || typeof value.code !== "string" || !Object.hasOwn(workspaceMemberFailures, value.code))
51721
51867
  return null;
51722
51868
  const code = value.code;
51723
51869
  return workspaceMemberFailures[code][0] === status ? code : null;
@@ -51726,14 +51872,14 @@ function parseWorkspaceMembersPage(value) {
51726
51872
  const fail = () => {
51727
51873
  throw new Error("The server returned an invalid workspace roster.");
51728
51874
  };
51729
- 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)
51875
+ 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)
51730
51876
  return fail();
51731
51877
  const members2 = value.members.map((row) => parseMember(row, fail));
51732
51878
  if (new Set(members2.map((row) => row.membershipId)).size !== members2.length)
51733
51879
  return fail();
51734
51880
  return { organizationId: value.organizationId, members: members2, nextCursor: value.nextCursor };
51735
51881
  }
51736
- var record6 = (value) => !!value && typeof value === "object" && !Array.isArray(value), cursor = (value) => typeof value === "string" && /^[A-Za-z0-9_-]{1,512}$/.test(value), 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), isRole = (value) => typeof value === "string" && ["owner", "admin", "member", "viewer"].includes(value), WorkspaceMemberInputError, invalidMemberResult = "The server returned an invalid workspace member result. Refresh the roster before another action.", workspaceMemberFailures;
51882
+ var record7 = (value) => !!value && typeof value === "object" && !Array.isArray(value), cursor = (value) => typeof value === "string" && /^[A-Za-z0-9_-]{1,512}$/.test(value), 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), isRole = (value) => typeof value === "string" && ["owner", "admin", "member", "viewer"].includes(value), WorkspaceMemberInputError, invalidMemberResult = "The server returned an invalid workspace member result. Refresh the roster before another action.", workspaceMemberFailures;
51737
51883
  var init_remote_workspace = __esm(() => {
51738
51884
  WorkspaceMemberInputError = class WorkspaceMemberInputError extends Error {
51739
51885
  constructor() {
@@ -51856,44 +52002,44 @@ var init_auth_store = __esm(() => {
51856
52002
 
51857
52003
  // src/lib/remote-run-contract.ts
51858
52004
  function normalizeRemoteSkillRunContract(payload, fallbackSkill) {
51859
- const record7 = isRecord4(payload) ? payload : {};
52005
+ const record8 = isRecord4(payload) ? payload : {};
51860
52006
  return {
51861
52007
  contractVersion: REMOTE_SKILL_RUN_CONTRACT_VERSION,
51862
- ...pickString(record7, "id"),
51863
- skill: pickStringValue(record7, "skill") ?? fallbackSkill,
51864
- ...pickString(record7, "requestedSlug"),
51865
- ...pickString(record7, "status"),
51866
- ...pickNumber(record7, "exitCode"),
51867
- ...pickString(record7, "correlationId"),
51868
- ...pickString(record7, "createdAt"),
51869
- ...pickString(record7, "startedAt"),
51870
- ...pickString(record7, "completedAt"),
51871
- ...pickNumber(record7, "durationMs"),
51872
- ...pickString(record7, "outputType"),
51873
- ...hasOwn(record7, "outputPreview") ? { outputPreview: record7.outputPreview } : {},
51874
- ...pickString(record7, "errorCode"),
51875
- ...pickString(record7, "errorMessage"),
51876
- ...pickString(record7, "error"),
51877
- ...pickString(record7, "code"),
51878
- ...hasOwn(record7, "details") ? { details: record7.details } : {}
52008
+ ...pickString(record8, "id"),
52009
+ skill: pickStringValue(record8, "skill") ?? fallbackSkill,
52010
+ ...pickString(record8, "requestedSlug"),
52011
+ ...pickString(record8, "status"),
52012
+ ...pickNumber(record8, "exitCode"),
52013
+ ...pickString(record8, "correlationId"),
52014
+ ...pickString(record8, "createdAt"),
52015
+ ...pickString(record8, "startedAt"),
52016
+ ...pickString(record8, "completedAt"),
52017
+ ...pickNumber(record8, "durationMs"),
52018
+ ...pickString(record8, "outputType"),
52019
+ ...hasOwn(record8, "outputPreview") ? { outputPreview: record8.outputPreview } : {},
52020
+ ...pickString(record8, "errorCode"),
52021
+ ...pickString(record8, "errorMessage"),
52022
+ ...pickString(record8, "error"),
52023
+ ...pickString(record8, "code"),
52024
+ ...hasOwn(record8, "details") ? { details: record8.details } : {}
51879
52025
  };
51880
52026
  }
51881
52027
  function isRecord4(value) {
51882
52028
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
51883
52029
  }
51884
- function hasOwn(record7, key) {
51885
- return Object.prototype.hasOwnProperty.call(record7, key);
52030
+ function hasOwn(record8, key) {
52031
+ return Object.prototype.hasOwnProperty.call(record8, key);
51886
52032
  }
51887
- function pickString(record7, key) {
51888
- const value = pickStringValue(record7, key);
52033
+ function pickString(record8, key) {
52034
+ const value = pickStringValue(record8, key);
51889
52035
  return value === undefined ? {} : { [key]: value };
51890
52036
  }
51891
- function pickStringValue(record7, key) {
51892
- const value = record7[key];
52037
+ function pickStringValue(record8, key) {
52038
+ const value = record8[key];
51893
52039
  return typeof value === "string" ? value : undefined;
51894
52040
  }
51895
- function pickNumber(record7, key) {
51896
- const value = record7[key];
52041
+ function pickNumber(record8, key) {
52042
+ const value = record8[key];
51897
52043
  return typeof value === "number" && Number.isFinite(value) ? { [key]: value } : {};
51898
52044
  }
51899
52045
  var REMOTE_SKILL_RUN_CONTRACT_VERSION = 1;
@@ -52116,7 +52262,7 @@ var init_remote_quote_errors = __esm(() => {
52116
52262
  function parseSkillsAccess(value) {
52117
52263
  if (value === undefined)
52118
52264
  return {};
52119
- if (!record7(value))
52265
+ if (!record8(value))
52120
52266
  throw new Error("Invalid Skills permission contract");
52121
52267
  const result = {};
52122
52268
  if (value.scopes !== undefined) {
@@ -52125,7 +52271,7 @@ function parseSkillsAccess(value) {
52125
52271
  result.scopes = [...value.scopes];
52126
52272
  }
52127
52273
  if (value.permissions !== undefined) {
52128
- if (!record7(value.permissions))
52274
+ if (!record8(value.permissions))
52129
52275
  throw new Error("Invalid Skills permission contract");
52130
52276
  result.permissions = {};
52131
52277
  for (const name of permissionNames) {
@@ -52143,7 +52289,7 @@ function assertSkillsPermission(access, permission) {
52143
52289
  if (access.permissions?.[permission] === false)
52144
52290
  throw new RemoteSkillsPermissionError(permission);
52145
52291
  }
52146
- var permissionNames, record7 = (value) => value !== null && typeof value === "object" && !Array.isArray(value), RemoteSkillsPermissionError;
52292
+ var permissionNames, record8 = (value) => value !== null && typeof value === "object" && !Array.isArray(value), RemoteSkillsPermissionError;
52147
52293
  var init_remote_permissions = __esm(() => {
52148
52294
  permissionNames = [
52149
52295
  "read",
@@ -52958,13 +53104,13 @@ class RemoteSkillsClient {
52958
53104
  return normalizeUpdatedSincePage(await response.json());
52959
53105
  }
52960
53106
  }
52961
- function requireOptionalString(record8, field2) {
52962
- if (record8[field2] === undefined)
53107
+ function requireOptionalString(record9, field2) {
53108
+ if (record9[field2] === undefined)
52963
53109
  return;
52964
- if (typeof record8[field2] !== "string") {
53110
+ if (typeof record9[field2] !== "string") {
52965
53111
  throw new Error(`Remote payload did not match the expected contract (${field2} must be a string when present)`);
52966
53112
  }
52967
- return record8[field2];
53113
+ return record9[field2];
52968
53114
  }
52969
53115
  function isVersionRecord(value) {
52970
53116
  return value !== null && typeof value === "object" && !Array.isArray(value);
@@ -52986,19 +53132,19 @@ function normalizePin(entry) {
52986
53132
  if (!entry || typeof entry !== "object") {
52987
53133
  throw new Error("Remote pin payload did not match the expected contract (expected an object)");
52988
53134
  }
52989
- const record8 = entry;
52990
- const slug2 = typeof record8.slug === "string" && record8.slug.trim() ? record8.slug.trim() : undefined;
53135
+ const record9 = entry;
53136
+ const slug2 = typeof record9.slug === "string" && record9.slug.trim() ? record9.slug.trim() : undefined;
52991
53137
  if (!slug2) {
52992
53138
  throw new Error("Remote pin payload did not match the expected contract (missing slug)");
52993
53139
  }
52994
53140
  let metadata;
52995
- if (record8.metadata !== undefined) {
52996
- if (!record8.metadata || typeof record8.metadata !== "object" || Array.isArray(record8.metadata)) {
53141
+ if (record9.metadata !== undefined) {
53142
+ if (!record9.metadata || typeof record9.metadata !== "object" || Array.isArray(record9.metadata)) {
52997
53143
  throw new Error("Remote pin payload did not match the expected contract (metadata must be a JSON object when present)");
52998
53144
  }
52999
- metadata = record8.metadata;
53145
+ metadata = record9.metadata;
53000
53146
  }
53001
- const pinnedAt = requireOptionalString(record8, "pinnedAt");
53147
+ const pinnedAt = requireOptionalString(record9, "pinnedAt");
53002
53148
  return {
53003
53149
  slug: slug2,
53004
53150
  ...pinnedAt !== undefined ? { pinnedAt } : {},
@@ -53015,16 +53161,16 @@ function normalizeSkillSummary(entry) {
53015
53161
  if (!entry || typeof entry !== "object") {
53016
53162
  throw new Error("Remote skill payload did not match the expected contract (expected an object)");
53017
53163
  }
53018
- const record8 = entry;
53019
- const slug2 = typeof record8.slug === "string" && record8.slug.trim() ? record8.slug.trim() : undefined;
53164
+ const record9 = entry;
53165
+ const slug2 = typeof record9.slug === "string" && record9.slug.trim() ? record9.slug.trim() : undefined;
53020
53166
  if (!slug2) {
53021
53167
  throw new Error("Remote skill payload did not match the expected contract (missing slug)");
53022
53168
  }
53023
53169
  return {
53024
53170
  slug: slug2,
53025
- ...requireOptionalString(record8, "name") !== undefined ? { name: requireOptionalString(record8, "name") } : {},
53026
- ...requireOptionalString(record8, "version") !== undefined ? { version: requireOptionalString(record8, "version") } : {},
53027
- ...requireOptionalString(record8, "updatedAt") !== undefined ? { updatedAt: requireOptionalString(record8, "updatedAt") } : {}
53171
+ ...requireOptionalString(record9, "name") !== undefined ? { name: requireOptionalString(record9, "name") } : {},
53172
+ ...requireOptionalString(record9, "version") !== undefined ? { version: requireOptionalString(record9, "version") } : {},
53173
+ ...requireOptionalString(record9, "updatedAt") !== undefined ? { updatedAt: requireOptionalString(record9, "updatedAt") } : {}
53028
53174
  };
53029
53175
  }
53030
53176
  function normalizeSkillSummaryList(payload) {
@@ -53081,12 +53227,12 @@ function normalizeUpdatedSincePage(payload) {
53081
53227
  if (!payload || typeof payload !== "object") {
53082
53228
  throw new Error("Updated-since payload did not match the expected contract (expected an object)");
53083
53229
  }
53084
- const record8 = payload;
53085
- if (!Array.isArray(record8.skills)) {
53230
+ const record9 = payload;
53231
+ if (!Array.isArray(record9.skills)) {
53086
53232
  throw new Error("Updated-since payload did not match the expected contract (missing skills array)");
53087
53233
  }
53088
- const skills = record8.skills.map(normalizeSkillSummary);
53089
- const nextCursor = record8.nextCursor === undefined || record8.nextCursor === null ? null : record8.nextCursor;
53234
+ const skills = record9.skills.map(normalizeSkillSummary);
53235
+ const nextCursor = record9.nextCursor === undefined || record9.nextCursor === null ? null : record9.nextCursor;
53090
53236
  if (nextCursor !== null && typeof nextCursor !== "string") {
53091
53237
  throw new Error("Updated-since payload did not match the expected contract (nextCursor must be a string or absent)");
53092
53238
  }
@@ -53207,7 +53353,7 @@ function invitationEmailIds(invitationId, challengeId) {
53207
53353
  }
53208
53354
  function invitationEmailInput(action, input2) {
53209
53355
  const keys = ["invitationId", "token", "challengeId", "confirm", ...action === "accept" ? ["code"] : []];
53210
- if (!record8(input2) || Object.keys(input2).length !== keys.length || keys.some((key) => !Object.hasOwn(input2, key)))
53356
+ if (!record9(input2) || Object.keys(input2).length !== keys.length || keys.some((key) => !Object.hasOwn(input2, key)))
53211
53357
  throw new InvitationEmailInputError;
53212
53358
  const value = { ...input2 };
53213
53359
  const ids = invitationEmailIds(value.invitationId, value.challengeId);
@@ -53236,12 +53382,12 @@ async function requestInvitationEmail(origin, action, input2) {
53236
53382
  signal: AbortSignal.timeout(15000)
53237
53383
  });
53238
53384
  const parsed = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(await readBoundedResponse(response, 4096)));
53239
- if (!response.ok && record8(parsed) && typeof parsed.code === "string" && Object.hasOwn(refusals, parsed.code)) {
53385
+ if (!response.ok && record9(parsed) && typeof parsed.code === "string" && Object.hasOwn(refusals, parsed.code)) {
53240
53386
  const code = parsed.code;
53241
53387
  if (response.status === refusals[code][0])
53242
53388
  throw new RemoteInvitationEmailError(code);
53243
53389
  }
53244
- if (!record8(parsed))
53390
+ if (!record9(parsed))
53245
53391
  throw new RemoteInvitationEmailUnconfirmedError(action);
53246
53392
  if (action === "challenge" && response.status === 202 && parsed.challengeId === value.challengeId && parsed.expiresIn === 600 && typeof parsed.message === "string" && parsed.message.length <= 256) {
53247
53393
  return { challengeId: value.challengeId, message: "If this invitation is eligible, a verification code will arrive. Delivery is not confirmed.", expiresIn: 600 };
@@ -53260,7 +53406,7 @@ function invitationEmailCustomerError(error61) {
53260
53406
  return { code: error61.code, error: error61.message };
53261
53407
  return { code: "INVITATION_EMAIL_UNAVAILABLE", error: "Unable to prepare this recovery action. Check the explicit server and stable profile. No credential was saved." };
53262
53408
  }
53263
- var InvitationEmailInputError, refusals, RemoteInvitationEmailError, RemoteInvitationEmailUnconfirmedError, record8 = (v) => !!v && typeof v === "object" && !Array.isArray(v), uuid11 = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v);
53409
+ var InvitationEmailInputError, refusals, RemoteInvitationEmailError, RemoteInvitationEmailUnconfirmedError, record9 = (v) => !!v && typeof v === "object" && !Array.isArray(v), uuid11 = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v);
53264
53410
  var init_remote_invitation_recovery = __esm(() => {
53265
53411
  init_fleet_credentials();
53266
53412
  init_remote_files();
@@ -53307,7 +53453,7 @@ function checkedPublicationDeclaration(value) {
53307
53453
  return bad();
53308
53454
  try {
53309
53455
  const manifest = JSON.parse(value.manifestText);
53310
- if (!record9(manifest) || manifest.version !== value.version || validatePortableManifestContract(manifest, { strict: true }).length || !hash3(manifest.provenance?.content_hash))
53456
+ if (!record10(manifest) || manifest.version !== value.version || validatePortableManifestContract(manifest, { strict: true }).length || !hash3(manifest.provenance?.content_hash))
53311
53457
  return bad();
53312
53458
  } catch {
53313
53459
  return bad();
@@ -53365,7 +53511,7 @@ async function boundedJson(url2, init, token, mutation, budget2 = 15000, signal)
53365
53511
  return invalid4();
53366
53512
  }
53367
53513
  if (!response.ok) {
53368
- const code = record9(body) && typeof body.code === "string" && Object.hasOwn(failures2, body.code) ? body.code : null;
53514
+ const code = record10(body) && typeof body.code === "string" && Object.hasOwn(failures2, body.code) ? body.code : null;
53369
53515
  if (code && failures2[code][0] === response.status)
53370
53516
  throw new PrivatePublicationError(code, failures2[code][1], mutation && code === "PUBLICATION_UNCERTAIN", response.status);
53371
53517
  throw new PrivatePublicationError("PUBLICATION_REQUEST_FAILED", "The publication request was refused. Inspect its status before retrying.", mutation && response.status >= 500, response.status);
@@ -53420,8 +53566,8 @@ class RemotePrivatePublicationsClient {
53420
53566
  if (options.timeoutMs !== undefined && (!Number.isSafeInteger(options.timeoutMs) || options.timeoutMs < 1 || options.timeoutMs > 15000))
53421
53567
  return bad();
53422
53568
  const response = await boundedJson(skillsApiRequestUrl(this.apiOrigin, "/api/v1/capabilities"), {}, this.#token, false, options.timeoutMs, options.signal);
53423
- const p = record9(response) && response.privatePublishing;
53424
- if (!record9(response) || response.contractVersion !== 1 || response.apiVersion !== 1 || !exact(p, ["contractVersion", "enabled", "authentication", "maxArchiveBytes", "uploadMaxTtlSeconds", "executionEnabled"]) || p.contractVersion !== 1 || typeof p.enabled !== "boolean" || p.authentication !== "interactive-session" || p.maxArchiveBytes !== PRIVATE_PUBLICATION_MAX_BYTES || p.uploadMaxTtlSeconds !== 300 || typeof p.executionEnabled !== "boolean")
53569
+ const p = record10(response) && response.privatePublishing;
53570
+ if (!record10(response) || response.contractVersion !== 1 || response.apiVersion !== 1 || !exact(p, ["contractVersion", "enabled", "authentication", "maxArchiveBytes", "uploadMaxTtlSeconds", "executionEnabled"]) || p.contractVersion !== 1 || typeof p.enabled !== "boolean" || p.authentication !== "interactive-session" || p.maxArchiveBytes !== PRIVATE_PUBLICATION_MAX_BYTES || p.uploadMaxTtlSeconds !== 300 || typeof p.executionEnabled !== "boolean")
53425
53571
  throw new PrivatePublicationError("PUBLICATION_CONTRACT_UNAVAILABLE", "This server does not support the hosted private publication contract.");
53426
53572
  return Object.freeze({ ...p });
53427
53573
  }
@@ -53437,7 +53583,7 @@ class RemotePrivatePublicationsClient {
53437
53583
  async#view(path, method, skillId, intentId, declaration, options = {}) {
53438
53584
  const value = await boundedJson(path, { method, ...method === "GET" ? {} : { body: JSON.stringify(declaration ?? {}) } }, this.#token, method !== "GET", options.timeoutMs, options.signal);
53439
53585
  try {
53440
- if (!record9(value) || !Object.keys(value).every((k) => k === "upload" || k === "changed") || value.changed !== undefined && typeof value.changed !== "boolean")
53586
+ if (!record10(value) || !Object.keys(value).every((k) => k === "upload" || k === "changed") || value.changed !== undefined && typeof value.changed !== "boolean")
53441
53587
  return invalid4();
53442
53588
  return checkedPublicationView(value.upload, skillId, intentId, declaration);
53443
53589
  } catch (error61) {
@@ -53562,7 +53708,7 @@ var PRIVATE_PUBLICATION_MAX_BYTES, failures2, PrivatePublicationError, bad = ()
53562
53708
  throw new PrivatePublicationError("INVALID_PUBLICATION_INPUT", "Invalid publication input or recovery data.");
53563
53709
  }, invalid4 = () => {
53564
53710
  throw new PrivatePublicationError("INVALID_PUBLICATION_RESPONSE", "The server returned an invalid publication result.");
53565
- }, publicationUuid = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), hash3 = (v) => typeof v === "string" && /^[a-f0-9]{64}$/.test(v), record9 = (v) => !!v && typeof v === "object" && !Array.isArray(v), exact = (v, keys) => record9(v) && Object.keys(v).sort().join(",") === keys.sort().join(","), date6 = (v) => typeof v === "string" && /^\d{4}-\d\d-\d\dT[0-9:.]+(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(v) && Number.isFinite(Date.parse(v)), publicationSha256 = (bytes) => createHash18("sha256").update(bytes).digest("hex");
53711
+ }, publicationUuid = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), hash3 = (v) => typeof v === "string" && /^[a-f0-9]{64}$/.test(v), record10 = (v) => !!v && typeof v === "object" && !Array.isArray(v), exact = (v, keys) => record10(v) && Object.keys(v).sort().join(",") === keys.sort().join(","), date6 = (v) => typeof v === "string" && /^\d{4}-\d\d-\d\dT[0-9:.]+(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(v) && Number.isFinite(Date.parse(v)), publicationSha256 = (bytes) => createHash18("sha256").update(bytes).digest("hex");
53566
53712
  var init_remote_private_publications = __esm(() => {
53567
53713
  init_fleet_credentials();
53568
53714
  init_remote_workspace_selection();
@@ -53626,10 +53772,10 @@ async function requestAuthApi(instance, path, options) {
53626
53772
  const text3 = await res.text();
53627
53773
  const body = text3 ? parseJsonBody(text3) : {};
53628
53774
  if (!res.ok) {
53629
- const record10 = isRecord6(body) ? body : {};
53630
- const detail = typeof record10.detail === "string" ? record10.detail : undefined;
53631
- const error61 = typeof record10.error === "string" ? record10.error : undefined;
53632
- const code = typeof record10.code === "string" ? record10.code : undefined;
53775
+ const record11 = isRecord6(body) ? body : {};
53776
+ const detail = typeof record11.detail === "string" ? record11.detail : undefined;
53777
+ const error61 = typeof record11.error === "string" ? record11.error : undefined;
53778
+ const code = typeof record11.code === "string" ? record11.code : undefined;
53633
53779
  throw new HostedApiError(detail || error61 || `${res.status} ${res.statusText}`, {
53634
53780
  status: res.status,
53635
53781
  code,
@@ -56327,7 +56473,7 @@ function createSkillRun(params, targetDir = process.cwd()) {
56327
56473
  mkdirSync11(logsDir, { recursive: true });
56328
56474
  mkdirSync11(exportDir, { recursive: true });
56329
56475
  mkdirSync11(join30(root, "tmp"), { recursive: true });
56330
- const record10 = {
56476
+ const record11 = {
56331
56477
  id,
56332
56478
  skill: skillName,
56333
56479
  status: params.status ?? "running",
@@ -56345,10 +56491,10 @@ function createSkillRun(params, targetDir = process.cwd()) {
56345
56491
  logsDir: toProjectRelative(targetDir, logsDir)
56346
56492
  }
56347
56493
  };
56348
- const context2 = { targetDir, runDir, exportDir, logsDir, record: record10 };
56494
+ const context2 = { targetDir, runDir, exportDir, logsDir, record: record11 };
56349
56495
  writeRunRecord(context2);
56350
56496
  writeArtifactsManifest(context2, []);
56351
- appendRunEvent(context2, "created", { status: record10.status });
56497
+ appendRunEvent(context2, "created", { status: record11.status });
56352
56498
  return context2;
56353
56499
  }
56354
56500
  function completeSkillRun(context2, patch) {
@@ -56393,9 +56539,9 @@ function findSkillRun(runId, targetDir = process.cwd()) {
56393
56539
  if (!existsSync14(runsRoot))
56394
56540
  return null;
56395
56541
  for (const day of readdirSync10(runsRoot)) {
56396
- const record10 = readRunRecord(join30(runsRoot, day, runId));
56397
- if (record10)
56398
- return record10;
56542
+ const record11 = readRunRecord(join30(runsRoot, day, runId));
56543
+ if (record11)
56544
+ return record11;
56399
56545
  }
56400
56546
  return null;
56401
56547
  }
@@ -58020,7 +58166,7 @@ function selectedSecretBindingsTemplate(scope, names, createClient = createSecre
58020
58166
  function refuse2(code2, message) {
58021
58167
  throw new SkillSelectionError(code2, message);
58022
58168
  }
58023
- function record10(value) {
58169
+ function record11(value) {
58024
58170
  return !!value && typeof value === "object" && !Array.isArray(value);
58025
58171
  }
58026
58172
  function exactKeys2(value, keys) {
@@ -58041,7 +58187,7 @@ function declaredSecretNames(value) {
58041
58187
  return value;
58042
58188
  }
58043
58189
  function validateSelectedSecretBindings(value, scope, names) {
58044
- if (!record10(value) || !exactKeys2(value, ["schema", "selection", "consumer", "secretsAuthority", "bindings"]) || value.schema !== "hasna.skills-secret-bindings.v1" || !record10(value.selection) || !exactKeys2(value.selection, ["authority", "workspaceId", "profileId", "profileRevision", "slug", "version", "bundleDigest"]) || !record10(value.consumer) || !exactKeys2(value.consumer, ["stationId", "workspaceDirectory"]) || !record10(value.bindings)) {
58190
+ if (!record11(value) || !exactKeys2(value, ["schema", "selection", "consumer", "secretsAuthority", "bindings"]) || value.schema !== "hasna.skills-secret-bindings.v1" || !record11(value.selection) || !exactKeys2(value.selection, ["authority", "workspaceId", "profileId", "profileRevision", "slug", "version", "bundleDigest"]) || !record11(value.consumer) || !exactKeys2(value.consumer, ["stationId", "workspaceDirectory"]) || !record11(value.bindings)) {
58045
58191
  return refuse2("INVALID_SECRET_BINDINGS", "Secret bindings do not match the hasna.skills-secret-bindings.v1 contract.");
58046
58192
  }
58047
58193
  for (const [key, expected] of Object.entries({ authority: scope.selection.authority, workspaceId: scope.selection.workspaceId, profileId: scope.profileId, profileRevision: scope.selection.profileRevision, slug: scope.selection.slug, version: scope.selection.version, bundleDigest: scope.selection.bundleDigest })) {
@@ -58179,7 +58325,7 @@ var init_execution_grants = __esm(() => {
58179
58325
  });
58180
58326
 
58181
58327
  // src/lib/execution-grant-client.ts
58182
- import { isDeepStrictEqual as isDeepStrictEqual3 } from "util";
58328
+ import { isDeepStrictEqual as isDeepStrictEqual4 } from "util";
58183
58329
  function id(value) {
58184
58330
  if (!grantIdentifier(value))
58185
58331
  throw new Error("Invalid execution grant profile or revision identifier.");
@@ -58222,7 +58368,7 @@ async function resolveExecutionGrant(input2) {
58222
58368
  if (!grantRecord(value) || Object.keys(value).length !== 3 || !grantIdentifier(value.policyRevision) || !grantIdentifier(value.grantId) || !grantRecord(value.bindings)) {
58223
58369
  throw new SkillSelectionError("INVALID_EXECUTION_GRANT", "The Skills API returned an invalid execution grant.");
58224
58370
  }
58225
- if (!isDeepStrictEqual3(value.bindings.selection, snapshot2.selection) || !isDeepStrictEqual3(value.bindings.consumer, snapshot2.consumer)) {
58371
+ if (!isDeepStrictEqual4(value.bindings.selection, snapshot2.selection) || !isDeepStrictEqual4(value.bindings.consumer, snapshot2.consumer)) {
58226
58372
  throw new SkillSelectionError("EXECUTION_GRANT_SCOPE_MISMATCH", "The Skills API returned a grant for a different selection or consumer.");
58227
58373
  }
58228
58374
  return value;