@hasna/skills 0.10.26 → 0.10.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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.28",
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,25 @@ 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", "personality"] : 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 (key === "personality")
47936
+ need4(typeof value === "string" && ["none", "friendly", "pragmatic"].includes(value));
47937
+ else if (version2 === 3 && key !== "model_verbosity") {
47938
+ need4(typeof value === "string" && value.length <= 128 && !/[\x00-\x1f\x7f]/.test(value));
47939
+ if (key !== "service_tier")
47940
+ need4(value.length > 0);
47941
+ } else
47804
47942
  need4(typeof value === "string" && (key === "model_reasoning_effort" ? EFFORT2.has(value) : VERBOSITY2.has(value)));
47805
47943
  delete target[key];
47806
47944
  }
47807
47945
  }
47808
- function settingsDigest2(text2) {
47946
+ function settingsDigest2(text2, version2 = 2) {
47809
47947
  let config2;
47810
47948
  try {
47811
47949
  config2 = Bun.TOML.parse(text2);
@@ -47813,8 +47951,9 @@ function settingsDigest2(text2) {
47813
47951
  throw new Error("Invalid Codex settings witness");
47814
47952
  }
47815
47953
  need4(isRecord3(config2));
47816
- normalize2(config2);
47817
- return sha2(`hasna.skills.codex-settings.v2\x00${JSON.stringify([canonical4(config2), numericTokens2(text2)])}`);
47954
+ const projected = version2 === 3 ? projectRegularCodexMcp(config2, text2) : { config: config2, numericSource: text2 };
47955
+ normalize2(projected.config, version2);
47956
+ return sha2(`hasna.skills.codex-settings.v${version2}\x00${JSON.stringify([canonical4(projected.config), numericTokens2(projected.numericSource)])}`);
47818
47957
  }
47819
47958
  function hashCodexSettingsReplacementV2(text2, budget = { remaining: 256 * 1024 * 1024 }) {
47820
47959
  need4(Buffer.byteLength(text2) <= 1024 * 1024 && budget.remaining >= Buffer.byteLength(text2));
@@ -47825,10 +47964,19 @@ function captureCodexSettingsV2(path, budget = { remaining: 256 * 1024 * 1024 })
47825
47964
  const text2 = readNativeSettingsWitnessFile(path, budget, "config.toml");
47826
47965
  return { path, hashMode: "codex-settings-v2", sha256: settingsDigest2(text2) };
47827
47966
  }
47967
+ function hashCodexSettingsReplacementV3(text2, budget = { remaining: 256 * 1024 * 1024 }) {
47968
+ need4(Buffer.byteLength(text2) <= 1024 * 1024 && budget.remaining >= Buffer.byteLength(text2));
47969
+ budget.remaining -= Buffer.byteLength(text2);
47970
+ return settingsDigest2(text2, 3);
47971
+ }
47972
+ function captureCodexSettingsV3(path, budget = { remaining: 256 * 1024 * 1024 }) {
47973
+ return { path, hashMode: "codex-settings-v3", sha256: settingsDigest2(readNativeSettingsWitnessFile(path, budget, "config.toml"), 3) };
47974
+ }
47828
47975
  var sha2 = (text2) => createHash10("sha256").update(text2).digest("hex"), EFFORT2, VERBOSITY2, MODEL, CODEX_DISCOVERY_PROJECTION_FIELDS, INFERENCE;
47829
47976
  var init_codex_settings_witness = __esm(() => {
47830
47977
  init_codex_settings_witness_v1();
47831
47978
  init_codex_settings_witness_v1();
47979
+ init_codex_mcp_discovery_projection();
47832
47980
  init_claude_settings_witness();
47833
47981
  EFFORT2 = new Set(["none", "minimal", "low", "medium", "high", "xhigh"]);
47834
47982
  VERBOSITY2 = new Set(["low", "medium", "high"]);
@@ -49585,7 +49733,7 @@ var init_codex_hook_discovery_recovery = __esm(() => {
49585
49733
  import { createHash as createHash16 } from "crypto";
49586
49734
  import { lstatSync as lstatSync17, readFileSync as readFileSync15, readdirSync as readdirSync7, realpathSync as realpathSync4 } from "fs";
49587
49735
  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";
49736
+ import { isDeepStrictEqual as isDeepStrictEqual3 } from "util";
49589
49737
  function parseConfig(text2, path, toml = false) {
49590
49738
  try {
49591
49739
  const value = toml ? Bun.TOML.parse(text2) : JSON.parse(text2);
@@ -49624,19 +49772,19 @@ function projectNativeDiscoveryFields(text2, format, fields2, path) {
49624
49772
  return digest(JSON.stringify(Object.fromEntries(fields2.map((field2) => [field2, object7[field2] ?? null]))));
49625
49773
  }
49626
49774
  function isSupersededCodexProjection(agent, configPath, source) {
49627
- return agent === "codex" && source.path === configPath && source.format === "toml" && isDeepStrictEqual2(source.fields, [...CODEX_DISCOVERY_PROJECTION_FIELDS]);
49775
+ return agent === "codex" && source.path === configPath && source.format === "toml" && isDeepStrictEqual3(source.fields, [...CODEX_DISCOVERY_PROJECTION_FIELDS]);
49628
49776
  }
49629
49777
  function supersedesCodexProjection(sources, configPath) {
49630
- return sources.some((source) => source.path === configPath && source.hashMode === "codex-settings-v2");
49778
+ return sources.some((source) => source.path === configPath && (source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3"));
49631
49779
  }
49632
49780
  function projected(source, changes, budget = discoveryByteBudget()) {
49633
- if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2") {
49781
+ if (source.hashMode === "codex-settings-v1" || source.hashMode === "codex-settings-v2" || source.hashMode === "codex-settings-v3") {
49634
49782
  if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
49635
49783
  throw new Error("Codex settings witnesses require exact typed metadata");
49636
- const current = (source.hashMode === "codex-settings-v2" ? captureCodexSettingsV2 : captureCodexSettings)(source.path, budget).sha256;
49784
+ const current = (source.hashMode === "codex-settings-v3" ? captureCodexSettingsV3 : source.hashMode === "codex-settings-v2" ? captureCodexSettingsV2 : captureCodexSettings)(source.path, budget).sha256;
49637
49785
  if (current !== source.sha256)
49638
49786
  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;
49787
+ 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
49788
  }
49641
49789
  if (source.hashMode === "claude-settings-v1" || source.hashMode === "claude-settings-v2" || source.hashMode === "claude-settings-v3") {
49642
49790
  if (source.format !== undefined || source.fields !== undefined || source.managedPlugins !== undefined || typeof source.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(source.sha256))
@@ -49736,7 +49884,7 @@ function codexInstallationRoots(binding) {
49736
49884
  });
49737
49885
  }
49738
49886
  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"))
49887
+ 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
49888
  throw new Error("Codex settings witnesses require explicit reviewed Codex configuration");
49741
49889
  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
49890
  throw new Error("Claude settings witnesses require explicit reviewed Claude configuration");
@@ -49819,10 +49967,10 @@ function resolveAgentDiscovery(options) {
49819
49967
  verifyAgentDiscovery(retained);
49820
49968
  if (!retained.sources.some((source) => source.path === canonical6(configPath) && source.format === undefined && source.fields === undefined))
49821
49969
  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)))
49970
+ 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
49971
  unresolved("retained settings witness names another configuration source");
49824
49972
  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))
49973
+ 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
49974
  unresolved("retained review is missing current runtime discovery coverage");
49827
49975
  return retained;
49828
49976
  }
@@ -49836,7 +49984,7 @@ function resolveAgentDiscovery(options) {
49836
49984
  if (review.sources.some((source) => source.format !== undefined || source.fields !== undefined))
49837
49985
  throw new Error("Explicit discovery reviews require full source-file hashes");
49838
49986
  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)))
49987
+ 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
49988
  throw new Error("Semantic settings witnesses must name the configured Claude configuration source");
49841
49989
  if (!review.sources.some((source) => source.path === canonical6(configPath)))
49842
49990
  throw new Error("Discovery review must include the agent configuration source");
@@ -51410,13 +51558,13 @@ var init_remote_recurring = __esm(() => {
51410
51558
 
51411
51559
  // src/lib/remote-invitations.ts
51412
51560
  function invitationFailure(value, status) {
51413
- if (!record4(value) || typeof value.code !== "string" || !Object.hasOwn(invitationFailures, value.code))
51561
+ if (!record5(value) || typeof value.code !== "string" || !Object.hasOwn(invitationFailures, value.code))
51414
51562
  return null;
51415
51563
  const code = value.code;
51416
51564
  return invitationFailures[code][0] === status ? code : null;
51417
51565
  }
51418
51566
  function invitationInput(action, input2) {
51419
- if (!record4(input2))
51567
+ if (!record5(input2))
51420
51568
  return inputFailure();
51421
51569
  const keys = {
51422
51570
  list: ["after"],
@@ -51467,7 +51615,7 @@ function invalid2() {
51467
51615
  throw new RemoteWorkspaceInvitationReadError;
51468
51616
  }
51469
51617
  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)
51618
+ 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
51619
  return invalid2();
51472
51620
  return {
51473
51621
  id: v.id,
@@ -51482,7 +51630,7 @@ function projection(v, organizationId) {
51482
51630
  };
51483
51631
  }
51484
51632
  function parseInvitationResult(action, value, input2, organizationId) {
51485
- if (!record4(value))
51633
+ if (!record5(value))
51486
51634
  return invalid2();
51487
51635
  const request = input2;
51488
51636
  if (action === "accept") {
@@ -51513,7 +51661,7 @@ function parseInvitationResult(action, value, input2, organizationId) {
51513
51661
  return invalid2();
51514
51662
  return { invitation, changed: value.changed };
51515
51663
  }
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 = () => {
51664
+ 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
51665
  throw new WorkspaceInvitationInputError;
51518
51666
  };
51519
51667
  var init_remote_invitations = __esm(() => {
@@ -51572,7 +51720,7 @@ function workspaceExpectedUserId(value) {
51572
51720
  return value;
51573
51721
  }
51574
51722
  function workspaceContext(value) {
51575
- if (!record5(value) || Object.keys(value).sort().join(",") !== "membershipId,userId" || !uuid8(value.userId) || !uuid8(value.membershipId))
51723
+ if (!record6(value) || Object.keys(value).sort().join(",") !== "membershipId,userId" || !uuid8(value.userId) || !uuid8(value.membershipId))
51576
51724
  throw new WorkspaceContextInputError;
51577
51725
  return { userId: value.userId, membershipId: value.membershipId };
51578
51726
  }
@@ -51580,15 +51728,15 @@ function invalid3() {
51580
51728
  throw new Error(invalidWorkspaceResult);
51581
51729
  }
51582
51730
  function organization(v) {
51583
- if (!record5(v) || !uuid8(v.id) || !text2(v.slug) || !text2(v.name))
51731
+ if (!record6(v) || !uuid8(v.id) || !text2(v.slug) || !text2(v.name))
51584
51732
  return invalid3();
51585
51733
  return { id: v.id, slug: v.slug, name: v.name };
51586
51734
  }
51587
51735
  function parseAccountWorkspaces(value) {
51588
- if (!record5(value) || !Array.isArray(value.workspaces) || !value.workspaces.length || value.workspaces.length > 1000)
51736
+ if (!record6(value) || !Array.isArray(value.workspaces) || !value.workspaces.length || value.workspaces.length > 1000)
51589
51737
  return invalid3();
51590
51738
  const workspaces = value.workspaces.map((v) => {
51591
- if (!record5(v) || !uuid8(v.membershipId) || !role2(v.role) || typeof v.current !== "boolean")
51739
+ if (!record6(v) || !uuid8(v.membershipId) || !role2(v.role) || typeof v.current !== "boolean")
51592
51740
  return invalid3();
51593
51741
  return { membershipId: v.membershipId, organization: organization(v.organization), role: v.role, current: v.current };
51594
51742
  });
@@ -51597,10 +51745,10 @@ function parseAccountWorkspaces(value) {
51597
51745
  return { workspaces };
51598
51746
  }
51599
51747
  function parseWorkspaceIdentity(value, expectedUserId) {
51600
- if (!record5(value))
51748
+ if (!record6(value))
51601
51749
  return invalid3();
51602
51750
  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))
51751
+ if (!record6(user) || !uuid8(user.id) || !uuid8(user.membershipId) || !text2(user.email, 320) || !(user.displayName === null || text2(user.displayName)) || !role2(user.role))
51604
51752
  return invalid3();
51605
51753
  if (user.id !== expectedUserId)
51606
51754
  throw new WorkspaceIdentityMismatchError;
@@ -51618,20 +51766,20 @@ function parseWorkspaceSession(value, expected) {
51618
51766
  return { token: sessionToken(value.token), ...identity3 };
51619
51767
  }
51620
51768
  function parseWorkspaceLogin(value, expectedUserId) {
51621
- const user = record5(value) && value.user;
51622
- if (!record5(value) || !record5(user) || !uuid8(user.id))
51769
+ const user = record6(value) && value.user;
51770
+ if (!record6(value) || !record6(user) || !uuid8(user.id))
51623
51771
  return invalid3();
51624
51772
  if (expectedUserId !== undefined && user.id !== expectedUserId)
51625
51773
  throw new WorkspaceIdentityMismatchError;
51626
51774
  return { token: sessionToken(value.token), userId: user.id };
51627
51775
  }
51628
51776
  function workspaceSelectionFailure(value, status) {
51629
- if (!record5(value) || typeof value.code !== "string" || !Object.hasOwn(workspaceSelectionFailures, value.code))
51777
+ if (!record6(value) || typeof value.code !== "string" || !Object.hasOwn(workspaceSelectionFailures, value.code))
51630
51778
  return null;
51631
51779
  const code = value.code;
51632
51780
  return workspaceSelectionFailures[code][0] === status ? code : null;
51633
51781
  }
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;
51782
+ 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
51783
  var init_remote_workspace_selection = __esm(() => {
51636
51784
  WorkspaceContextInputError = class WorkspaceContextInputError extends Error {
51637
51785
  constructor() {
@@ -51657,7 +51805,7 @@ var init_remote_workspace_selection = __esm(() => {
51657
51805
 
51658
51806
  // src/lib/remote-workspace.ts
51659
51807
  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))
51808
+ 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
51809
  throw new Error("Use a roster limit from 1 to 100 and an unchanged continuation cursor.");
51662
51810
  const query = new URLSearchParams;
51663
51811
  if (options.limit !== undefined)
@@ -51673,7 +51821,7 @@ function timestamp2(value) {
51673
51821
  return Number.isFinite(time3) && new Date(time3).toISOString().slice(0, 23) === value.slice(0, 23);
51674
51822
  }
51675
51823
  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))
51824
+ 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
51825
  return fail();
51678
51826
  return {
51679
51827
  membershipId: row.membershipId,
@@ -51685,7 +51833,7 @@ function parseMember(row, fail) {
51685
51833
  };
51686
51834
  }
51687
51835
  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"))
51836
+ if (typeof membershipId !== "string" || !uuid10(membershipId) || membershipId !== membershipId.toLowerCase() || !record7(input2) || Object.keys(input2).sort().join(",") !== (roleChange ? "expectedRole,role" : "expectedRole"))
51689
51837
  throw new WorkspaceMemberInputError;
51690
51838
  const expectedRole = input2.expectedRole, role3 = roleChange ? input2.role : undefined;
51691
51839
  if (!isRole(expectedRole) || roleChange && !isRole(role3))
@@ -51704,7 +51852,7 @@ function parseWorkspaceMemberRoleResult(value, membershipId, role3) {
51704
51852
  const fail = () => {
51705
51853
  throw new Error(invalidMemberResult);
51706
51854
  };
51707
- if (!record6(value) || !uuid10(value.organizationId) || typeof value.changed !== "boolean")
51855
+ if (!record7(value) || !uuid10(value.organizationId) || typeof value.changed !== "boolean")
51708
51856
  return fail();
51709
51857
  const member = parseMember(value.member, fail);
51710
51858
  if (member.membershipId !== membershipId || member.role !== role3)
@@ -51712,12 +51860,12 @@ function parseWorkspaceMemberRoleResult(value, membershipId, role3) {
51712
51860
  return { organizationId: value.organizationId, member, changed: value.changed };
51713
51861
  }
51714
51862
  function parseWorkspaceMemberRemovalResult(value, membershipId) {
51715
- if (!record6(value) || !uuid10(value.organizationId) || value.membershipId !== membershipId || value.removed !== true || typeof value.alreadyRemoved !== "boolean")
51863
+ if (!record7(value) || !uuid10(value.organizationId) || value.membershipId !== membershipId || value.removed !== true || typeof value.alreadyRemoved !== "boolean")
51716
51864
  throw new Error(invalidMemberResult);
51717
51865
  return { organizationId: value.organizationId, membershipId, removed: true, alreadyRemoved: value.alreadyRemoved };
51718
51866
  }
51719
51867
  function workspaceMemberFailure(value, status) {
51720
- if (!record6(value) || typeof value.code !== "string" || !Object.hasOwn(workspaceMemberFailures, value.code))
51868
+ if (!record7(value) || typeof value.code !== "string" || !Object.hasOwn(workspaceMemberFailures, value.code))
51721
51869
  return null;
51722
51870
  const code = value.code;
51723
51871
  return workspaceMemberFailures[code][0] === status ? code : null;
@@ -51726,14 +51874,14 @@ function parseWorkspaceMembersPage(value) {
51726
51874
  const fail = () => {
51727
51875
  throw new Error("The server returned an invalid workspace roster.");
51728
51876
  };
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)
51877
+ 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
51878
  return fail();
51731
51879
  const members2 = value.members.map((row) => parseMember(row, fail));
51732
51880
  if (new Set(members2.map((row) => row.membershipId)).size !== members2.length)
51733
51881
  return fail();
51734
51882
  return { organizationId: value.organizationId, members: members2, nextCursor: value.nextCursor };
51735
51883
  }
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;
51884
+ 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
51885
  var init_remote_workspace = __esm(() => {
51738
51886
  WorkspaceMemberInputError = class WorkspaceMemberInputError extends Error {
51739
51887
  constructor() {
@@ -51856,44 +52004,44 @@ var init_auth_store = __esm(() => {
51856
52004
 
51857
52005
  // src/lib/remote-run-contract.ts
51858
52006
  function normalizeRemoteSkillRunContract(payload, fallbackSkill) {
51859
- const record7 = isRecord4(payload) ? payload : {};
52007
+ const record8 = isRecord4(payload) ? payload : {};
51860
52008
  return {
51861
52009
  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 } : {}
52010
+ ...pickString(record8, "id"),
52011
+ skill: pickStringValue(record8, "skill") ?? fallbackSkill,
52012
+ ...pickString(record8, "requestedSlug"),
52013
+ ...pickString(record8, "status"),
52014
+ ...pickNumber(record8, "exitCode"),
52015
+ ...pickString(record8, "correlationId"),
52016
+ ...pickString(record8, "createdAt"),
52017
+ ...pickString(record8, "startedAt"),
52018
+ ...pickString(record8, "completedAt"),
52019
+ ...pickNumber(record8, "durationMs"),
52020
+ ...pickString(record8, "outputType"),
52021
+ ...hasOwn(record8, "outputPreview") ? { outputPreview: record8.outputPreview } : {},
52022
+ ...pickString(record8, "errorCode"),
52023
+ ...pickString(record8, "errorMessage"),
52024
+ ...pickString(record8, "error"),
52025
+ ...pickString(record8, "code"),
52026
+ ...hasOwn(record8, "details") ? { details: record8.details } : {}
51879
52027
  };
51880
52028
  }
51881
52029
  function isRecord4(value) {
51882
52030
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
51883
52031
  }
51884
- function hasOwn(record7, key) {
51885
- return Object.prototype.hasOwnProperty.call(record7, key);
52032
+ function hasOwn(record8, key) {
52033
+ return Object.prototype.hasOwnProperty.call(record8, key);
51886
52034
  }
51887
- function pickString(record7, key) {
51888
- const value = pickStringValue(record7, key);
52035
+ function pickString(record8, key) {
52036
+ const value = pickStringValue(record8, key);
51889
52037
  return value === undefined ? {} : { [key]: value };
51890
52038
  }
51891
- function pickStringValue(record7, key) {
51892
- const value = record7[key];
52039
+ function pickStringValue(record8, key) {
52040
+ const value = record8[key];
51893
52041
  return typeof value === "string" ? value : undefined;
51894
52042
  }
51895
- function pickNumber(record7, key) {
51896
- const value = record7[key];
52043
+ function pickNumber(record8, key) {
52044
+ const value = record8[key];
51897
52045
  return typeof value === "number" && Number.isFinite(value) ? { [key]: value } : {};
51898
52046
  }
51899
52047
  var REMOTE_SKILL_RUN_CONTRACT_VERSION = 1;
@@ -52116,7 +52264,7 @@ var init_remote_quote_errors = __esm(() => {
52116
52264
  function parseSkillsAccess(value) {
52117
52265
  if (value === undefined)
52118
52266
  return {};
52119
- if (!record7(value))
52267
+ if (!record8(value))
52120
52268
  throw new Error("Invalid Skills permission contract");
52121
52269
  const result = {};
52122
52270
  if (value.scopes !== undefined) {
@@ -52125,7 +52273,7 @@ function parseSkillsAccess(value) {
52125
52273
  result.scopes = [...value.scopes];
52126
52274
  }
52127
52275
  if (value.permissions !== undefined) {
52128
- if (!record7(value.permissions))
52276
+ if (!record8(value.permissions))
52129
52277
  throw new Error("Invalid Skills permission contract");
52130
52278
  result.permissions = {};
52131
52279
  for (const name of permissionNames) {
@@ -52143,7 +52291,7 @@ function assertSkillsPermission(access, permission) {
52143
52291
  if (access.permissions?.[permission] === false)
52144
52292
  throw new RemoteSkillsPermissionError(permission);
52145
52293
  }
52146
- var permissionNames, record7 = (value) => value !== null && typeof value === "object" && !Array.isArray(value), RemoteSkillsPermissionError;
52294
+ var permissionNames, record8 = (value) => value !== null && typeof value === "object" && !Array.isArray(value), RemoteSkillsPermissionError;
52147
52295
  var init_remote_permissions = __esm(() => {
52148
52296
  permissionNames = [
52149
52297
  "read",
@@ -52958,13 +53106,13 @@ class RemoteSkillsClient {
52958
53106
  return normalizeUpdatedSincePage(await response.json());
52959
53107
  }
52960
53108
  }
52961
- function requireOptionalString(record8, field2) {
52962
- if (record8[field2] === undefined)
53109
+ function requireOptionalString(record9, field2) {
53110
+ if (record9[field2] === undefined)
52963
53111
  return;
52964
- if (typeof record8[field2] !== "string") {
53112
+ if (typeof record9[field2] !== "string") {
52965
53113
  throw new Error(`Remote payload did not match the expected contract (${field2} must be a string when present)`);
52966
53114
  }
52967
- return record8[field2];
53115
+ return record9[field2];
52968
53116
  }
52969
53117
  function isVersionRecord(value) {
52970
53118
  return value !== null && typeof value === "object" && !Array.isArray(value);
@@ -52986,19 +53134,19 @@ function normalizePin(entry) {
52986
53134
  if (!entry || typeof entry !== "object") {
52987
53135
  throw new Error("Remote pin payload did not match the expected contract (expected an object)");
52988
53136
  }
52989
- const record8 = entry;
52990
- const slug2 = typeof record8.slug === "string" && record8.slug.trim() ? record8.slug.trim() : undefined;
53137
+ const record9 = entry;
53138
+ const slug2 = typeof record9.slug === "string" && record9.slug.trim() ? record9.slug.trim() : undefined;
52991
53139
  if (!slug2) {
52992
53140
  throw new Error("Remote pin payload did not match the expected contract (missing slug)");
52993
53141
  }
52994
53142
  let metadata;
52995
- if (record8.metadata !== undefined) {
52996
- if (!record8.metadata || typeof record8.metadata !== "object" || Array.isArray(record8.metadata)) {
53143
+ if (record9.metadata !== undefined) {
53144
+ if (!record9.metadata || typeof record9.metadata !== "object" || Array.isArray(record9.metadata)) {
52997
53145
  throw new Error("Remote pin payload did not match the expected contract (metadata must be a JSON object when present)");
52998
53146
  }
52999
- metadata = record8.metadata;
53147
+ metadata = record9.metadata;
53000
53148
  }
53001
- const pinnedAt = requireOptionalString(record8, "pinnedAt");
53149
+ const pinnedAt = requireOptionalString(record9, "pinnedAt");
53002
53150
  return {
53003
53151
  slug: slug2,
53004
53152
  ...pinnedAt !== undefined ? { pinnedAt } : {},
@@ -53015,16 +53163,16 @@ function normalizeSkillSummary(entry) {
53015
53163
  if (!entry || typeof entry !== "object") {
53016
53164
  throw new Error("Remote skill payload did not match the expected contract (expected an object)");
53017
53165
  }
53018
- const record8 = entry;
53019
- const slug2 = typeof record8.slug === "string" && record8.slug.trim() ? record8.slug.trim() : undefined;
53166
+ const record9 = entry;
53167
+ const slug2 = typeof record9.slug === "string" && record9.slug.trim() ? record9.slug.trim() : undefined;
53020
53168
  if (!slug2) {
53021
53169
  throw new Error("Remote skill payload did not match the expected contract (missing slug)");
53022
53170
  }
53023
53171
  return {
53024
53172
  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") } : {}
53173
+ ...requireOptionalString(record9, "name") !== undefined ? { name: requireOptionalString(record9, "name") } : {},
53174
+ ...requireOptionalString(record9, "version") !== undefined ? { version: requireOptionalString(record9, "version") } : {},
53175
+ ...requireOptionalString(record9, "updatedAt") !== undefined ? { updatedAt: requireOptionalString(record9, "updatedAt") } : {}
53028
53176
  };
53029
53177
  }
53030
53178
  function normalizeSkillSummaryList(payload) {
@@ -53081,12 +53229,12 @@ function normalizeUpdatedSincePage(payload) {
53081
53229
  if (!payload || typeof payload !== "object") {
53082
53230
  throw new Error("Updated-since payload did not match the expected contract (expected an object)");
53083
53231
  }
53084
- const record8 = payload;
53085
- if (!Array.isArray(record8.skills)) {
53232
+ const record9 = payload;
53233
+ if (!Array.isArray(record9.skills)) {
53086
53234
  throw new Error("Updated-since payload did not match the expected contract (missing skills array)");
53087
53235
  }
53088
- const skills = record8.skills.map(normalizeSkillSummary);
53089
- const nextCursor = record8.nextCursor === undefined || record8.nextCursor === null ? null : record8.nextCursor;
53236
+ const skills = record9.skills.map(normalizeSkillSummary);
53237
+ const nextCursor = record9.nextCursor === undefined || record9.nextCursor === null ? null : record9.nextCursor;
53090
53238
  if (nextCursor !== null && typeof nextCursor !== "string") {
53091
53239
  throw new Error("Updated-since payload did not match the expected contract (nextCursor must be a string or absent)");
53092
53240
  }
@@ -53207,7 +53355,7 @@ function invitationEmailIds(invitationId, challengeId) {
53207
53355
  }
53208
53356
  function invitationEmailInput(action, input2) {
53209
53357
  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)))
53358
+ if (!record9(input2) || Object.keys(input2).length !== keys.length || keys.some((key) => !Object.hasOwn(input2, key)))
53211
53359
  throw new InvitationEmailInputError;
53212
53360
  const value = { ...input2 };
53213
53361
  const ids = invitationEmailIds(value.invitationId, value.challengeId);
@@ -53236,12 +53384,12 @@ async function requestInvitationEmail(origin, action, input2) {
53236
53384
  signal: AbortSignal.timeout(15000)
53237
53385
  });
53238
53386
  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)) {
53387
+ if (!response.ok && record9(parsed) && typeof parsed.code === "string" && Object.hasOwn(refusals, parsed.code)) {
53240
53388
  const code = parsed.code;
53241
53389
  if (response.status === refusals[code][0])
53242
53390
  throw new RemoteInvitationEmailError(code);
53243
53391
  }
53244
- if (!record8(parsed))
53392
+ if (!record9(parsed))
53245
53393
  throw new RemoteInvitationEmailUnconfirmedError(action);
53246
53394
  if (action === "challenge" && response.status === 202 && parsed.challengeId === value.challengeId && parsed.expiresIn === 600 && typeof parsed.message === "string" && parsed.message.length <= 256) {
53247
53395
  return { challengeId: value.challengeId, message: "If this invitation is eligible, a verification code will arrive. Delivery is not confirmed.", expiresIn: 600 };
@@ -53260,7 +53408,7 @@ function invitationEmailCustomerError(error61) {
53260
53408
  return { code: error61.code, error: error61.message };
53261
53409
  return { code: "INVITATION_EMAIL_UNAVAILABLE", error: "Unable to prepare this recovery action. Check the explicit server and stable profile. No credential was saved." };
53262
53410
  }
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);
53411
+ 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
53412
  var init_remote_invitation_recovery = __esm(() => {
53265
53413
  init_fleet_credentials();
53266
53414
  init_remote_files();
@@ -53307,7 +53455,7 @@ function checkedPublicationDeclaration(value) {
53307
53455
  return bad();
53308
53456
  try {
53309
53457
  const manifest = JSON.parse(value.manifestText);
53310
- if (!record9(manifest) || manifest.version !== value.version || validatePortableManifestContract(manifest, { strict: true }).length || !hash3(manifest.provenance?.content_hash))
53458
+ if (!record10(manifest) || manifest.version !== value.version || validatePortableManifestContract(manifest, { strict: true }).length || !hash3(manifest.provenance?.content_hash))
53311
53459
  return bad();
53312
53460
  } catch {
53313
53461
  return bad();
@@ -53365,7 +53513,7 @@ async function boundedJson(url2, init, token, mutation, budget2 = 15000, signal)
53365
53513
  return invalid4();
53366
53514
  }
53367
53515
  if (!response.ok) {
53368
- const code = record9(body) && typeof body.code === "string" && Object.hasOwn(failures2, body.code) ? body.code : null;
53516
+ const code = record10(body) && typeof body.code === "string" && Object.hasOwn(failures2, body.code) ? body.code : null;
53369
53517
  if (code && failures2[code][0] === response.status)
53370
53518
  throw new PrivatePublicationError(code, failures2[code][1], mutation && code === "PUBLICATION_UNCERTAIN", response.status);
53371
53519
  throw new PrivatePublicationError("PUBLICATION_REQUEST_FAILED", "The publication request was refused. Inspect its status before retrying.", mutation && response.status >= 500, response.status);
@@ -53420,8 +53568,8 @@ class RemotePrivatePublicationsClient {
53420
53568
  if (options.timeoutMs !== undefined && (!Number.isSafeInteger(options.timeoutMs) || options.timeoutMs < 1 || options.timeoutMs > 15000))
53421
53569
  return bad();
53422
53570
  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")
53571
+ const p = record10(response) && response.privatePublishing;
53572
+ 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
53573
  throw new PrivatePublicationError("PUBLICATION_CONTRACT_UNAVAILABLE", "This server does not support the hosted private publication contract.");
53426
53574
  return Object.freeze({ ...p });
53427
53575
  }
@@ -53437,7 +53585,7 @@ class RemotePrivatePublicationsClient {
53437
53585
  async#view(path, method, skillId, intentId, declaration, options = {}) {
53438
53586
  const value = await boundedJson(path, { method, ...method === "GET" ? {} : { body: JSON.stringify(declaration ?? {}) } }, this.#token, method !== "GET", options.timeoutMs, options.signal);
53439
53587
  try {
53440
- if (!record9(value) || !Object.keys(value).every((k) => k === "upload" || k === "changed") || value.changed !== undefined && typeof value.changed !== "boolean")
53588
+ if (!record10(value) || !Object.keys(value).every((k) => k === "upload" || k === "changed") || value.changed !== undefined && typeof value.changed !== "boolean")
53441
53589
  return invalid4();
53442
53590
  return checkedPublicationView(value.upload, skillId, intentId, declaration);
53443
53591
  } catch (error61) {
@@ -53562,7 +53710,7 @@ var PRIVATE_PUBLICATION_MAX_BYTES, failures2, PrivatePublicationError, bad = ()
53562
53710
  throw new PrivatePublicationError("INVALID_PUBLICATION_INPUT", "Invalid publication input or recovery data.");
53563
53711
  }, invalid4 = () => {
53564
53712
  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");
53713
+ }, 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
53714
  var init_remote_private_publications = __esm(() => {
53567
53715
  init_fleet_credentials();
53568
53716
  init_remote_workspace_selection();
@@ -53626,10 +53774,10 @@ async function requestAuthApi(instance, path, options) {
53626
53774
  const text3 = await res.text();
53627
53775
  const body = text3 ? parseJsonBody(text3) : {};
53628
53776
  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;
53777
+ const record11 = isRecord6(body) ? body : {};
53778
+ const detail = typeof record11.detail === "string" ? record11.detail : undefined;
53779
+ const error61 = typeof record11.error === "string" ? record11.error : undefined;
53780
+ const code = typeof record11.code === "string" ? record11.code : undefined;
53633
53781
  throw new HostedApiError(detail || error61 || `${res.status} ${res.statusText}`, {
53634
53782
  status: res.status,
53635
53783
  code,
@@ -56327,7 +56475,7 @@ function createSkillRun(params, targetDir = process.cwd()) {
56327
56475
  mkdirSync11(logsDir, { recursive: true });
56328
56476
  mkdirSync11(exportDir, { recursive: true });
56329
56477
  mkdirSync11(join30(root, "tmp"), { recursive: true });
56330
- const record10 = {
56478
+ const record11 = {
56331
56479
  id,
56332
56480
  skill: skillName,
56333
56481
  status: params.status ?? "running",
@@ -56345,10 +56493,10 @@ function createSkillRun(params, targetDir = process.cwd()) {
56345
56493
  logsDir: toProjectRelative(targetDir, logsDir)
56346
56494
  }
56347
56495
  };
56348
- const context2 = { targetDir, runDir, exportDir, logsDir, record: record10 };
56496
+ const context2 = { targetDir, runDir, exportDir, logsDir, record: record11 };
56349
56497
  writeRunRecord(context2);
56350
56498
  writeArtifactsManifest(context2, []);
56351
- appendRunEvent(context2, "created", { status: record10.status });
56499
+ appendRunEvent(context2, "created", { status: record11.status });
56352
56500
  return context2;
56353
56501
  }
56354
56502
  function completeSkillRun(context2, patch) {
@@ -56393,9 +56541,9 @@ function findSkillRun(runId, targetDir = process.cwd()) {
56393
56541
  if (!existsSync14(runsRoot))
56394
56542
  return null;
56395
56543
  for (const day of readdirSync10(runsRoot)) {
56396
- const record10 = readRunRecord(join30(runsRoot, day, runId));
56397
- if (record10)
56398
- return record10;
56544
+ const record11 = readRunRecord(join30(runsRoot, day, runId));
56545
+ if (record11)
56546
+ return record11;
56399
56547
  }
56400
56548
  return null;
56401
56549
  }
@@ -58020,7 +58168,7 @@ function selectedSecretBindingsTemplate(scope, names, createClient = createSecre
58020
58168
  function refuse2(code2, message) {
58021
58169
  throw new SkillSelectionError(code2, message);
58022
58170
  }
58023
- function record10(value) {
58171
+ function record11(value) {
58024
58172
  return !!value && typeof value === "object" && !Array.isArray(value);
58025
58173
  }
58026
58174
  function exactKeys2(value, keys) {
@@ -58041,7 +58189,7 @@ function declaredSecretNames(value) {
58041
58189
  return value;
58042
58190
  }
58043
58191
  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)) {
58192
+ 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
58193
  return refuse2("INVALID_SECRET_BINDINGS", "Secret bindings do not match the hasna.skills-secret-bindings.v1 contract.");
58046
58194
  }
58047
58195
  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 +58327,7 @@ var init_execution_grants = __esm(() => {
58179
58327
  });
58180
58328
 
58181
58329
  // src/lib/execution-grant-client.ts
58182
- import { isDeepStrictEqual as isDeepStrictEqual3 } from "util";
58330
+ import { isDeepStrictEqual as isDeepStrictEqual4 } from "util";
58183
58331
  function id(value) {
58184
58332
  if (!grantIdentifier(value))
58185
58333
  throw new Error("Invalid execution grant profile or revision identifier.");
@@ -58222,7 +58370,7 @@ async function resolveExecutionGrant(input2) {
58222
58370
  if (!grantRecord(value) || Object.keys(value).length !== 3 || !grantIdentifier(value.policyRevision) || !grantIdentifier(value.grantId) || !grantRecord(value.bindings)) {
58223
58371
  throw new SkillSelectionError("INVALID_EXECUTION_GRANT", "The Skills API returned an invalid execution grant.");
58224
58372
  }
58225
- if (!isDeepStrictEqual3(value.bindings.selection, snapshot2.selection) || !isDeepStrictEqual3(value.bindings.consumer, snapshot2.consumer)) {
58373
+ if (!isDeepStrictEqual4(value.bindings.selection, snapshot2.selection) || !isDeepStrictEqual4(value.bindings.consumer, snapshot2.consumer)) {
58226
58374
  throw new SkillSelectionError("EXECUTION_GRANT_SCOPE_MISMATCH", "The Skills API returned a grant for a different selection or consumer.");
58227
58375
  }
58228
58376
  return value;