@everfur/sdk 0.6.0 → 0.7.1

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 (156) hide show
  1. package/CHANGELOG.md +228 -0
  2. package/dist/{Chat-CHqcgMyw.d.ts → Chat-CFi5cNUF.d.ts} +4 -4
  3. package/dist/{Chat-BoAvCWhI.d.cts → Chat-DQOsAumH.d.cts} +4 -4
  4. package/dist/{DepthViews-B0g83e_N.d.cts → DepthViews-C409ubw-.d.cts} +1 -1
  5. package/dist/{DepthViews-7Y8Ur058.d.ts → DepthViews-D81c95Ra.d.cts} +1 -1
  6. package/dist/{DepthViews-Dg2bIon_.d.ts → DepthViews-es8mIK0w.d.ts} +1 -1
  7. package/dist/{DepthViews-CT5mQld9.d.cts → DepthViews-uilL1NJZ.d.ts} +1 -1
  8. package/dist/IntakeMedia-BcjjUizr.d.ts +103 -0
  9. package/dist/IntakeMedia-CL_S2tZE.d.cts +103 -0
  10. package/dist/animations/index.cjs +1 -1
  11. package/dist/animations/index.d.cts +3 -3
  12. package/dist/animations/index.d.ts +3 -3
  13. package/dist/animations/index.js +1 -1
  14. package/dist/{attachments-C3HJNYQ7.d.cts → attachments-B2GjBgvF.d.cts} +2 -2
  15. package/dist/{attachments-rkox0ewd.d.cts → attachments-DI710no4.d.cts} +5 -5
  16. package/dist/{attachments-CfxsVg7W.d.ts → attachments-DNaSbmA3.d.ts} +2 -2
  17. package/dist/{attachments-CThFsH4b.d.ts → attachments-SF88N654.d.ts} +5 -5
  18. package/dist/{bookingCopy-Y3OGdoMT.d.ts → bookingCopy-D2N3RhsV.d.ts} +451 -50
  19. package/dist/{bookingCopy-Do3zMeXb.d.cts → bookingCopy-xlXxORCA.d.cts} +451 -50
  20. package/dist/{bookingTypes-DCs8mmBb.d.cts → bookingTypes-D4pD3tHs.d.cts} +13 -1
  21. package/dist/{bookingTypes-DCs8mmBb.d.ts → bookingTypes-D4pD3tHs.d.ts} +13 -1
  22. package/dist/{branding-DYWma2il.d.ts → branding-Bio5MM6g.d.cts} +3 -3
  23. package/dist/{branding-ChXm8gxI.d.cts → branding-ytH4jJq1.d.ts} +3 -3
  24. package/dist/{callCopy-CPe9mbwG.d.cts → callCopy-DHjem0R-.d.cts} +12 -1
  25. package/dist/{callCopy-CPe9mbwG.d.ts → callCopy-DHjem0R-.d.ts} +12 -1
  26. package/dist/{casesRepository-Jj6t60AY.d.cts → casesRepository-B-md8h1S.d.cts} +1 -1
  27. package/dist/{casesRepository-BbgXYPxa.d.ts → casesRepository-CC6951TK.d.ts} +1 -1
  28. package/dist/chat/index.cjs +1 -1
  29. package/dist/chat/index.d.cts +9 -9
  30. package/dist/chat/index.d.ts +9 -9
  31. package/dist/chat/index.js +1 -1
  32. package/dist/client/index.cjs +2 -2
  33. package/dist/client/index.d.cts +10 -10
  34. package/dist/client/index.d.ts +10 -10
  35. package/dist/client/index.js +2 -2
  36. package/dist/{config-Dfbj5mlx.d.ts → config-BM0sv5jx.d.ts} +1 -1
  37. package/dist/{config-BZX97FmW.d.cts → config-Daa1plhQ.d.cts} +1 -1
  38. package/dist/consent/index.cjs +1 -1
  39. package/dist/consent/index.d.cts +5 -5
  40. package/dist/consent/index.d.ts +5 -5
  41. package/dist/consent/index.js +1 -1
  42. package/dist/{context-Cbe0zYym.d.ts → context-CDV2pwGI.d.ts} +7 -7
  43. package/dist/{context-DJXnZ1Mx.d.cts → context-DQHtwcHN.d.cts} +7 -7
  44. package/dist/{copy-dKK5KoAQ.d.cts → copy-BEx5F71o.d.cts} +2 -2
  45. package/dist/{copy-DHekqSKE.d.ts → copy-Cl1l-qmY.d.ts} +2 -2
  46. package/dist/core/index.cjs +7 -7
  47. package/dist/core/index.d.cts +21 -21
  48. package/dist/core/index.d.ts +21 -21
  49. package/dist/core/index.js +7 -7
  50. package/dist/{depth-NmWSbvfi.d.cts → depth-CAAwiStc.d.cts} +132 -38
  51. package/dist/{depth-CrpRjWGB.d.ts → depth-DfNRVtrV.d.ts} +132 -38
  52. package/dist/{entitlementRepository-tVNazi8R.d.ts → entitlementRepository-CVWvND1P.d.ts} +3 -3
  53. package/dist/{entitlementRepository-iL-9vS1i.d.cts → entitlementRepository-DPvWjV-N.d.cts} +3 -3
  54. package/dist/{identity-B8rp0L9G.d.ts → identity-BhT7oJDS.d.ts} +1 -1
  55. package/dist/{identity-D7PO5s9m.d.cts → identity-DUlshgow.d.cts} +1 -1
  56. package/dist/index.cjs +6 -6
  57. package/dist/index.d.cts +17 -17
  58. package/dist/index.d.ts +17 -17
  59. package/dist/index.js +6 -6
  60. package/dist/notifications/index.d.cts +2 -2
  61. package/dist/notifications/index.d.ts +2 -2
  62. package/dist/{pets-BWx9BKea.d.cts → pets-Bneph9m1.d.cts} +1 -1
  63. package/dist/{pets-BQbXmICf.d.ts → pets-DjcLmRrW.d.ts} +1 -1
  64. package/dist/{petsRepository-SqIvEMiT.d.cts → petsRepository-BnVre3q7.d.cts} +1 -1
  65. package/dist/{petsRepository-0oBVydl6.d.ts → petsRepository-BwxmfX_s.d.ts} +1 -1
  66. package/dist/photo/index.cjs +1 -1
  67. package/dist/photo/index.js +1 -1
  68. package/dist/{ports-ChnzSy4E.d.cts → ports-BPKxFOSe.d.cts} +10 -9
  69. package/dist/{ports-iXPWd7Vt.d.ts → ports-Di9rdLO9.d.ts} +10 -9
  70. package/dist/records/depth/index.cjs +2 -2
  71. package/dist/records/depth/index.d.cts +7 -7
  72. package/dist/records/depth/index.d.ts +7 -7
  73. package/dist/records/depth/index.js +2 -2
  74. package/dist/records/index.cjs +3 -3
  75. package/dist/records/index.d.cts +19 -10
  76. package/dist/records/index.d.ts +19 -10
  77. package/dist/records/index.js +3 -3
  78. package/dist/{requestFunnel-CQzz2DIW.d.ts → requestFunnel-CiSX2pun.d.ts} +2 -2
  79. package/dist/{requestFunnel-DAwb7haa.d.cts → requestFunnel-DMR_1T3O.d.cts} +2 -2
  80. package/dist/{runtimeTypes-DB9-kigO.d.cts → runtimeTypes-2gJ5hYoE.d.cts} +5 -5
  81. package/dist/{runtimeTypes-BNOxfmfg.d.ts → runtimeTypes-CkMFCbHW.d.ts} +5 -5
  82. package/dist/server/events/index.cjs +1 -1
  83. package/dist/server/events/index.d.cts +2 -2
  84. package/dist/server/events/index.d.ts +2 -2
  85. package/dist/server/events/index.js +1 -1
  86. package/dist/server/index.cjs +1 -1
  87. package/dist/server/index.d.cts +3 -3
  88. package/dist/server/index.d.ts +3 -3
  89. package/dist/server/index.js +1 -1
  90. package/dist/televet/booking/index.cjs +4 -1
  91. package/dist/televet/booking/index.d.cts +116 -29
  92. package/dist/televet/booking/index.d.ts +116 -29
  93. package/dist/televet/booking/index.js +4 -1
  94. package/dist/televet/call/index.cjs +1 -1
  95. package/dist/televet/call/index.d.cts +1 -1
  96. package/dist/televet/call/index.d.ts +1 -1
  97. package/dist/televet/call/index.js +1 -1
  98. package/dist/televet/index.cjs +1 -1
  99. package/dist/televet/index.js +1 -1
  100. package/dist/testing/index.cjs +3 -3
  101. package/dist/testing/index.d.cts +1 -1
  102. package/dist/testing/index.d.ts +1 -1
  103. package/dist/testing/index.js +3 -3
  104. package/dist/testing/rn/index.cjs +1 -1
  105. package/dist/testing/rn/index.d.cts +14 -12
  106. package/dist/testing/rn/index.d.ts +14 -12
  107. package/dist/testing/rn/index.js +1 -1
  108. package/dist/testing/web/index.d.cts +9 -9
  109. package/dist/testing/web/index.d.ts +9 -9
  110. package/dist/{timelineRows-Dll2IGFg.d.ts → timelineRows-D3171ksh.d.ts} +1 -1
  111. package/dist/{timelineRows-BuNhzDbH.d.cts → timelineRows-DDnz4gx2.d.cts} +1 -1
  112. package/dist/{tokens-ARWZtMOU.d.cts → tokens-BYtbKwFh.d.cts} +6 -3
  113. package/dist/{tokens-ARWZtMOU.d.ts → tokens-BYtbKwFh.d.ts} +6 -3
  114. package/dist/{typeStyle-YCS8dt19.d.cts → typeStyle-BqfwxZH4.d.cts} +2 -2
  115. package/dist/{typeStyle-8iEqQmP_.d.ts → typeStyle-DKz02DGU.d.ts} +2 -2
  116. package/dist/{uploadTransport-C1p8FuG8.d.cts → uploadTransport-BM_pnEWj.d.cts} +5 -0
  117. package/dist/{uploadTransport-bZIKBTyK.d.ts → uploadTransport-C6kGP1Kd.d.ts} +5 -0
  118. package/dist/{useRecordsDepth-CNEHZJtj.d.cts → useRecordsDepth-COJ0wSYK.d.cts} +1 -1
  119. package/dist/{useRecordsDepth-CuNdne6E.d.ts → useRecordsDepth-Z9FF5X4E.d.ts} +1 -1
  120. package/dist/video/index.cjs +1 -1
  121. package/dist/video/index.js +1 -1
  122. package/dist/{view-DFy8EDwf.d.ts → view-DoQEHXJR.d.ts} +47 -5
  123. package/dist/{view-BhqWlYrZ.d.cts → view-nRy6SitU.d.cts} +47 -5
  124. package/dist/web/consent/index.cjs +1 -1
  125. package/dist/web/consent/index.d.cts +5 -5
  126. package/dist/web/consent/index.d.ts +5 -5
  127. package/dist/web/consent/index.js +1 -1
  128. package/dist/web/index.cjs +7 -7
  129. package/dist/web/index.d.cts +23 -22
  130. package/dist/web/index.d.ts +23 -22
  131. package/dist/web/index.js +7 -7
  132. package/dist/web/notifications/index.d.cts +3 -3
  133. package/dist/web/notifications/index.d.ts +3 -3
  134. package/dist/web/records/depth/index.cjs +2 -2
  135. package/dist/web/records/depth/index.d.cts +7 -7
  136. package/dist/web/records/depth/index.d.ts +7 -7
  137. package/dist/web/records/depth/index.js +2 -2
  138. package/dist/web/records/index.cjs +3 -3
  139. package/dist/web/records/index.d.cts +28 -17
  140. package/dist/web/records/index.d.ts +28 -17
  141. package/dist/web/records/index.js +3 -3
  142. package/dist/web/televet/booking/index.cjs +4 -2
  143. package/dist/web/televet/booking/index.d.cts +227 -123
  144. package/dist/web/televet/booking/index.d.ts +227 -123
  145. package/dist/web/televet/booking/index.js +4 -2
  146. package/dist/web/televet/call/index.cjs +1 -1
  147. package/dist/web/televet/call/index.d.cts +1 -1
  148. package/dist/web/televet/call/index.d.ts +1 -1
  149. package/dist/web/televet/call/index.js +1 -1
  150. package/dist/web/televet/index.cjs +3 -3
  151. package/dist/web/televet/index.d.cts +12 -4
  152. package/dist/web/televet/index.d.ts +12 -4
  153. package/dist/web/televet/index.js +3 -3
  154. package/package.json +1 -1
  155. package/dist/BookedScreen-BJPbXLCG.d.ts +0 -54
  156. package/dist/BookedScreen-Cnld-jB_.d.cts +0 -54
package/CHANGELOG.md CHANGED
@@ -10,6 +10,234 @@ changes that has not been earned by any production integration yet.
10
10
 
11
11
  ## [Unreleased]
12
12
 
13
+ ## [0.7.1] - 2026-10-01
14
+
15
+ ### Fixed
16
+
17
+ - **`RecordShareAudience` is now exported (type-only) from `@everfur/sdk/records/depth` and
18
+ `@everfur/sdk/web/records/depth`**, the audience `RecordsDepthClient.createShare(petRef, { audience })` takes.
19
+ Before, both depth API reports carried an api-extractor warning pinned to a hashed build file
20
+ (`dist/depth-<hash>.d.ts`), so `npm run api:check` failed on every version bump until the reports were
21
+ regenerated.
22
+ - **`EverfurTelevetHost` takes `onPickMedia` (web).** The intake step has had a picker seam since booking photos
23
+ shipped (`onPickMedia` on `EverfurTelevet`), but the default in-page visit never reached it: the host and
24
+ `EverfurTelevetDialog` rendered the flow without a picker, so a partner on the button, chat or its own host
25
+ could not offer photos even with booking media served. The host now passes it through, as it does
26
+ `onAddToCalendar`. Absent, the intake step has no attachment row, as before.
27
+
28
+ ## [0.7.0] - 2026-10-01
29
+
30
+ ### Added
31
+
32
+ - **Records share: send a pet's record to a vet, groomer or kennel by email, and share it for an audience while
33
+ the server says so (web and React Native).** The share sheet gains the design's `Who it’s for` (`Vet` /
34
+ `Groomer` / `Boarding`), `Send to` (`vet@example.com…`) and `Send` / `Sending…`, over `POST
35
+ /widget/v1/records/pets/{pet_ref}/everfur_record/share/email`. The server mints the link and emails it; the
36
+ link is NEVER returned, so it never reaches `onOpenUrl`, the clipboard or the screen, and the new row under
37
+ `Active links` has no URL. The sheet says `Sent to {email}. The link works for 7 days.` (and `Add an email to
38
+ send {pet}’s record.` for an empty field). This works with EFBackend's `partner.records_share_audience_enabled`
39
+ off (default), where the pick only chooses the email's wording. ONLY while it is on, `GET
40
+ /widget/v1/records/features` serves `share_audiences` (parsed fail closed: malformed is no audiences, never
41
+ the upload types), the copy-link mint sends `{audience}`, and the sheet draws the lead (`Pick who it’s for; we
42
+ include the right pages.`, the web's `Share a snapshot of what {pet}’s vets recorded. ...`) and a `What’s
43
+ included` list derived from the served scope with the SDK's own section labels (a boarding list never
44
+ mentions a phone number). With it off neither is drawn, because the content is the same for everyone. New:
45
+ `RecordsDepthClient.emailShare`, `readFeatures?()`, `createShare(petRef, { audience })`,
46
+ `RecordsFeatures.shareAudiences`, `mapShareAudiences`, `mapRecordShareEmailReceipt`, `isShareRecipientEmail`,
47
+ `RecordShareAudience` and friends, `audience` on `RecordShare` and `RecordShareLink`, and `shareAudiences`,
48
+ `features`, `sending`, `sendEmail` on `useRecordShares`. The nameless `Add an email to send the record.` and
49
+ the mail failure `Could not send the email. Please try again.` are owner-approved (2026-10-01).
50
+ - **Vet messages and the visit summary, in your app (preview, dark until Everfur turns it on).** The Everfur app's
51
+ vet thread and visit summary on both platforms, over the five partner routes of EFBackend #1809
52
+ (`/widget/v1/televet/messages/threads`, one pet's thread and its send, the read receipt, and
53
+ `/consults/{consult_id}/summary`), which sit behind `partner.televet_messages_enabled` (default OFF). While the
54
+ switch is off the thread list answers 404 and nothing below is drawn. While it is on: the visits screen gains the
55
+ design's "Messages" card (one row per pet, the newest message, "New" / web "New reply" while unread), the visit
56
+ before the call gains "Running late? Message {vet}", a finished visit opens its approved summary ("What {vet} saw",
57
+ "{pet}’s plan" word for word, "From this visit", the vet card, "Book a follow-up"), and the thread screen reads and
58
+ sends text with the design's composer and note. New exports from `@everfur/sdk/televet/booking` and
59
+ `@everfur/sdk/web/televet/booking`: `TelevetVetThreadScreen`, `TelevetVisitSummaryScreen`, `useVetThreads`,
60
+ `useVetThread`, `useVisitSummary`, `vetThreadPetRef`, `VET_MESSAGES_COPY`, the wire types (`VetThread`,
61
+ `VetMessage`, `VisitSummary`, ...), the path builders and `isVetMessagesDark` / `isVetThreadVetFirst`.
62
+ `TelevetBookingController` gains five optional methods (`listVetThreads`, `listVetMessages`, `sendVetMessage`,
63
+ `markVetThreadRead`, `visitSummary`); an injected controller without them gets no Messages card, as a dark tenant
64
+ does. `TelevetScreen` gains `thread` and `summary`. The 409 line (`Your vet will write first. You can reply once
65
+ they do.`) and a message's attachment count (`{n} attached`) are owner-approved (2026-10-01).
66
+
67
+ - **Records: a photo of a paper record uploads, while Everfur says so (web and React Native).** The SDK now reads
68
+ `GET /widget/v1/records/features` (zod-parsed, fail closed: a failed or malformed answer is PDF only). While the
69
+ answer carries `upload_content_types` (EFBackend `partner.records_image_upload_enabled`, off by default), the
70
+ upload accepts JPEG, PNG and HEIC/HEIF as well as PDF: the controller's gate admits them and initiate declares
71
+ the photo's own type; the web picker names a photo from its first bytes, never `File.type`. The upload card
72
+ then reads the design's photo lines (`A PDF, or a photo of a paper record. Add them all; we sort them by date.`,
73
+ `Have more?` over `PDFs and photos of paper records both work. ...`, the web refusal `We can’t read this kind of
74
+ file. Upload a PDF or a photo of the record.`), and the dashboard's upload way carries `A PDF, or a photo of a
75
+ paper record.`. React Native adds `Take a photo` (`of a paper record`) when the host sets `camera` on the config
76
+ and `Choose from photos` when it passes the new `onPickPhotos` (on `EverfurRecords`, `EverfurRecordsUpload` and
77
+ `EverfurRecordsRequest`), with `Choose a file` over `PDF`. With the switch off, or with no photo path wired on
78
+ React Native, every surface is exactly as before. New API: `RecordsController.readFeatures?()`,
79
+ `useEverfurRecords({ readUploadFeatures })` and `uploadContentTypes` on its state, `acceptsPhotos`,
80
+ `RecordsFeatures`, `RecordsUploadContentType`, `RecordsPhotoContentType`, and on web `recordsDocumentAccept` plus
81
+ an optional `types` argument on `fileToHandle`, `isUploadableHandle` and `pickDocument`.
82
+
83
+ ### Changed
84
+
85
+ - **The vet booking asks the emergency question itself, straight after Describe (web and React Native).** With no
86
+ `onTriageReason` seam, `EverfurTelevetBooking` now asks `TelevetBookingController.triage`, a new optional method
87
+ that posts the member's words to `POST /widget/v1/televet/consults/triage` (served dark on the partner plane
88
+ behind `partner.televet_early_triage_enabled`, the booking's own classifier). An emergency or fallback verdict
89
+ opens the existing approved emergency warning before the vet picker, instead of only at Confirm. Every failure
90
+ of the read (the dark 404, 403, 429, 5xx, an unreadable body) answers `null` and the flow goes on exactly as
91
+ before; one attempt, no retry. A host seam still wins. `TelevetTriageVerdict` now lives in the core booking
92
+ types and is re-exported unchanged; `KNOWN_PARTNER_ROUTES` gains the route and `KNOWN_ABSENT_ROUTES` loses it.
93
+ - **Televet booking: photos, videos and documents reach the vet when the partner plane serves them.** A pick
94
+ from the host's `onPickMedia` is presigned when picked through the new `POST
95
+ /widget/v1/televet/attachments/initiate` (EFBackend #1806, dark behind `partner.televet_booking_media_enabled`)
96
+ and sent at Confirm, one at a time, through the chat attachment transport (the S3 POST, no bytes before Confirm);
97
+ its `s3_key` goes in `media_refs`. What did not go is counted into the existing attachment notice: a failed post
98
+ or presign, the server's own `FILE_TOO_LARGE` / `INVALID_CONTENT_TYPE`, the local type and size rules (the
99
+ server's list: JPEG, PNG, WebP, HEIC/HEIF, PDF, CSV, MP4, MOV; 25 MB, video 200 MB), and any key the booking
100
+ did not keep. DARK (the presign's 404, or an injected controller with no `initiateAttachment`), nothing is sent,
101
+ `media_refs` is `[]` and every pick is reported unsent, exactly as before. Two approved design lines render only
102
+ when true: `Optional. A close-up in good light helps.` under the row once the presign has answered, and `{pet}’s
103
+ records, your notes and the photo go to {vet} ahead of the call.` on the confirmation when the records were
104
+ shared and exactly one photo went and the consult kept it. New: `TelevetBookingController.initiateAttachment`,
105
+ `TelevetIntakeMedia`'s `meta` and `TelevetBookedScreen`'s `sentPhoto`. On the web the bytes are read back from
106
+ the host's `blob:` URL, so a host page's CSP needs `connect-src` for `blob:` and the upload bucket, and a web
107
+ upload in production also needs the televet media bucket's CORS for the partner origin (EFBackend #1825).
108
+ - **Televet cancel: "What changed?" is optional on both platforms.** The question is marked `Optional`, as the
109
+ approved design marks it (web `cancel`, mobile `vet-cancel`, 30 Sep 2026). The web no longer refuses a cancel
110
+ with no answer picked (`Tell us why you are cancelling.` is gone); like React Native it sends the reviewed fixed
111
+ reason (`Cancelled by the pet parent in the app.`) instead, and a picked answer can be taken back. A picked
112
+ answer still sends its own words. The wire always carries a `reason` (never a `reason_code`), so the cancel is
113
+ valid whether or not the server's optional-reason flag is on.
114
+ - **Records: clinic search results show their distance in miles.** The clinic picker draws `3.2 mi` (and says `3.2
115
+ miles away`) as the design does, converted locally from the wire's `distance_km`; it drew kilometres. Web and React
116
+ Native.
117
+ - **Records: a source document reads its page count.** A row under `Sources on file` now reads `{n} pages · {date}`
118
+ (the design's `3 pages · Aug 14`; one page reads `1 page`) when the record wire counts the document's pages.
119
+ EFBackend serves `documents[].page_count` only while its `partner.records_document_page_count_enabled` switch is
120
+ armed (default off); until then, and for a document the record worker has not counted, the row keeps its date alone.
121
+ Web and React Native.
122
+ - **Visual and copy change: chat reads and looks like the Everfur app design (web and React Native).** By owner
123
+ decision (30 Sep 2026) the design artifacts count as approved, so chat carries their wording verbatim (the web
124
+ surface the web design's, React Native the mobile design's where they differ) and their layout on the theme's
125
+ derived tokens, so partner palettes still apply. Copy: the composer asks `Ask anything about {pet}…` (web: `Ask a
126
+ follow-up…` once a reply is on screen, `Tell us what’s happening…` under an emergency banner) and is named
127
+ `Message`; the reply is headed `Everfur` (not drawn for a `hide_powered_by` tenant); the waiting line is `Reading
128
+ {pet}’s records…` and a settled reply is announced as `Everfur answered.` rather than read out; the emergency tier
129
+ is `Call a vet now`, with the ASPCA Animal Poison Control call (owner-approved) and `Nearest emergency vet` when
130
+ the host's `onFindVet` is the route; the history is `Chats` (`Search chats…`, `Chats and vet messages · {n}` once
131
+ every row is loaded, `New reply · {date}` on an unread row, `No chats match that.`); the pet sheet is `Your pets`
132
+ with `Add a pet`; the switch control is `{pet}. Switch pet`; the web vet-prep chip is `Book a video visit` and
133
+ the React Native one drops its full stop. The fixed clinical disclaimer band is replaced on chat by the design's
134
+ one-line footnote under the composer (compiled and frozen in the chat copy module; records keep the band).
135
+ Layout: 20 px bubbles with a 6 px tail (a vet's at the top left, still pink), the body size on every box, the
136
+ sender's name over a reply, a left-aligned hello with edge-less starter chips, the web's outline follow-up chips
137
+ and the mobile design's headed follow-up rows, a Dark Green send disc on the web composer, a white history panel
138
+ (the web rail was brand green), and the emergency banner painted from the theme's alert red. New bubbles pop from
139
+ their corner and starter chips rise, both off under reduced motion. The quick prompts stay the compiled templates:
140
+ the design's chips name one sample pet's records, and the SDK has no served source of record-personalised prompts.
141
+ The web chat's geometry guard now pins the design and records where it departs from the shipped web app.
142
+ `TypingIndicator` (`@everfur/sdk/testing/rn`) takes an optional `petName` for the reading line; called with no
143
+ props it reads `your pet`, as before it drew with none.
144
+
145
+ - **Visual and copy change: the records surfaces read and look like the Everfur app designs (web and React Native,
146
+ medical records only).** By owner decision (30 Sep 2026) the records screens port the owner-approved design
147
+ artifacts' wording and layout. The clinical disclaimer band under every records screen is replaced by the
148
+ artifacts' one-line footnote, `Everfur summarizes what your vet recorded. It is informational, not
149
+ diagnostic.` (compiled, not overridable, `RECORDS_FOOTNOTE`); chat and televet keep the band. Titles follow the
150
+ pet (`Rex's Records` on the web, the pet's name on React Native, `Request Rex's records`, `Send Rex's record`,
151
+ `Rex's health record`; the nameless forms are unchanged), the full record is `Visits & records`, the clinic
152
+ release is `Check and send` with the artifact's checkbox wording around the drawn signature (kept), `What we ask
153
+ for`, `What happens next` and `Send request`, the clinic picker gains its lead and `How it works`, the request
154
+ screen gains `Request sent`, `Where it stands` and `Request details`, a clinic request's tracker reads `Request
155
+ sent`, `Clinic notified`, `Waiting for records…` with a `Now` pill, and the in-flight dashboard reads `Rex's
156
+ records are on the way` with `Another clinic` and `Upload a document` beside it. Cards take the artifacts'
157
+ radius 20 and neutral edge, buttons are 52 tall and press to 0.97, status pills are the artifacts' mono capitals,
158
+ sections rise in on the web, and the record tiles' tints are derived from the theme. Every motion rests under
159
+ reduced motion. Lines whose promise the partner wire cannot keep yet are held back and the truthful line stays:
160
+ photo upload, send-by-email and audiences, "We'll text you",
161
+ reminders, a follow-up date, clinic search by phone or fax, and the birth-date line of the release.
162
+ The share sheet states the link's terms (`Sent as a secure link that works for 7 days. You can stop sharing it
163
+ any time.`; by owner decision a new link lives 7 days) and, on React Native, `Link copied. It works for 7 days.`
164
+ and `Couldn't copy. The link is {url}`. The vendored platform contract is re-synced to EFBackend main (digests
165
+ only). `buildRequestTimeline` (a hook-based UI's rail) now reads the same words for a clinic request and takes an
166
+ optional `{ petName }` for its last step (`Added to Rex's records`); no other export changes.
167
+
168
+ - **Visual and copy change: the vet visit surfaces follow the owner-approved Everfur app designs of 30 Sep 2026
169
+ (web and React Native).** The booking is the designs' eight steps, "Step n of 8": who, where the pet will be
170
+ during the visit (new, asked on every booking and seeded with `usState`; what each place permits is read from
171
+ the served state policy), what's going on (now on React Native too, with the designs' twelve issues for every
172
+ pet), the description, an explicit emergency check (new: seven signs and a yes or no; "Yes" shows the exits and
173
+ holds the flow until "I’ve handled this, continue booking", which sends `emergency_acknowledged: true`), your
174
+ vet, the time (grouped Morning, Afternoon, Evening) and the review ("Book the visit", the attestation "{pet} and I
175
+ will be in {state} during the visit.", a Change on When; on the web a press with a box unticked says "Check both
176
+ boxes to book the visit."). The flow bar, option cards, chips, day and time chips, review rows, confirmation,
177
+ visits page ("Video visits", "Next video visit", "Past video visits", the vet footnote), cancel ("What changed?"
178
+ with four answers, sent as the reason) and reschedule (a "Move to ..." button; picking no longer moves the visit)
179
+ are restyled from theme tokens only, and the waiting room words follow ("Waiting room", "Before {vet} joins",
180
+ "15 minutes"). The ASPCA Animal Poison Control row is now drawn on both platforms (owner approval). The
181
+ `VetVisitButton` default label is "Vet" (was "Talk to a vet"). Not ported, because this plane cannot keep the
182
+ promise yet: text-message reminders, a photo reaching the vet, an optional cancel reason, vet messages, the visit
183
+ summary, the device checks and "joins in about 3 minutes". Public API: `TelevetBookingStep` and
184
+ `TELEVET_BOOKING_STEPS` gain `where` and `emergency`; `TELEVET_BOOKING_COPY` gains keys and changes values;
185
+ `televetIssueChips` no longer filters by species; the web `TelevetBookingChrome` takes `showBack`, the RN one
186
+ `triageOpen`; `TelevetBookedScreen` takes `sharedRecords`; `TelevetSlotPicker` takes `periodLabels`.
187
+
188
+ - **Visual change: the default theme adopts the Everfur design tokens of 26 Sep 2026 (web and React Native).** By
189
+ owner decision (30 Sep 2026) the compiled light default follows the design tokens ahead of the Everfur apps. Body
190
+ text is solid black (`text.primary`, `onBubbleVet` `#111111` -> `#000000`). Off-White is retired: the card,
191
+ composer and popover grounds are white (`surfaceCream`, `composerFill` `#FDFBF8` -> `#FFFFFF`), so
192
+ `surface_style: 'cream'` now paints white on the light palette. The warm greys become the design tokens' neutral
193
+ ones: `text.muted` `#6E6660` -> `#6B6B6B`, `borderRingCream` `#D8D2C8` -> `#E4E4E4`, `surfaceSubtle`
194
+ `#EFE9E3` -> `#F1F5F2` (mist), `skeleton` -> `#E9F1E9`, `badgeBgNeutral` follows the new grey. The reds are the
195
+ one alert red: `danger` `#B91C1C` and `errorRed` `#CC1600` -> `#C03410`, `badgeBgCritical` -> that red at 6%.
196
+ The type scale moves to the design tokens': `caption` 12 -> 13, `bodyTight` 13 -> 15, `body` 14 -> 17,
197
+ `subtitle` 16 -> 20, `heading` 18 -> 22 (`nano` to `tiny` and `verdict` are unchanged), and the React Native chat
198
+ bubble and field line heights follow the body size. Every ink still passes the contrast guards on both palettes.
199
+ The dark palette's `text.muted` is the neutral `#9A9A9A` (was `#9A938C`); the rest of the dark palette, the vet
200
+ bubble's pink and the motion curves are unchanged. No font is bundled: the design tokens' Azeret reaches a surface
201
+ only when a branding supplies it (`fonts`, or `font_urls` on the web). Partner branding resolves exactly as before
202
+ (lock > partner code > console > this default); only the default moved. A partner `font_size_base` still sets the
203
+ body size, and the other sizes now scale from the new 17 px body rather than 14.
204
+
205
+ ### Fixed
206
+
207
+ - **Televet booking: the step counter counts the steps the owner sees (web and React Native).** A one-pet household
208
+ never sees the pet step, but the bar still counted it, so the flow opened on `Step 2 of 8` and never showed a
209
+ first step (partner smoke test of 0.6.0). It now reads `Step 1 of 7` ... `Step 7 of 7` there (seven segments on
210
+ React Native) and keeps the design's eight for a household with a pet to choose. New optional
211
+ `TelevetBookingChromeProps.stepContext` (the reducer's `TelevetBookingContext`) for a host driving the chrome
212
+ itself; absent, the bar counts eight as before.
213
+ - **Records: no empty heading on the upload screen (web and React Native).** Its header row passed an empty title
214
+ and still drew an `<h2>` (a Text with the header role on React Native) that a screen reader lists and reads as
215
+ nothing (partner smoke test of 0.6.0). The header row now draws a spacer for an empty title, and on the web the
216
+ screen's own title (`Upload a document`) is the heading focus moves to when the member arrives.
217
+ - **Records: a date in the record's Identity section reads as a date.** The server sends identity values raw, so the
218
+ date of birth showed as `2022-07-27`; a bare calendar date now uses the records date format (`Jul 27, 2022`) on
219
+ web and React Native. Species and sex still show as sent (`dog`, `female`): the SDK has no vocabulary for them,
220
+ so display labels for those are a server item.
221
+ - **Records clinic request forms (`EverfurClinicRequest`, `EverfurClinicRequestBatch`, web and React Native): search
222
+ results no longer fill the page.** The forms asked for 100 clinics and drew every one inline (about 6,750 px on
223
+ the partner smoke test of 0.6.0). They now ask for one page of 25 (the clinic picker's page size), draw the first
224
+ five, and add five more per `Load more` (the SDK's existing label); a member who still has not found the clinic
225
+ refines the search.
226
+ - **"Please add your signature before submitting." no longer greets a form just opened.** It was an alert from the
227
+ first render. It now appears only once everything else is filled in, when the missing signature is what keeps
228
+ Send closed.
229
+ - **The signature pad's `Draw your signature in the box above.` is gone in typed mode (web),** where there is
230
+ nothing to draw. No typed-mode hint exists in the consumer apps or the designs, so the line stays empty.
231
+ - **Chat: opening chat no longer creates an empty conversation (web and React Native).** The bootstrap prime
232
+ POSTed `/widget/v1/conversations` on every mount (twice under React StrictMode's double mount), so the member's
233
+ history filled with empty `New conversation` rows (partner smoke test of 0.6.0). The prime still reads the head
234
+ of the list (resuming a thread with an unread reply, which is also what delivers an owed check-in) and prefetches
235
+ the suggested prompts; the conversation is now created by the first send, which pays that one round trip before
236
+ it streams. `runtime.prepare()` no longer creates one either. `ChatController.primeConversation()` now settles to
237
+ `ConversationId | null` (null: no thread opened yet), and a failed head read is the prime's reported failure
238
+ (except a 403, since a key without history read can still chat). The web `Everfur answered.` announcement now
239
+ also fires for the first reply of a new thread, as it already did on React Native.
240
+
13
241
  ## [0.6.0] - 2026-09-29
14
242
 
15
243
  ### Added
@@ -2,9 +2,9 @@ import { ReactNode } from 'react';
2
2
  import { StyleProp, ViewStyle } from 'react-native';
3
3
  import { P as PetRef, C as ConversationId } from './ids-B2GAAifq.js';
4
4
  import { F as FileHandle } from './ports-BN6RHF9W.js';
5
- import { a as ChatCheckinTarget } from './ports-iXPWd7Vt.js';
6
- import { W as WidgetPet, P as PetProfileInput } from './petsRepository-0oBVydl6.js';
7
- import { U as UrgencyDisplayLevel, L as LifecyclePort, E as EverfurChatDraftStore } from './attachments-CThFsH4b.js';
5
+ import { a as ChatCheckinTarget } from './ports-Di9rdLO9.js';
6
+ import { W as WidgetPet, P as PetProfileInput } from './petsRepository-BwxmfX_s.js';
7
+ import { U as UrgencyDisplayLevel, L as LifecyclePort, E as EverfurChatDraftStore } from './attachments-SF88N654.js';
8
8
 
9
9
  /** Where a picked image comes from: the host's photo library, or its camera. */
10
10
  type AttachmentSource = 'photo' | 'camera';
@@ -48,7 +48,7 @@ interface EverfurChatProps {
48
48
  /** Called after the user picked another pet in the header switcher and the provider re-scoped to it. */
49
49
  readonly onPetChange?: (petRef: PetRef) => void;
50
50
  /**
51
- * Your vet-visit preparation screen. Given, the empty thread's `Help me prep for {pet}'s vet visit.` chip
51
+ * Your vet-visit preparation screen. Given, the empty thread's `Help me prep for {pet}’s vet visit` chip
52
52
  * routes to it with the pet; absent, that chip is the Everfur vet visit entry inside Chat, shown only
53
53
  * while Everfur has it switched on for your tenant, else not shown at all.
54
54
  */
@@ -2,9 +2,9 @@ import { ReactNode } from 'react';
2
2
  import { StyleProp, ViewStyle } from 'react-native';
3
3
  import { P as PetRef, C as ConversationId } from './ids-B2GAAifq.cjs';
4
4
  import { F as FileHandle } from './ports-BN6RHF9W.cjs';
5
- import { a as ChatCheckinTarget } from './ports-ChnzSy4E.cjs';
6
- import { W as WidgetPet, P as PetProfileInput } from './petsRepository-SqIvEMiT.cjs';
7
- import { U as UrgencyDisplayLevel, L as LifecyclePort, E as EverfurChatDraftStore } from './attachments-rkox0ewd.cjs';
5
+ import { a as ChatCheckinTarget } from './ports-BPKxFOSe.cjs';
6
+ import { W as WidgetPet, P as PetProfileInput } from './petsRepository-BnVre3q7.cjs';
7
+ import { U as UrgencyDisplayLevel, L as LifecyclePort, E as EverfurChatDraftStore } from './attachments-DI710no4.cjs';
8
8
 
9
9
  /** Where a picked image comes from: the host's photo library, or its camera. */
10
10
  type AttachmentSource = 'photo' | 'camera';
@@ -48,7 +48,7 @@ interface EverfurChatProps {
48
48
  /** Called after the user picked another pet in the header switcher and the provider re-scoped to it. */
49
49
  readonly onPetChange?: (petRef: PetRef) => void;
50
50
  /**
51
- * Your vet-visit preparation screen. Given, the empty thread's `Help me prep for {pet}'s vet visit.` chip
51
+ * Your vet-visit preparation screen. Given, the empty thread's `Help me prep for {pet}’s vet visit` chip
52
52
  * routes to it with the pet; absent, that chip is the Everfur vet visit entry inside Chat, shown only
53
53
  * while Everfur has it switched on for your tenant, else not shown at all.
54
54
  */
@@ -1,6 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { StyleProp, ViewStyle } from 'react-native';
3
- import { f as RecordsScreenBaseProps } from './useRecordsDepth-CNEHZJtj.cjs';
3
+ import { f as RecordsScreenBaseProps } from './useRecordsDepth-COJ0wSYK.cjs';
4
4
 
5
5
  interface EverfurRecordsDepthProps extends Pick<RecordsScreenBaseProps, 'petRef' | 'petName' | 'onNavigate' | 'onBack'> {
6
6
  readonly style?: StyleProp<ViewStyle>;
@@ -1,5 +1,5 @@
1
1
  import { CSSProperties, ReactNode } from 'react';
2
- import { f as RecordsScreenBaseProps } from './useRecordsDepth-CuNdne6E.js';
2
+ import { f as RecordsScreenBaseProps } from './useRecordsDepth-COJ0wSYK.cjs';
3
3
 
4
4
  interface EverfurRecordsDepthProps extends Pick<RecordsScreenBaseProps, 'petRef' | 'petName' | 'onNavigate' | 'onBack'> {
5
5
  readonly style?: CSSProperties;
@@ -1,6 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { StyleProp, ViewStyle } from 'react-native';
3
- import { f as RecordsScreenBaseProps } from './useRecordsDepth-CuNdne6E.js';
3
+ import { f as RecordsScreenBaseProps } from './useRecordsDepth-Z9FF5X4E.js';
4
4
 
5
5
  interface EverfurRecordsDepthProps extends Pick<RecordsScreenBaseProps, 'petRef' | 'petName' | 'onNavigate' | 'onBack'> {
6
6
  readonly style?: StyleProp<ViewStyle>;
@@ -1,5 +1,5 @@
1
1
  import { CSSProperties, ReactNode } from 'react';
2
- import { f as RecordsScreenBaseProps } from './useRecordsDepth-CNEHZJtj.cjs';
2
+ import { f as RecordsScreenBaseProps } from './useRecordsDepth-Z9FF5X4E.js';
3
3
 
4
4
  interface EverfurRecordsDepthProps extends Pick<RecordsScreenBaseProps, 'petRef' | 'petName' | 'onNavigate' | 'onBack'> {
5
5
  readonly style?: CSSProperties;
@@ -0,0 +1,103 @@
1
+ import { ReactNode } from 'react';
2
+ import { T as TelevetConsult } from './bookingTypes-D4pD3tHs.js';
3
+
4
+ /** The calendar entry a booked visit asks the host to write. */
5
+ interface TelevetCalendarEvent {
6
+ /**
7
+ * A stable key for THIS consult's entry.
8
+ *
9
+ * Keyed on the CONSULT so a re-press updates the same entry rather than writing a second event for one
10
+ * visit, and so a later cancel or reschedule can address the SAME row. A host that ignores the key writes
11
+ * duplicates the owner has to clean up by hand.
12
+ */
13
+ readonly key: string;
14
+ readonly title: string;
15
+ readonly startDate: Date;
16
+ readonly endDate: Date;
17
+ /** The reminder offset in minutes, negative for "before". The platform queues its own at the same offset. */
18
+ readonly alarmOffsetMinutes: number;
19
+ }
20
+ /**
21
+ * Writes the entry. Resolves true when it landed in a calendar; false when the host has no calendar to write to
22
+ * or the entry could not be written; `'handed-off'` when the entry was handed to the member to add themselves (a
23
+ * file download, as `downloadTelevetCalendarFile` does), which puts nothing in a calendar yet. On true the
24
+ * confirmation says the visit was added; on `'handed-off'` it keeps Add to Calendar, enabled, so the member can
25
+ * press it again, as the consumer web app's link can be.
26
+ */
27
+ type TelevetCalendarWriter = (event: TelevetCalendarEvent) => Promise<boolean | 'handed-off'>;
28
+ /** The calendar key for a consult. One definition, so a cancel and a reschedule address the booked row. */
29
+ declare function televetConsultCalendarKey(consultId: string): string;
30
+ interface TelevetBookedScreenProps {
31
+ readonly consult: TelevetConsult;
32
+ readonly petName: string | null;
33
+ readonly onDone: () => void;
34
+ /** Absent, there is no Add to calendar control. */
35
+ readonly onAddToCalendar?: TelevetCalendarWriter | undefined;
36
+ /**
37
+ * Has the host PROVEN it can host the call in place? Defaults to false.
38
+ *
39
+ * Fail closed: a host that has not said so is assumed not to have mounted the call surface, and the in-place
40
+ * join promise is withheld rather than printed on a hope.
41
+ */
42
+ readonly canJoinInApp?: boolean;
43
+ /**
44
+ * How long the visit is, in minutes: the booked slot's served length (`televetSlotMinutes`), which is the
45
+ * length the platform runs the visit for. The calendar entry ends this long after the start.
46
+ *
47
+ * Absent, or not a positive number, the entry falls back to `CONSULT_MINUTES`, the same fallback the review's
48
+ * length row uses for a slot that does not say. The prebuilt flow always passes the slot's length.
49
+ */
50
+ readonly lengthMinutes?: number | undefined;
51
+ /**
52
+ * Did the owner share the pet's records with the vet on the review? Only then may step 02 say the records go
53
+ * to the vet ahead of the call; otherwise it keeps the deck's own summary line.
54
+ */
55
+ readonly sharedRecords?: boolean | undefined;
56
+ /**
57
+ * Did exactly one PHOTO go with this booking, and did the consult keep it? Only then may step 02 say the photo
58
+ * goes to the vet (the artifact's photo form). Defaults to false.
59
+ */
60
+ readonly sentPhoto?: boolean | undefined;
61
+ }
62
+ declare function TelevetBookedScreen({ consult, petName, onDone, onAddToCalendar, canJoinInApp, lengthMinutes, sharedRecords, sentPhoto, }: TelevetBookedScreenProps): ReactNode;
63
+
64
+ /** A picked-but-not-yet-uploaded attachment, in the host's own terms. */
65
+ interface TelevetIntakeMediaItem {
66
+ readonly uri: string;
67
+ readonly filename: string;
68
+ readonly mimeType: string;
69
+ readonly fileSize: number;
70
+ }
71
+ /**
72
+ * The host's media picker.
73
+ *
74
+ * Resolves the picks, or null when the owner cancelled. The SDK takes no picker dependency and opens no file
75
+ * dialog of its own; a partner supplies whichever picker its site already has, typically an `<input
76
+ * type="file">` whose `File` objects it turns into object URLs.
77
+ *
78
+ * `limit` is the remaining headroom, so the host can cap its own selection rather than returning picks this
79
+ * row has to silently discard.
80
+ */
81
+ type TelevetMediaPicker = (limit: number) => Promise<readonly TelevetIntakeMediaItem[] | null>;
82
+ interface TelevetIntakeMediaProps {
83
+ readonly media: readonly TelevetIntakeMediaItem[];
84
+ readonly onChange: (next: readonly TelevetIntakeMediaItem[]) => void;
85
+ /** Absent, the row renders nothing at all. There is no disabled Add control. */
86
+ readonly onPickMedia?: TelevetMediaPicker | undefined;
87
+ /**
88
+ * The list's accessible name.
89
+ *
90
+ * Required, with no default string here: naming the group is what makes the tiles announce as a set, and
91
+ * the name is user-facing copy this SDK does not author. The intake step passes a ported key down.
92
+ */
93
+ readonly listLabel: string;
94
+ /**
95
+ * A line under the row, or nothing. The booking passes the artifact's "Optional. A close-up in good light
96
+ * helps." only once the televet presign has answered, because the advice is true only when a photo can reach
97
+ * the vet. Absent, nothing is drawn.
98
+ */
99
+ readonly meta?: string | null | undefined;
100
+ }
101
+ declare function TelevetIntakeMedia({ media, onChange, onPickMedia, listLabel, meta }: TelevetIntakeMediaProps): ReactNode;
102
+
103
+ export { type TelevetCalendarWriter as T, type TelevetMediaPicker as a, type TelevetCalendarEvent as b, type TelevetIntakeMediaItem as c, TelevetBookedScreen as d, type TelevetBookedScreenProps as e, TelevetIntakeMedia as f, type TelevetIntakeMediaProps as g, televetConsultCalendarKey as t };
@@ -0,0 +1,103 @@
1
+ import { ReactNode } from 'react';
2
+ import { T as TelevetConsult } from './bookingTypes-D4pD3tHs.cjs';
3
+
4
+ /** The calendar entry a booked visit asks the host to write. */
5
+ interface TelevetCalendarEvent {
6
+ /**
7
+ * A stable key for THIS consult's entry.
8
+ *
9
+ * Keyed on the CONSULT so a re-press updates the same entry rather than writing a second event for one
10
+ * visit, and so a later cancel or reschedule can address the SAME row. A host that ignores the key writes
11
+ * duplicates the owner has to clean up by hand.
12
+ */
13
+ readonly key: string;
14
+ readonly title: string;
15
+ readonly startDate: Date;
16
+ readonly endDate: Date;
17
+ /** The reminder offset in minutes, negative for "before". The platform queues its own at the same offset. */
18
+ readonly alarmOffsetMinutes: number;
19
+ }
20
+ /**
21
+ * Writes the entry. Resolves true when it landed in a calendar; false when the host has no calendar to write to
22
+ * or the entry could not be written; `'handed-off'` when the entry was handed to the member to add themselves (a
23
+ * file download, as `downloadTelevetCalendarFile` does), which puts nothing in a calendar yet. On true the
24
+ * confirmation says the visit was added; on `'handed-off'` it keeps Add to Calendar, enabled, so the member can
25
+ * press it again, as the consumer web app's link can be.
26
+ */
27
+ type TelevetCalendarWriter = (event: TelevetCalendarEvent) => Promise<boolean | 'handed-off'>;
28
+ /** The calendar key for a consult. One definition, so a cancel and a reschedule address the booked row. */
29
+ declare function televetConsultCalendarKey(consultId: string): string;
30
+ interface TelevetBookedScreenProps {
31
+ readonly consult: TelevetConsult;
32
+ readonly petName: string | null;
33
+ readonly onDone: () => void;
34
+ /** Absent, there is no Add to calendar control. */
35
+ readonly onAddToCalendar?: TelevetCalendarWriter | undefined;
36
+ /**
37
+ * Has the host PROVEN it can host the call in place? Defaults to false.
38
+ *
39
+ * Fail closed: a host that has not said so is assumed not to have mounted the call surface, and the in-place
40
+ * join promise is withheld rather than printed on a hope.
41
+ */
42
+ readonly canJoinInApp?: boolean;
43
+ /**
44
+ * How long the visit is, in minutes: the booked slot's served length (`televetSlotMinutes`), which is the
45
+ * length the platform runs the visit for. The calendar entry ends this long after the start.
46
+ *
47
+ * Absent, or not a positive number, the entry falls back to `CONSULT_MINUTES`, the same fallback the review's
48
+ * length row uses for a slot that does not say. The prebuilt flow always passes the slot's length.
49
+ */
50
+ readonly lengthMinutes?: number | undefined;
51
+ /**
52
+ * Did the owner share the pet's records with the vet on the review? Only then may step 02 say the records go
53
+ * to the vet ahead of the call; otherwise it keeps the deck's own summary line.
54
+ */
55
+ readonly sharedRecords?: boolean | undefined;
56
+ /**
57
+ * Did exactly one PHOTO go with this booking, and did the consult keep it? Only then may step 02 say the photo
58
+ * goes to the vet (the artifact's photo form). Defaults to false.
59
+ */
60
+ readonly sentPhoto?: boolean | undefined;
61
+ }
62
+ declare function TelevetBookedScreen({ consult, petName, onDone, onAddToCalendar, canJoinInApp, lengthMinutes, sharedRecords, sentPhoto, }: TelevetBookedScreenProps): ReactNode;
63
+
64
+ /** A picked-but-not-yet-uploaded attachment, in the host's own terms. */
65
+ interface TelevetIntakeMediaItem {
66
+ readonly uri: string;
67
+ readonly filename: string;
68
+ readonly mimeType: string;
69
+ readonly fileSize: number;
70
+ }
71
+ /**
72
+ * The host's media picker.
73
+ *
74
+ * Resolves the picks, or null when the owner cancelled. The SDK takes no picker dependency and opens no file
75
+ * dialog of its own; a partner supplies whichever picker its site already has, typically an `<input
76
+ * type="file">` whose `File` objects it turns into object URLs.
77
+ *
78
+ * `limit` is the remaining headroom, so the host can cap its own selection rather than returning picks this
79
+ * row has to silently discard.
80
+ */
81
+ type TelevetMediaPicker = (limit: number) => Promise<readonly TelevetIntakeMediaItem[] | null>;
82
+ interface TelevetIntakeMediaProps {
83
+ readonly media: readonly TelevetIntakeMediaItem[];
84
+ readonly onChange: (next: readonly TelevetIntakeMediaItem[]) => void;
85
+ /** Absent, the row renders nothing at all. There is no disabled Add control. */
86
+ readonly onPickMedia?: TelevetMediaPicker | undefined;
87
+ /**
88
+ * The list's accessible name.
89
+ *
90
+ * Required, with no default string here: naming the group is what makes the tiles announce as a set, and
91
+ * the name is user-facing copy this SDK does not author. The intake step passes a ported key down.
92
+ */
93
+ readonly listLabel: string;
94
+ /**
95
+ * A line under the row, or nothing. The booking passes the artifact's "Optional. A close-up in good light
96
+ * helps." only once the televet presign has answered, because the advice is true only when a photo can reach
97
+ * the vet. Absent, nothing is drawn.
98
+ */
99
+ readonly meta?: string | null | undefined;
100
+ }
101
+ declare function TelevetIntakeMedia({ media, onChange, onPickMedia, listLabel, meta }: TelevetIntakeMediaProps): ReactNode;
102
+
103
+ export { type TelevetCalendarWriter as T, type TelevetMediaPicker as a, type TelevetCalendarEvent as b, type TelevetIntakeMediaItem as c, TelevetBookedScreen as d, type TelevetBookedScreenProps as e, TelevetIntakeMedia as f, type TelevetIntakeMediaProps as g, televetConsultCalendarKey as t };