@everfur/cli 0.8.0 → 0.9.0

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.
@@ -1,10 +1,11 @@
1
1
  #!/usr/bin/env node
2
+ /*! @everfur/cli. Copyright (c) 2026 Strand Health Inc. dba Everfur. All rights reserved. Use is subject to the Everfur SDK License: https://docs.everfur.com/license */
2
3
  import { mkdirSync, writeFileSync, renameSync, readFileSync, readdirSync, statSync } from 'fs';
3
4
  import { join, isAbsolute, resolve, dirname, relative, sep } from 'path';
5
+ import { createHash, createHmac } from 'crypto';
4
6
  import { parse } from 'yaml';
5
7
  import Ajv2020 from 'ajv/dist/2020.js';
6
8
  import addFormats from 'ajv-formats';
7
- import { createHash } from 'crypto';
8
9
  import { z } from 'zod';
9
10
 
10
11
  var NO_CONTRACT_CACHE = Object.freeze({
@@ -270,8 +271,15 @@ function apiUrl(endpoint, path) {
270
271
  const suffix = path.startsWith("/") ? path : `/${path}`;
271
272
  return endpoint.prefixIncluded ? `${endpoint.baseUrl}${suffix}` : `${endpoint.baseUrl}${API_PREFIX}${suffix}`;
272
273
  }
273
-
274
- // src/config/credentials.ts
274
+ var SECRET_KEY_API_HOSTS = /* @__PURE__ */ new Set(["api.everfur.com", "api-staging.everfur.com"]);
275
+ var ALLOW_CUSTOM_API_HOST_ENV_VAR = "EVERFUR_ALLOW_CUSTOM_API_HOST";
276
+ function secretKeyHostProblem(endpoint, env) {
277
+ if ((env[ALLOW_CUSTOM_API_HOST_ENV_VAR] ?? "").trim() === "1") return null;
278
+ const url = new URL(endpoint.baseUrl);
279
+ if (url.protocol === "https:" && SECRET_KEY_API_HOSTS.has(url.hostname)) return null;
280
+ if (LOCAL_HTTP_HOSTS.has(url.hostname)) return null;
281
+ return `${BASE_URL_ENV_VAR} names ${url.host}, which is not api.everfur.com, api-staging.everfur.com or this machine, so the secret key is not sent to it. Set ${ALLOW_CUSTOM_API_HOST_ENV_VAR}=1 in the shell only if that host is an Everfur API you trust`;
282
+ }
275
283
  var REDACTED = "[redacted]";
276
284
  var PARTNER_KEY = Object.freeze({
277
285
  envVar: "EVERFUR_PARTNER_KEY",
@@ -310,6 +318,18 @@ var ADMIN_TOKEN = Object.freeze({
310
318
  length: null,
311
319
  summary: "Admin bearer token for the /admin routes. Required by `sandbox create`."
312
320
  });
321
+ var WEBHOOK_SIGNING_SECRET = Object.freeze({
322
+ envVar: "EVERFUR_WEBHOOK_SECRET",
323
+ prefix: "whsec_",
324
+ length: null,
325
+ summary: "A claims webhook endpoint signing secret (whsec_...). Read only to sign test deliveries to your own receiver."
326
+ });
327
+ var CLAIMS_INBOUND_SECRET = Object.freeze({
328
+ envVar: "EVERFUR_CLAIMS_INBOUND_SECRET",
329
+ prefix: "whsec_",
330
+ length: 70,
331
+ summary: "A claims inbound endpoint shared secret (whsec_...). Read only to sign sandbox sample events."
332
+ });
313
333
  function publishableKeyShapes() {
314
334
  return [...PARTNER_KEY.alsoAccepts ?? [], PARTNER_KEY.prefix].map((prefix) => `${prefix}...`).join(" or ");
315
335
  }
@@ -382,6 +402,12 @@ function resolveCredential(env, spec) {
382
402
  matchedPrefix: accepted.find((p) => raw.startsWith(p)) ?? null
383
403
  });
384
404
  }
405
+ function hmacSha256Hex(credential, message) {
406
+ return hmacSha256(credential, message).toString("hex");
407
+ }
408
+ function hmacSha256(credential, message) {
409
+ return createHmac("sha256", Buffer.from(credential.reveal(), "utf8")).update(message).digest();
410
+ }
385
411
 
386
412
  // src/detect/theme-color.ts
387
413
  var NAMED = Object.freeze({ white: "#FFFFFF", black: "#000000" });
@@ -4849,7 +4875,7 @@ function sdkInstallSpec() {
4849
4875
  return `${SDK_PACKAGE}@^${SDK_MIN_VERSION}` ;
4850
4876
  }
4851
4877
  var SDK_PACKAGE_PLATFORMS = /* @__PURE__ */ new Set(["expo-managed", "bare-react-native", "web"]);
4852
- var SDK_MIN_VERSION = "0.11.0";
4878
+ var SDK_MIN_VERSION = "0.17.0";
4853
4879
  var SDK_WEB_MIN_VERSION = SDK_MIN_VERSION;
4854
4880
  var SDK_TELEVET_MIN_VERSION = SDK_MIN_VERSION;
4855
4881
  function sdkInstallSpecFor(options) {
@@ -5450,8 +5476,8 @@ function booleanAttribute(outcome, key) {
5450
5476
  }
5451
5477
 
5452
5478
  // src/version.ts
5453
- var CLI_VERSION = "0.8.0";
5454
- var CLI_PUBLISHED_VERSION = "0.7.0";
5479
+ var CLI_VERSION = "0.9.0";
5480
+ var CLI_PUBLISHED_VERSION = "0.8.0";
5455
5481
 
5456
5482
  // src/commands/diagnose/reasons.ts
5457
5483
  var REASON_CODES = Object.freeze([
@@ -6411,6 +6437,16 @@ var THEME_SLOT_NAMES = Object.freeze([
6411
6437
  // tab the tabs and segmented controls
6412
6438
  // bookingStep the container of one booking step
6413
6439
  // dialog the dialogs and sheets
6440
+ // And since 15 Oct 2026 the Health Plan's cart bar (`cartBar`): the bar that carries the cart count, the subtotal
6441
+ // and the checkout control. Its default fill is the brand colour, so its text is guarded on that.
6442
+ // And the Health Plan's own two (15 Oct 2026), so a shop can differ from every other SDK card and chip:
6443
+ // planCard a Health Plan product card (fill, edge, radius, ink). Unset, it follows `card`.
6444
+ // planReasonLabel the label of a reason drawn as a row (`reasonVariant: 'rows'`): only its ink is read. Unset,
6445
+ // it follows the `chip` ink, then brand ink.
6446
+ // And the plan page's two link washes (22 Oct 2026), so a partner can give his exact tints rather than the mix:
6447
+ // planWash the soft link wash (the icon tiles, the tip, the "Add her weight" row): only its fill is read.
6448
+ // planChip the stronger link wash of a chip: only its fill is read.
6449
+ // Unset, each is the link ink mixed over the card (12% and 20%).
6414
6450
  "header",
6415
6451
  "banner",
6416
6452
  "chip",
@@ -6418,8 +6454,18 @@ var THEME_SLOT_NAMES = Object.freeze([
6418
6454
  "input",
6419
6455
  "tab",
6420
6456
  "bookingStep",
6421
- "dialog"
6457
+ "dialog",
6458
+ "cartBar",
6459
+ "planCard",
6460
+ "planReasonLabel",
6461
+ "planWash",
6462
+ "planChip"
6422
6463
  ]);
6464
+ var THEME_SLOT_KEYS_BY_SLOT = Object.freeze({
6465
+ planReasonLabel: Object.freeze(["textColor"]),
6466
+ planWash: Object.freeze(["backgroundColor"]),
6467
+ planChip: Object.freeze(["backgroundColor"])
6468
+ });
6423
6469
  var SLOT_MIN_CONTRAST = 4.5;
6424
6470
  var EMPTY = Object.freeze({});
6425
6471
  function isSlotName(value) {
@@ -6437,13 +6483,22 @@ function parseThemeSlots(json) {
6437
6483
  let any = false;
6438
6484
  for (const [name, raw] of Object.entries(json)) {
6439
6485
  if (!isSlotName(name) || raw === null || typeof raw !== "object") continue;
6440
- const slot = parseSlot(raw);
6486
+ const parsed = parseSlot(raw);
6487
+ if (parsed === null) continue;
6488
+ const slot = restrictSlotKeys(name, parsed);
6441
6489
  if (slot === null) continue;
6442
6490
  out[name] = slot;
6443
6491
  any = true;
6444
6492
  }
6445
6493
  return any ? Object.freeze(out) : null;
6446
6494
  }
6495
+ function restrictSlotKeys(name, slot) {
6496
+ const allowed = THEME_SLOT_KEYS_BY_SLOT[name];
6497
+ if (allowed === void 0) return slot;
6498
+ const out = {};
6499
+ for (const key of allowed) if (slot[key] !== void 0) out[key] = slot[key];
6500
+ return Object.keys(out).length === 0 ? null : Object.freeze(out);
6501
+ }
6447
6502
  function pick(raw, snake, camel) {
6448
6503
  return raw[snake] !== void 0 ? raw[snake] : raw[camel];
6449
6504
  }
@@ -6475,7 +6530,9 @@ var DECORATIVE_EDGE_SLOTS = /* @__PURE__ */ new Set([
6475
6530
  "banner",
6476
6531
  "header",
6477
6532
  "dialog",
6478
- "bookingStep"
6533
+ "bookingStep",
6534
+ "cartBar",
6535
+ "planCard"
6479
6536
  ]);
6480
6537
  function sameColor(a, b) {
6481
6538
  const left = parseColor(a);
@@ -7263,7 +7320,12 @@ function slotGrounds(c) {
7263
7320
  input: [c.surface, c.composerFill, c.surfaceCream, c.surfaceSubtle],
7264
7321
  tab: [c.surface, c.background],
7265
7322
  bookingStep: [c.surface, c.background],
7266
- dialog: [c.surface]
7323
+ dialog: [c.surface],
7324
+ cartBar: [c.brand],
7325
+ planCard: [c.surface],
7326
+ planReasonLabel: [c.surface],
7327
+ planWash: [c.surface],
7328
+ planChip: [c.surface]
7267
7329
  };
7268
7330
  }
7269
7331
  function slotSurrounds(c) {
@@ -7277,6 +7339,11 @@ function slotSurrounds(c) {
7277
7339
  };
7278
7340
  }
7279
7341
 
7342
+ // src/registry/sdk/client/wire/read.ts
7343
+ function isRecord(value) {
7344
+ return typeof value === "object" && value !== null && !Array.isArray(value);
7345
+ }
7346
+
7280
7347
  // src/registry/sdk/client/theme/appearance.ts
7281
7348
  var APPEARANCE_PRESET_NAMES = Object.freeze(["everfur", "minimal", "night"]);
7282
7349
  var APPEARANCE_PRESETS = Object.freeze({
@@ -7289,9 +7356,6 @@ var APPEARANCE_SIZE_RANGES = Object.freeze({
7289
7356
  borderRadius: Object.freeze({ min: 0, max: 32, default: 14 }),
7290
7357
  spacingUnit: Object.freeze({ min: 3, max: 6, default: 4 })
7291
7358
  });
7292
- function isRecord(value) {
7293
- return value !== null && typeof value === "object" && !Array.isArray(value);
7294
- }
7295
7359
  function isPreset(value) {
7296
7360
  return typeof value === "string" && APPEARANCE_PRESET_NAMES.includes(value.trim().toLowerCase());
7297
7361
  }
@@ -7380,6 +7444,73 @@ function expandAppearance(appearance) {
7380
7444
  }
7381
7445
  return Object.keys(out).length === 0 ? null : Object.freeze(out);
7382
7446
  }
7447
+ var PRESENTATION_WIRE_NAMES = Object.freeze({
7448
+ chatAnswerStyle: "chat_answer_style",
7449
+ chatHistoryStyle: "chat_history_style",
7450
+ chatTopCard: "chat_top_card",
7451
+ chatFollowUpCount: "chat_follow_up_count",
7452
+ chatFollowUpsExcludeTelevet: "chat_follow_ups_exclude_televet",
7453
+ chatComposerMic: "chat_composer_mic",
7454
+ chatComposerUpload: "chat_composer_upload",
7455
+ safetyDisclaimerPlacement: "safety_disclaimer_placement",
7456
+ healthPlanLayout: "health_plan_layout",
7457
+ recordsTopRiskLine: "records_top_risk_line",
7458
+ recordsClearResultsFilter: "records_clear_results_filter",
7459
+ chatComposerStyle: "chat_composer_style",
7460
+ chatComposerPlaceholder: "chat_composer_placeholder",
7461
+ chatHistoryBar: "chat_history_bar",
7462
+ chatGeneralBanner: "chat_general_banner",
7463
+ chatSendButton: "chat_send_button",
7464
+ chatTextingAsk: "chat_texting_ask"
7465
+ });
7466
+ var FIELDS = Object.keys(PRESENTATION_WIRE_NAMES);
7467
+ var PRESENTATION_LOCK = "presentation";
7468
+ var PRESENTATION_LOCK_PREFIX = "presentation.";
7469
+ function isPresentationLockName(name) {
7470
+ if (name === PRESENTATION_LOCK) return true;
7471
+ if (!name.startsWith(PRESENTATION_LOCK_PREFIX)) return false;
7472
+ const field = name.slice(PRESENTATION_LOCK_PREFIX.length);
7473
+ return Object.values(PRESENTATION_WIRE_NAMES).includes(field);
7474
+ }
7475
+ var ENUMS = {
7476
+ chatAnswerStyle: ["bubbles", "cards"],
7477
+ chatHistoryStyle: ["drawer", "sheet"],
7478
+ chatTopCard: ["none", "focus"],
7479
+ safetyDisclaimerPlacement: ["composer", "answer_footer"],
7480
+ healthPlanLayout: ["standard", "focus_plan"],
7481
+ chatComposerStyle: ["standard", "compact"],
7482
+ chatComposerPlaceholder: ["generic", "pet_name"],
7483
+ chatHistoryBar: ["pinned", "scroll"],
7484
+ chatSendButton: ["always_dark", "dim_when_empty"]
7485
+ };
7486
+ var BOOLS = /* @__PURE__ */ new Set([
7487
+ "chatFollowUpsExcludeTelevet",
7488
+ "chatComposerMic",
7489
+ "chatComposerUpload",
7490
+ "recordsTopRiskLine",
7491
+ "recordsClearResultsFilter",
7492
+ "chatGeneralBanner",
7493
+ "chatTextingAsk"
7494
+ ]);
7495
+ function parseField(field, value) {
7496
+ if (value === null || value === void 0) return void 0;
7497
+ const allowed = ENUMS[field];
7498
+ if (allowed !== void 0) return typeof value === "string" && allowed.includes(value) ? value : void 0;
7499
+ if (BOOLS.has(field)) return typeof value === "boolean" ? value : void 0;
7500
+ return typeof value === "number" && Number.isInteger(value) && value >= 0 && value <= 3 ? value : void 0;
7501
+ }
7502
+ function parsePresentation(raw) {
7503
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return null;
7504
+ const source = raw;
7505
+ const out = {};
7506
+ for (const field of FIELDS) {
7507
+ const wire = PRESENTATION_WIRE_NAMES[field];
7508
+ const value = Object.prototype.hasOwnProperty.call(source, wire) ? source[wire] : source[field];
7509
+ const parsed = parseField(field, value);
7510
+ if (parsed !== void 0) out[field] = parsed;
7511
+ }
7512
+ return Object.keys(out).length === 0 ? null : Object.freeze(out);
7513
+ }
7383
7514
 
7384
7515
  // src/registry/sdk/client/theme/fontSources.ts
7385
7516
  var MAX_FONT_SOURCES = 4;
@@ -7416,15 +7547,12 @@ function familyName(value) {
7416
7547
  if (trimmed.length === 0 || trimmed.length > FAMILY_MAX_LENGTH) return null;
7417
7548
  return /[\u0000-\u001F\u007F]/.test(trimmed) ? null : trimmed;
7418
7549
  }
7419
- function isRecord2(value) {
7420
- return value !== null && typeof value === "object" && !Array.isArray(value);
7421
- }
7422
7550
  function pick2(raw, ...keys) {
7423
7551
  for (const key of keys) if (raw[key] !== void 0 && raw[key] !== null) return raw[key];
7424
7552
  return void 0;
7425
7553
  }
7426
7554
  function parseFontSource(raw) {
7427
- if (!isRecord2(raw)) return null;
7555
+ if (!isRecord(raw)) return null;
7428
7556
  const family = familyName(raw["family"]);
7429
7557
  if (family === null) return null;
7430
7558
  const srcRaw = pick2(raw, "src");
@@ -7515,6 +7643,7 @@ function lockedFieldsOf(b) {
7515
7643
  }
7516
7644
  function isThemeLockName(name) {
7517
7645
  if (name === "hide_powered_by" || LOCKABLE_THEME_FIELDS.includes(name)) return true;
7646
+ if (isPresentationLockName(name)) return true;
7518
7647
  return name.startsWith(SLOT_LOCK_PREFIX) && THEME_SLOT_NAMES.includes(name.slice(SLOT_LOCK_PREFIX.length));
7519
7648
  }
7520
7649
  function parseClientBranding(json) {
@@ -7555,6 +7684,7 @@ function parseFlat(raw) {
7555
7684
  slots: parseThemeSlots(pick3(raw, "slots")),
7556
7685
  accessibilityMaxFontScale: parseMaxFontScale(pick3(raw, "accessibility_max_font_scale", "accessibilityMaxFontScale")),
7557
7686
  lockedFields: parseLockedFields(pick3(raw, "locked_fields", "lockedFields")),
7687
+ presentation: parsePresentation(pick3(raw, "presentation")),
7558
7688
  schemaVersion: parseSchemaVersion(pick3(raw, "schema_version", "schemaVersion")),
7559
7689
  backgroundColor: parseColor(pick3(raw, "background_color", "backgroundColor")),
7560
7690
  backgroundColorDark: parseColor(pick3(raw, "background_color_dark", "backgroundColorDark")),
@@ -7650,6 +7780,9 @@ function parseSchemaVersion(value) {
7650
7780
  function toWireName(name) {
7651
7781
  const trimmed = name.trim();
7652
7782
  if (trimmed.startsWith(SLOT_LOCK_PREFIX)) return trimmed;
7783
+ if (trimmed.startsWith(PRESENTATION_LOCK_PREFIX)) {
7784
+ return PRESENTATION_LOCK_PREFIX + trimmed.slice(PRESENTATION_LOCK_PREFIX.length).replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase();
7785
+ }
7653
7786
  return trimmed.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase();
7654
7787
  }
7655
7788
  function parseLockedFields(value) {
@@ -12861,7 +12994,7 @@ var FRAME_CHAT_VET_NOTE = " A frame takes no onFindVet or onVetPrep: functions d
12861
12994
  var RECORDS_DEPTH_SENTENCE = " Lab markers, share links, the record PDF link, fact edits and the signature gallery need the platform flag partner.records_full_depth_enabled; while it is off for your tenant the SDK hides them, so their absence is not a defect in your integration.";
12862
12995
  var RECORDS_SURFACE_NOTE = Object.freeze({
12863
12996
  native: ` EverfurRecords is the app's records flow: it opens on the pet's dashboard and owns its own stack (the hardware back key pops it on React Native), every screen is also exported by name for your own navigator (the mount-records-screens step names them), and initialScreen={{ name: 'request', requestId }} opens a request directly. The mount passes petName={selectedPet.name} for headings such as "{petName}'s lab trends".` + RECORDS_DEPTH_SENTENCE,
12864
- web: ` The mount is ${WEB_RECORDS_SURFACE}, written into the file: it renders EverfurRecordsPage, the SDK's page-shaped root ported from Everfur's own web records page (one scrolling document with the pet's requests), and opens what the page links to (the full record with its vaccinations, the timeline, and an upload on an empty page) in the records flow EverfurRecords in the same place, whose back from its first screen returns to the page, so moving between them stays in place and adds no route to your app. The share link and the record PDF still open in a new tab, the SDK's web default, until the SDK changes it. The page holds no clinic request of its own: a plan that also asks for records-clinic mounts that surface beside it. When the flow sends a clinic request (one clinic or a batch), or the member opens their records from a published request, it lands on its own dashboard, whose back returns to the page. The mount passes petName={selectedPet.name} for headings such as "{petName}'s lab trends".` + RECORDS_DEPTH_SENTENCE
12997
+ web: ` The mount is ${WEB_RECORDS_SURFACE}, written into the file: it renders EverfurRecordsPage, the SDK's page-shaped root ported from Everfur's own web records page (one scrolling document with the pet's requests), and opens what the page links to (the full record with its vaccinations, the timeline, and an upload on an empty page) in the records flow EverfurRecords in the same place, whose back from its first screen returns to the page, so moving between them stays in place and adds no route to your app. The share link and the record PDF still open in a new tab, the SDK's web default, until the SDK changes it. The page also opens its clinic-request flow with consent and signature. A plan that also asks for records-clinic mounts its dedicated request surface beside the page. When the flow sends a clinic request (one clinic or a batch), or the member opens their records from a published request, it lands on its own dashboard, whose back returns to the page. The mount passes petName={selectedPet.name} for headings such as "{petName}'s lab trends".` + RECORDS_DEPTH_SENTENCE
12865
12998
  });
12866
12999
  function recordsScreensStep(surface) {
12867
13000
  const web = surface === "web";
@@ -13840,8 +13973,8 @@ function planIntegration(input) {
13840
13973
  // src/registry/sdk/client/contract/contract.generated.ts
13841
13974
  var CONTRACT_SOURCE = Object.freeze({
13842
13975
  digestAlgorithm: "sha256",
13843
- digest: "860245ebc1d82ec87e76bd5d9eb33d845fddc73ab1998b9e7b67457defe81f48",
13844
- generatedAt: "2026-10-07T05:52:37Z",
13976
+ digest: "f2c258aa21d5f24e8b1056db2114c3b4e5317c82119d86022fde295b059b4bfe",
13977
+ generatedAt: "2026-10-31T06:47:06Z",
13845
13978
  capabilitySchemaVersion: 1,
13846
13979
  errorSchemaVersion: 1
13847
13980
  });
@@ -13868,6 +14001,8 @@ var CONTRACT_RETRYABILITY = Object.freeze([
13868
14001
  Object.freeze({ wireCode: "attachment_unreadable", envelope: "http_envelope", httpStatus: 400, retryable: false }),
13869
14002
  Object.freeze({ wireCode: "authExpired", envelope: "http_envelope", httpStatus: 401, retryable: true }),
13870
14003
  Object.freeze({ wireCode: "authRejected", envelope: "http_envelope", httpStatus: 401, retryable: false }),
14004
+ Object.freeze({ wireCode: "catalog_empty_refused", envelope: "http_envelope", httpStatus: 409, retryable: false }),
14005
+ Object.freeze({ wireCode: "catalog_shrink_refused", envelope: "http_envelope", httpStatus: 409, retryable: false }),
13871
14006
  Object.freeze({ wireCode: "consent_invalid", envelope: "http_envelope", httpStatus: 422, retryable: false }),
13872
14007
  Object.freeze({ wireCode: "consent_required", envelope: "http_envelope", httpStatus: 422, retryable: false }),
13873
14008
  Object.freeze({ wireCode: "consent_scope_wrong_route", envelope: "http_envelope", httpStatus: 400, retryable: false }),
@@ -13892,6 +14027,7 @@ var CONTRACT_RETRYABILITY = Object.freeze([
13892
14027
  Object.freeze({ wireCode: "invalid_request", envelope: "oauth_error", httpStatus: 400, retryable: false }),
13893
14028
  Object.freeze({ wireCode: "invalid_scope", envelope: "oauth_error", httpStatus: 400, retryable: false }),
13894
14029
  Object.freeze({ wireCode: "invalid_target", envelope: "oauth_error", httpStatus: 400, retryable: false }),
14030
+ Object.freeze({ wireCode: "linked_account_read_only", envelope: "http_envelope", httpStatus: 409, retryable: false }),
13895
14031
  Object.freeze({ wireCode: "mcp_connection_not_found", envelope: "http_envelope", httpStatus: 404, retryable: false }),
13896
14032
  Object.freeze({ wireCode: "mcp_request_conflict", envelope: "http_envelope", httpStatus: 409, retryable: false }),
13897
14033
  Object.freeze({ wireCode: "mcp_request_gone", envelope: "http_envelope", httpStatus: 410, retryable: false }),
@@ -13928,6 +14064,7 @@ var CONTRACT_RETRYABILITY = Object.freeze([
13928
14064
  Object.freeze({ wireCode: "unrestrictedKeyRequired", envelope: "http_envelope", httpStatus: 403, retryable: false }),
13929
14065
  Object.freeze({ wireCode: "unsupported_grant_type", envelope: "oauth_error", httpStatus: 400, retryable: false }),
13930
14066
  Object.freeze({ wireCode: "unsupported_response_type", envelope: "oauth_error", httpStatus: 302, retryable: false }),
14067
+ Object.freeze({ wireCode: "user_ref_invalid", envelope: "http_envelope", httpStatus: 400, retryable: false }),
13931
14068
  Object.freeze({ wireCode: "verify_mint_rate_limited", envelope: "http_envelope", httpStatus: 429, retryable: true }),
13932
14069
  Object.freeze({ wireCode: "verify_mint_refused", envelope: "http_envelope", httpStatus: 403, retryable: false }),
13933
14070
  Object.freeze({ wireCode: "verify_mint_unavailable", envelope: "http_envelope", httpStatus: 503, retryable: true }),
@@ -13986,6 +14123,9 @@ var NORMALIZED_FOLD = Object.freeze({
13986
14123
  // revoke, decided on the key's shape alone. A partner_server 403 that no retry or fresh token fixes, so it
13987
14124
  // folds with `insufficientCapability`. It never reaches a device runtime.
13988
14125
  unrestrictedKeyRequired: "accessDenied",
14126
+ // the session mint and revoke reject a malformed user_ref (a partner_server 400 checked before any
14127
+ // credential work). Fixing the user_ref is the only cure, so it is a non-retryable input fault.
14128
+ user_ref_invalid: "validationFailed",
13989
14129
  // the partner events server surface (POST/GET /partners/events). Every one is a non-retryable input
13990
14130
  // fault, so each folds to validationFailed; the 413 matches the ValidationException the rest of the API
13991
14131
  // answers for an oversized body. `idempotency_key_reused` is the same client bug as
@@ -14175,7 +14315,18 @@ var NORMALIZED_FOLD = Object.freeze({
14175
14315
  // `already_mapped`, so a client that timed out learns the pet id instead of a conflict.
14176
14316
  partner_visit_owner_only: "accessDenied",
14177
14317
  partner_visit_link_conflict: "conflict",
14178
- partner_visit_pet_already_mapped: "conflict"
14318
+ partner_visit_pet_already_mapped: "conflict",
14319
+ // The 409 a write gets when the member's Everfur account is linked to this partner read-only. On the wire it
14320
+ // is `ConflictException` with this token as `reason_code`, and `isLinkedAccountReadOnly` already keeps it on
14321
+ // `conflict` (an `accessDenied` would read as a consent or plan gate), so the registered code folds the same.
14322
+ linked_account_read_only: "conflict",
14323
+ // The partner catalog replace's two guards (PUT /partners/catalog/products), read off `reason_code` on a
14324
+ // `ConflictException` 409: an empty list, or one that would deactivate most of the active products, sent
14325
+ // without `confirm_empty` or `confirm_shrink`. NOTHING is written. They fold with the envelope's
14326
+ // ConflictException, the reading `src/server/catalog.ts` (CATALOG_REASONS) already gives them, and that table
14327
+ // keeps both non-retryable. Server to server only; neither reaches a device runtime.
14328
+ catalog_empty_refused: "conflict",
14329
+ catalog_shrink_refused: "conflict"
14179
14330
  });
14180
14331
  var CONTRACT_ERROR_ROWS = Object.freeze(
14181
14332
  CONTRACT_RETRYABILITY.map(
@@ -14343,16 +14494,16 @@ function userFacingError(code) {
14343
14494
  var MANIFEST_default = {
14344
14495
  sdk: {
14345
14496
  name: "@everfur/sdk",
14346
- version: "0.11.0"
14497
+ version: "0.17.0"
14347
14498
  },
14348
14499
  files: [
14349
14500
  {
14350
14501
  path: "client/contract/contract.generated.ts",
14351
- sha256: "7d0a933511698d009787ae98833f9ac4be12f49b4157d710bdff3dac758f4a92"
14502
+ sha256: "dbfc4cc268c85c1c6177a4772a08cadd75c551f22dfe995f48b9ebdcc0df3731"
14352
14503
  },
14353
14504
  {
14354
14505
  path: "client/errors/EverfurError.ts",
14355
- sha256: "3465877ba734750fd8985d9c8c02ab3d1188f9dd19a9e1c3ecf8cc86d6ac5806"
14506
+ sha256: "82c84b6152adb24ec0c78fac93579e16e1e24d3584aa38a6f5b5e6ca2699e382"
14356
14507
  },
14357
14508
  {
14358
14509
  path: "client/errors/codes.ts",
@@ -14360,7 +14511,7 @@ var MANIFEST_default = {
14360
14511
  },
14361
14512
  {
14362
14513
  path: "client/errors/contract.ts",
14363
- sha256: "eb68d4729cf54c7d6935096cef1372cbdbfbc34f73b7b5b436302506a5204cc7"
14514
+ sha256: "b7aa7fed5f456a9a299f99ff49bdc594e83581e2bdf7b3ee4f683fdcb2ab7ba9"
14364
14515
  },
14365
14516
  {
14366
14517
  path: "client/theme/adjustments.ts",
@@ -14368,11 +14519,11 @@ var MANIFEST_default = {
14368
14519
  },
14369
14520
  {
14370
14521
  path: "client/theme/appearance.ts",
14371
- sha256: "fe9db62840ed13a43cb51066b19220d4552e8b2c51f117c8c62d093cfa677009"
14522
+ sha256: "1e045809a1944ae09d98f614a3d6eab43bb8db463589f4f1cef5aa3fd281cc08"
14372
14523
  },
14373
14524
  {
14374
14525
  path: "client/theme/branding.ts",
14375
- sha256: "15d9c3c725e7daf08ad6209101346381698b4dc85257c92a46b08a9ff77ea49b"
14526
+ sha256: "bd886ecce5ea14d3f00815a972af7691120e72d383af542e3d4050fa17e46da8"
14376
14527
  },
14377
14528
  {
14378
14529
  path: "client/theme/color.ts",
@@ -14384,7 +14535,7 @@ var MANIFEST_default = {
14384
14535
  },
14385
14536
  {
14386
14537
  path: "client/theme/fontSources.ts",
14387
- sha256: "69bbe37f7ef1d51f00b988af67b0b0e17baa84e87d32a405e931e0a8028ac54b"
14538
+ sha256: "c734b1ec50b8615653b7d027534a264e11defe2892397c41bcf88285e6a3a699"
14388
14539
  },
14389
14540
  {
14390
14541
  path: "client/theme/globals.ts",
@@ -14398,21 +14549,29 @@ var MANIFEST_default = {
14398
14549
  path: "client/theme/input.ts",
14399
14550
  sha256: "cc601aed813c6f5ae61822ee18cd717f0b9fa1fba5b743d63c6edfec0f0bc2e2"
14400
14551
  },
14552
+ {
14553
+ path: "client/theme/presentation.ts",
14554
+ sha256: "af152d2acce2383e7382061d2bc6b2d10c3c04df8348fc462636cb72445882e0"
14555
+ },
14401
14556
  {
14402
14557
  path: "client/theme/resolve.ts",
14403
14558
  sha256: "cad427919d7371f8f9ea7cc32b98ff9dd9454a9123bc73d345bfaf80952c9cae"
14404
14559
  },
14405
14560
  {
14406
14561
  path: "client/theme/slotGrounds.ts",
14407
- sha256: "c40192ff1793d44e9967892565827b27f8800dffab9d9a77b9c27e7399fc0a61"
14562
+ sha256: "a80402d0c572e1ca5fc77f378b171bbd53fa7c37127b6693d1ab0d6b660c3df2"
14408
14563
  },
14409
14564
  {
14410
14565
  path: "client/theme/slots.ts",
14411
- sha256: "47105b734b77269949db05d8014f3b0eb2a2171958343866adb5421615d86cd9"
14566
+ sha256: "64c108b2751ac28b48a7b837b25271a28058e93be32ee241b397c0f7df6b5d84"
14412
14567
  },
14413
14568
  {
14414
14569
  path: "client/theme/tokens.ts",
14415
14570
  sha256: "f9446c1cb689ea0af89c3289f7c8efa8330ca21a8710cdd8affa4fb1cc4ffd8e"
14571
+ },
14572
+ {
14573
+ path: "client/wire/read.ts",
14574
+ sha256: "fd03f0123d2ee1bf1ede61d5a114efd6dfe68b44b9329796ba17e2717174eb11"
14416
14575
  }
14417
14576
  ]
14418
14577
  };
@@ -16516,6 +16675,43 @@ var REFUSAL_POLICY = Object.freeze({
16516
16675
  // hosted only: the connected tenant has no publishable key, or one of a shape no deployment issues. Its keys are
16517
16676
  // Everfur's to issue and nothing a developer exports reaches them, so the refusal is reported, never "fixed" locally
16518
16677
  TENANT_PUBLISHABLE_KEY_UNUSABLE: { retryable: false, nextAction: "report_to_developer", docsPath: null },
16678
+ // the claims tools (claims-tools.ts). The sandbox tool reads the sandbox tenant's secret key from a local shell
16679
+ // only; the sandbox routes refuse a live key (sandbox_key_required) and answer 404 while switched off for the tenant
16680
+ CLAIMS_SERVER_KEY_UNAVAILABLE: { retryable: false, nextAction: "fix_environment", docsPath: null },
16681
+ CLAIMS_SERVER_KEY_MALFORMED: { retryable: false, nextAction: "fix_environment", docsPath: null },
16682
+ CLAIMS_SANDBOX_KEY_REQUIRED: { retryable: false, nextAction: "use_sandbox_tenant", docsPath: null },
16683
+ CLAIMS_SANDBOX_NOT_ENABLED: { retryable: false, nextAction: "report_to_developer", docsPath: null },
16684
+ CLAIMS_SANDBOX_CALL_FAILED: { retryable: "from_failure", nextAction: "from_failure", docsPath: null },
16685
+ CLAIMS_ARGUMENTS_INVALID: { retryable: false, nextAction: "fix_arguments", docsPath: null },
16686
+ // everfur_verify_claims_receiver: the URL is not localhost or public https, the signing secret is not usable, or
16687
+ // the receiver failed a check (each failed check carries its own fix)
16688
+ CLAIMS_RECEIVER_URL_REFUSED: { retryable: false, nextAction: "fix_arguments", docsPath: null },
16689
+ CLAIMS_WEBHOOK_SECRET_UNUSABLE: { retryable: false, nextAction: "fix_environment", docsPath: null },
16690
+ CLAIMS_RECEIVER_CHECKS_FAILED: { retryable: false, nextAction: "report_to_developer", docsPath: null },
16691
+ // the sandbox and verify claims tools on the Everfur-hosted server, which holds no local key or signing secret
16692
+ CLAIMS_TOOL_NOT_HOSTED: { retryable: false, nextAction: "report_to_developer", docsPath: null },
16693
+ // the inbound claims tools (claims-inbound-tools.ts): a mapping the checks refuse, an activation no person
16694
+ // confirmed, the inbound secret or URL not usable here, and samples that did not apply
16695
+ CLAIMS_MAPPING_INVALID: { retryable: false, nextAction: "fix_arguments", docsPath: null },
16696
+ CLAIMS_MAPPING_CONFIRMATION_REQUIRED: { retryable: false, nextAction: "report_to_developer", docsPath: null },
16697
+ // activate_draft with no draft saved (the active mapping, if any, is named): a person saves and confirms a new one
16698
+ CLAIMS_MAPPING_DRAFT_MISSING: { retryable: false, nextAction: "report_to_developer", docsPath: null },
16699
+ CLAIMS_INBOUND_SECRET_UNUSABLE: { retryable: false, nextAction: "fix_environment", docsPath: null },
16700
+ CLAIMS_INBOUND_URL_UNUSABLE: { retryable: false, nextAction: "fix_environment", docsPath: null },
16701
+ CLAIMS_INBOUND_SAMPLES_FAILED: { retryable: false, nextAction: "report_to_developer", docsPath: null },
16702
+ // create_endpoint: no person confirmed the one-time create, the tenant already has its endpoint, or the endpoint
16703
+ // was created and its URL or secret (shown once) could not be written to the env file
16704
+ CLAIMS_INBOUND_CREATE_CONFIRMATION_REQUIRED: { retryable: false, nextAction: "report_to_developer", docsPath: null },
16705
+ CLAIMS_INBOUND_ENDPOINT_EXISTS: { retryable: false, nextAction: "report_to_developer", docsPath: null },
16706
+ CLAIMS_INBOUND_CREDENTIALS_NOT_WRITTEN: { retryable: false, nextAction: "report_to_developer", docsPath: null },
16707
+ // the one-time and replacing sandbox actions: no person has confirmed yet (a local code was written, or none could
16708
+ // be), or the person declined when the client asked them
16709
+ CLAIMS_HUMAN_CONFIRMATION_REQUIRED: { retryable: false, nextAction: "report_to_developer", docsPath: null },
16710
+ CLAIMS_HUMAN_DECLINED: { retryable: false, nextAction: "report_to_developer", docsPath: null },
16711
+ // the sandbox claims tools: EVERFUR_API_BASE_URL names a host the secret key is not sent to
16712
+ CLAIMS_API_HOST_NOT_ALLOWED: { retryable: false, nextAction: "fix_environment", docsPath: null },
16713
+ // everfur_explain_claims_error
16714
+ UNKNOWN_CLAIMS_ERROR_CODE: { retryable: false, nextAction: "fix_arguments", docsPath: null },
16519
16715
  // any tool: a body threw instead of returning a document
16520
16716
  INTERNAL_ERROR: { retryable: false, nextAction: "report_to_developer", docsPath: null }
16521
16717
  });
@@ -16761,6 +16957,15 @@ var DIAGNOSE = "everfur_diagnose";
16761
16957
  var EXPLAIN = "everfur_explain_error";
16762
16958
  var SEND = "everfur_send_test_message";
16763
16959
  var SEARCH = "everfur_search_docs";
16960
+ var CLAIMS_PLAN = "everfur_plan_claims_integration";
16961
+ var CLAIMS_SANDBOX = "everfur_send_claims_test_events";
16962
+ var CLAIMS_VERIFY = "everfur_verify_claims_receiver";
16963
+ var CLAIMS_EXPLAIN = "everfur_explain_claims_error";
16964
+ var CLAIMS_PROPOSE = "everfur_propose_claims_mapping";
16965
+ var CLAIMS_SAVE = "everfur_save_claims_mapping";
16966
+ var CLAIMS_SETUP = "everfur_claims_inbound_signing_setup";
16967
+ var CLAIMS_SAMPLES = "everfur_send_claims_inbound_samples";
16968
+ var CLAIMS_INBOUND = [CLAIMS_SAVE, CLAIMS_SETUP, CLAIMS_SAMPLES];
16764
16969
  var TENANT_READS = [
16765
16970
  "everfur_get_tenant_status",
16766
16971
  "everfur_list_webhook_endpoints",
@@ -16781,12 +16986,12 @@ var MEANINGS = Object.freeze({
16781
16986
  nextAction: "Ask the developer each fact in error.details.missing_facts, then call everfur_plan_integration again with the same arguments plus those answers. Do not guess them."
16782
16987
  },
16783
16988
  PROJECT_SOURCE_REQUIRED: {
16784
- tools: [PLAN],
16989
+ tools: [PLAN, CLAIMS_PLAN],
16785
16990
  meaning: "Neither project_root nor project_details was passed, so there was no project to plan for.",
16786
16991
  nextAction: "Call again with project_details (the dependencies, package manager and file-presence markers) on a remote or hosted server, or project_root on a server that runs beside the project."
16787
16992
  },
16788
16993
  PROJECT_SOURCE_AMBIGUOUS: {
16789
- tools: [PLAN],
16994
+ tools: [PLAN, CLAIMS_PLAN],
16790
16995
  meaning: "Both project_root and project_details were passed, and the plan takes exactly one project source.",
16791
16996
  nextAction: "Call again with one of them: project_root on a server beside the project, project_details on a remote one."
16792
16997
  },
@@ -16811,23 +17016,23 @@ var MEANINGS = Object.freeze({
16811
17016
  nextAction: "Ask the developer which was meant: omit environment to plan for the connected tenant's own mode, or connect with a tenant of the mode the environment needs. On a local server, pass the environment of the key's tenant, or set EVERFUR_PARTNER_KEY to the key of the tenant meant."
16812
17017
  },
16813
17018
  UNKNOWN_PLAN_STEP: {
16814
- tools: [PLAN],
17019
+ tools: [PLAN, CLAIMS_PLAN],
16815
17020
  meaning: "A step id in steps is not a step of this plan. error.details.unknown lists the ids that are not, and error.details.steps every id the plan has.",
16816
17021
  nextAction: "Call again with the same arguments and plan_id, and steps taken from error.details.steps."
16817
17022
  },
16818
17023
  UNKNOWN_PLAN_PAGE: {
16819
- tools: [PLAN],
17024
+ tools: [PLAN, CLAIMS_PLAN],
16820
17025
  meaning: "The page asked for is not a page of this plan, or page and steps were both given. error.details.pages is how many pages the plan has.",
16821
17026
  nextAction: "Call again with the same arguments and plan_id, and page from 1 to error.details.pages, or with steps and no page."
16822
17027
  },
16823
17028
  PLAN_CHANGED: {
16824
- tools: [PLAN],
17029
+ tools: [PLAN, CLAIMS_PLAN],
16825
17030
  meaning: "The plan_id passed is not the plan these arguments produce now: the arguments differ from the call that returned it, the project changed in a way that changes a step (a command run or a file written from the plan can), or the contract changed. error.details carries both ids.",
16826
17031
  nextAction: "Call again with the same arguments and without plan_id, page and steps for the summary of the current plan, then fetch its pages with the plan_id it returns."
16827
17032
  },
16828
17033
  // shared wire configuration
16829
17034
  WIRE_NOT_CONFIGURED: {
16830
- tools: [PLAN, VERIFY, DIAGNOSE, EXPLAIN, SEND, SEARCH],
17035
+ tools: [PLAN, VERIFY, DIAGNOSE, EXPLAIN, SEND, SEARCH, CLAIMS_SANDBOX],
16831
17036
  meaning: "The server could not set up its connection to the Everfur API: the API base URL is missing or not usable. error.details names what is wrong.",
16832
17037
  nextAction: "Fix the server's environment as error.details says (EVERFUR_API_BASE_URL on a server you run), then call again."
16833
17038
  },
@@ -17010,6 +17215,122 @@ var MEANINGS = Object.freeze({
17010
17215
  meaning: "On the Everfur-hosted server: the connected tenant has no active publishable key, or one of a shape no deployment issues, so the call was not made. Everfur issues the tenant's keys; nothing the developer exports reaches them.",
17011
17216
  nextAction: "Tell the developer what error.details.how_to_fix says."
17012
17217
  },
17218
+ // the claims tools (claims-tools.ts)
17219
+ CLAIMS_SERVER_KEY_UNAVAILABLE: {
17220
+ tools: [CLAIMS_SANDBOX, ...CLAIMS_INBOUND],
17221
+ meaning: "The sandbox tenant's secret key is not set in the environment of the local shell this server runs from, so no sandbox route was called.",
17222
+ nextAction: "Tell the developer the sandbox tool needs the sandbox tenant's secret key exported from a local shell only, never in a committed MCP configuration."
17223
+ },
17224
+ CLAIMS_SERVER_KEY_MALFORMED: {
17225
+ tools: [CLAIMS_SANDBOX, ...CLAIMS_INBOUND],
17226
+ meaning: "The secret key set in the local shell is not of the shape a partner secret key has, so no sandbox route was called.",
17227
+ nextAction: "Tell the developer to check the key exported in that shell; the value is never shown."
17228
+ },
17229
+ CLAIMS_SANDBOX_KEY_REQUIRED: {
17230
+ tools: [CLAIMS_SANDBOX, ...CLAIMS_INBOUND],
17231
+ meaning: "The sandbox route answered 403 sandbox_key_required: the key is a live tenant's key, and the sandbox routes take only a sandbox tenant's.",
17232
+ nextAction: "Use the sandbox tenant's secret key, then call again."
17233
+ },
17234
+ CLAIMS_SANDBOX_NOT_ENABLED: {
17235
+ tools: [CLAIMS_SANDBOX, ...CLAIMS_INBOUND],
17236
+ meaning: "The sandbox route answered 404 with no code of its own: the sandbox webhook or claims-inbound routes are not switched on for this tenant or deployment, the endpoint_id names no endpoint of this tenant, or (inbound) the tenant has no claims portal or no inbound endpoint exists yet. The sandbox key can create the sandbox inbound endpoint once (everfur_claims_inbound_signing_setup, create_endpoint with confirm: true from a person); its inbound URL and first secret are shown once, at creation. Live inbound endpoints are set up by Everfur.",
17237
+ nextAction: "Check the endpoint_id with list_endpoints; when list_endpoints itself answers this, switching the routes on is a step Everfur holds. When an inbound route answers it and the routes are on, the sandbox endpoint may not exist yet: offer create_endpoint, and create it only when a person confirms."
17238
+ },
17239
+ CLAIMS_SANDBOX_CALL_FAILED: {
17240
+ tools: [CLAIMS_SANDBOX, ...CLAIMS_INBOUND],
17241
+ meaning: "A sandbox route failed on the wire or answered an error with a code (error.details.code), such as webhook_url_rejected, webhook_endpoint_limit_reached or webhook_test_rate_limited.",
17242
+ nextAction: `Explain error.details.code with everfur_explain_claims_error (not everfur_explain_error) when there is one; after a 429, wait for error.details.retry_after. ${FROM_FAILURE}`
17243
+ },
17244
+ CLAIMS_ARGUMENTS_INVALID: {
17245
+ tools: [CLAIMS_SANDBOX, CLAIMS_PROPOSE, ...CLAIMS_INBOUND],
17246
+ meaning: "The action lacks an argument it needs (error.details.arguments), or secret_env_file cannot take the signing secret. Nothing was created.",
17247
+ nextAction: "Call again with the arguments named in error.details.arguments."
17248
+ },
17249
+ CLAIMS_RECEIVER_URL_REFUSED: {
17250
+ tools: [CLAIMS_VERIFY],
17251
+ meaning: "receiver_url is neither http(s) on localhost or 127.0.0.1 nor a public https URL, so nothing was sent to it.",
17252
+ nextAction: "Call again with the receiver on localhost or on its public https URL."
17253
+ },
17254
+ CLAIMS_WEBHOOK_SECRET_UNUSABLE: {
17255
+ tools: [CLAIMS_VERIFY],
17256
+ meaning: "The endpoint signing secret the checks sign with is not set in this server's environment, or is not a whsec_ value, so nothing was sent.",
17257
+ nextAction: "Tell the developer to set the same whsec_ signing secret their receiver reads in the environment this server runs from."
17258
+ },
17259
+ CLAIMS_RECEIVER_CHECKS_FAILED: {
17260
+ tools: [CLAIMS_VERIFY],
17261
+ meaning: "The receiver failed at least one check. Each check in the result says what was expected, what came back and the fix.",
17262
+ nextAction: "Apply the fix of each FAIL check to the receiver, then run the checks again."
17263
+ },
17264
+ CLAIMS_TOOL_NOT_HOSTED: {
17265
+ tools: [CLAIMS_SANDBOX, CLAIMS_VERIFY, ...CLAIMS_INBOUND],
17266
+ meaning: "This claims tool runs only on an MCP server on the developer's own machine; the Everfur-hosted server holds no sandbox key and no signing secret for a tenant.",
17267
+ nextAction: "Tell the developer to run the tool from the local MCP server or the CLI."
17268
+ },
17269
+ CLAIMS_MAPPING_INVALID: {
17270
+ tools: [CLAIMS_SAVE],
17271
+ meaning: "The mapping does not pass the mapping checks (error.details.problems: a path, a transform, a limit, or pii_paths hiding a field the mapping reads), or the API refused to save or activate it. Nothing was saved or activated.",
17272
+ nextAction: "Fix each problem in the mapping (everfur_propose_claims_mapping can propose one again), then save again."
17273
+ },
17274
+ CLAIMS_MAPPING_CONFIRMATION_REQUIRED: {
17275
+ tools: [CLAIMS_SAVE],
17276
+ meaning: "activate_draft was called without confirm: true and the confirmation phrase the save answer gave, or the phrase does not match the current draft. Nothing was activated.",
17277
+ nextAction: "Show the developer the draft and its phrase; activate only when a person who read it types the phrase back. Never activate on your own."
17278
+ },
17279
+ CLAIMS_MAPPING_DRAFT_MISSING: {
17280
+ tools: [CLAIMS_SAVE],
17281
+ meaning: "activate_draft found no mapping draft saved: none was ever saved, or it was already activated (error.details.active_version names the active one). Nothing was activated.",
17282
+ nextAction: "To change the active mapping, save a new draft with save_draft, show it and its phrase to the developer, and activate only when a person who read it types the phrase back."
17283
+ },
17284
+ CLAIMS_INBOUND_SECRET_UNUSABLE: {
17285
+ tools: [CLAIMS_SAMPLES],
17286
+ meaning: "The inbound endpoint's shared secret is not set in this server's environment or in secret_env_file, or is not a whsec_ value, so nothing was sent.",
17287
+ nextAction: "Rotate the sandbox secret into a local env file with everfur_claims_inbound_signing_setup (rotate_secret: true), then pass that file as secret_env_file."
17288
+ },
17289
+ CLAIMS_INBOUND_URL_UNUSABLE: {
17290
+ tools: [CLAIMS_SAMPLES],
17291
+ meaning: "The sandbox inbound URL is not set in this server's environment or in secret_env_file, is malformed, or names another host than the configured Everfur API, so nothing was sent.",
17292
+ nextAction: "Tell the developer to set the inbound URL from where it was saved when the sandbox endpoint was created (shown once), on the same API host as EVERFUR_API_BASE_URL; with no endpoint yet, offer create_endpoint."
17293
+ },
17294
+ CLAIMS_INBOUND_CREATE_CONFIRMATION_REQUIRED: {
17295
+ tools: [CLAIMS_SETUP],
17296
+ meaning: "create_endpoint was called without confirm: true. Creating the sandbox inbound endpoint is a one-time action (its URL and secret are shown once, and no route deletes a sandbox endpoint), so a person decides it. Nothing was created.",
17297
+ nextAction: "Show the developer the signing config; call create_endpoint with confirm: true only when a person asks for it. Never confirm on your own."
17298
+ },
17299
+ CLAIMS_INBOUND_ENDPOINT_EXISTS: {
17300
+ tools: [CLAIMS_SETUP],
17301
+ meaning: "The create answered 409 endpoint_exists: this sandbox tenant already has its inbound endpoint, whose URL was shown once, at creation. Nothing was created.",
17302
+ nextAction: "Tell the developer to set EVERFUR_CLAIMS_INBOUND_URL from where they saved it, and offer rotate_secret for a new secret or rotate_token for a new URL."
17303
+ },
17304
+ CLAIMS_INBOUND_CREDENTIALS_NOT_WRITTEN: {
17305
+ tools: [CLAIMS_SETUP],
17306
+ meaning: "The sandbox inbound endpoint was created, but its URL or secret (error.details.url_written, secret_written) could not be written to secret_env_file, and the API shows them only once.",
17307
+ nextAction: "Tell the developer plainly: the endpoint exists; a lost secret is recovered with rotate_secret and a lost URL with rotate_token, each with a writable secret_env_file. Never create again."
17308
+ },
17309
+ CLAIMS_HUMAN_CONFIRMATION_REQUIRED: {
17310
+ tools: [CLAIMS_SANDBOX, CLAIMS_SAVE, CLAIMS_SETUP],
17311
+ meaning: "A person must confirm this one-time or replacing sandbox action, and this client cannot ask them directly, so a one-time code was written to a local file (error.details.code_file, mode 600) and printed on the server's stderr. Nothing was done.",
17312
+ nextAction: "Tell the developer the file path and ask them to type the code back only if they want the action; call again with confirmation_code set to what they typed. Never open the file yourself."
17313
+ },
17314
+ CLAIMS_HUMAN_DECLINED: {
17315
+ tools: [CLAIMS_SANDBOX, CLAIMS_SAVE, CLAIMS_SETUP],
17316
+ meaning: "The client asked the person to confirm the action, and they declined or cancelled. Nothing was done.",
17317
+ nextAction: "Do not retry on your own; ask the developer what they want changed."
17318
+ },
17319
+ CLAIMS_API_HOST_NOT_ALLOWED: {
17320
+ tools: [CLAIMS_SANDBOX, CLAIMS_PROPOSE, ...CLAIMS_INBOUND],
17321
+ meaning: "EVERFUR_API_BASE_URL names a host other than api.everfur.com, api-staging.everfur.com or this machine, so the secret key is not sent to it. Nothing was sent.",
17322
+ nextAction: "Tell the developer to point EVERFUR_API_BASE_URL at the Everfur API, or to set EVERFUR_ALLOW_CUSTOM_API_HOST=1 in the shell for an Everfur API they trust."
17323
+ },
17324
+ CLAIMS_INBOUND_SAMPLES_FAILED: {
17325
+ tools: [CLAIMS_SAMPLES],
17326
+ meaning: "At least one sample did not end applied or duplicate, or a check failed. Each result carries its reason code and the fix.",
17327
+ nextAction: "Apply each result's fix (the mapping, the signing or the sample), then send the samples again."
17328
+ },
17329
+ UNKNOWN_CLAIMS_ERROR_CODE: {
17330
+ tools: [CLAIMS_EXPLAIN],
17331
+ meaning: "The code is not a Claims API code, a webhook delivery state or a profile import code. error.details.near_misses lists close spellings.",
17332
+ nextAction: "Check the code was copied exactly; when it was, say it is unknown."
17333
+ },
17013
17334
  // any tool
17014
17335
  INTERNAL_ERROR: {
17015
17336
  tools: ["any tool"],
@@ -17257,7 +17578,7 @@ var SDK_SUB_ENUMS = Object.freeze([
17257
17578
  },
17258
17579
  {
17259
17580
  name: "DictationErrorKind",
17260
- file: "src/web/chat/dictation/webSpeechDictation.ts",
17581
+ file: "src/react/chat/dictation/dictation.ts",
17261
17582
  declaration: "type",
17262
17583
  members: {
17263
17584
  permissionDenied: { meaning: "The browser refused microphone or speech recognition access (not-allowed, service-not-allowed).", retryable: false, nextAction: "The person allows the microphone in the browser's site settings." },
@@ -17418,4 +17739,4 @@ function resolveAfterRegistryMiss(code, registry) {
17418
17739
  return { kind: "unknown", suggestions: suggestCodes(code, knownCodes(registry)) };
17419
17740
  }
17420
17741
 
17421
- export { ADMIN_TOKEN, ALL_CAPABILITIES, API_BASE_URL_BY_ENVIRONMENT, API_PREFIX, BACKEND_LANGUAGE_QUESTION, BASE_URL_ENV_VAR, CAPABILITIES_TREE, CAPABILITY_QUESTION, CLI_VERSION, CREDENTIAL_SPECS, DEFAULT_TIMEOUT_MS, DIAGNOSTICS_PATH, DOCS_KEY, EMPTY_REGISTRY, ENVELOPE_SHAPE, ENVIRONMENTS, ERRORS_DOCUMENT_KEY, EVERFUR_LOADER_HOSTS, ExitCode, IDEMPOTENT_METHODS, IDENTITY_QUESTION, IDENTITY_TREE, MAX_TIMEOUT_MS, MIN_TIMEOUT_MS, MISSING_FACT_NAMES, NEXT_ACTIONS, NO_CONTRACT_CACHE, PARTNER_KEY, PARTNER_SECRET_KEY, PLAN_DOCUMENT_KIND, PLAN_SCHEMA_VERSION, PLATFORM_TREE, REASON_CODES, REDACTED, REFUSAL_POLICY, SCHEMAS, SESSION_MINT_TREE, SESSION_TOKEN, SURFACES, THEME_TOKEN_ORDER, TOOL_CODES, TransportError, VERIFY_IDENTITY_MODES, WEB_EMBEDDING_QUESTION, alsoInLines, apiUrl, blockedCapabilities, buildDecisionSpace, buildDiagnosisDocument, buildExplanationDocument, buildSupportBundle, checkTenantMode, chooseWidgetAuth, clampTimeout, contractUnavailableOutcome, countsAsNotOn, createApiClient, createContractProvider, createMemoryFileSystem, createRecordingClock, describeFailure, detectProject, detectTheme, detectThemeFromText, diagnoseFailure, diagnoseVerdict, diagnosis_v1_schema_default, digestOfProjection, digestsEqual, editDistance, entryFromRow, ephemeralCredential, errorCodeOf, errorOutcome, error_explanation_v1_schema_default, expandCapabilities, fail, failedResult, failureDetails, fetchContract, fetchTransport, isCorrelatableRequestId, isEverfurLoaderHost, isIdempotent, isJsonObject, isKnownReasonCode, isWorkspaceRootEvidence, knownCodes, loadDecisionSpace, loadDecisionSpaceFromContract, loadErrorRegistry, loadErrorRegistryFromContract, missingFactsFor, nextActionFor, nextActionFor2, nodeContractCache, nodeFileSystem, normalizeSurfaces, offlineDocument, parseDiagnostics, parseEnvironment, parseIdentityMode, parseLoaderUrl, parseOrigin, parseSurfaces, planIntegration, plan_v1_schema_default, plannableCapabilities, refusal, registryAlsoIn, renderExplanation, renderOffline, renderSupportBundle, resolveAfterRegistryMiss, resolveContractPath, resolveCredential, resolveEndpoint, resolveOffline, resolveWithoutRegistry, runVerification, succeed, suggestCodes, systemClock, themePropFromSource, toolCodeExplanation, toolCodeMeaning, uuidFromKey, validateContractFile, validateContractPublicEnvelope, validateContractText, validateDiagnosisDocument, validateErrorExplanationDocument, validatePlanDocument, validateSandboxCreateDocument, validateVerificationDocument, verification_v1_schema_default, verifyDigest, walkSingle, walkTree, withPrefix };
17742
+ export { ADMIN_TOKEN, ALLOW_CUSTOM_API_HOST_ENV_VAR, ALL_CAPABILITIES, API_BASE_URL_BY_ENVIRONMENT, API_BASE_URL_PLACEHOLDER, API_PREFIX, BACKEND_LANGUAGE_QUESTION, BASE_URL_ENV_VAR, CAPABILITIES_TREE, CAPABILITY_QUESTION, CLAIMS_INBOUND_SECRET, CLI_VERSION, CREDENTIAL_SPECS, DEFAULT_TIMEOUT_MS, DIAGNOSTICS_PATH, DOCS_KEY, EMPTY_REGISTRY, ENVELOPE_SHAPE, ENVIRONMENTS, ERRORS_DOCUMENT_KEY, EVERFUR_LOADER_HOSTS, ExitCode, IDEMPOTENT_METHODS, IDENTITY_QUESTION, IDENTITY_TREE, MAX_TIMEOUT_MS, MIN_TIMEOUT_MS, MISSING_FACT_NAMES, NEXT_ACTIONS, NO_CONTRACT_CACHE, PARTNER_KEY, PARTNER_SECRET_KEY, PLAN_DOCUMENT_KIND, PLAN_SCHEMA_VERSION, PLATFORM_TREE, REASON_CODES, REDACTED, REFUSAL_POLICY, SCHEMAS, SESSION_MINT_TREE, SESSION_TOKEN, SURFACES, THEME_TOKEN_ORDER, TOOL_CODES, TransportError, VERIFY_IDENTITY_MODES, WEBHOOK_PUBLIC_PATH, WEBHOOK_RECEIVER_PATH, WEBHOOK_SIGNING_SECRET, WEB_EMBEDDING_QUESTION, alsoInLines, apiUrl, blockedCapabilities, buildDecisionSpace, buildDiagnosisDocument, buildExplanationDocument, buildSupportBundle, checkTenantMode, chooseWidgetAuth, clampTimeout, contractUnavailableOutcome, countsAsNotOn, createApiClient, createContractProvider, createMemoryFileSystem, createRecordingClock, describeFailure, detectProject, detectTheme, detectThemeFromText, diagnoseFailure, diagnoseVerdict, diagnosis_v1_schema_default, digestOfProjection, digestsEqual, editDistance, entryFromRow, ephemeralCredential, errorCodeOf, errorOutcome, error_explanation_v1_schema_default, expandCapabilities, fail, failedResult, failureDetails, fetchContract, fetchTransport, hmacSha256, hmacSha256Hex, importPath, isCorrelatableRequestId, isEverfurLoaderHost, isIdempotent, isJsonObject, isKnownReasonCode, isWorkspaceRootEvidence, knownCodes, loadDecisionSpace, loadDecisionSpaceFromContract, loadErrorRegistry, loadErrorRegistryFromContract, missingFactsFor, nextActionFor, nextActionFor2, nodeContractCache, nodeFileSystem, normalizeSurfaces, offlineDocument, parseDiagnostics, parseEnvironment, parseIdentityMode, parseLoaderUrl, parseOrigin, parseSurfaces, planIntegration, plan_v1_schema_default, plannableCapabilities, refusal, registryAlsoIn, renderExplanation, renderOffline, renderSupportBundle, resolveAfterRegistryMiss, resolveContractPath, resolveCredential, resolveEndpoint, resolveOffline, resolveWithoutRegistry, runVerification, secretKeyHostProblem, succeed, suggestCodes, systemClock, themePropFromSource, toolCodeExplanation, toolCodeMeaning, uuidFromKey, validateContractFile, validateContractPublicEnvelope, validateContractText, validateDiagnosisDocument, validateErrorExplanationDocument, validatePlanDocument, validateSandboxCreateDocument, validateVerificationDocument, verification_v1_schema_default, verifyDigest, walkSingle, walkTree, webhookRouteFile, withPrefix };