@everfur/sdk 0.1.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 (89) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/LICENSE +21 -0
  3. package/README.md +161 -0
  4. package/animations/package.json +8 -0
  5. package/chat/package.json +8 -0
  6. package/client/package.json +8 -0
  7. package/core/package.json +8 -0
  8. package/dist/CameraPort-Cv31Pz7g.d.cts +29 -0
  9. package/dist/CameraPort-Cv31Pz7g.d.ts +29 -0
  10. package/dist/ChatController-CKdBvPj2.d.ts +146 -0
  11. package/dist/ChatController-CpUMvvZf.d.cts +146 -0
  12. package/dist/EverfurResult-D92-uL82.d.cts +240 -0
  13. package/dist/EverfurResult-D92-uL82.d.ts +240 -0
  14. package/dist/FilePort-BabWrv7I.d.cts +22 -0
  15. package/dist/FilePort-BabWrv7I.d.ts +22 -0
  16. package/dist/PhotoController-BItt5M7u.d.cts +43 -0
  17. package/dist/PhotoController-D8zMTdcW.d.ts +43 -0
  18. package/dist/TelemetryPort-BDNr00hu.d.cts +12 -0
  19. package/dist/TelemetryPort-BDNr00hu.d.ts +12 -0
  20. package/dist/animations/index.cjs +1997 -0
  21. package/dist/animations/index.d.cts +517 -0
  22. package/dist/animations/index.d.ts +517 -0
  23. package/dist/animations/index.js +1972 -0
  24. package/dist/cacheEpoch-DknKn3S0.d.cts +36 -0
  25. package/dist/cacheEpoch-DknKn3S0.d.ts +36 -0
  26. package/dist/chat/index.cjs +1170 -0
  27. package/dist/chat/index.d.cts +59 -0
  28. package/dist/chat/index.d.ts +59 -0
  29. package/dist/chat/index.js +1167 -0
  30. package/dist/client/index.cjs +2317 -0
  31. package/dist/client/index.d.cts +65 -0
  32. package/dist/client/index.d.ts +65 -0
  33. package/dist/client/index.js +2217 -0
  34. package/dist/config-BSjBdxrZ.d.cts +501 -0
  35. package/dist/config-CiJ0PVBB.d.ts +501 -0
  36. package/dist/core/index.cjs +3175 -0
  37. package/dist/core/index.d.cts +70 -0
  38. package/dist/core/index.d.ts +70 -0
  39. package/dist/core/index.js +3163 -0
  40. package/dist/identity-Brl-lDd6.d.cts +91 -0
  41. package/dist/identity-DK9zORrG.d.ts +91 -0
  42. package/dist/ids-CJ1S6adf.d.cts +46 -0
  43. package/dist/ids-CJ1S6adf.d.ts +46 -0
  44. package/dist/index.cjs +4488 -0
  45. package/dist/index.d.cts +156 -0
  46. package/dist/index.d.ts +156 -0
  47. package/dist/index.js +4464 -0
  48. package/dist/petsRepository-BEGb97M9.d.cts +326 -0
  49. package/dist/petsRepository-Bu18r2kK.d.ts +326 -0
  50. package/dist/photo/index.cjs +2189 -0
  51. package/dist/photo/index.d.cts +43 -0
  52. package/dist/photo/index.d.ts +43 -0
  53. package/dist/photo/index.js +2186 -0
  54. package/dist/projection-CeIUsbSk.d.cts +8 -0
  55. package/dist/projection-CeIUsbSk.d.ts +8 -0
  56. package/dist/records/index.cjs +2840 -0
  57. package/dist/records/index.d.cts +224 -0
  58. package/dist/records/index.d.ts +224 -0
  59. package/dist/records/index.js +2834 -0
  60. package/dist/requestFunnel-DuUH-kAe.d.cts +28 -0
  61. package/dist/requestFunnel-dio5OmR9.d.ts +28 -0
  62. package/dist/resolve-Dq_4_agU.d.cts +86 -0
  63. package/dist/resolve-Dq_4_agU.d.ts +86 -0
  64. package/dist/runtime-BgQnA594.d.cts +349 -0
  65. package/dist/runtime-CBA-LvdM.d.ts +349 -0
  66. package/dist/server/index.cjs +533 -0
  67. package/dist/server/index.d.cts +48 -0
  68. package/dist/server/index.d.ts +48 -0
  69. package/dist/server/index.js +530 -0
  70. package/dist/testing/index.cjs +825 -0
  71. package/dist/testing/index.d.cts +113 -0
  72. package/dist/testing/index.d.ts +113 -0
  73. package/dist/testing/index.js +822 -0
  74. package/dist/testing/rn/index.cjs +449 -0
  75. package/dist/testing/rn/index.d.cts +49 -0
  76. package/dist/testing/rn/index.d.ts +49 -0
  77. package/dist/testing/rn/index.js +444 -0
  78. package/dist/video/index.cjs +1941 -0
  79. package/dist/video/index.d.cts +66 -0
  80. package/dist/video/index.d.ts +66 -0
  81. package/dist/video/index.js +1938 -0
  82. package/package.json +311 -0
  83. package/photo/package.json +8 -0
  84. package/records/package.json +8 -0
  85. package/server/device-blocked.cjs +15 -0
  86. package/server/package.json +9 -0
  87. package/testing/package.json +8 -0
  88. package/testing/rn/package.json +8 -0
  89. package/video/package.json +8 -0
@@ -0,0 +1,449 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+ require('react-native-safe-area-context');
5
+ var reactNative = require('react-native');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+
8
+ // src/rn/testing.ts
9
+
10
+ // src/client/errors/EverfurResult.ts
11
+ var EverfurConfigError = class _EverfurConfigError extends Error {
12
+ constructor(kind, message) {
13
+ super(message);
14
+ this.name = "EverfurConfigError";
15
+ this.kind = kind;
16
+ Object.setPrototypeOf(this, _EverfurConfigError.prototype);
17
+ }
18
+ };
19
+
20
+ // src/client/theme/tokens.ts
21
+ function deepFreeze(value) {
22
+ if (value !== null && typeof value === "object" && !Object.isFrozen(value)) {
23
+ Object.freeze(value);
24
+ for (const key of Object.keys(value)) {
25
+ deepFreeze(value[key]);
26
+ }
27
+ }
28
+ return value;
29
+ }
30
+ var SPACE = { xs: 4, sm: 8, md: 12, lg: 16, xl: 24, xxl: 32 };
31
+ var RADIUS = { tile: 5, xs: 6, sm: 10, md: 14, lg: 20, xl: 28, pill: 500 };
32
+ var TYPE_SIZE = {
33
+ nano: 8,
34
+ small: 9,
35
+ micro: 10,
36
+ tiny: 11,
37
+ caption: 12,
38
+ bodyTight: 13,
39
+ body: 14,
40
+ subtitle: 16,
41
+ heading: 18,
42
+ verdict: 24
43
+ };
44
+ var LINE_HEIGHT = { tight: 1.15, snug: 1.3, normal: 1.4, relaxed: 1.55 };
45
+ var WEIGHT = { regular: "400", medium: "500", bold: "700" };
46
+ var LETTER_SPACING = {
47
+ eyebrow: 1,
48
+ monoWide: 0.9,
49
+ headerBrand: -0.42,
50
+ tight: -0.35
51
+ };
52
+ function baseType() {
53
+ return {
54
+ family: "System",
55
+ mono: "monospace",
56
+ fontUrl: null,
57
+ size: TYPE_SIZE,
58
+ lineHeight: LINE_HEIGHT,
59
+ weight: WEIGHT,
60
+ letterSpacing: LETTER_SPACING
61
+ };
62
+ }
63
+ var MOTION = {
64
+ duration: { instant: 80, fast: 140, normal: 220, slow: 320 },
65
+ spring: { gentle: { damping: 18, stiffness: 200 } },
66
+ easing: { standard: "cubic-bezier(0.4, 0, 0.2, 1)" },
67
+ reducedMotion: false
68
+ };
69
+ var LIGHT_COLOR = {
70
+ brand: "#10462E",
71
+ brandSoft: "rgba(16,70,46,0.10)",
72
+ brandSofter: "rgba(16,70,46,0.15)",
73
+ brandBorder: "rgba(16,70,46,0.18)",
74
+ borderHairlineGreen: "rgba(16,70,46,0.25)",
75
+ surface: "#FFFFFF",
76
+ surfaceCream: "#FDFBF8",
77
+ surfaceSubtle: "#EFE9E3",
78
+ background: "#FFFFFF",
79
+ borderRingCream: "#D8D2C8",
80
+ text: {
81
+ primary: "#111111",
82
+ secondary: "#0E462E",
83
+ muted: "#6E6660",
84
+ placeholder: "rgba(0,0,0,0.30)",
85
+ onBrand: "#FFFFFF",
86
+ metaCool: "#3D3D3D"
87
+ },
88
+ primary: "#10462E",
89
+ onPrimary: "#FFFFFF",
90
+ accent: "#10462E",
91
+ onAccent: "#FFFFFF",
92
+ accentEdge: "#07C168",
93
+ success: "#07C168",
94
+ danger: "#B91C1C",
95
+ errorRed: "#FF1B00",
96
+ warningStrong: "#A45610",
97
+ cautionAccent: "#D9821D",
98
+ riskConcern: "#EFA700",
99
+ badgeBgPositive: "rgba(7,193,104,0.12)",
100
+ badgeBgCaution: "rgba(217,130,29,0.14)",
101
+ badgeBgCritical: "rgba(185,28,28,0.12)",
102
+ badgeBgNeutral: "rgba(110,102,96,0.12)",
103
+ bubbleUser: "#10462E",
104
+ bubbleAssistant: "#FFFFFF",
105
+ skeleton: "#EFE9E3",
106
+ scanButtonPink: "#FFC3BC",
107
+ checkupCardLowRiskBg: "rgba(7,193,104,0.10)",
108
+ checkupCardConcernBg: "rgba(239,167,0,0.10)"
109
+ };
110
+ var EVERFUR_LIGHT = deepFreeze({
111
+ brightness: "light",
112
+ meta: { displayName: "Everfur", logoUrl: null, placeholder: null, hidePoweredBy: false },
113
+ color: LIGHT_COLOR,
114
+ space: SPACE,
115
+ radius: RADIUS,
116
+ type: baseType(),
117
+ motion: MOTION
118
+ });
119
+ var DARK_COLOR = {
120
+ brand: "#6BD39A",
121
+ brandSoft: "rgba(107,211,154,0.12)",
122
+ brandSofter: "rgba(107,211,154,0.18)",
123
+ brandBorder: "rgba(107,211,154,0.22)",
124
+ borderHairlineGreen: "rgba(107,211,154,0.28)",
125
+ surface: "#1C1F23",
126
+ surfaceCream: "#23272C",
127
+ surfaceSubtle: "#23272C",
128
+ background: "#15171A",
129
+ borderRingCream: "#3A3F45",
130
+ text: {
131
+ primary: "#F5F3F0",
132
+ secondary: "#A9E4C4",
133
+ muted: "#9A938C",
134
+ placeholder: "rgba(255,255,255,0.35)",
135
+ onBrand: "#0E1F17",
136
+ metaCool: "#C9C9C9"
137
+ },
138
+ primary: "#6BD39A",
139
+ onPrimary: "#0E1F17",
140
+ accent: "#6BD39A",
141
+ onAccent: "#0E1F17",
142
+ accentEdge: "#34D888",
143
+ success: "#07C168",
144
+ danger: "#B91C1C",
145
+ errorRed: "#FF1B00",
146
+ warningStrong: "#A45610",
147
+ cautionAccent: "#D9821D",
148
+ riskConcern: "#EFA700",
149
+ badgeBgPositive: "rgba(7,193,104,0.18)",
150
+ badgeBgCaution: "rgba(217,130,29,0.20)",
151
+ badgeBgCritical: "rgba(185,28,28,0.22)",
152
+ badgeBgNeutral: "rgba(255,255,255,0.10)",
153
+ bubbleUser: "#6BD39A",
154
+ bubbleAssistant: "#1C1F23",
155
+ skeleton: "#23272C",
156
+ scanButtonPink: "#FFC3BC",
157
+ checkupCardLowRiskBg: "rgba(7,193,104,0.16)",
158
+ checkupCardConcernBg: "rgba(239,167,0,0.16)"
159
+ };
160
+ deepFreeze({
161
+ brightness: "dark",
162
+ meta: { displayName: "Everfur", logoUrl: null, placeholder: null, hidePoweredBy: false },
163
+ color: DARK_COLOR,
164
+ space: SPACE,
165
+ radius: RADIUS,
166
+ type: baseType(),
167
+ motion: MOTION
168
+ });
169
+ var EVERFUR_THEME_CONTEXT_SYMBOL = /* @__PURE__ */ Symbol.for("@everfur/sdk#EverfurThemeContext@v1");
170
+ var globalThemeHost = globalThis;
171
+ var EverfurThemeContext = globalThemeHost[EVERFUR_THEME_CONTEXT_SYMBOL] ?? (globalThemeHost[EVERFUR_THEME_CONTEXT_SYMBOL] = react.createContext(EVERFUR_LIGHT));
172
+ EverfurThemeContext.displayName ??= "EverfurThemeContext";
173
+ function useEverfurTheme() {
174
+ return react.useContext(EverfurThemeContext);
175
+ }
176
+
177
+ // src/rn/facade.ts
178
+ var EVERFUR_CONTEXT_SYMBOL = /* @__PURE__ */ Symbol.for("@everfur/sdk#EverfurContext@v1");
179
+ var globalContextHost = globalThis;
180
+ var EverfurContext = globalContextHost[EVERFUR_CONTEXT_SYMBOL] ?? (globalContextHost[EVERFUR_CONTEXT_SYMBOL] = react.createContext(null));
181
+ EverfurContext.displayName ??= "EverfurContext";
182
+ function useEverfurContext() {
183
+ const ctx = react.useContext(EverfurContext);
184
+ if (ctx === null) {
185
+ throw new EverfurConfigError(
186
+ "not-initialized",
187
+ "Everfur hooks must be called inside <EverfurProvider>. Wrap your tree once, high."
188
+ );
189
+ }
190
+ return ctx;
191
+ }
192
+ var DOT_SIZE = 6;
193
+ var LOOP_MS = 520;
194
+ var STAGGER_MS = Math.round(LOOP_MS * 0.18);
195
+ var OPACITY_REST = 0.44;
196
+ var OPACITY_STATIC = 0.5;
197
+ var TRI_IN = [0, 0.5, 1];
198
+ var DOT_INDICES = [0, 1, 2];
199
+ function TypingIndicator() {
200
+ const theme = useEverfurTheme();
201
+ const styles = react.useMemo(() => makeStyles(theme), [theme]);
202
+ const animate = !theme.motion.reducedMotion;
203
+ return /* @__PURE__ */ jsxRuntime.jsx(
204
+ reactNative.View,
205
+ {
206
+ style: styles.card,
207
+ accessible: true,
208
+ accessibilityRole: "text",
209
+ accessibilityLabel: "Assistant is typing",
210
+ accessibilityLiveRegion: "polite",
211
+ accessibilityState: { busy: true },
212
+ children: DOT_INDICES.map(
213
+ (index) => animate ? /* @__PURE__ */ jsxRuntime.jsx(AnimatedDot, { index, style: styles.dot }, index) : /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles.dot, styles.dotStatic] }, index)
214
+ )
215
+ }
216
+ );
217
+ }
218
+ function AnimatedDot({ index, style }) {
219
+ const t = react.useRef(new reactNative.Animated.Value(0)).current;
220
+ react.useEffect(() => {
221
+ const anim = reactNative.Animated.sequence([
222
+ reactNative.Animated.delay(index * STAGGER_MS),
223
+ reactNative.Animated.loop(reactNative.Animated.timing(t, { toValue: 1, duration: LOOP_MS, useNativeDriver: true }))
224
+ ]);
225
+ anim.start();
226
+ return () => anim.stop();
227
+ }, [t, index]);
228
+ const opacity = t.interpolate({ inputRange: TRI_IN, outputRange: [OPACITY_REST, 1, OPACITY_REST] });
229
+ const translateY = t.interpolate({ inputRange: TRI_IN, outputRange: [0, -3.5, 0] });
230
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNative.Animated.View, { style: [style, { opacity, transform: [{ translateY }] }] });
231
+ }
232
+ function makeStyles(theme) {
233
+ const c = theme.color;
234
+ const s = theme.space;
235
+ const r = theme.radius;
236
+ return reactNative.StyleSheet.create({
237
+ card: {
238
+ alignSelf: "flex-start",
239
+ flexDirection: "row",
240
+ alignItems: "center",
241
+ gap: s.xs,
242
+ paddingHorizontal: s.md,
243
+ paddingVertical: s.sm,
244
+ backgroundColor: c.surfaceCream,
245
+ borderRadius: r.md,
246
+ borderWidth: reactNative.StyleSheet.hairlineWidth,
247
+ borderColor: c.brandBorder
248
+ },
249
+ dot: { width: DOT_SIZE, height: DOT_SIZE, borderRadius: r.pill, backgroundColor: c.brand },
250
+ dotStatic: { opacity: OPACITY_STATIC }
251
+ });
252
+ }
253
+ var ROTATION_PERIOD_MS = 1400;
254
+ var REVEAL_DELAY_MS = 300;
255
+ function AnalyzingIndicator() {
256
+ const theme = useEverfurTheme();
257
+ const styles = react.useMemo(() => makeStyles2(theme), [theme]);
258
+ const reduced = theme.motion.reducedMotion;
259
+ const [visible, setVisible] = react.useState(false);
260
+ react.useEffect(() => {
261
+ const id = setTimeout(() => setVisible(true), REVEAL_DELAY_MS);
262
+ return () => clearTimeout(id);
263
+ }, []);
264
+ const spin = react.useRef(new reactNative.Animated.Value(0)).current;
265
+ react.useEffect(() => {
266
+ if (reduced || !visible) return;
267
+ const loop = reactNative.Animated.loop(
268
+ reactNative.Animated.timing(spin, {
269
+ toValue: 1,
270
+ duration: ROTATION_PERIOD_MS,
271
+ easing: reactNative.Easing.linear,
272
+ useNativeDriver: true
273
+ })
274
+ );
275
+ loop.start();
276
+ return () => loop.stop();
277
+ }, [reduced, visible, spin]);
278
+ const arcMotionStyle = reduced ? null : { transform: [{ rotate: spin.interpolate({ inputRange: [0, 1], outputRange: ["0deg", "360deg"] }) }] };
279
+ return /* @__PURE__ */ jsxRuntime.jsx(
280
+ reactNative.View,
281
+ {
282
+ style: styles.wrap,
283
+ accessible: true,
284
+ accessibilityState: { busy: true },
285
+ accessibilityLabel: "Analyzing photo",
286
+ children: visible ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
287
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.Animated.View, { style: [styles.ring, arcMotionStyle] }),
288
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles.statusLine, children: "Analyzing" })
289
+ ] }) : null
290
+ }
291
+ );
292
+ }
293
+ function makeStyles2(theme) {
294
+ const { color, space, radius, type } = theme;
295
+ const medium = type.weight.medium;
296
+ const ringSize = space.xxl * 2;
297
+ const ringThickness = space.xs;
298
+ return reactNative.StyleSheet.create({
299
+ wrap: {
300
+ flexGrow: 1,
301
+ alignItems: "center",
302
+ justifyContent: "center",
303
+ padding: space.xl,
304
+ gap: space.md
305
+ },
306
+ // One rotating ring: success on the top/right, cream on the remainder. Only the success sweep is perceptible
307
+ // (the cream half is uniform), so this reads as a cream ring with a rotating success arc - the mobile look.
308
+ ring: {
309
+ width: ringSize,
310
+ height: ringSize,
311
+ borderRadius: radius.pill,
312
+ borderWidth: ringThickness,
313
+ borderTopColor: color.success,
314
+ borderRightColor: color.success,
315
+ borderBottomColor: color.borderRingCream,
316
+ borderLeftColor: color.borderRingCream
317
+ },
318
+ // Neutral SDK-owned structural status word (not clinical / product copy), on the brand-green secondary ramp
319
+ // so it sits in the same family as the verdict hero. Legible in both themes via the token.
320
+ statusLine: {
321
+ color: color.text.secondary,
322
+ fontFamily: type.family,
323
+ fontSize: type.size.subtitle,
324
+ lineHeight: type.size.subtitle * type.lineHeight.snug,
325
+ fontWeight: medium,
326
+ letterSpacing: type.letterSpacing.tight,
327
+ textAlign: "center"
328
+ }
329
+ });
330
+ }
331
+ var PULSE_PERIOD_MS = 1100;
332
+ var PULSE_MAX_SCALE = 1.6;
333
+ var PULSE_START_OPACITY = 0.35;
334
+ function toneSpec(theme, tier) {
335
+ const { color } = theme;
336
+ switch (tier) {
337
+ case "low_risk":
338
+ return { accent: color.success, wash: color.badgeBgPositive, label: "Low risk", pulse: false };
339
+ case "concern":
340
+ return { accent: color.cautionAccent, wash: color.badgeBgCaution, label: "Concern", pulse: true };
341
+ case "uncertain":
342
+ return { accent: color.text.muted, wash: color.badgeBgNeutral, label: "Uncertain", pulse: false };
343
+ }
344
+ }
345
+ function SeverityBadge({ riskTier }) {
346
+ const theme = useEverfurTheme();
347
+ const styles = react.useMemo(() => makeStyles3(theme), [theme]);
348
+ const pulse = react.useRef(new reactNative.Animated.Value(0)).current;
349
+ const spec = riskTier === null ? null : toneSpec(theme, riskTier);
350
+ const shouldPulse = spec !== null && spec.pulse && !theme.motion.reducedMotion;
351
+ react.useEffect(() => {
352
+ if (!shouldPulse) return;
353
+ const loop = reactNative.Animated.loop(
354
+ reactNative.Animated.timing(pulse, {
355
+ toValue: 1,
356
+ duration: PULSE_PERIOD_MS,
357
+ easing: reactNative.Easing.out(reactNative.Easing.quad),
358
+ useNativeDriver: true
359
+ })
360
+ );
361
+ loop.start();
362
+ return () => loop.stop();
363
+ }, [shouldPulse, pulse]);
364
+ if (spec === null) return null;
365
+ return /* @__PURE__ */ jsxRuntime.jsxs(
366
+ reactNative.View,
367
+ {
368
+ style: [styles.pill, { backgroundColor: spec.wash }],
369
+ accessible: true,
370
+ accessibilityRole: "text",
371
+ accessibilityLabel: spec.label,
372
+ children: [
373
+ /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles.dotWrap, children: [
374
+ shouldPulse ? /* @__PURE__ */ jsxRuntime.jsx(
375
+ reactNative.Animated.View,
376
+ {
377
+ pointerEvents: "none",
378
+ style: [
379
+ styles.dotRing,
380
+ {
381
+ backgroundColor: spec.accent,
382
+ opacity: pulse.interpolate({ inputRange: [0, 1], outputRange: [PULSE_START_OPACITY, 0] }),
383
+ transform: [{ scale: pulse.interpolate({ inputRange: [0, 1], outputRange: [1, PULSE_MAX_SCALE] }) }]
384
+ }
385
+ ]
386
+ }
387
+ ) : null,
388
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles.dot, { backgroundColor: spec.accent }] })
389
+ ] }),
390
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles.label, { color: spec.accent }], children: spec.label })
391
+ ]
392
+ }
393
+ );
394
+ }
395
+ function makeStyles3(theme) {
396
+ const { space, radius, type } = theme;
397
+ const bold = type.weight.bold;
398
+ const dotSize = space.sm;
399
+ return reactNative.StyleSheet.create({
400
+ pill: {
401
+ alignSelf: "flex-start",
402
+ flexDirection: "row",
403
+ alignItems: "center",
404
+ gap: space.sm,
405
+ paddingHorizontal: space.md,
406
+ paddingVertical: space.xs,
407
+ borderRadius: radius.pill
408
+ },
409
+ dotWrap: {
410
+ width: dotSize,
411
+ height: dotSize,
412
+ alignItems: "center",
413
+ justifyContent: "center"
414
+ },
415
+ dot: {
416
+ width: dotSize,
417
+ height: dotSize,
418
+ borderRadius: radius.pill
419
+ },
420
+ // The pulsing attention ring behind the dot (concern only). backgroundColor + animated opacity/scale set inline.
421
+ dotRing: {
422
+ position: "absolute",
423
+ width: dotSize,
424
+ height: dotSize,
425
+ borderRadius: radius.pill
426
+ },
427
+ label: {
428
+ fontFamily: type.family,
429
+ fontSize: type.size.caption,
430
+ lineHeight: type.size.caption * type.lineHeight.snug,
431
+ fontWeight: bold,
432
+ letterSpacing: type.letterSpacing.eyebrow
433
+ }
434
+ });
435
+ }
436
+
437
+ // src/rn/testing.ts
438
+ function useEverfurTestEntitlements() {
439
+ const { runtime } = useEverfurContext();
440
+ return react.useMemo(
441
+ () => ({ apply: (snapshot) => runtime.updateEntitlements(snapshot) }),
442
+ [runtime]
443
+ );
444
+ }
445
+
446
+ exports.AnalyzingIndicator = AnalyzingIndicator;
447
+ exports.SeverityBadge = SeverityBadge;
448
+ exports.TypingIndicator = TypingIndicator;
449
+ exports.useEverfurTestEntitlements = useEverfurTestEntitlements;
@@ -0,0 +1,49 @@
1
+ import { h as EntitlementSnapshot } from '../../runtime-BgQnA594.cjs';
2
+ export { C as ClientBranding } from '../../petsRepository-BEGb97M9.cjs';
3
+ export { a as CapabilityDisabled, c as DisabledLevel, E as EntitlementDecision } from '../../resolve-Dq_4_agU.cjs';
4
+ import { ReactNode } from 'react';
5
+ import { R as RiskTier } from '../../PhotoController-BItt5M7u.cjs';
6
+ import '../../EverfurResult-D92-uL82.cjs';
7
+ import '../../identity-Brl-lDd6.cjs';
8
+ import '../../ids-CJ1S6adf.cjs';
9
+ import '../../config-BSjBdxrZ.cjs';
10
+ import '../../cacheEpoch-DknKn3S0.cjs';
11
+ import '../../TelemetryPort-BDNr00hu.cjs';
12
+ import '../../ChatController-CpUMvvZf.cjs';
13
+ import '../../requestFunnel-DuUH-kAe.cjs';
14
+ import '../../FilePort-BabWrv7I.cjs';
15
+ import '../../CameraPort-Cv31Pz7g.cjs';
16
+ import '../../projection-CeIUsbSk.cjs';
17
+
18
+ /**
19
+ * The streaming "assistant is thinking" indicator: animated three-dot bounce under normal motion, three
20
+ * static dots under reduced motion. Pure / presentational -- takes no data, reads only theme tokens.
21
+ */
22
+ declare function TypingIndicator(): ReactNode;
23
+
24
+ /** The busy analyzing indicator: a rotating success arc over a cream ring + a neutral SDK status line. */
25
+ declare function AnalyzingIndicator(): ReactNode;
26
+
27
+ /** A tone-driven severity pill for the BE-owned riskTier. Renders nothing when the tier is null. */
28
+ declare function SeverityBadge({ riskTier }: {
29
+ readonly riskTier: RiskTier | null;
30
+ }): ReactNode;
31
+
32
+ /** The testing seam handle: apply a resolved verdict to THIS provider's runtime. */
33
+ interface EverfurTestEntitlements {
34
+ /**
35
+ * Replace the entitlement verdict the current <EverfurProvider>'s runtime renders. Drives the SDK's own
36
+ * `useCapability` / `CapabilityGate` across every subpath (they read this one store), so a test/demo can
37
+ * flip a capability on or off and watch the real gates react. Render-only: the server stays authoritative.
38
+ */
39
+ apply(snapshot: EntitlementSnapshot): void;
40
+ }
41
+ /**
42
+ * TEST / DEMO ONLY. Obtain a handle to push a simulated server entitlement verdict into the enclosing
43
+ * <EverfurProvider>'s runtime. Must be called inside an <EverfurProvider>.
44
+ *
45
+ * @throws {EverfurConfigError} kind 'not-initialized' when called outside an <EverfurProvider>.
46
+ */
47
+ declare function useEverfurTestEntitlements(): EverfurTestEntitlements;
48
+
49
+ export { AnalyzingIndicator, EntitlementSnapshot, type EverfurTestEntitlements, RiskTier, SeverityBadge, TypingIndicator, useEverfurTestEntitlements };
@@ -0,0 +1,49 @@
1
+ import { h as EntitlementSnapshot } from '../../runtime-CBA-LvdM.js';
2
+ export { C as ClientBranding } from '../../petsRepository-Bu18r2kK.js';
3
+ export { a as CapabilityDisabled, c as DisabledLevel, E as EntitlementDecision } from '../../resolve-Dq_4_agU.js';
4
+ import { ReactNode } from 'react';
5
+ import { R as RiskTier } from '../../PhotoController-D8zMTdcW.js';
6
+ import '../../EverfurResult-D92-uL82.js';
7
+ import '../../identity-DK9zORrG.js';
8
+ import '../../ids-CJ1S6adf.js';
9
+ import '../../config-CiJ0PVBB.js';
10
+ import '../../cacheEpoch-DknKn3S0.js';
11
+ import '../../TelemetryPort-BDNr00hu.js';
12
+ import '../../ChatController-CKdBvPj2.js';
13
+ import '../../requestFunnel-dio5OmR9.js';
14
+ import '../../FilePort-BabWrv7I.js';
15
+ import '../../CameraPort-Cv31Pz7g.js';
16
+ import '../../projection-CeIUsbSk.js';
17
+
18
+ /**
19
+ * The streaming "assistant is thinking" indicator: animated three-dot bounce under normal motion, three
20
+ * static dots under reduced motion. Pure / presentational -- takes no data, reads only theme tokens.
21
+ */
22
+ declare function TypingIndicator(): ReactNode;
23
+
24
+ /** The busy analyzing indicator: a rotating success arc over a cream ring + a neutral SDK status line. */
25
+ declare function AnalyzingIndicator(): ReactNode;
26
+
27
+ /** A tone-driven severity pill for the BE-owned riskTier. Renders nothing when the tier is null. */
28
+ declare function SeverityBadge({ riskTier }: {
29
+ readonly riskTier: RiskTier | null;
30
+ }): ReactNode;
31
+
32
+ /** The testing seam handle: apply a resolved verdict to THIS provider's runtime. */
33
+ interface EverfurTestEntitlements {
34
+ /**
35
+ * Replace the entitlement verdict the current <EverfurProvider>'s runtime renders. Drives the SDK's own
36
+ * `useCapability` / `CapabilityGate` across every subpath (they read this one store), so a test/demo can
37
+ * flip a capability on or off and watch the real gates react. Render-only: the server stays authoritative.
38
+ */
39
+ apply(snapshot: EntitlementSnapshot): void;
40
+ }
41
+ /**
42
+ * TEST / DEMO ONLY. Obtain a handle to push a simulated server entitlement verdict into the enclosing
43
+ * <EverfurProvider>'s runtime. Must be called inside an <EverfurProvider>.
44
+ *
45
+ * @throws {EverfurConfigError} kind 'not-initialized' when called outside an <EverfurProvider>.
46
+ */
47
+ declare function useEverfurTestEntitlements(): EverfurTestEntitlements;
48
+
49
+ export { AnalyzingIndicator, EntitlementSnapshot, type EverfurTestEntitlements, RiskTier, SeverityBadge, TypingIndicator, useEverfurTestEntitlements };