@everfur/sdk 0.3.0 → 0.4.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.
Files changed (165) hide show
  1. package/CHANGELOG.md +69 -4
  2. package/README.md +6 -1
  3. package/dist/{Chat-DwAC2vhB.d.ts → Chat-BZZ-Py5l.d.ts} +3 -3
  4. package/dist/{Chat-DPUD6dnc.d.cts → Chat-Dq4fffIO.d.cts} +3 -3
  5. package/dist/{DepthViews-DNEM96Se.d.ts → DepthViews-BG3E25MD.d.ts} +1 -1
  6. package/dist/{DepthViews-DP0R-DhB.d.cts → DepthViews-B_hIypI6.d.cts} +1 -1
  7. package/dist/{DepthViews-DbFhR4Du.d.cts → DepthViews-CL75jyRA.d.cts} +1 -1
  8. package/dist/{DepthViews-D_3hl4xk.d.ts → DepthViews-CkYri51q.d.ts} +1 -1
  9. package/dist/animations/index.cjs +1 -1
  10. package/dist/animations/index.d.cts +3 -3
  11. package/dist/animations/index.d.ts +3 -3
  12. package/dist/animations/index.js +1 -1
  13. package/dist/{attachments-CQgFrEQ7.d.cts → attachments-BorG422I.d.cts} +2 -2
  14. package/dist/{attachments-5NeobOCd.d.ts → attachments-BrUWQYNK.d.ts} +5 -4
  15. package/dist/{attachments-D8T5re7e.d.cts → attachments-D_SECjr1.d.cts} +5 -4
  16. package/dist/{attachments-Bw3iMQgu.d.ts → attachments-DpldrvIW.d.ts} +2 -2
  17. package/dist/bookingCopy-CqtDYvCR.d.ts +732 -0
  18. package/dist/bookingCopy-SREvkG19.d.cts +732 -0
  19. package/dist/{entitlementRepository-DSbzuyAW.d.ts → branding-CsRdeNwK.d.cts} +1 -133
  20. package/dist/{entitlementRepository-DKdXFgTo.d.cts → branding-CsRdeNwK.d.ts} +1 -133
  21. package/dist/callCopy-DoQKG3-L.d.cts +40 -0
  22. package/dist/callCopy-DoQKG3-L.d.ts +40 -0
  23. package/dist/casesRepository-DwtZVsbj.d.cts +51 -0
  24. package/dist/casesRepository-v6QczS9N.d.ts +51 -0
  25. package/dist/chat/index.cjs +1 -1
  26. package/dist/chat/index.d.cts +9 -8
  27. package/dist/chat/index.d.ts +9 -8
  28. package/dist/chat/index.js +1 -1
  29. package/dist/client/index.cjs +5 -5
  30. package/dist/client/index.d.cts +10 -8
  31. package/dist/client/index.d.ts +10 -8
  32. package/dist/client/index.js +5 -5
  33. package/dist/{config-CzTZGlfF.d.cts → config--Wu1Umhd.d.cts} +2 -2
  34. package/dist/{config-DW60uRb9.d.ts → config-C7eb_IMD.d.ts} +2 -2
  35. package/dist/consent/index.cjs +1 -1
  36. package/dist/consent/index.d.cts +5 -5
  37. package/dist/consent/index.d.ts +5 -5
  38. package/dist/consent/index.js +1 -1
  39. package/dist/{context-XvTzq1tE.d.cts → context-CL3lyuy1.d.cts} +6 -6
  40. package/dist/{context-DXhqHlPU.d.ts → context-CahAEha8.d.ts} +6 -6
  41. package/dist/{copy-Mjoo91aS.d.ts → copy-DdVFDL01.d.ts} +2 -2
  42. package/dist/{copy-bKDNigLb.d.cts → copy-UeUJVk8X.d.cts} +2 -2
  43. package/dist/core/index.cjs +7 -7
  44. package/dist/core/index.d.cts +118 -29
  45. package/dist/core/index.d.ts +118 -29
  46. package/dist/core/index.js +7 -7
  47. package/dist/{depth-CErXCU8J.d.cts → depth-D5HwcvKC.d.cts} +34 -3
  48. package/dist/{depth-DjDcJ6kH.d.ts → depth-DvPwPuT_.d.ts} +34 -3
  49. package/dist/entitlementRepository-B7egEdW6.d.ts +43 -0
  50. package/dist/entitlementRepository-BpJ7tiwl.d.cts +43 -0
  51. package/dist/{identity-DI4eVx9S.d.cts → identity-C2-08BZW.d.cts} +2 -2
  52. package/dist/{identity-BMx2SUOM.d.ts → identity-CEi9GRFZ.d.ts} +2 -2
  53. package/dist/index.cjs +6 -6
  54. package/dist/index.d.cts +17 -16
  55. package/dist/index.d.ts +17 -16
  56. package/dist/index.js +6 -6
  57. package/dist/notifications/index.cjs +2 -2
  58. package/dist/notifications/index.d.cts +2 -2
  59. package/dist/notifications/index.d.ts +2 -2
  60. package/dist/notifications/index.js +2 -2
  61. package/dist/optionalModule-DbJmsq5f.d.cts +21 -0
  62. package/dist/optionalModule-DbJmsq5f.d.ts +21 -0
  63. package/dist/{pets-CtQdRpWo.d.ts → pets-DJv2sj2H.d.ts} +1 -1
  64. package/dist/{pets-aB8q0JyX.d.cts → pets-JVCXgRgR.d.cts} +1 -1
  65. package/dist/{casesRepository-DHwtGRYY.d.cts → petsRepository-B_gKbAzJ.d.cts} +2 -48
  66. package/dist/{casesRepository-ClLv6qMl.d.ts → petsRepository-Bk6GDwLs.d.ts} +2 -48
  67. package/dist/photo/index.cjs +1 -1
  68. package/dist/photo/index.js +1 -1
  69. package/dist/{ports-DEBzEhbp.d.cts → ports-BY2ph0_y.d.cts} +5 -15
  70. package/dist/{ports-DMolTRzU.d.ts → ports-D7YW8qz9.d.ts} +5 -15
  71. package/dist/records/depth/index.cjs +2 -2
  72. package/dist/records/depth/index.d.cts +7 -7
  73. package/dist/records/depth/index.d.ts +7 -7
  74. package/dist/records/depth/index.js +2 -2
  75. package/dist/records/index.cjs +3 -3
  76. package/dist/records/index.d.cts +9 -9
  77. package/dist/records/index.d.ts +9 -9
  78. package/dist/records/index.js +3 -3
  79. package/dist/{requestFunnel-L-BQfi0z.d.cts → requestFunnel-BjDpqqvm.d.cts} +25 -2
  80. package/dist/{requestFunnel-CjW7uDuA.d.ts → requestFunnel-DFMGcluw.d.ts} +25 -2
  81. package/dist/{runtime-B8s-_hv8.d.cts → runtimeTypes-gZEJu-da.d.cts} +9 -99
  82. package/dist/{runtime-BR9ysG0J.d.ts → runtimeTypes-w5KqBMcs.d.ts} +9 -99
  83. package/dist/server/events/index.cjs +1 -1
  84. package/dist/server/events/index.d.cts +2 -2
  85. package/dist/server/events/index.d.ts +2 -2
  86. package/dist/server/events/index.js +1 -1
  87. package/dist/server/index.cjs +1 -1
  88. package/dist/server/index.d.cts +3 -3
  89. package/dist/server/index.d.ts +3 -3
  90. package/dist/server/index.js +1 -1
  91. package/dist/televet/booking/index.cjs +1 -0
  92. package/dist/televet/booking/index.d.cts +294 -0
  93. package/dist/televet/booking/index.d.ts +294 -0
  94. package/dist/televet/booking/index.js +1 -0
  95. package/dist/televet/call/index.cjs +1 -0
  96. package/dist/televet/call/index.d.cts +141 -0
  97. package/dist/televet/call/index.d.ts +141 -0
  98. package/dist/televet/call/index.js +1 -0
  99. package/dist/televet/index.cjs +1 -1
  100. package/dist/televet/index.d.cts +87 -5
  101. package/dist/televet/index.d.ts +87 -5
  102. package/dist/televet/index.js +1 -1
  103. package/dist/testing/index.cjs +3 -3
  104. package/dist/testing/index.d.cts +2 -2
  105. package/dist/testing/index.d.ts +2 -2
  106. package/dist/testing/index.js +3 -3
  107. package/dist/testing/rn/index.cjs +1 -1
  108. package/dist/testing/rn/index.d.cts +9 -8
  109. package/dist/testing/rn/index.d.ts +9 -8
  110. package/dist/testing/rn/index.js +1 -1
  111. package/dist/testing/web/index.cjs +1 -1
  112. package/dist/testing/web/index.d.cts +9 -8
  113. package/dist/testing/web/index.d.ts +9 -8
  114. package/dist/testing/web/index.js +1 -1
  115. package/dist/{timelineRows-DZed6dAM.d.ts → timelineRows-C15jxFFH.d.ts} +1 -1
  116. package/dist/{timelineRows-CaohZzXS.d.cts → timelineRows-odO8g9r2.d.cts} +1 -1
  117. package/dist/typeStyle-CKqVYD6L.d.cts +111 -0
  118. package/dist/typeStyle-DmoyacDG.d.ts +111 -0
  119. package/dist/{useRecordsDepth-BHBzJ76R.d.cts → useRecordsDepth-C6rjEaLn.d.cts} +1 -1
  120. package/dist/{useRecordsDepth-BU-OhzH6.d.ts → useRecordsDepth-crhBllQK.d.ts} +1 -1
  121. package/dist/video/index.cjs +1 -1
  122. package/dist/video/index.js +1 -1
  123. package/dist/{view-DtSPYpKa.d.ts → view-Bxwxp4xD.d.ts} +2 -2
  124. package/dist/{view-C3qPIXGX.d.cts → view-DyitEO0m.d.cts} +2 -2
  125. package/dist/web/consent/index.cjs +1 -1
  126. package/dist/web/consent/index.d.cts +5 -5
  127. package/dist/web/consent/index.d.ts +5 -5
  128. package/dist/web/consent/index.js +1 -1
  129. package/dist/web/index.cjs +7 -7
  130. package/dist/web/index.d.cts +18 -17
  131. package/dist/web/index.d.ts +18 -17
  132. package/dist/web/index.js +7 -7
  133. package/dist/web/notifications/index.cjs +2 -2
  134. package/dist/web/notifications/index.d.cts +3 -3
  135. package/dist/web/notifications/index.d.ts +3 -3
  136. package/dist/web/notifications/index.js +2 -2
  137. package/dist/web/records/depth/index.cjs +2 -2
  138. package/dist/web/records/depth/index.d.cts +7 -7
  139. package/dist/web/records/depth/index.d.ts +7 -7
  140. package/dist/web/records/depth/index.js +2 -2
  141. package/dist/web/records/index.cjs +3 -3
  142. package/dist/web/records/index.d.cts +102 -11
  143. package/dist/web/records/index.d.ts +102 -11
  144. package/dist/web/records/index.js +3 -3
  145. package/dist/web/televet/booking/index.cjs +1 -0
  146. package/dist/web/televet/booking/index.d.cts +349 -0
  147. package/dist/web/televet/booking/index.d.ts +349 -0
  148. package/dist/web/televet/booking/index.js +1 -0
  149. package/dist/web/televet/call/index.cjs +1 -0
  150. package/dist/web/televet/call/index.d.cts +142 -0
  151. package/dist/web/televet/call/index.d.ts +142 -0
  152. package/dist/web/televet/call/index.js +1 -0
  153. package/dist/web/televet/index.cjs +1 -1
  154. package/dist/web/televet/index.d.cts +90 -4
  155. package/dist/web/televet/index.d.ts +90 -4
  156. package/dist/web/televet/index.js +1 -1
  157. package/package.json +72 -4
  158. package/televet/booking/package.json +8 -0
  159. package/televet/call/package.json +8 -0
  160. package/web/televet/booking/native-blocked.cjs +12 -0
  161. package/web/televet/booking/package.json +8 -0
  162. package/web/televet/call/native-blocked.cjs +12 -0
  163. package/web/televet/call/package.json +8 -0
  164. package/dist/typeStyle-0TydiZ1w.d.cts +0 -19
  165. package/dist/typeStyle-CWMsoe6b.d.ts +0 -19
@@ -1,8 +1,3 @@
1
- import { E as EverfurError } from './EverfurResult-DN9pL2Ab.js';
2
- import { R as RequestFunnel } from './requestFunnel-CjW7uDuA.js';
3
- import { A as AuthContext } from './identity-BMx2SUOM.js';
4
- import { E as EntitlementDecision } from './resolve-D4Ywz5OS.js';
5
-
6
1
  /** The fixed set of slot names, in the order the surfaces list them. */
7
2
  declare const THEME_SLOT_NAMES: readonly ["composerInput", "sendButton", "userBubble", "assistantBubble", "recordCard", "vetVisitButton", "primaryButton", "link"];
8
3
  type EverfurThemeSlotName = (typeof THEME_SLOT_NAMES)[number];
@@ -567,132 +562,5 @@ declare const MAX_FONT_SCALE_CEILING = 3.1;
567
562
  * constructor so it is portable + total on React Native (whose URL global is incomplete) and never throws.
568
563
  */
569
564
  declare function hardenHttpsUrl(url: string | null): string | null;
570
- /**
571
- * Overlay `b` onto `base`, field by field: a non-null branding field WINS; a null field KEEPS the base. A
572
- * valid brightness re-selects the matching compiled palette (light/dark); an invalid/absent brightness leaves
573
- * the base palette untouched. Slots merge per slot, per key. Returns a NEW deeply-frozen theme; `base` and `b`
574
- * are never mutated.
575
- *
576
- * The name is historical (the server was once the only overlay); `resolveTheme` applies it twice, server then
577
- * client, which is how the client wins per field. NOTE: foreground legibility (onPrimary/onAccent, the slot
578
- * guard) and URL hardening are applied by `resolveTheme`, the total entry point. Call this directly only when
579
- * you will finalize the result yourself.
580
- */
581
- declare function withServerBranding(base: EverfurTheme, b: ClientBranding | null): EverfurTheme;
582
- /**
583
- * Inputs to the total theme resolve. All optional; `resolveTheme(undefined)` yields the compiled Everfur
584
- * default. Merge order: compiled default <- server branding (render_hints) <- client theme prop, per field, with
585
- * the tenant's locked fields and the attribution kept from the server (see `resolveTheme`).
586
- */
587
- interface ResolveThemeInput {
588
- /** Server-driven branding from the live entitlements render_hints (the tenant's console branding). */
589
- readonly branding?: ClientBranding | null;
590
- /**
591
- * The clamped client `theme` prop. It WINS per cosmetic field over the server branding, except the fields the
592
- * server lists in `locked_fields`. Its hidePoweredBy is IGNORED: whether the Everfur attribution shows is
593
- * decided by server branding alone.
594
- */
595
- readonly clientOverride?: ClientBranding | null;
596
- /**
597
- * The device color scheme (useColorScheme / `prefers-color-scheme`). Read ONLY when the settled brightness is
598
- * `auto` (an explicit opt-in); with no brightness set anywhere the theme is light, as Everfur's own apps are.
599
- */
600
- readonly colorScheme?: 'light' | 'dark' | null;
601
- /** AccessibilityInfo reduced-motion / `prefers-reduced-motion`: collapses the motion tokens. */
602
- readonly reducedMotion?: boolean;
603
- /**
604
- * The user's text scale as the host reads it (React Native: `PixelRatio.getFontScale()`; the browser: the
605
- * browser's default font size over 16px). Floored at `TEXT_SCALE_FLOOR`; absent or junk reads as 1. Flowing
606
- * content follows it uncapped; each chrome tier follows it up to that tier's cap (`type.scaleCaps`).
607
- */
608
- readonly textScale?: number;
609
- /**
610
- * Multiply the type sizes by the effective scale, per tier (`type.size` for content, `type.tierSizes` for every
611
- * tier). A browser host passes true (CSS px do not follow the user's setting on their own); a React Native host
612
- * leaves it false and lets the platform scale every Text natively, capped per tier by `maxFontSizeMultiplier`.
613
- */
614
- readonly scaleTypeSizes?: boolean;
615
- /** The user asked for more contrast (`prefers-contrast: more`): the palette is derived by `deriveHighContrast`. */
616
- readonly highContrast?: boolean;
617
- /**
618
- * The family the platform's generic mono keyword (`SYSTEM_MONO_FAMILY`) maps to on this host. React Native on iOS
619
- * has no family named `monospace` (a Text asking for it renders proportional, and the legacy architecture
620
- * red-boxes in development), so the React Native host passes `Menlo` there. Applied to the compiled default mono
621
- * only: a partner's own mono face is never touched. Absent or blank, the keyword stands (the web maps it to its
622
- * mono stack in CSS).
623
- */
624
- readonly platformMonoFamily?: string;
625
- /**
626
- * Whether a family name is registered with the platform, when the host can tell: true or false, else null. A
627
- * NAMED face (one per-weight name, rendered without a weight) that the host reports unregistered falls back to
628
- * the platform font of its group WITH its numeric weight, so medium and bold survive instead of every weight
629
- * collapsing to the platform's regular. Only named faces are asked about; a throw reads as null.
630
- */
631
- readonly isFontRegistered?: (family: string) => boolean | null;
632
- }
633
- /** The smallest effective text scale the resolver will report (a device may ask for less; the surfaces stop here). */
634
- declare const TEXT_SCALE_FLOOR = 0.5;
635
- /**
636
- * Resolve the final, legible, deeply-frozen theme. Never throws, never returns null/transparent.
637
- *
638
- * PRECEDENCE (per field, owner decision of 18 September 2026; the same rule EFBackend render_hint_fold states):
639
- * a field in `locked_fields` (plus `hide_powered_by` always) is server-wins; every other cosmetic field is
640
- * client-wins.
641
- * - A server branding with an unknown `schema_version` is dropped whole (default plus client theme).
642
- * - `hide_powered_by`, and every name the server lists in `locked_fields`, are SERVER-WINS: the client's value
643
- * for such a field is discarded before the merge, so the server's value or the compiled default stands.
644
- * `slots` in the list locks every slot; `slots.<name>` locks one.
645
- * - Every other cosmetic field is CLIENT-WINS: the client `theme` prop overrides the console value, and the
646
- * console fills the fields the prop leaves unset. Brightness is settled the same way; set nowhere, it is
647
- * LIGHT (owner decision OD28: Everfur's own apps are light-only), and `auto` follows the device scheme.
648
- * - Slots overlay slot by slot (a named slot replaces the one below it whole) in the same order, after the
649
- * field precedence.
650
- * Then the total-resolve guarantees: onPrimary/onAccent via WCAG, the slot contrast guard, https-only logo/font
651
- * URLs, a non-empty displayName, the text scale (floored; tiered caps on the chrome), motion collapsed under reduced
652
- * motion, and the high-contrast derivation when the user asked for it.
653
- */
654
- declare function resolveTheme(input?: ResolveThemeInput): EverfurTheme;
655
- /**
656
- * The console's preview helper: resolve a draft branding exactly as the device would, from the raw shapes (the
657
- * partner's `theme` prop and the server-shaped branding object the console is about to publish), with the device
658
- * inputs of the preview. Pure and total: any shape is tolerated, nothing throws.
659
- */
660
- declare function previewTheme(input: EverfurThemeInput | null, hints: unknown, options?: Omit<ResolveThemeInput, 'branding' | 'clientOverride'>): EverfurTheme;
661
-
662
- /** The conditional-GET endpoint (SPEC-00 §5.3). Relative; the transport prefixes the resolved base URL. */
663
- declare const ENTITLEMENTS_PATH = "/widget/v1/entitlements";
664
- /**
665
- * The settled outcome of one entitlement fetch. `updated` carries a fresh verdict + the cadence to re-poll on;
666
- * `notModified` means the cached verdict still holds; `failed` carries a normalized error and means keep-last.
667
- */
668
- type EntitlementResolution = {
669
- readonly kind: 'updated';
670
- readonly revision: number;
671
- readonly region: string;
672
- readonly ttlSeconds: number;
673
- readonly decisions: readonly EntitlementDecision[];
674
- /**
675
- * Server-driven branding parsed from the SAME 200 body's render_hints (orthogonal to capabilities).
676
- * null when absent or unparseable (fail-closed -> the compiled Everfur default theme). OPTIONAL so a
677
- * hand-built resolution (tests / injected resolve) need not supply it.
678
- */
679
- readonly branding?: ClientBranding | null;
680
- } | {
681
- readonly kind: 'notModified';
682
- } | {
683
- readonly kind: 'failed';
684
- readonly error: EverfurError;
685
- };
686
- interface FetchEntitlementsArgs {
687
- /** The revision we last stored; echoed as If-None-Match so an unchanged verdict returns 304. */
688
- readonly cachedRevision?: number | null;
689
- /** Optional region hint; forwarded as ?region. */
690
- readonly region?: string;
691
- }
692
- /**
693
- * Fetch the server-resolved entitlement verdict once. Never throws: a 304, a domain error, a network reject,
694
- * and a malformed body all SETTLE to an EntitlementResolution. Fail-closed on every non-`updated` path.
695
- */
696
- declare function fetchEntitlements(auth: AuthContext, args?: FetchEntitlementsArgs, funnel?: RequestFunnel): Promise<EntitlementResolution>;
697
565
 
698
- export { TEXT_SCALE_FLOOR as $, THEME_SLOT_NAMES as A, previewTheme as B, type ClientBranding as C, DEFAULT_MAX_FONT_SCALE as D, type EverfurFontWeight as E, EASING_CURVES as F, ENTITLEMENTS_PATH as G, EVERFUR_DARK as H, EVERFUR_LIGHT as I, type EntitlementResolution as J, type EverfurEasingCurve as K, type EverfurTextScaleTier as L, type FetchEntitlementsArgs as M, LOCKABLE_THEME_FIELDS as N, type LockableThemeField as O, MAX_FONT_SCALE_CEILING as P, type ResolveThemeInput as Q, type RadiusScale as R, type SurfaceStyle as S, THEME_SLOT_KEYS as T, SLOT_LOCK_PREFIX as U, SLOT_MIN_BORDER_CONTRAST as V, SLOT_MIN_CONTRAST as W, SYSTEM_FONT_FAMILY as X, SYSTEM_MONO_FAMILY as Y, type SlotGrounds as Z, type SlotLockName as _, type EverfurTheme as a, TEXT_SCALE_TIER_CAPS as a0, THEME_SCHEMA_VERSIONS as a1, type ThemeLockName as a2, cssCubicBezier as a3, deepFreeze as a4, fetchEntitlements as a5, guardSlotContrast as a6, hardenHttpsUrl as a7, isEmptyBranding as a8, isKnownBrandingSchema as a9, lockedFieldsOf as aa, mergeThemeSlots as ab, parseClientBranding as ac, parseThemeSlots as ad, resolveTheme as ae, withServerBranding as af, type EverfurFontFaceKey as b, type EverfurThemeInput as c, type EverfurColorTokens as d, type EverfurFontFamilies as e, type EverfurLetterSpacingTokens as f, type EverfurLineHeightTokens as g, type EverfurMotionDurationTokens as h, type EverfurMotionTokens as i, type EverfurRadiusTokens as j, type EverfurSpaceTokens as k, type EverfurSpringToken as l, type EverfurTextColorTokens as m, type EverfurThemeFontFaceKey as n, type EverfurThemeFontUrlsInput as o, type EverfurThemeFontsInput as p, type EverfurThemeMeta as q, type EverfurThemeSlot as r, type EverfurThemeSlotInput as s, type EverfurThemeSlotKey as t, type EverfurThemeSlotName as u, type EverfurThemeSlots as v, type EverfurThemeSlotsInput as w, type EverfurTypeSizeTokens as x, type EverfurTypeTokens as y, type EverfurWeightTokens as z };
566
+ export { guardSlotContrast as $, THEME_SLOT_NAMES as A, EASING_CURVES as B, type ClientBranding as C, DEFAULT_MAX_FONT_SCALE as D, type EverfurThemeInput as E, EVERFUR_DARK as F, EVERFUR_LIGHT as G, type EverfurEasingCurve as H, type EverfurTextScaleTier as I, type LockableThemeField as J, SLOT_LOCK_PREFIX as K, LOCKABLE_THEME_FIELDS as L, MAX_FONT_SCALE_CEILING as M, SLOT_MIN_BORDER_CONTRAST as N, SLOT_MIN_CONTRAST as O, SYSTEM_FONT_FAMILY as P, SYSTEM_MONO_FAMILY as Q, type RadiusScale as R, type SurfaceStyle as S, THEME_SLOT_KEYS as T, type SlotGrounds as U, type SlotLockName as V, TEXT_SCALE_TIER_CAPS as W, THEME_SCHEMA_VERSIONS as X, type ThemeLockName as Y, cssCubicBezier as Z, deepFreeze as _, type EverfurTheme as a, hardenHttpsUrl as a0, isEmptyBranding as a1, isKnownBrandingSchema as a2, lockedFieldsOf as a3, mergeThemeSlots as a4, parseClientBranding as a5, parseThemeSlots as a6, type EverfurFontWeight as b, type EverfurFontFaceKey as c, type EverfurColorTokens as d, type EverfurFontFamilies as e, type EverfurLetterSpacingTokens as f, type EverfurLineHeightTokens as g, type EverfurMotionDurationTokens as h, type EverfurMotionTokens as i, type EverfurRadiusTokens as j, type EverfurSpaceTokens as k, type EverfurSpringToken as l, type EverfurTextColorTokens as m, type EverfurThemeFontFaceKey as n, type EverfurThemeFontUrlsInput as o, type EverfurThemeFontsInput as p, type EverfurThemeMeta as q, type EverfurThemeSlot as r, type EverfurThemeSlotInput as s, type EverfurThemeSlotKey as t, type EverfurThemeSlotName as u, type EverfurThemeSlots as v, type EverfurThemeSlotsInput as w, type EverfurTypeSizeTokens as x, type EverfurTypeTokens as y, type EverfurWeightTokens as z };
@@ -1,8 +1,3 @@
1
- import { E as EverfurError } from './EverfurResult-DN9pL2Ab.cjs';
2
- import { R as RequestFunnel } from './requestFunnel-L-BQfi0z.cjs';
3
- import { A as AuthContext } from './identity-DI4eVx9S.cjs';
4
- import { E as EntitlementDecision } from './resolve-D4Ywz5OS.cjs';
5
-
6
1
  /** The fixed set of slot names, in the order the surfaces list them. */
7
2
  declare const THEME_SLOT_NAMES: readonly ["composerInput", "sendButton", "userBubble", "assistantBubble", "recordCard", "vetVisitButton", "primaryButton", "link"];
8
3
  type EverfurThemeSlotName = (typeof THEME_SLOT_NAMES)[number];
@@ -567,132 +562,5 @@ declare const MAX_FONT_SCALE_CEILING = 3.1;
567
562
  * constructor so it is portable + total on React Native (whose URL global is incomplete) and never throws.
568
563
  */
569
564
  declare function hardenHttpsUrl(url: string | null): string | null;
570
- /**
571
- * Overlay `b` onto `base`, field by field: a non-null branding field WINS; a null field KEEPS the base. A
572
- * valid brightness re-selects the matching compiled palette (light/dark); an invalid/absent brightness leaves
573
- * the base palette untouched. Slots merge per slot, per key. Returns a NEW deeply-frozen theme; `base` and `b`
574
- * are never mutated.
575
- *
576
- * The name is historical (the server was once the only overlay); `resolveTheme` applies it twice, server then
577
- * client, which is how the client wins per field. NOTE: foreground legibility (onPrimary/onAccent, the slot
578
- * guard) and URL hardening are applied by `resolveTheme`, the total entry point. Call this directly only when
579
- * you will finalize the result yourself.
580
- */
581
- declare function withServerBranding(base: EverfurTheme, b: ClientBranding | null): EverfurTheme;
582
- /**
583
- * Inputs to the total theme resolve. All optional; `resolveTheme(undefined)` yields the compiled Everfur
584
- * default. Merge order: compiled default <- server branding (render_hints) <- client theme prop, per field, with
585
- * the tenant's locked fields and the attribution kept from the server (see `resolveTheme`).
586
- */
587
- interface ResolveThemeInput {
588
- /** Server-driven branding from the live entitlements render_hints (the tenant's console branding). */
589
- readonly branding?: ClientBranding | null;
590
- /**
591
- * The clamped client `theme` prop. It WINS per cosmetic field over the server branding, except the fields the
592
- * server lists in `locked_fields`. Its hidePoweredBy is IGNORED: whether the Everfur attribution shows is
593
- * decided by server branding alone.
594
- */
595
- readonly clientOverride?: ClientBranding | null;
596
- /**
597
- * The device color scheme (useColorScheme / `prefers-color-scheme`). Read ONLY when the settled brightness is
598
- * `auto` (an explicit opt-in); with no brightness set anywhere the theme is light, as Everfur's own apps are.
599
- */
600
- readonly colorScheme?: 'light' | 'dark' | null;
601
- /** AccessibilityInfo reduced-motion / `prefers-reduced-motion`: collapses the motion tokens. */
602
- readonly reducedMotion?: boolean;
603
- /**
604
- * The user's text scale as the host reads it (React Native: `PixelRatio.getFontScale()`; the browser: the
605
- * browser's default font size over 16px). Floored at `TEXT_SCALE_FLOOR`; absent or junk reads as 1. Flowing
606
- * content follows it uncapped; each chrome tier follows it up to that tier's cap (`type.scaleCaps`).
607
- */
608
- readonly textScale?: number;
609
- /**
610
- * Multiply the type sizes by the effective scale, per tier (`type.size` for content, `type.tierSizes` for every
611
- * tier). A browser host passes true (CSS px do not follow the user's setting on their own); a React Native host
612
- * leaves it false and lets the platform scale every Text natively, capped per tier by `maxFontSizeMultiplier`.
613
- */
614
- readonly scaleTypeSizes?: boolean;
615
- /** The user asked for more contrast (`prefers-contrast: more`): the palette is derived by `deriveHighContrast`. */
616
- readonly highContrast?: boolean;
617
- /**
618
- * The family the platform's generic mono keyword (`SYSTEM_MONO_FAMILY`) maps to on this host. React Native on iOS
619
- * has no family named `monospace` (a Text asking for it renders proportional, and the legacy architecture
620
- * red-boxes in development), so the React Native host passes `Menlo` there. Applied to the compiled default mono
621
- * only: a partner's own mono face is never touched. Absent or blank, the keyword stands (the web maps it to its
622
- * mono stack in CSS).
623
- */
624
- readonly platformMonoFamily?: string;
625
- /**
626
- * Whether a family name is registered with the platform, when the host can tell: true or false, else null. A
627
- * NAMED face (one per-weight name, rendered without a weight) that the host reports unregistered falls back to
628
- * the platform font of its group WITH its numeric weight, so medium and bold survive instead of every weight
629
- * collapsing to the platform's regular. Only named faces are asked about; a throw reads as null.
630
- */
631
- readonly isFontRegistered?: (family: string) => boolean | null;
632
- }
633
- /** The smallest effective text scale the resolver will report (a device may ask for less; the surfaces stop here). */
634
- declare const TEXT_SCALE_FLOOR = 0.5;
635
- /**
636
- * Resolve the final, legible, deeply-frozen theme. Never throws, never returns null/transparent.
637
- *
638
- * PRECEDENCE (per field, owner decision of 18 September 2026; the same rule EFBackend render_hint_fold states):
639
- * a field in `locked_fields` (plus `hide_powered_by` always) is server-wins; every other cosmetic field is
640
- * client-wins.
641
- * - A server branding with an unknown `schema_version` is dropped whole (default plus client theme).
642
- * - `hide_powered_by`, and every name the server lists in `locked_fields`, are SERVER-WINS: the client's value
643
- * for such a field is discarded before the merge, so the server's value or the compiled default stands.
644
- * `slots` in the list locks every slot; `slots.<name>` locks one.
645
- * - Every other cosmetic field is CLIENT-WINS: the client `theme` prop overrides the console value, and the
646
- * console fills the fields the prop leaves unset. Brightness is settled the same way; set nowhere, it is
647
- * LIGHT (owner decision OD28: Everfur's own apps are light-only), and `auto` follows the device scheme.
648
- * - Slots overlay slot by slot (a named slot replaces the one below it whole) in the same order, after the
649
- * field precedence.
650
- * Then the total-resolve guarantees: onPrimary/onAccent via WCAG, the slot contrast guard, https-only logo/font
651
- * URLs, a non-empty displayName, the text scale (floored; tiered caps on the chrome), motion collapsed under reduced
652
- * motion, and the high-contrast derivation when the user asked for it.
653
- */
654
- declare function resolveTheme(input?: ResolveThemeInput): EverfurTheme;
655
- /**
656
- * The console's preview helper: resolve a draft branding exactly as the device would, from the raw shapes (the
657
- * partner's `theme` prop and the server-shaped branding object the console is about to publish), with the device
658
- * inputs of the preview. Pure and total: any shape is tolerated, nothing throws.
659
- */
660
- declare function previewTheme(input: EverfurThemeInput | null, hints: unknown, options?: Omit<ResolveThemeInput, 'branding' | 'clientOverride'>): EverfurTheme;
661
-
662
- /** The conditional-GET endpoint (SPEC-00 §5.3). Relative; the transport prefixes the resolved base URL. */
663
- declare const ENTITLEMENTS_PATH = "/widget/v1/entitlements";
664
- /**
665
- * The settled outcome of one entitlement fetch. `updated` carries a fresh verdict + the cadence to re-poll on;
666
- * `notModified` means the cached verdict still holds; `failed` carries a normalized error and means keep-last.
667
- */
668
- type EntitlementResolution = {
669
- readonly kind: 'updated';
670
- readonly revision: number;
671
- readonly region: string;
672
- readonly ttlSeconds: number;
673
- readonly decisions: readonly EntitlementDecision[];
674
- /**
675
- * Server-driven branding parsed from the SAME 200 body's render_hints (orthogonal to capabilities).
676
- * null when absent or unparseable (fail-closed -> the compiled Everfur default theme). OPTIONAL so a
677
- * hand-built resolution (tests / injected resolve) need not supply it.
678
- */
679
- readonly branding?: ClientBranding | null;
680
- } | {
681
- readonly kind: 'notModified';
682
- } | {
683
- readonly kind: 'failed';
684
- readonly error: EverfurError;
685
- };
686
- interface FetchEntitlementsArgs {
687
- /** The revision we last stored; echoed as If-None-Match so an unchanged verdict returns 304. */
688
- readonly cachedRevision?: number | null;
689
- /** Optional region hint; forwarded as ?region. */
690
- readonly region?: string;
691
- }
692
- /**
693
- * Fetch the server-resolved entitlement verdict once. Never throws: a 304, a domain error, a network reject,
694
- * and a malformed body all SETTLE to an EntitlementResolution. Fail-closed on every non-`updated` path.
695
- */
696
- declare function fetchEntitlements(auth: AuthContext, args?: FetchEntitlementsArgs, funnel?: RequestFunnel): Promise<EntitlementResolution>;
697
565
 
698
- export { TEXT_SCALE_FLOOR as $, THEME_SLOT_NAMES as A, previewTheme as B, type ClientBranding as C, DEFAULT_MAX_FONT_SCALE as D, type EverfurFontWeight as E, EASING_CURVES as F, ENTITLEMENTS_PATH as G, EVERFUR_DARK as H, EVERFUR_LIGHT as I, type EntitlementResolution as J, type EverfurEasingCurve as K, type EverfurTextScaleTier as L, type FetchEntitlementsArgs as M, LOCKABLE_THEME_FIELDS as N, type LockableThemeField as O, MAX_FONT_SCALE_CEILING as P, type ResolveThemeInput as Q, type RadiusScale as R, type SurfaceStyle as S, THEME_SLOT_KEYS as T, SLOT_LOCK_PREFIX as U, SLOT_MIN_BORDER_CONTRAST as V, SLOT_MIN_CONTRAST as W, SYSTEM_FONT_FAMILY as X, SYSTEM_MONO_FAMILY as Y, type SlotGrounds as Z, type SlotLockName as _, type EverfurTheme as a, TEXT_SCALE_TIER_CAPS as a0, THEME_SCHEMA_VERSIONS as a1, type ThemeLockName as a2, cssCubicBezier as a3, deepFreeze as a4, fetchEntitlements as a5, guardSlotContrast as a6, hardenHttpsUrl as a7, isEmptyBranding as a8, isKnownBrandingSchema as a9, lockedFieldsOf as aa, mergeThemeSlots as ab, parseClientBranding as ac, parseThemeSlots as ad, resolveTheme as ae, withServerBranding as af, type EverfurFontFaceKey as b, type EverfurThemeInput as c, type EverfurColorTokens as d, type EverfurFontFamilies as e, type EverfurLetterSpacingTokens as f, type EverfurLineHeightTokens as g, type EverfurMotionDurationTokens as h, type EverfurMotionTokens as i, type EverfurRadiusTokens as j, type EverfurSpaceTokens as k, type EverfurSpringToken as l, type EverfurTextColorTokens as m, type EverfurThemeFontFaceKey as n, type EverfurThemeFontUrlsInput as o, type EverfurThemeFontsInput as p, type EverfurThemeMeta as q, type EverfurThemeSlot as r, type EverfurThemeSlotInput as s, type EverfurThemeSlotKey as t, type EverfurThemeSlotName as u, type EverfurThemeSlots as v, type EverfurThemeSlotsInput as w, type EverfurTypeSizeTokens as x, type EverfurTypeTokens as y, type EverfurWeightTokens as z };
566
+ export { guardSlotContrast as $, THEME_SLOT_NAMES as A, EASING_CURVES as B, type ClientBranding as C, DEFAULT_MAX_FONT_SCALE as D, type EverfurThemeInput as E, EVERFUR_DARK as F, EVERFUR_LIGHT as G, type EverfurEasingCurve as H, type EverfurTextScaleTier as I, type LockableThemeField as J, SLOT_LOCK_PREFIX as K, LOCKABLE_THEME_FIELDS as L, MAX_FONT_SCALE_CEILING as M, SLOT_MIN_BORDER_CONTRAST as N, SLOT_MIN_CONTRAST as O, SYSTEM_FONT_FAMILY as P, SYSTEM_MONO_FAMILY as Q, type RadiusScale as R, type SurfaceStyle as S, THEME_SLOT_KEYS as T, type SlotGrounds as U, type SlotLockName as V, TEXT_SCALE_TIER_CAPS as W, THEME_SCHEMA_VERSIONS as X, type ThemeLockName as Y, cssCubicBezier as Z, deepFreeze as _, type EverfurTheme as a, hardenHttpsUrl as a0, isEmptyBranding as a1, isKnownBrandingSchema as a2, lockedFieldsOf as a3, mergeThemeSlots as a4, parseClientBranding as a5, parseThemeSlots as a6, type EverfurFontWeight as b, type EverfurFontFaceKey as c, type EverfurColorTokens as d, type EverfurFontFamilies as e, type EverfurLetterSpacingTokens as f, type EverfurLineHeightTokens as g, type EverfurMotionDurationTokens as h, type EverfurMotionTokens as i, type EverfurRadiusTokens as j, type EverfurSpaceTokens as k, type EverfurSpringToken as l, type EverfurTextColorTokens as m, type EverfurThemeFontFaceKey as n, type EverfurThemeFontUrlsInput as o, type EverfurThemeFontsInput as p, type EverfurThemeMeta as q, type EverfurThemeSlot as r, type EverfurThemeSlotInput as s, type EverfurThemeSlotKey as t, type EverfurThemeSlotName as u, type EverfurThemeSlots as v, type EverfurThemeSlotsInput as w, type EverfurTypeSizeTokens as x, type EverfurTypeTokens as y, type EverfurWeightTokens as z };
@@ -0,0 +1,40 @@
1
+ /** The phases the in-app call surface moves through. The consumer app's `CallPhase`, verbatim. */
2
+ type VetCallPhase = 'joining' | 'joined' | 'left' | 'error';
3
+ /**
4
+ * Refuses anything that is not an https room.
5
+ *
6
+ * NEVER THROWS and never echoes the input: an unparseable value returns false rather than raising, because
7
+ * the caller is already on a failure path when it asks.
8
+ */
9
+ declare function isSafeRoomUrl(url: string): boolean;
10
+ /**
11
+ * The whole credential floor: an https room AND a non-empty join token. The call surface renders nothing and
12
+ * creates no call object unless this is true.
13
+ */
14
+ declare function isUsableRoomCredential(roomUrl: string, token: string): boolean;
15
+
16
+ /** The consult length the lobby quotes, in minutes. everfur-mobile-2026-7 televetTime.ts:85 `CONSULT_MINUTES`. */
17
+ declare const VET_CALL_CONSULT_MINUTES = 10;
18
+ declare const VET_CALL_COPY: Readonly<{
19
+ /** Controls, shared by the lobby and the live call. */
20
+ muteCta: "Mute";
21
+ unmuteCta: "Unmute";
22
+ cameraOffCta: "Camera off";
23
+ cameraOnCta: "Camera on";
24
+ leaveCta: "Leave";
25
+ /** The lobby: the member is in the room and the clinician is not. */
26
+ lobbyTitleNoName: "Your vet is joining";
27
+ lobbySubtitle: "Usually under a minute";
28
+ lobbyPrepLabel: "WHILE YOU WAIT";
29
+ lobbyPrepNoPet: "Have your pet nearby and somewhere well lit.";
30
+ /** `{name}` is DATA from the consult, never a key. Absent, `lobbyTitleNoName` is used instead. */
31
+ lobbyTitle: (clinicianName: string | null | undefined) => string;
32
+ /** `{pet}` is DATA from the roster. Absent, the pet-free form is used instead. */
33
+ lobbyPrep: (petName: string | null | undefined) => string;
34
+ /** `{n}` is `VET_CALL_CONSULT_MINUTES`, never a hardcoded number. */
35
+ lobbyDuration: (minutes: number) => string;
36
+ /** The consumer app's `visit.joinFailedReason` (:735), shown when the call object errors. */
37
+ joinFailedReason: "That did not open. Try again.";
38
+ }>;
39
+
40
+ export { VET_CALL_CONSULT_MINUTES as V, VET_CALL_COPY as a, type VetCallPhase as b, isUsableRoomCredential as c, isSafeRoomUrl as i };
@@ -0,0 +1,40 @@
1
+ /** The phases the in-app call surface moves through. The consumer app's `CallPhase`, verbatim. */
2
+ type VetCallPhase = 'joining' | 'joined' | 'left' | 'error';
3
+ /**
4
+ * Refuses anything that is not an https room.
5
+ *
6
+ * NEVER THROWS and never echoes the input: an unparseable value returns false rather than raising, because
7
+ * the caller is already on a failure path when it asks.
8
+ */
9
+ declare function isSafeRoomUrl(url: string): boolean;
10
+ /**
11
+ * The whole credential floor: an https room AND a non-empty join token. The call surface renders nothing and
12
+ * creates no call object unless this is true.
13
+ */
14
+ declare function isUsableRoomCredential(roomUrl: string, token: string): boolean;
15
+
16
+ /** The consult length the lobby quotes, in minutes. everfur-mobile-2026-7 televetTime.ts:85 `CONSULT_MINUTES`. */
17
+ declare const VET_CALL_CONSULT_MINUTES = 10;
18
+ declare const VET_CALL_COPY: Readonly<{
19
+ /** Controls, shared by the lobby and the live call. */
20
+ muteCta: "Mute";
21
+ unmuteCta: "Unmute";
22
+ cameraOffCta: "Camera off";
23
+ cameraOnCta: "Camera on";
24
+ leaveCta: "Leave";
25
+ /** The lobby: the member is in the room and the clinician is not. */
26
+ lobbyTitleNoName: "Your vet is joining";
27
+ lobbySubtitle: "Usually under a minute";
28
+ lobbyPrepLabel: "WHILE YOU WAIT";
29
+ lobbyPrepNoPet: "Have your pet nearby and somewhere well lit.";
30
+ /** `{name}` is DATA from the consult, never a key. Absent, `lobbyTitleNoName` is used instead. */
31
+ lobbyTitle: (clinicianName: string | null | undefined) => string;
32
+ /** `{pet}` is DATA from the roster. Absent, the pet-free form is used instead. */
33
+ lobbyPrep: (petName: string | null | undefined) => string;
34
+ /** `{n}` is `VET_CALL_CONSULT_MINUTES`, never a hardcoded number. */
35
+ lobbyDuration: (minutes: number) => string;
36
+ /** The consumer app's `visit.joinFailedReason` (:735), shown when the call object errors. */
37
+ joinFailedReason: "That did not open. Try again.";
38
+ }>;
39
+
40
+ export { VET_CALL_CONSULT_MINUTES as V, VET_CALL_COPY as a, type VetCallPhase as b, isUsableRoomCredential as c, isSafeRoomUrl as i };
@@ -0,0 +1,51 @@
1
+ import { c as EverfurResult } from './EverfurResult-DN9pL2Ab.cjs';
2
+ import { A as AuthContext } from './identity-C2-08BZW.cjs';
3
+ import { P as PetRef } from './ids-B2GAAifq.cjs';
4
+
5
+ /** The owner's answer to a check-in, the wire values of the consumer `CheckinResponse` enum. */
6
+ type CheckinAnswer = 'better' | 'same' | 'worse';
7
+ /** The closed answer set, in the order the consumer surfaces offer it. */
8
+ declare const CHECKIN_ANSWERS: readonly CheckinAnswer[];
9
+ /**
10
+ * The member-safe view of one watch case (consumer `WatchCaseView`). Case STATE only: the concern itself
11
+ * never rides on this row. `status` is the server's vocabulary (`watching` while open, then `resolved`,
12
+ * `escalated` or `lapsed`), carried as a string so a status added later never breaks a frozen client.
13
+ */
14
+ interface WatchCase {
15
+ readonly caseId: string;
16
+ readonly status: string;
17
+ /** The body-region copy hint (`ears`, `eyes`, ..., `general`), never a diagnosis. */
18
+ readonly bodyLocation: string | null;
19
+ readonly lastResponse: CheckinAnswer | null;
20
+ readonly checkInDueAt: string | null;
21
+ readonly openedAt: string | null;
22
+ readonly resolvedAt: string | null;
23
+ /** The server's own non-diagnostic post-answer line, stamped only on a BETTER resolve. */
24
+ readonly resolutionText: string | null;
25
+ }
26
+ /** The result of recording a check-in. `ctaDeepLink` is set only on a WORSE escalation (an `everfur://` pointer). */
27
+ interface CheckinOutcome {
28
+ readonly case: WatchCase;
29
+ readonly ctaDeepLink: string | null;
30
+ }
31
+ interface CasesRepository {
32
+ /**
33
+ * `GET /widget/v1/pets/{pet_ref}/cases` - the pet's open (`watching`) cases. Settles `ok([])` when the pet
34
+ * has none, which the server makes indistinguishable from a non-member or the feature being off.
35
+ */
36
+ list(petRef: PetRef, opts?: {
37
+ signal?: AbortSignal;
38
+ }): Promise<EverfurResult<readonly WatchCase[]>>;
39
+ /**
40
+ * `POST /widget/v1/pets/{pet_ref}/cases/{case_id}/checkin` - record the owner's answer. Settles
41
+ * `ok(CheckinOutcome)` on 200; a case that is stale, closed, another member's or gated off is the ordinary
42
+ * not-found error. A malformed case id or an answer outside the closed set is refused before the wire.
43
+ */
44
+ checkin(petRef: PetRef, caseId: string, answer: CheckinAnswer, opts?: {
45
+ signal?: AbortSignal;
46
+ }): Promise<EverfurResult<CheckinOutcome>>;
47
+ }
48
+ /** Build the repository over a device AuthContext (personalized bearer XOR anonymous pk). */
49
+ declare function createCasesRepository(auth: AuthContext): CasesRepository;
50
+
51
+ export { type CheckinAnswer as C, type WatchCase as W, type CheckinOutcome as a, CHECKIN_ANSWERS as b, type CasesRepository as c, createCasesRepository as d };
@@ -0,0 +1,51 @@
1
+ import { c as EverfurResult } from './EverfurResult-DN9pL2Ab.js';
2
+ import { A as AuthContext } from './identity-CEi9GRFZ.js';
3
+ import { P as PetRef } from './ids-B2GAAifq.js';
4
+
5
+ /** The owner's answer to a check-in, the wire values of the consumer `CheckinResponse` enum. */
6
+ type CheckinAnswer = 'better' | 'same' | 'worse';
7
+ /** The closed answer set, in the order the consumer surfaces offer it. */
8
+ declare const CHECKIN_ANSWERS: readonly CheckinAnswer[];
9
+ /**
10
+ * The member-safe view of one watch case (consumer `WatchCaseView`). Case STATE only: the concern itself
11
+ * never rides on this row. `status` is the server's vocabulary (`watching` while open, then `resolved`,
12
+ * `escalated` or `lapsed`), carried as a string so a status added later never breaks a frozen client.
13
+ */
14
+ interface WatchCase {
15
+ readonly caseId: string;
16
+ readonly status: string;
17
+ /** The body-region copy hint (`ears`, `eyes`, ..., `general`), never a diagnosis. */
18
+ readonly bodyLocation: string | null;
19
+ readonly lastResponse: CheckinAnswer | null;
20
+ readonly checkInDueAt: string | null;
21
+ readonly openedAt: string | null;
22
+ readonly resolvedAt: string | null;
23
+ /** The server's own non-diagnostic post-answer line, stamped only on a BETTER resolve. */
24
+ readonly resolutionText: string | null;
25
+ }
26
+ /** The result of recording a check-in. `ctaDeepLink` is set only on a WORSE escalation (an `everfur://` pointer). */
27
+ interface CheckinOutcome {
28
+ readonly case: WatchCase;
29
+ readonly ctaDeepLink: string | null;
30
+ }
31
+ interface CasesRepository {
32
+ /**
33
+ * `GET /widget/v1/pets/{pet_ref}/cases` - the pet's open (`watching`) cases. Settles `ok([])` when the pet
34
+ * has none, which the server makes indistinguishable from a non-member or the feature being off.
35
+ */
36
+ list(petRef: PetRef, opts?: {
37
+ signal?: AbortSignal;
38
+ }): Promise<EverfurResult<readonly WatchCase[]>>;
39
+ /**
40
+ * `POST /widget/v1/pets/{pet_ref}/cases/{case_id}/checkin` - record the owner's answer. Settles
41
+ * `ok(CheckinOutcome)` on 200; a case that is stale, closed, another member's or gated off is the ordinary
42
+ * not-found error. A malformed case id or an answer outside the closed set is refused before the wire.
43
+ */
44
+ checkin(petRef: PetRef, caseId: string, answer: CheckinAnswer, opts?: {
45
+ signal?: AbortSignal;
46
+ }): Promise<EverfurResult<CheckinOutcome>>;
47
+ }
48
+ /** Build the repository over a device AuthContext (personalized bearer XOR anonymous pk). */
49
+ declare function createCasesRepository(auth: AuthContext): CasesRepository;
50
+
51
+ export { type CheckinAnswer as C, type WatchCase as W, type CheckinOutcome as a, CHECKIN_ANSWERS as b, type CasesRepository as c, createCasesRepository as d };