@appilots/sdk 0.13.0 → 0.14.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.
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var chunkALJGKORS_js = require('./chunk-ALJGKORS.js');
4
- var chunkAJDHZRBN_js = require('./chunk-AJDHZRBN.js');
5
- var chunkUZ2D4BVX_js = require('./chunk-UZ2D4BVX.js');
3
+ var chunkGDCBLSYT_js = require('./chunk-GDCBLSYT.js');
4
+ var chunkJGUDXRXN_js = require('./chunk-JGUDXRXN.js');
5
+ var chunkQAZ4TN3Z_js = require('./chunk-QAZ4TN3Z.js');
6
6
  var React8 = require('react');
7
7
  var reactNative = require('react-native');
8
8
  var reactNativeSafeAreaContext = require('react-native-safe-area-context');
@@ -45,15 +45,15 @@ function useSafeAreaInsetsOrDefault() {
45
45
  return NO_INSETS;
46
46
  }
47
47
  function probeHostModalOpen() {
48
- const stack = [chunkUZ2D4BVX_js.getFiberRoot()];
48
+ const stack = [chunkQAZ4TN3Z_js.getFiberRoot()];
49
49
  const seen = /* @__PURE__ */ new Set();
50
50
  while (stack.length) {
51
51
  const node = stack.pop();
52
52
  if (!node || seen.has(node)) continue;
53
53
  seen.add(node);
54
54
  if (node.sibling) stack.push(node.sibling);
55
- if (chunkUZ2D4BVX_js.shouldSkipSubtree(node)) continue;
56
- if (chunkUZ2D4BVX_js.isModalFiber(node) && node.child) return true;
55
+ if (chunkQAZ4TN3Z_js.shouldSkipSubtree(node)) continue;
56
+ if (chunkQAZ4TN3Z_js.isModalFiber(node) && node.child) return true;
57
57
  if (node.child) stack.push(node.child);
58
58
  }
59
59
  return false;
@@ -84,14 +84,14 @@ function useHostModalOpen(enabled) {
84
84
 
85
85
  // src/components/breadcrumbPresentation.ts
86
86
  var DEFAULT_BREADCRUMB_PALETTE = {
87
- primary: chunkUZ2D4BVX_js.defaultLightTheme.colors.primary,
88
- text: chunkUZ2D4BVX_js.defaultLightTheme.colors.text,
89
- textSecondary: chunkUZ2D4BVX_js.defaultLightTheme.colors.textSecondary,
90
- surface: chunkUZ2D4BVX_js.defaultLightTheme.colors.surface,
91
- border: chunkUZ2D4BVX_js.defaultLightTheme.colors.border,
92
- success: chunkUZ2D4BVX_js.defaultLightTheme.colors.success,
93
- warning: chunkUZ2D4BVX_js.defaultLightTheme.colors.warning,
94
- error: chunkUZ2D4BVX_js.defaultLightTheme.colors.error
87
+ primary: chunkQAZ4TN3Z_js.defaultLightTheme.colors.primary,
88
+ text: chunkQAZ4TN3Z_js.defaultLightTheme.colors.text,
89
+ textSecondary: chunkQAZ4TN3Z_js.defaultLightTheme.colors.textSecondary,
90
+ surface: chunkQAZ4TN3Z_js.defaultLightTheme.colors.surface,
91
+ border: chunkQAZ4TN3Z_js.defaultLightTheme.colors.border,
92
+ success: chunkQAZ4TN3Z_js.defaultLightTheme.colors.success,
93
+ warning: chunkQAZ4TN3Z_js.defaultLightTheme.colors.warning,
94
+ error: chunkQAZ4TN3Z_js.defaultLightTheme.colors.error
95
95
  };
96
96
  var KNOWN_TINTS = {
97
97
  [DEFAULT_BREADCRUMB_PALETTE.primary.toUpperCase()]: "#EEF2FF",
@@ -138,13 +138,15 @@ var PT_BR_CONFIRM_FALLBACK = {
138
138
  confirmDestructiveApprove: "Sim, executar",
139
139
  confirmApprove: "Confirmar",
140
140
  confirmCancel: "Cancelar",
141
- confirmThisAction: "esta a\xE7\xE3o"
141
+ confirmThisAction: "esta a\xE7\xE3o",
142
+ confirmExpired: "Esta confirma\xE7\xE3o expirou. Pe\xE7a de novo ao assistente para continuar."
142
143
  };
143
144
  function deriveConfirmCardContent(action, palette = DEFAULT_BREADCRUMB_PALETTE, strings) {
144
145
  const payload = action.payload ?? {};
145
146
  const isDestructive = isDestructiveAction(action);
146
147
  const copy = { ...PT_BR_CONFIRM_FALLBACK, ...strings ?? {} };
147
- const actionName = typeof payload.actionDescription === "string" && payload.actionDescription || copy.confirmThisAction;
148
+ const described = typeof payload.actionDescription === "string" ? payload.actionDescription : "";
149
+ const actionName = described || copy.confirmThisAction;
148
150
  const message = typeof payload.message === "string" && payload.message || copy.confirmMessage.replace("{action}", actionName);
149
151
  const title = typeof payload.title === "string" && payload.title || (isDestructive ? copy.confirmDestructiveTitle : copy.confirmTitle);
150
152
  const confirmLabel = typeof payload.confirmLabel === "string" && payload.confirmLabel || (isDestructive ? copy.confirmDestructiveApprove : copy.confirmApprove);
@@ -155,6 +157,10 @@ function deriveConfirmCardContent(action, palette = DEFAULT_BREADCRUMB_PALETTE,
155
157
  message,
156
158
  confirmLabel,
157
159
  cancelLabel,
160
+ // A bare "Confirm" heard out of context says nothing about what it does.
161
+ confirmA11yLabel: described ? `${confirmLabel}: ${described}` : confirmLabel,
162
+ cancelA11yLabel: described ? `${cancelLabel}: ${described}` : cancelLabel,
163
+ expiredMessage: copy.confirmExpired ?? PT_BR_CONFIRM_FALLBACK.confirmExpired,
158
164
  glyph: isDestructive ? "\u26A0" : "?",
159
165
  actionColor: isDestructive ? palette.error : palette.primary,
160
166
  cardBackground: palette.surface,
@@ -164,6 +170,79 @@ function deriveConfirmCardContent(action, palette = DEFAULT_BREADCRUMB_PALETTE,
164
170
  cancelTextColor: palette.textSecondary
165
171
  };
166
172
  }
173
+ var TARGET_ANNOUNCEMENT = {
174
+ "pt-BR": {
175
+ press: "Tocando em {label}",
176
+ toggle: "Alternando {label}",
177
+ focus: "Selecionando {label}",
178
+ fill: "Preenchendo {label}"
179
+ },
180
+ en: {
181
+ press: "Tapping {label}",
182
+ toggle: "Toggling {label}",
183
+ focus: "Selecting {label}",
184
+ fill: "Filling in {label}"
185
+ },
186
+ es: {
187
+ press: "Tocando {label}",
188
+ toggle: "Cambiando {label}",
189
+ focus: "Seleccionando {label}",
190
+ fill: "Rellenando {label}"
191
+ },
192
+ fr: {
193
+ press: "Appui sur {label}",
194
+ toggle: "Bascule de {label}",
195
+ focus: "S\xE9lection de {label}",
196
+ fill: "Saisie de {label}"
197
+ }
198
+ };
199
+ function targetAnnouncement(verb, label, locale = "pt-BR") {
200
+ return (TARGET_ANNOUNCEMENT[locale] ?? TARGET_ANNOUNCEMENT["pt-BR"])[verb].replace(
201
+ "{label}",
202
+ label
203
+ );
204
+ }
205
+ function executorNamesTarget(action) {
206
+ if (action.type === "form_fill") return true;
207
+ if (action.type !== "ui_interaction") return false;
208
+ const interaction = action.payload?.action;
209
+ return !["scroll", "scroll_to"].includes(String(interaction ?? "press"));
210
+ }
211
+ function actionAnnouncement(action, locale, named) {
212
+ const { state, label } = chunkQAZ4TN3Z_js.describeAction(action, locale);
213
+ if (state === "failed") return label;
214
+ const executorNames = executorNamesTarget(action);
215
+ if (state === "running") return executorNames ? null : label;
216
+ if (state === "success") return executorNames && !named ? label : null;
217
+ return null;
218
+ }
219
+ var reduceMotion = false;
220
+ var listeners = /* @__PURE__ */ new Set();
221
+ var subscription;
222
+ function set(value) {
223
+ if (value === reduceMotion) return;
224
+ reduceMotion = value;
225
+ for (const listener of listeners) listener();
226
+ }
227
+ function subscribe(onChange) {
228
+ listeners.add(onChange);
229
+ if (!subscription) {
230
+ subscription = reactNative.AccessibilityInfo.addEventListener("reduceMotionChanged", set);
231
+ reactNative.AccessibilityInfo.isReduceMotionEnabled().then(set, () => {
232
+ });
233
+ }
234
+ return () => {
235
+ listeners.delete(onChange);
236
+ if (listeners.size === 0) {
237
+ subscription?.remove();
238
+ subscription = void 0;
239
+ }
240
+ };
241
+ }
242
+ var get = () => reduceMotion;
243
+ function useReduceMotion() {
244
+ return React8.useSyncExternalStore(subscribe, get, get);
245
+ }
167
246
 
168
247
  // src/components/ActionBreadcrumb.tsx
169
248
  function ActionBreadcrumb({
@@ -176,7 +255,8 @@ function ActionBreadcrumb({
176
255
  locale,
177
256
  requireApprovalFor,
178
257
  onApprove,
179
- onReject
258
+ onReject,
259
+ onConfirmCardGone
180
260
  }) {
181
261
  if (actions.length === 0) return null;
182
262
  const resolvedPalette = {
@@ -198,7 +278,8 @@ function ActionBreadcrumb({
198
278
  locale,
199
279
  needsApproval: requireApprovalFor?.(action) ?? false,
200
280
  onApprove,
201
- onReject
281
+ onReject,
282
+ onConfirmCardGone
202
283
  }
203
284
  )));
204
285
  }
@@ -213,7 +294,8 @@ function BreadcrumbRow(props) {
213
294
  fontFamily: props.fontFamily,
214
295
  confirmStrings: props.confirmStrings,
215
296
  onApprove: props.onApprove,
216
- onReject: props.onReject
297
+ onReject: props.onReject,
298
+ onGone: props.onConfirmCardGone
217
299
  }
218
300
  );
219
301
  }
@@ -230,45 +312,44 @@ function RegularBreadcrumbRow({
230
312
  onApprove,
231
313
  onReject
232
314
  }) {
233
- const { label, state } = chunkUZ2D4BVX_js.describeAction(action, locale);
315
+ const { label, state } = chunkQAZ4TN3Z_js.describeAction(action, locale);
234
316
  const tone = deriveStateTone(palette)[state];
235
317
  const fade = React8.useRef(new reactNative.Animated.Value(0)).current;
236
318
  const pulse = React8.useRef(new reactNative.Animated.Value(1)).current;
237
319
  const lastState = React8.useRef(state);
320
+ const reduceMotion2 = useReduceMotion();
238
321
  React8.useEffect(() => {
322
+ if (reduceMotion2) {
323
+ fade.setValue(1);
324
+ return;
325
+ }
239
326
  reactNative.Animated.timing(fade, {
240
327
  toValue: 1,
241
328
  duration: 180,
242
329
  useNativeDriver: true
243
330
  }).start();
244
- }, [fade]);
331
+ }, [fade, reduceMotion2]);
245
332
  React8.useEffect(() => {
246
333
  if (lastState.current === state) return;
247
334
  lastState.current = state;
335
+ if (reduceMotion2) return;
248
336
  pulse.setValue(0.4);
249
337
  reactNative.Animated.timing(pulse, {
250
338
  toValue: 1,
251
339
  duration: 220,
252
340
  useNativeDriver: true
253
341
  }).start();
254
- }, [state, pulse]);
342
+ }, [state, pulse, reduceMotion2]);
255
343
  const isDestructive = isDestructiveAction(action);
256
- return /* @__PURE__ */ React8__namespace.default.createElement(reactNative.Animated.View, { style: [styles.row, { opacity: fade }] }, /* @__PURE__ */ React8__namespace.default.createElement(
257
- reactNative.Animated.View,
344
+ return /* @__PURE__ */ React8__namespace.default.createElement(reactNative.Animated.View, { style: [styles.row, { opacity: fade }] }, /* @__PURE__ */ React8__namespace.default.createElement(reactNative.Animated.View, { style: [styles.labelGroup, { opacity: pulse }] }, /* @__PURE__ */ React8__namespace.default.createElement(StateIcon, { state, tone, primaryColor }), /* @__PURE__ */ React8__namespace.default.createElement(
345
+ reactNative.Text,
258
346
  {
259
- style: { opacity: pulse, flexDirection: "row", alignItems: "flex-start", flex: 1 }
347
+ style: [styles.label, { color: state === "failed" ? tone.color : textColor, fontFamily }],
348
+ accessibilityLabel: `${state}: ${label}`
260
349
  },
261
- /* @__PURE__ */ React8__namespace.default.createElement(StateIcon, { state, tone, primaryColor }),
262
- /* @__PURE__ */ React8__namespace.default.createElement(
263
- reactNative.Text,
264
- {
265
- style: [styles.label, { color: state === "failed" ? tone.color : textColor, fontFamily }],
266
- accessibilityLabel: `${state}: ${label}`
267
- },
268
- label,
269
- isDestructive && /* @__PURE__ */ React8__namespace.default.createElement(reactNative.Text, { style: [styles.destructiveTag, { color: palette.error }] }, " \u26A0 destrutiva")
270
- )
271
- ), needsApproval && action.status === "pending" && onApprove && onReject && /* @__PURE__ */ React8__namespace.default.createElement(reactNative.View, { style: styles.approvalButtons }, /* @__PURE__ */ React8__namespace.default.createElement(
350
+ label,
351
+ isDestructive && /* @__PURE__ */ React8__namespace.default.createElement(reactNative.Text, { style: [styles.destructiveTag, { color: palette.error }] }, " \u26A0 destrutiva")
352
+ )), needsApproval && action.status === "pending" && onApprove && onReject && /* @__PURE__ */ React8__namespace.default.createElement(reactNative.View, { style: styles.approvalButtons }, /* @__PURE__ */ React8__namespace.default.createElement(
272
353
  reactNative.TouchableOpacity,
273
354
  {
274
355
  onPress: () => onReject(action.id),
@@ -290,13 +371,15 @@ function RegularBreadcrumbRow({
290
371
  /* @__PURE__ */ React8__namespace.default.createElement(reactNative.Text, { style: styles.approveBtnText }, "Aprovar")
291
372
  )));
292
373
  }
374
+ var MIN_TOUCH_TARGET = 44;
293
375
  function ConfirmCard({
294
376
  action,
295
377
  palette,
296
378
  fontFamily,
297
379
  confirmStrings,
298
380
  onApprove,
299
- onReject
381
+ onReject,
382
+ onGone
300
383
  }) {
301
384
  const {
302
385
  isDestructive,
@@ -304,6 +387,9 @@ function ConfirmCard({
304
387
  message,
305
388
  confirmLabel,
306
389
  cancelLabel,
390
+ confirmA11yLabel,
391
+ cancelA11yLabel,
392
+ expiredMessage,
307
393
  glyph,
308
394
  actionColor,
309
395
  cardBackground,
@@ -312,6 +398,23 @@ function ConfirmCard({
312
398
  cancelBackground,
313
399
  cancelTextColor
314
400
  } = deriveConfirmCardContent(action, palette, confirmStrings);
401
+ const summaryRef = React8.useRef(null);
402
+ const expiresAt = chunkQAZ4TN3Z_js.confirmExpiresAt(action);
403
+ const [expired, setExpired] = React8.useState(() => expiresAt !== void 0 && expiresAt <= Date.now());
404
+ const onGoneRef = React8.useRef(onGone);
405
+ onGoneRef.current = onGone;
406
+ React8.useEffect(() => {
407
+ if (summaryRef.current) reactNative.AccessibilityInfo.sendAccessibilityEvent(summaryRef.current, "focus");
408
+ return () => onGoneRef.current?.();
409
+ }, []);
410
+ React8.useEffect(() => {
411
+ if (expiresAt === void 0 || expired) return;
412
+ const timer = setTimeout(() => setExpired(true), expiresAt - Date.now());
413
+ return () => clearTimeout(timer);
414
+ }, [expiresAt, expired]);
415
+ React8.useEffect(() => {
416
+ if (expired) reactNative.AccessibilityInfo.announceForAccessibility(expiredMessage);
417
+ }, [expired, expiredMessage]);
315
418
  return /* @__PURE__ */ React8__namespace.default.createElement(
316
419
  reactNative.View,
317
420
  {
@@ -319,26 +422,46 @@ function ConfirmCard({
319
422
  confirmCardStyles.card,
320
423
  { backgroundColor: cardBackground, borderColor: cardBorderColor }
321
424
  ],
322
- testID: "assistant-confirm-card"
425
+ testID: "assistant-confirm-card",
426
+ onAccessibilityEscape: () => onReject?.(action.id)
323
427
  },
324
- /* @__PURE__ */ React8__namespace.default.createElement(reactNative.View, { style: confirmCardStyles.headerRow }, /* @__PURE__ */ React8__namespace.default.createElement(reactNative.Text, { style: [confirmCardStyles.glyph, { color: actionColor }] }, glyph), /* @__PURE__ */ React8__namespace.default.createElement(
428
+ /* @__PURE__ */ React8__namespace.default.createElement(
429
+ reactNative.View,
430
+ {
431
+ ref: summaryRef,
432
+ accessible: true,
433
+ accessibilityLabel: `${title}. ${message}`,
434
+ accessibilityLiveRegion: "polite"
435
+ },
436
+ /* @__PURE__ */ React8__namespace.default.createElement(reactNative.View, { style: confirmCardStyles.headerRow }, /* @__PURE__ */ React8__namespace.default.createElement(reactNative.Text, { style: [confirmCardStyles.glyph, { color: actionColor }] }, glyph), /* @__PURE__ */ React8__namespace.default.createElement(
437
+ reactNative.Text,
438
+ {
439
+ style: [
440
+ confirmCardStyles.title,
441
+ { color: isDestructive ? palette.error : palette.text, fontFamily }
442
+ ]
443
+ },
444
+ title
445
+ )),
446
+ /* @__PURE__ */ React8__namespace.default.createElement(reactNative.Text, { style: [confirmCardStyles.message, { color: messageColor, fontFamily }] }, message)
447
+ ),
448
+ expired && /* @__PURE__ */ React8__namespace.default.createElement(
325
449
  reactNative.Text,
326
450
  {
327
- style: [
328
- confirmCardStyles.title,
329
- { color: isDestructive ? palette.error : palette.text, fontFamily }
330
- ]
451
+ style: [confirmCardStyles.expired, { color: palette.error, fontFamily }],
452
+ accessibilityLiveRegion: "assertive",
453
+ testID: "assistant-confirm-expired"
331
454
  },
332
- title
333
- )),
334
- /* @__PURE__ */ React8__namespace.default.createElement(reactNative.Text, { style: [confirmCardStyles.message, { color: messageColor, fontFamily }] }, message),
455
+ expiredMessage
456
+ ),
335
457
  /* @__PURE__ */ React8__namespace.default.createElement(reactNative.View, { style: confirmCardStyles.buttons }, /* @__PURE__ */ React8__namespace.default.createElement(
336
458
  reactNative.TouchableOpacity,
337
459
  {
338
460
  onPress: () => onReject?.(action.id),
339
461
  style: [confirmCardStyles.btn, { backgroundColor: cancelBackground }],
340
462
  activeOpacity: 0.7,
341
- accessibilityLabel: cancelLabel,
463
+ accessibilityRole: "button",
464
+ accessibilityLabel: cancelA11yLabel,
342
465
  testID: "assistant-confirm-reject"
343
466
  },
344
467
  /* @__PURE__ */ React8__namespace.default.createElement(reactNative.Text, { style: [confirmCardStyles.cancelText, { color: cancelTextColor, fontFamily }] }, cancelLabel)
@@ -346,13 +469,17 @@ function ConfirmCard({
346
469
  reactNative.TouchableOpacity,
347
470
  {
348
471
  onPress: () => onApprove?.(action.id),
472
+ disabled: expired,
349
473
  style: [
350
474
  confirmCardStyles.btn,
351
475
  confirmCardStyles.confirmBtn,
352
- { backgroundColor: actionColor }
476
+ { backgroundColor: actionColor },
477
+ expired && confirmCardStyles.disabledBtn
353
478
  ],
354
479
  activeOpacity: 0.7,
355
- accessibilityLabel: confirmLabel,
480
+ accessibilityRole: "button",
481
+ accessibilityState: { disabled: expired },
482
+ accessibilityLabel: confirmA11yLabel,
356
483
  testID: "assistant-confirm-approve"
357
484
  },
358
485
  /* @__PURE__ */ React8__namespace.default.createElement(reactNative.Text, { style: [confirmCardStyles.confirmText, { fontFamily }] }, confirmLabel)
@@ -389,18 +516,33 @@ var confirmCardStyles = reactNative.StyleSheet.create({
389
516
  // color set inline — theme-driven (textSecondary).
390
517
  marginBottom: 12
391
518
  },
519
+ // Wraps: on one line the two buttons ran off the LEFT edge at iOS AX5
520
+ // and Cancel was unreachable — on the one card that gates something
521
+ // irreversible.
392
522
  buttons: {
393
523
  flexDirection: "row",
524
+ flexWrap: "wrap",
394
525
  gap: 8,
395
526
  justifyContent: "flex-end"
396
527
  },
397
528
  btn: {
529
+ minHeight: MIN_TOUCH_TARGET,
530
+ maxWidth: "100%",
531
+ justifyContent: "center",
398
532
  paddingHorizontal: 14,
399
533
  paddingVertical: 8,
400
534
  borderRadius: 10,
401
535
  minWidth: 96,
402
536
  alignItems: "center"
403
537
  },
538
+ disabledBtn: {
539
+ opacity: 0.4
540
+ },
541
+ expired: {
542
+ fontSize: 13,
543
+ fontWeight: "600",
544
+ marginBottom: 12
545
+ },
404
546
  cancelText: {
405
547
  fontSize: 13,
406
548
  fontWeight: "600"
@@ -420,7 +562,11 @@ function StateIcon({
420
562
  tone,
421
563
  primaryColor
422
564
  }) {
423
- return /* @__PURE__ */ React8__namespace.default.createElement(reactNative.View, { style: [styles.iconCircle, { backgroundColor: tone.iconBg }] }, state === "running" ? /* @__PURE__ */ React8__namespace.default.createElement(reactNative.ActivityIndicator, { size: "small", color: primaryColor }) : /* @__PURE__ */ React8__namespace.default.createElement(reactNative.Text, { style: [styles.iconGlyph, { color: tone.color }] }, iconGlyphFor(state)));
565
+ return /* @__PURE__ */ React8__namespace.default.createElement(reactNative.View, { style: [styles.iconCircle, { backgroundColor: tone.iconBg }] }, state === "running" ? /* @__PURE__ */ React8__namespace.default.createElement(reactNative.ActivityIndicator, { size: "small", color: primaryColor }) : (
566
+ // Decorative, inside a fixed circle: capped so it cannot clip. The
567
+ // state is also in the row's accessibilityLabel.
568
+ /* @__PURE__ */ React8__namespace.default.createElement(reactNative.Text, { maxFontSizeMultiplier: 1.3, style: [styles.iconGlyph, { color: tone.color }] }, iconGlyphFor(state))
569
+ ));
424
570
  }
425
571
  var styles = reactNative.StyleSheet.create({
426
572
  container: {
@@ -428,12 +574,26 @@ var styles = reactNative.StyleSheet.create({
428
574
  marginBottom: 8,
429
575
  paddingVertical: 4
430
576
  },
577
+ // Wraps so Approve/Reject drop below the label at large text sizes. On
578
+ // one line they squeezed the label to zero width (iOS AX5): the user was
579
+ // asked to approve an action they could not read.
431
580
  row: {
432
581
  flexDirection: "row",
582
+ flexWrap: "wrap",
583
+ gap: 8,
433
584
  alignItems: "center",
434
585
  paddingVertical: 6,
435
586
  paddingHorizontal: 4
436
587
  },
588
+ labelGroup: {
589
+ flexDirection: "row",
590
+ alignItems: "flex-start",
591
+ flexGrow: 1,
592
+ flexShrink: 1,
593
+ flexBasis: 0,
594
+ // What forces the wrap: the label keeps at least half the row.
595
+ minWidth: "50%"
596
+ },
437
597
  iconCircle: {
438
598
  width: 22,
439
599
  height: 22,
@@ -461,9 +621,11 @@ var styles = reactNative.StyleSheet.create({
461
621
  approvalButtons: {
462
622
  flexDirection: "row",
463
623
  gap: 6,
464
- marginLeft: 8
624
+ marginLeft: "auto"
465
625
  },
466
626
  btn: {
627
+ minHeight: MIN_TOUCH_TARGET,
628
+ justifyContent: "center",
467
629
  paddingHorizontal: 10,
468
630
  paddingVertical: 5,
469
631
  borderRadius: 8
@@ -527,6 +689,7 @@ var APPILOTS_SKIP_PROPS = {
527
689
  };
528
690
 
529
691
  // src/components/AgentPill.tsx
692
+ var PILL_MAX_FONT_SCALE = 1.5;
530
693
  function toneFor(state, colors) {
531
694
  switch (state) {
532
695
  case "success":
@@ -541,6 +704,7 @@ function AgentPill({
541
704
  label,
542
705
  state,
543
706
  onExpand,
707
+ expandRef,
544
708
  onStop,
545
709
  position,
546
710
  insets,
@@ -549,15 +713,20 @@ function AgentPill({
549
713
  strings
550
714
  }) {
551
715
  const atTop = position === "top-left" || position === "top-right";
716
+ const reduceMotion2 = useReduceMotion();
552
717
  const enter = React8.useRef(new reactNative.Animated.Value(0)).current;
553
718
  React8.useEffect(() => {
719
+ if (reduceMotion2) {
720
+ enter.setValue(1);
721
+ return;
722
+ }
554
723
  reactNative.Animated.spring(enter, {
555
724
  toValue: 1,
556
725
  useNativeDriver: true,
557
726
  tension: 70,
558
727
  friction: 12
559
728
  }).start();
560
- }, [enter]);
729
+ }, [enter, reduceMotion2]);
561
730
  const translateY = enter.interpolate({
562
731
  inputRange: [0, 1],
563
732
  outputRange: [atTop ? -80 : 80, 0]
@@ -578,6 +747,7 @@ function AgentPill({
578
747
  reactNative.TouchableOpacity,
579
748
  {
580
749
  ...APPILOTS_SKIP_PROPS,
750
+ ref: expandRef,
581
751
  testID: "appilots-agent-pill",
582
752
  accessibilityRole: "button",
583
753
  accessibilityLabel: strings.expandA11y,
@@ -590,7 +760,8 @@ function AgentPill({
590
760
  reactNative.Text,
591
761
  {
592
762
  testID: "appilots-agent-pill-label",
593
- numberOfLines: 1,
763
+ numberOfLines: 2,
764
+ maxFontSizeMultiplier: PILL_MAX_FONT_SCALE,
594
765
  style: [styles2.label, { color: colors.text, fontFamily }]
595
766
  },
596
767
  label
@@ -662,16 +833,22 @@ function SpotlightOverlay({
662
833
  fontFamily,
663
834
  window: win
664
835
  }) {
665
- const pulse = React8.useRef(new reactNative.Animated.Value(0)).current;
836
+ const reduceMotion2 = useReduceMotion();
837
+ const pulse = React8.useRef(new reactNative.Animated.Value(reduceMotion2 ? 1 : 0)).current;
666
838
  React8.useEffect(() => {
839
+ if (reduceMotion2) {
840
+ pulse.stopAnimation();
841
+ pulse.setValue(1);
842
+ return;
843
+ }
667
844
  pulse.setValue(0);
668
845
  reactNative.Animated.timing(pulse, {
669
846
  toValue: 1,
670
847
  duration: 220,
671
848
  useNativeDriver: true
672
849
  }).start();
673
- }, [seq, pulse]);
674
- if (!chunkUZ2D4BVX_js.isRectOnScreen(rect, win)) return null;
850
+ }, [seq, pulse, reduceMotion2]);
851
+ if (!chunkQAZ4TN3Z_js.isRectOnScreen(rect, win)) return null;
675
852
  const frame = {
676
853
  left: rect.x - PADDING,
677
854
  top: rect.y - PADDING,
@@ -761,36 +938,98 @@ var NEVER = () => () => {
761
938
  };
762
939
  var NULL_TARGET = () => null;
763
940
  function useSpotlight(enabled) {
764
- const subscribe = React8.useCallback(
765
- (onChange) => enabled ? chunkAJDHZRBN_js.subscribeSpotlight(onChange) : NEVER(),
941
+ const subscribe2 = React8.useCallback(
942
+ (onChange) => enabled ? chunkJGUDXRXN_js.subscribeSpotlight(onChange) : NEVER(),
766
943
  [enabled]
767
944
  );
768
- return React8.useSyncExternalStore(subscribe, enabled ? chunkAJDHZRBN_js.getSpotlightTarget : NULL_TARGET, NULL_TARGET);
945
+ return React8.useSyncExternalStore(subscribe2, enabled ? chunkJGUDXRXN_js.getSpotlightTarget : NULL_TARGET, NULL_TARGET);
769
946
  }
770
947
 
771
948
  // src/components/pillStatus.ts
772
949
  function resolvePillStatus(actions, busy, strings) {
773
950
  for (let i = actions.length - 1; i >= 0; i--) {
774
951
  const action = actions[i];
775
- if (action.status === "executing") return chunkUZ2D4BVX_js.describeAction(action, strings.locale);
952
+ if (action.status === "executing") return chunkQAZ4TN3Z_js.describeAction(action, strings.locale);
776
953
  }
777
954
  if (!busy) {
778
955
  for (let i = actions.length - 1; i >= 0; i--) {
779
956
  const action = actions[i];
780
957
  if (action.status === "completed" || action.status === "failed") {
781
- return chunkUZ2D4BVX_js.describeAction(action, strings.locale);
958
+ return chunkQAZ4TN3Z_js.describeAction(action, strings.locale);
782
959
  }
783
960
  }
784
961
  return { label: strings.done, state: "success" };
785
962
  }
786
963
  return { label: strings.working, state: "running" };
787
964
  }
788
-
789
- // src/components/speech.ts
790
- function isSpeechHost(value) {
791
- if (!value || typeof value !== "object") return false;
792
- const candidate = value;
793
- return typeof candidate.start === "function" && typeof candidate.stop === "function" && typeof candidate.cancel === "function";
965
+ var STREAMING_PREFIX = "streaming_";
966
+ function announce(message) {
967
+ if (reactNative.Platform.OS === "ios" && reactNative.AccessibilityInfo.announceForAccessibilityWithOptions) {
968
+ reactNative.AccessibilityInfo.announceForAccessibilityWithOptions(message, { queue: true });
969
+ } else {
970
+ reactNative.AccessibilityInfo.announceForAccessibility(message);
971
+ }
972
+ }
973
+ var speakable = (content) => content.replace(/[*`#]+/g, "").trim();
974
+ function useChatAnnouncements({
975
+ messages,
976
+ actions,
977
+ awaitingApproval,
978
+ acting,
979
+ locale,
980
+ strings
981
+ }) {
982
+ const seenMessages = React8.useRef(null);
983
+ if (!seenMessages.current) seenMessages.current = new Set(messages.map((m) => m.id));
984
+ const seenActions = React8.useRef(null);
985
+ if (!seenActions.current) seenActions.current = new Map(actions.map((a) => [a.id, a.status]));
986
+ const prev = React8.useRef({ awaitingApproval, acting });
987
+ const namedSinceSettle = React8.useRef(false);
988
+ const localeRef = React8.useRef(locale);
989
+ localeRef.current = locale;
990
+ React8.useEffect(
991
+ () => chunkJGUDXRXN_js.subscribeSpotlightAnnouncement((label, verb) => {
992
+ namedSinceSettle.current = true;
993
+ announce(targetAnnouncement(verb, label, localeRef.current));
994
+ }),
995
+ []
996
+ );
997
+ React8.useEffect(() => {
998
+ const out = [];
999
+ for (const message of messages) {
1000
+ if (message.role === "user" || message.id.startsWith(STREAMING_PREFIX)) continue;
1001
+ if (seenMessages.current.has(message.id)) continue;
1002
+ seenMessages.current.add(message.id);
1003
+ const text = speakable(message.content);
1004
+ if (text) out.push(text);
1005
+ }
1006
+ for (const action of actions) {
1007
+ if (action.type === "confirm") continue;
1008
+ if (seenActions.current.get(action.id) === action.status) continue;
1009
+ seenActions.current.set(action.id, action.status);
1010
+ const line = actionAnnouncement(action, locale, namedSinceSettle.current);
1011
+ if (action.status === "completed" || action.status === "failed") {
1012
+ namedSinceSettle.current = false;
1013
+ }
1014
+ if (line) out.push(line);
1015
+ }
1016
+ if (awaitingApproval && !prev.current.awaitingApproval) out.push(strings.a11yAwaitingApproval);
1017
+ if (prev.current.acting && !acting) out.push(strings.a11yTurnDone);
1018
+ prev.current = { awaitingApproval, acting };
1019
+ for (const line of out) announce(line);
1020
+ }, [messages, actions, awaitingApproval, acting, locale, strings]);
1021
+ }
1022
+ function useStillWorking(active, template) {
1023
+ const [seconds, setSeconds] = React8.useState(0);
1024
+ React8.useEffect(() => {
1025
+ setSeconds(0);
1026
+ if (!active) return;
1027
+ return chunkQAZ4TN3Z_js.startStillWorkingTimer((elapsed) => {
1028
+ setSeconds(elapsed);
1029
+ reactNative.AccessibilityInfo.announceForAccessibility(template.replace("{seconds}", String(elapsed)));
1030
+ });
1031
+ }, [active, template]);
1032
+ return seconds;
794
1033
  }
795
1034
  function useVoiceInput({
796
1035
  host,
@@ -827,7 +1066,7 @@ function useVoiceInput({
827
1066
  if (!mounted.current) return;
828
1067
  setState("listening");
829
1068
  }).catch((err) => {
830
- chunkUZ2D4BVX_js.appilotsDebugWarn("useVoiceInput: start failed", err);
1069
+ chunkQAZ4TN3Z_js.appilotsDebugWarn("useVoiceInput: start failed", err);
831
1070
  if (!mounted.current) return;
832
1071
  setState("error");
833
1072
  });
@@ -843,7 +1082,7 @@ function useVoiceInput({
843
1082
  const trimmed = text?.trim();
844
1083
  if (trimmed) onTranscriptRef.current(trimmed);
845
1084
  }).catch((err) => {
846
- chunkUZ2D4BVX_js.appilotsDebugWarn("useVoiceInput: stop failed", err);
1085
+ chunkQAZ4TN3Z_js.appilotsDebugWarn("useVoiceInput: stop failed", err);
847
1086
  if (!mounted.current) return;
848
1087
  setState("error");
849
1088
  setPartial("");
@@ -853,7 +1092,7 @@ function useVoiceInput({
853
1092
  if (!host) return;
854
1093
  setPartial("");
855
1094
  setState("idle");
856
- void host.cancel().catch((err) => chunkUZ2D4BVX_js.appilotsDebugWarn("useVoiceInput: cancel failed", err));
1095
+ void host.cancel().catch((err) => chunkQAZ4TN3Z_js.appilotsDebugWarn("useVoiceInput: cancel failed", err));
857
1096
  }, [host]);
858
1097
  React8.useEffect(() => {
859
1098
  if (!host?.onPartial) return;
@@ -863,6 +1102,15 @@ function useVoiceInput({
863
1102
  });
864
1103
  return dispose;
865
1104
  }, [host, state]);
1105
+ React8.useEffect(() => {
1106
+ if (!host?.onEnd) return;
1107
+ if (state !== "listening") return;
1108
+ return host.onEnd((error) => {
1109
+ if (!mounted.current) return;
1110
+ setPartial("");
1111
+ setState(error ? "error" : "idle");
1112
+ });
1113
+ }, [host, state]);
866
1114
  return { state, partial, start, stop, cancel };
867
1115
  }
868
1116
 
@@ -916,7 +1164,7 @@ function resolveExperience(requested, caps) {
916
1164
  field: "input",
917
1165
  from: input.join("+"),
918
1166
  to: input.filter((mode) => mode !== "voice").join("+") || "text",
919
- reason: 'input:"voice" needs a SpeechHost passed to <AppilotsChat speech={...} />. The SDK ships no speech engine of its own \u2014 see docs/experience.md.'
1167
+ reason: 'input:"voice" needs a SpeechHost passed to <AppilotsChat speech={...} />. The SDK ships no speech engine of its own \u2014 see https://docs.appilots.com/docs/guides/voice-input.'
920
1168
  });
921
1169
  input = input.filter((mode) => mode !== "voice");
922
1170
  }
@@ -995,7 +1243,7 @@ function segmentKey(segment, index) {
995
1243
  return `${segment.kind}-${index}-${segment.value.slice(0, 12)}`;
996
1244
  }
997
1245
  function renderInlineSegments(text, theme, baseStyle) {
998
- const segments = chunkUZ2D4BVX_js.parseInlineMarkdown(text);
1246
+ const segments = chunkQAZ4TN3Z_js.parseInlineMarkdown(text);
999
1247
  return segments.map((segment, index) => {
1000
1248
  const key = segmentKey(segment, index);
1001
1249
  switch (segment.kind) {
@@ -1057,7 +1305,7 @@ function InlineMarkdown({
1057
1305
  return /* @__PURE__ */ React8__namespace.default.createElement(reactNative.Text, { style: baseStyle }, renderInlineSegments(text, theme, baseStyle));
1058
1306
  }
1059
1307
  function ChatMarkdown({ content, theme, contentWidth }) {
1060
- const prepared = chunkUZ2D4BVX_js.enhancePlainAssistantContent(content);
1308
+ const prepared = chunkQAZ4TN3Z_js.enhancePlainAssistantContent(content);
1061
1309
  const baseTextStyle = {
1062
1310
  color: theme.color,
1063
1311
  fontFamily: theme.fontFamily,
@@ -1065,14 +1313,14 @@ function ChatMarkdown({ content, theme, contentWidth }) {
1065
1313
  lineHeight: theme.lineHeight
1066
1314
  };
1067
1315
  const rootStyle = contentWidth ? [styles4.root, { width: contentWidth }] : styles4.root;
1068
- if (!chunkUZ2D4BVX_js.looksLikeMarkdown(prepared)) {
1316
+ if (!chunkQAZ4TN3Z_js.looksLikeMarkdown(prepared)) {
1069
1317
  const paragraphs = prepared.split(/\n\n+/).map((part) => part.trim()).filter(Boolean);
1070
1318
  if (paragraphs.length > 1) {
1071
1319
  return /* @__PURE__ */ React8__namespace.default.createElement(reactNative.View, { style: rootStyle }, paragraphs.map((paragraph, index) => /* @__PURE__ */ React8__namespace.default.createElement(reactNative.View, { key: `plain-p-${index}`, style: index > 0 ? styles4.blockGap : void 0 }, /* @__PURE__ */ React8__namespace.default.createElement(reactNative.Text, { style: baseTextStyle }, paragraph))));
1072
1320
  }
1073
1321
  return /* @__PURE__ */ React8__namespace.default.createElement(reactNative.Text, { style: baseTextStyle }, prepared);
1074
1322
  }
1075
- const blocks = chunkUZ2D4BVX_js.parseMarkdownBlocks(prepared);
1323
+ const blocks = chunkQAZ4TN3Z_js.parseMarkdownBlocks(prepared);
1076
1324
  return /* @__PURE__ */ React8__namespace.default.createElement(reactNative.View, { style: rootStyle }, blocks.map((block, blockIndex) => {
1077
1325
  if (block.kind === "paragraph") {
1078
1326
  return /* @__PURE__ */ React8__namespace.default.createElement(reactNative.View, { key: `p-${blockIndex}`, style: blockIndex > 0 ? styles4.blockGap : void 0 }, /* @__PURE__ */ React8__namespace.default.createElement(InlineMarkdown, { text: block.text, theme }));
@@ -1181,7 +1429,7 @@ var styles4 = reactNative.StyleSheet.create({
1181
1429
  textDecorationLine: "underline"
1182
1430
  }
1183
1431
  });
1184
- var ThemeContext = React8.createContext(chunkUZ2D4BVX_js.defaultLightTheme);
1432
+ var ThemeContext = React8.createContext(chunkQAZ4TN3Z_js.defaultLightTheme);
1185
1433
  function AppilotsThemeProvider({
1186
1434
  theme,
1187
1435
  mode = "auto",
@@ -1189,7 +1437,7 @@ function AppilotsThemeProvider({
1189
1437
  }) {
1190
1438
  const systemScheme = reactNative.useColorScheme();
1191
1439
  const tokens = React8.useMemo(
1192
- () => chunkUZ2D4BVX_js.mergeThemeTokens(chunkUZ2D4BVX_js.resolveBaseTheme(mode, systemScheme), theme ?? void 0),
1440
+ () => chunkQAZ4TN3Z_js.mergeThemeTokens(chunkQAZ4TN3Z_js.resolveBaseTheme(mode, systemScheme), theme ?? void 0),
1193
1441
  [mode, systemScheme, theme]
1194
1442
  );
1195
1443
  return /* @__PURE__ */ React8__namespace.default.createElement(ThemeContext.Provider, { value: tokens }, children);
@@ -1312,17 +1560,21 @@ function isImageSource(value) {
1312
1560
  return typeof value === "number" || /^https?:\/\//i.test(value.trim());
1313
1561
  }
1314
1562
  var { height: SCREEN_HEIGHT, width: SCREEN_WIDTH } = reactNative.Dimensions.get("window");
1563
+ var A11Y_FOCUS_DELAY_MS = 500;
1315
1564
  var CHAT_HORIZONTAL_PADDING = 16;
1316
1565
  var BUBBLE_HORIZONTAL_PADDING = 14;
1317
1566
  var ASSISTANT_CONTENT_WIDTH = SCREEN_WIDTH - CHAT_HORIZONTAL_PADDING * 2 - BUBBLE_HORIZONTAL_PADDING * 2;
1567
+ var MIN_TOUCH_TARGET2 = 44;
1568
+ var LARGE_TEXT_FONT_SCALE = 1.6;
1569
+ var INPUT_MAX_HEIGHT = 120;
1318
1570
  function AppilotsChat(props) {
1319
- const { degraded } = chunkUZ2D4BVX_js.useAppilotsContext();
1571
+ const { degraded } = chunkQAZ4TN3Z_js.useAppilotsContext();
1320
1572
  if (degraded) return null;
1321
- return /* @__PURE__ */ React8__namespace.default.createElement(chunkUZ2D4BVX_js.AppilotsErrorBoundary, { surface: "chat", fallback: null }, /* @__PURE__ */ React8__namespace.default.createElement(AppilotsChatSurface, { ...props }));
1573
+ return /* @__PURE__ */ React8__namespace.default.createElement(chunkQAZ4TN3Z_js.AppilotsErrorBoundary, { surface: "chat", fallback: null }, /* @__PURE__ */ React8__namespace.default.createElement(AppilotsChatSurface, { ...props }));
1322
1574
  }
1323
1575
  function AppilotsChatSurface(props) {
1324
1576
  const [conversationLocale, setConversationLocale] = React8.useState(null);
1325
- const { remotePersonalization } = chunkUZ2D4BVX_js.useAppilotsContext();
1577
+ const { remotePersonalization } = chunkQAZ4TN3Z_js.useAppilotsContext();
1326
1578
  const themeProp = React8.useMemo(() => {
1327
1579
  if (!props.theme) return void 0;
1328
1580
  return isLegacyTheme(props.theme) ? translateLegacyTheme(props.theme) : props.theme;
@@ -1334,7 +1586,7 @@ function AppilotsChatSurface(props) {
1334
1586
  mode: resolveThemeMode(props.themeMode, remotePersonalization)
1335
1587
  },
1336
1588
  /* @__PURE__ */ React8__namespace.default.createElement(
1337
- chunkAJDHZRBN_js.AppilotsI18nProvider,
1589
+ chunkJGUDXRXN_js.AppilotsI18nProvider,
1338
1590
  {
1339
1591
  locale: conversationLocale ?? resolveLocaleProp(props.locale, remotePersonalization)
1340
1592
  },
@@ -1364,7 +1616,7 @@ function AppilotsChatInner({
1364
1616
  speech: speechProp
1365
1617
  }) {
1366
1618
  const theme = useAppilotsTheme();
1367
- const { strings, t, locale: resolvedLocale } = chunkAJDHZRBN_js.useAppilotsI18n();
1619
+ const { strings, t, locale: resolvedLocale } = chunkJGUDXRXN_js.useAppilotsI18n();
1368
1620
  const {
1369
1621
  messages,
1370
1622
  mission,
@@ -1380,7 +1632,7 @@ function AppilotsChatInner({
1380
1632
  clearMessages,
1381
1633
  escalation,
1382
1634
  requestHuman
1383
- } = chunkAJDHZRBN_js.useAppilotsChat({
1635
+ } = chunkJGUDXRXN_js.useAppilotsChat({
1384
1636
  errorPrefix: t("somethingWentWrong"),
1385
1637
  escalationStrings: {
1386
1638
  requested: t("escalationRequested"),
@@ -1392,8 +1644,8 @@ function AppilotsChatInner({
1392
1644
  React8.useEffect(() => {
1393
1645
  onReplyLocaleChange(replyLocale);
1394
1646
  }, [replyLocale, onReplyLocaleChange]);
1395
- const { pendingActions, executingActions, completedActions, approveAction, rejectAction } = chunkAJDHZRBN_js.useAppilotsActions({ autoExecute });
1396
- const { emit, remotePersonalization } = chunkUZ2D4BVX_js.useAppilotsContext();
1647
+ const { pendingActions, executingActions, completedActions, approveAction, rejectAction } = chunkJGUDXRXN_js.useAppilotsActions({ autoExecute });
1648
+ const { emit, remotePersonalization } = chunkQAZ4TN3Z_js.useAppilotsContext();
1397
1649
  const {
1398
1650
  headerTitle: resolvedTitle,
1399
1651
  assistantAvatar,
@@ -1424,15 +1676,16 @@ function AppilotsChatInner({
1424
1676
  return void 0;
1425
1677
  }, [messages]);
1426
1678
  const insets = useSafeAreaInsetsOrDefault();
1679
+ const { fontScale } = reactNative.useWindowDimensions();
1427
1680
  const [internalVisible, setInternalVisible] = React8.useState(mode === "inline");
1428
1681
  const [inputText, setInputText] = React8.useState("");
1429
1682
  const flatListRef = React8.useRef(null);
1430
1683
  const slideAnim = React8.useRef(new reactNative.Animated.Value(SCREEN_HEIGHT)).current;
1431
1684
  const wantsSheet = mode === "inline" ? true : controlledVisible !== void 0 ? controlledVisible : internalVisible;
1432
- const speechHost = isSpeechHost(speechProp) ? speechProp : null;
1685
+ const speechHost = chunkQAZ4TN3Z_js.isSpeechHost(speechProp) ? speechProp : null;
1433
1686
  const hasGeometry = React8.useSyncExternalStore(
1434
- chunkUZ2D4BVX_js.subscribeGeometryHost,
1435
- () => chunkUZ2D4BVX_js.geometryAvailability() !== "unavailable",
1687
+ chunkQAZ4TN3Z_js.subscribeGeometryHost,
1688
+ () => chunkQAZ4TN3Z_js.geometryAvailability() !== "unavailable",
1436
1689
  () => false
1437
1690
  );
1438
1691
  const capabilities = React8.useMemo(
@@ -1446,7 +1699,7 @@ function AppilotsChatInner({
1446
1699
  const presence = mode === "inline" ? "sheet" : experience.presence;
1447
1700
  React8.useEffect(() => {
1448
1701
  if (!__DEV__ || downgrades.length === 0) return;
1449
- if (!chunkUZ2D4BVX_js.isGeometryResolved()) return;
1702
+ if (!chunkQAZ4TN3Z_js.isGeometryResolved()) return;
1450
1703
  for (const line of formatDowngrades(downgrades)) {
1451
1704
  console.warn(line);
1452
1705
  }
@@ -1461,9 +1714,19 @@ function AppilotsChatInner({
1461
1714
  },
1462
1715
  [autoExecute]
1463
1716
  );
1464
- const awaitingUser = pendingActions.some((action) => requireApproval(action)) || escalation?.status === "pending" || escalation?.status === "active";
1717
+ const awaitingApproval = pendingActions.some((action) => requireApproval(action));
1718
+ const awaitingUser = awaitingApproval || escalation?.status === "pending" || escalation?.status === "active";
1465
1719
  const busy = isLoading || executingActions.length > 0;
1720
+ const stillWorkingSeconds = useStillWorking(busy && !awaitingUser, strings.stillWorking);
1466
1721
  const acting = busy && hasStartedActing;
1722
+ useChatAnnouncements({
1723
+ messages,
1724
+ actions: allActions,
1725
+ awaitingApproval,
1726
+ acting,
1727
+ locale: resolvedLocale,
1728
+ strings
1729
+ });
1467
1730
  const hostModalOpen = useHostModalOpen(
1468
1731
  usesPill(presence) && (busy || wantsSheet || unreadResult)
1469
1732
  );
@@ -1479,20 +1742,20 @@ function AppilotsChatInner({
1479
1742
  const isVisible = mode === "inline" ? true : surface === "sheet";
1480
1743
  const spotlight = useSpotlight(experience.spotlight !== "off");
1481
1744
  React8.useEffect(() => {
1482
- chunkAJDHZRBN_js.setSpotlightMode(experience.spotlight);
1483
- return () => chunkAJDHZRBN_js.setSpotlightMode("off");
1745
+ chunkJGUDXRXN_js.setSpotlightMode(experience.spotlight);
1746
+ return () => chunkJGUDXRXN_js.setSpotlightMode("off");
1484
1747
  }, [experience.spotlight]);
1485
1748
  const { label: pillLabel, state: pillState } = surface === "pill" ? resolvePillStatus(allActions, busy, {
1486
1749
  working: strings.pillWorking,
1487
1750
  done: strings.pillDone,
1488
1751
  locale: resolvedLocale
1489
1752
  }) : { label: "", state: "pending" };
1490
- const showSuggestedPrompts = chunkAJDHZRBN_js.shouldShowSuggestedPrompts({
1753
+ const showSuggestedPrompts = chunkJGUDXRXN_js.shouldShowSuggestedPrompts({
1491
1754
  isVisible,
1492
1755
  messageCount: messages.length,
1493
1756
  inputText
1494
1757
  });
1495
- const { prompts: suggestedPrompts } = chunkAJDHZRBN_js.useSuggestedPrompts({
1758
+ const { prompts: suggestedPrompts } = chunkJGUDXRXN_js.useSuggestedPrompts({
1496
1759
  enabled: showSuggestedPrompts,
1497
1760
  limit: 3
1498
1761
  });
@@ -1538,6 +1801,19 @@ function AppilotsChatInner({
1538
1801
  friction: 11
1539
1802
  }).start();
1540
1803
  }, [isVisible, slideAnim, mode]);
1804
+ const titleRef = React8.useRef(null);
1805
+ const launcherRef = React8.useRef(null);
1806
+ const pillRef = React8.useRef(null);
1807
+ const wasVisibleRef = React8.useRef(isVisible);
1808
+ React8.useEffect(() => {
1809
+ if (mode === "inline" || wasVisibleRef.current === isVisible) return;
1810
+ wasVisibleRef.current = isVisible;
1811
+ const timer = setTimeout(() => {
1812
+ const target = isVisible ? titleRef.current : pillRef.current ?? launcherRef.current;
1813
+ if (target) reactNative.AccessibilityInfo.sendAccessibilityEvent(target, "focus");
1814
+ }, A11Y_FOCUS_DELAY_MS);
1815
+ return () => clearTimeout(timer);
1816
+ }, [isVisible, mode]);
1541
1817
  React8.useEffect(() => {
1542
1818
  if (messages.length > 0) {
1543
1819
  setTimeout(() => flatListRef.current?.scrollToEnd({ animated: true }), 100);
@@ -1609,7 +1885,7 @@ function AppilotsChatInner({
1609
1885
  }
1610
1886
  const isUser = item.role === "user";
1611
1887
  const isHumanAgent = item.role === "human_agent";
1612
- const useWideAssistantLayout = !isUser && chunkUZ2D4BVX_js.needsWideChatLayout(item.content);
1888
+ const useWideAssistantLayout = !isUser && chunkQAZ4TN3Z_js.needsWideChatLayout(item.content);
1613
1889
  if (isHumanAgent) {
1614
1890
  return /* @__PURE__ */ React8__namespace.default.createElement(reactNative.View, { style: styles5.humanAgentContainer, testID: "human-agent-message" }, /* @__PURE__ */ React8__namespace.default.createElement(reactNative.View, { style: styles5.humanAgentLabelRow }, /* @__PURE__ */ React8__namespace.default.createElement(HeadsetIcon, { size: 11, color: theme.colors.secondary }), /* @__PURE__ */ React8__namespace.default.createElement(
1615
1891
  reactNative.Text,
@@ -1680,6 +1956,10 @@ function AppilotsChatInner({
1680
1956
  },
1681
1957
  [theme, lastAssistantMessageId, escalation, requestHuman, strings]
1682
1958
  );
1959
+ const composerRef = React8.useRef(null);
1960
+ const returnFocusToComposer = React8.useCallback(() => {
1961
+ if (composerRef.current) reactNative.AccessibilityInfo.sendAccessibilityEvent(composerRef.current, "focus");
1962
+ }, []);
1683
1963
  const renderBreadcrumb = React8.useCallback(
1684
1964
  (actions) => /* @__PURE__ */ React8__namespace.default.createElement(
1685
1965
  ActionBreadcrumb,
@@ -1696,7 +1976,8 @@ function AppilotsChatInner({
1696
1976
  confirmDestructiveApprove: strings.confirmDestructiveApprove,
1697
1977
  confirmApprove: strings.confirmApprove,
1698
1978
  confirmCancel: strings.confirmCancel,
1699
- confirmThisAction: strings.confirmThisAction
1979
+ confirmThisAction: strings.confirmThisAction,
1980
+ confirmExpired: strings.confirmExpired
1700
1981
  },
1701
1982
  palette: {
1702
1983
  textSecondary: theme.colors.textSecondary,
@@ -1708,7 +1989,8 @@ function AppilotsChatInner({
1708
1989
  },
1709
1990
  requireApprovalFor: requireApproval,
1710
1991
  onApprove: approveAction,
1711
- onReject: rejectAction
1992
+ onReject: rejectAction,
1993
+ onConfirmCardGone: returnFocusToComposer
1712
1994
  }
1713
1995
  ),
1714
1996
  [
@@ -1725,7 +2007,8 @@ function AppilotsChatInner({
1725
2007
  resolvedLocale,
1726
2008
  requireApproval,
1727
2009
  approveAction,
1728
- rejectAction
2010
+ rejectAction,
2011
+ returnFocusToComposer
1729
2012
  ]
1730
2013
  );
1731
2014
  const resolvedHeaderTitle = resolvedTitle ?? t("chatTitle");
@@ -1768,6 +2051,7 @@ function AppilotsChatInner({
1768
2051
  mode === "fullscreen" && styles5.chatContainerFullscreen,
1769
2052
  mode === "sidebar" && styles5.chatContainerSidebar,
1770
2053
  mode === "inline" && styles5.chatContainerInline,
2054
+ mode === "bubble" && fontScale >= LARGE_TEXT_FONT_SCALE && styles5.chatContainerFullscreen,
1771
2055
  {
1772
2056
  backgroundColor: theme.colors.background,
1773
2057
  borderTopLeftRadius: theme.radii.lg,
@@ -1778,6 +2062,8 @@ function AppilotsChatInner({
1778
2062
  /* @__PURE__ */ React8__namespace.default.createElement(reactNative.View, { style: [styles5.header, { borderBottomColor: theme.colors.border }] }, /* @__PURE__ */ React8__namespace.default.createElement(reactNative.View, { style: styles5.headerLeft }, renderAvatar(), /* @__PURE__ */ React8__namespace.default.createElement(
1779
2063
  reactNative.Text,
1780
2064
  {
2065
+ ref: titleRef,
2066
+ accessibilityRole: "header",
1781
2067
  style: [
1782
2068
  styles5.headerTitle,
1783
2069
  {
@@ -1904,8 +2190,7 @@ function AppilotsChatInner({
1904
2190
  color: theme.colors.textSecondary,
1905
2191
  fontFamily: theme.typography.fontFamily
1906
2192
  }
1907
- ],
1908
- numberOfLines: 2
2193
+ ]
1909
2194
  },
1910
2195
  resolvedEmptySubtitle
1911
2196
  ), showSuggestedPrompts && suggestedPrompts.length > 0 && /* @__PURE__ */ React8__namespace.default.createElement(reactNative.View, { style: styles5.chipsContainer, testID: "assistant-suggested-prompts" }, suggestedPrompts.map((prompt) => /* @__PURE__ */ React8__namespace.default.createElement(
@@ -1934,8 +2219,7 @@ function AppilotsChatInner({
1934
2219
  fontFamily: theme.typography.fontFamily,
1935
2220
  fontSize: theme.typography.fontSizeSm
1936
2221
  }
1937
- ],
1938
- numberOfLines: 1
2222
+ ]
1939
2223
  },
1940
2224
  prompt.text
1941
2225
  )
@@ -1957,16 +2241,17 @@ function AppilotsChatInner({
1957
2241
  { color: theme.colors.textSecondary, fontFamily: theme.typography.fontFamily }
1958
2242
  ]
1959
2243
  },
1960
- strings[loadingStatusKey] ?? strings.thinking
2244
+ stillWorkingSeconds ? strings.stillWorking.replace("{seconds}", String(stillWorkingSeconds)) : strings[loadingStatusKey] ?? strings.thinking
1961
2245
  )
1962
2246
  ) : null
1963
2247
  }
1964
2248
  ),
1965
- mission && !["completed", "cancelled"].includes(mission.status) && /* @__PURE__ */ React8__namespace.default.createElement(reactNative.View, { style: { padding: 12, gap: 8 }, testID: "appilots-mission-controls" }, /* @__PURE__ */ React8__namespace.default.createElement(reactNative.Text, { style: { color: theme.colors.text }, testID: "appilots-mission-progress" }, mission.progressText, mission.status === "paused" ? ` \xB7 ${strings.missionPaused}` : ""), /* @__PURE__ */ React8__namespace.default.createElement(reactNative.View, { style: { flexDirection: "row", gap: 12 } }, mission.status === "running" ? /* @__PURE__ */ React8__namespace.default.createElement(
2249
+ mission && !["completed", "cancelled"].includes(mission.status) && /* @__PURE__ */ React8__namespace.default.createElement(reactNative.View, { style: { padding: 12, gap: 8 }, testID: "appilots-mission-controls" }, /* @__PURE__ */ React8__namespace.default.createElement(reactNative.Text, { style: { color: theme.colors.text }, testID: "appilots-mission-progress" }, mission.progressText, mission.status === "paused" ? ` \xB7 ${strings.missionPaused}` : ""), /* @__PURE__ */ React8__namespace.default.createElement(reactNative.View, { style: styles5.missionButtons }, mission.status === "running" ? /* @__PURE__ */ React8__namespace.default.createElement(
1966
2250
  reactNative.TouchableOpacity,
1967
2251
  {
1968
2252
  onPress: () => void pauseMission(),
1969
2253
  testID: "appilots-mission-pause",
2254
+ style: styles5.missionButton,
1970
2255
  accessibilityRole: "button"
1971
2256
  },
1972
2257
  /* @__PURE__ */ React8__namespace.default.createElement(reactNative.Text, { style: { color: theme.colors.text } }, strings.missionPause)
@@ -1976,6 +2261,7 @@ function AppilotsChatInner({
1976
2261
  onPress: () => void resumeMission(),
1977
2262
  disabled: isLoading,
1978
2263
  testID: "appilots-mission-resume",
2264
+ style: styles5.missionButton,
1979
2265
  accessibilityRole: "button"
1980
2266
  },
1981
2267
  /* @__PURE__ */ React8__namespace.default.createElement(reactNative.Text, { style: { color: theme.colors.text } }, strings.missionResume)
@@ -1984,6 +2270,7 @@ function AppilotsChatInner({
1984
2270
  {
1985
2271
  onPress: () => void cancelMission(),
1986
2272
  testID: "appilots-mission-cancel",
2273
+ style: styles5.missionButton,
1987
2274
  accessibilityRole: "button"
1988
2275
  },
1989
2276
  /* @__PURE__ */ React8__namespace.default.createElement(reactNative.Text, { style: { color: theme.colors.text } }, strings.missionCancel)
@@ -2002,6 +2289,7 @@ function AppilotsChatInner({
2002
2289
  /* @__PURE__ */ React8__namespace.default.createElement(
2003
2290
  reactNative.TextInput,
2004
2291
  {
2292
+ ref: composerRef,
2005
2293
  style: [
2006
2294
  styles5.input,
2007
2295
  {
@@ -2010,7 +2298,12 @@ function AppilotsChatInner({
2010
2298
  borderRadius: theme.radii.md,
2011
2299
  fontFamily: theme.typography.fontFamily,
2012
2300
  fontSize: theme.typography.fontSizeBase,
2013
- lineHeight: theme.typography.fontSizeBase * 1.35
2301
+ lineHeight: theme.typography.fontSizeBase * 1.35,
2302
+ // The 120pt cap is ~5 lines at default size and barely one at
2303
+ // iOS AX5, where even the placeholder was cut. It grows with
2304
+ // the text, but never past a quarter of the screen, so the
2305
+ // keyboard still leaves room for the transcript.
2306
+ maxHeight: Math.min(INPUT_MAX_HEIGHT * fontScale, SCREEN_HEIGHT * 0.25)
2014
2307
  }
2015
2308
  ],
2016
2309
  placeholder: resolvedPlaceholder,
@@ -2105,6 +2398,7 @@ function AppilotsChatInner({
2105
2398
  reactNative.TouchableOpacity,
2106
2399
  {
2107
2400
  ...APPILOTS_SKIP_PROPS,
2401
+ ref: launcherRef,
2108
2402
  onPress: openChat,
2109
2403
  activeOpacity: 0.8,
2110
2404
  accessibilityRole: "button",
@@ -2118,6 +2412,7 @@ function AppilotsChatInner({
2118
2412
  reactNative.TouchableOpacity,
2119
2413
  {
2120
2414
  ...APPILOTS_SKIP_PROPS,
2415
+ ref: launcherRef,
2121
2416
  style: [
2122
2417
  styles5.fab,
2123
2418
  fabPositionStyle,
@@ -2170,6 +2465,7 @@ function AppilotsChatInner({
2170
2465
  },
2171
2466
  strings: { expandA11y: strings.pillExpandA11y, stopA11y: strings.pillStopA11y },
2172
2467
  onExpand: openChat,
2468
+ expandRef: pillRef,
2173
2469
  onStop: busy ? cancelMessage : void 0
2174
2470
  }
2175
2471
  ), /* @__PURE__ */ React8__namespace.default.createElement(SheetHost, { useModal: presence === "sheet", visible: isVisible, onRequestClose: closeChat }, /* @__PURE__ */ React8__namespace.default.createElement(
@@ -2177,6 +2473,7 @@ function AppilotsChatInner({
2177
2473
  {
2178
2474
  ...APPILOTS_SKIP_PROPS,
2179
2475
  pointerEvents: presence === "sheet" ? "auto" : "box-none",
2476
+ onAccessibilityEscape: closeChat,
2180
2477
  style: [
2181
2478
  mode === "fullscreen" ? styles5.modalContainerFullscreen : styles5.modalContainer,
2182
2479
  mode === "sidebar" && styles5.modalContainerSidebar,
@@ -2227,6 +2524,7 @@ function SheetHost({
2227
2524
  {
2228
2525
  ...APPILOTS_SKIP_PROPS,
2229
2526
  pointerEvents: "box-none",
2527
+ accessibilityViewIsModal: true,
2230
2528
  style: [reactNative.StyleSheet.absoluteFill, styles5.sheetOverlay]
2231
2529
  },
2232
2530
  children
@@ -2325,8 +2623,13 @@ var styles5 = reactNative.StyleSheet.create({
2325
2623
  maxHeight: "100%",
2326
2624
  flex: 1
2327
2625
  },
2626
+ // Wraps instead of squeezing: at large text sizes the title alone is
2627
+ // wider than the row, and without the wrap it pushed Clear and ✕ off the
2628
+ // right edge — the chat could not be closed (measured at iOS AX5).
2328
2629
  header: {
2329
2630
  flexDirection: "row",
2631
+ flexWrap: "wrap",
2632
+ rowGap: 4,
2330
2633
  alignItems: "center",
2331
2634
  justifyContent: "space-between",
2332
2635
  paddingHorizontal: 16,
@@ -2336,7 +2639,8 @@ var styles5 = reactNative.StyleSheet.create({
2336
2639
  headerLeft: {
2337
2640
  flexDirection: "row",
2338
2641
  alignItems: "center",
2339
- gap: 8
2642
+ gap: 8,
2643
+ flexShrink: 1
2340
2644
  },
2341
2645
  headerDot: {
2342
2646
  width: 8,
@@ -2355,24 +2659,30 @@ var styles5 = reactNative.StyleSheet.create({
2355
2659
  justifyContent: "center"
2356
2660
  },
2357
2661
  headerTitle: {
2358
- fontWeight: "600"
2662
+ fontWeight: "600",
2663
+ flexShrink: 1
2359
2664
  },
2360
2665
  headerActions: {
2361
2666
  flexDirection: "row",
2362
2667
  alignItems: "center",
2363
- gap: 12
2668
+ gap: 4,
2669
+ // Stays right-aligned when the header wraps it onto its own line.
2670
+ marginLeft: "auto"
2364
2671
  },
2365
2672
  headerButton: {
2673
+ minWidth: MIN_TOUCH_TARGET2,
2674
+ minHeight: MIN_TOUCH_TARGET2,
2366
2675
  paddingHorizontal: 8,
2367
- paddingVertical: 4
2676
+ alignItems: "center",
2677
+ justifyContent: "center"
2368
2678
  },
2369
2679
  headerButtonText: {
2370
2680
  fontSize: 13
2371
2681
  },
2372
2682
  closeButton: {
2373
- width: 28,
2374
- height: 28,
2375
- borderRadius: 14,
2683
+ minWidth: MIN_TOUCH_TARGET2,
2684
+ minHeight: MIN_TOUCH_TARGET2,
2685
+ borderRadius: MIN_TOUCH_TARGET2 / 2,
2376
2686
  alignItems: "center",
2377
2687
  justifyContent: "center"
2378
2688
  },
@@ -2454,6 +2764,8 @@ var styles5 = reactNative.StyleSheet.create({
2454
2764
  maxWidth: 320
2455
2765
  },
2456
2766
  chip: {
2767
+ minHeight: MIN_TOUCH_TARGET2,
2768
+ justifyContent: "center",
2457
2769
  paddingHorizontal: 16,
2458
2770
  paddingVertical: 10,
2459
2771
  borderWidth: 1,
@@ -2516,16 +2828,16 @@ var styles5 = reactNative.StyleSheet.create({
2516
2828
  },
2517
2829
  input: {
2518
2830
  flex: 1,
2519
- minHeight: 38,
2520
- maxHeight: 120,
2831
+ minHeight: MIN_TOUCH_TARGET2,
2832
+ maxHeight: INPUT_MAX_HEIGHT,
2521
2833
  paddingHorizontal: 16,
2522
2834
  paddingTop: reactNative.Platform.OS === "ios" ? 9 : 8,
2523
2835
  paddingBottom: reactNative.Platform.OS === "ios" ? 9 : 8,
2524
2836
  textAlignVertical: "top"
2525
2837
  },
2526
2838
  sendButton: {
2527
- width: 38,
2528
- height: 38,
2839
+ minWidth: MIN_TOUCH_TARGET2,
2840
+ minHeight: MIN_TOUCH_TARGET2,
2529
2841
  alignItems: "center",
2530
2842
  justifyContent: "center"
2531
2843
  },
@@ -2534,6 +2846,15 @@ var styles5 = reactNative.StyleSheet.create({
2534
2846
  fontSize: 18,
2535
2847
  fontWeight: "700"
2536
2848
  },
2849
+ missionButtons: {
2850
+ flexDirection: "row",
2851
+ flexWrap: "wrap",
2852
+ columnGap: 12
2853
+ },
2854
+ missionButton: {
2855
+ minHeight: MIN_TOUCH_TARGET2,
2856
+ justifyContent: "center"
2857
+ },
2537
2858
  poweredByContainer: {
2538
2859
  alignItems: "center",
2539
2860
  paddingVertical: 4
@@ -2624,9 +2945,9 @@ function createAppilotsInput(WrappedComponent) {
2624
2945
  label: label ?? fieldId,
2625
2946
  screen: appilotsScreen
2626
2947
  };
2627
- chunkUZ2D4BVX_js.componentRegistry.register(fieldId, entry);
2948
+ chunkQAZ4TN3Z_js.componentRegistry.register(fieldId, entry);
2628
2949
  return () => {
2629
- chunkUZ2D4BVX_js.componentRegistry.unregister(fieldId);
2950
+ chunkQAZ4TN3Z_js.componentRegistry.unregister(fieldId);
2630
2951
  };
2631
2952
  }, [
2632
2953
  fieldId,
@@ -2686,9 +3007,9 @@ function createAppilotsButton(WrappedComponent) {
2686
3007
  label: title ?? targetId,
2687
3008
  screen: appilotsScreen
2688
3009
  };
2689
- chunkUZ2D4BVX_js.componentRegistry.register(targetId, entry);
3010
+ chunkQAZ4TN3Z_js.componentRegistry.register(targetId, entry);
2690
3011
  return () => {
2691
- chunkUZ2D4BVX_js.componentRegistry.unregister(targetId);
3012
+ chunkQAZ4TN3Z_js.componentRegistry.unregister(targetId);
2692
3013
  };
2693
3014
  }, [targetId, appilotsEnabled, press, title, appilotsScreen]);
2694
3015
  return /* @__PURE__ */ React8__namespace.default.createElement(
@@ -2732,9 +3053,9 @@ function createAppilotsSwitch(WrappedComponent) {
2732
3053
  label: label ?? toggleId,
2733
3054
  screen: appilotsScreen
2734
3055
  };
2735
- chunkUZ2D4BVX_js.componentRegistry.register(toggleId, entry);
3056
+ chunkQAZ4TN3Z_js.componentRegistry.register(toggleId, entry);
2736
3057
  return () => {
2737
- chunkUZ2D4BVX_js.componentRegistry.unregister(toggleId);
3058
+ chunkQAZ4TN3Z_js.componentRegistry.unregister(toggleId);
2738
3059
  };
2739
3060
  }, [toggleId, appilotsEnabled, getValue, setValue, label, appilotsScreen]);
2740
3061
  return /* @__PURE__ */ React8__namespace.default.createElement(
@@ -2755,231 +3076,235 @@ function createAppilotsSwitch(WrappedComponent) {
2755
3076
 
2756
3077
  Object.defineProperty(exports, "AppilotsNavigationContainer", {
2757
3078
  enumerable: true,
2758
- get: function () { return chunkALJGKORS_js.AppilotsNavigationContainer; }
3079
+ get: function () { return chunkGDCBLSYT_js.AppilotsNavigationContainer; }
2759
3080
  });
2760
3081
  Object.defineProperty(exports, "AppilotsI18nProvider", {
2761
3082
  enumerable: true,
2762
- get: function () { return chunkAJDHZRBN_js.AppilotsI18nProvider; }
3083
+ get: function () { return chunkJGUDXRXN_js.AppilotsI18nProvider; }
2763
3084
  });
2764
3085
  Object.defineProperty(exports, "REVEAL_MARGIN", {
2765
3086
  enumerable: true,
2766
- get: function () { return chunkAJDHZRBN_js.REVEAL_MARGIN; }
3087
+ get: function () { return chunkJGUDXRXN_js.REVEAL_MARGIN; }
2767
3088
  });
2768
3089
  Object.defineProperty(exports, "SPOTLIGHT_TTL_MS", {
2769
3090
  enumerable: true,
2770
- get: function () { return chunkAJDHZRBN_js.SPOTLIGHT_TTL_MS; }
3091
+ get: function () { return chunkJGUDXRXN_js.SPOTLIGHT_TTL_MS; }
2771
3092
  });
2772
3093
  Object.defineProperty(exports, "appilotsSelfCheck", {
2773
3094
  enumerable: true,
2774
- get: function () { return chunkAJDHZRBN_js.appilotsSelfCheck; }
3095
+ get: function () { return chunkJGUDXRXN_js.appilotsSelfCheck; }
2775
3096
  });
2776
3097
  Object.defineProperty(exports, "captureSnapshot", {
2777
3098
  enumerable: true,
2778
- get: function () { return chunkAJDHZRBN_js.captureSnapshot; }
3099
+ get: function () { return chunkJGUDXRXN_js.captureSnapshot; }
2779
3100
  });
2780
3101
  Object.defineProperty(exports, "detectDeviceLocale", {
2781
3102
  enumerable: true,
2782
- get: function () { return chunkAJDHZRBN_js.detectDeviceLocale; }
3103
+ get: function () { return chunkJGUDXRXN_js.detectDeviceLocale; }
2783
3104
  });
2784
3105
  Object.defineProperty(exports, "executeAction", {
2785
3106
  enumerable: true,
2786
- get: function () { return chunkAJDHZRBN_js.executeAction; }
3107
+ get: function () { return chunkJGUDXRXN_js.executeAction; }
2787
3108
  });
2788
3109
  Object.defineProperty(exports, "getSpotlightMode", {
2789
3110
  enumerable: true,
2790
- get: function () { return chunkAJDHZRBN_js.getSpotlightMode; }
3111
+ get: function () { return chunkJGUDXRXN_js.getSpotlightMode; }
2791
3112
  });
2792
3113
  Object.defineProperty(exports, "getSpotlightTarget", {
2793
3114
  enumerable: true,
2794
- get: function () { return chunkAJDHZRBN_js.getSpotlightTarget; }
3115
+ get: function () { return chunkJGUDXRXN_js.getSpotlightTarget; }
2795
3116
  });
2796
3117
  Object.defineProperty(exports, "offsetToReveal", {
2797
3118
  enumerable: true,
2798
- get: function () { return chunkAJDHZRBN_js.offsetToReveal; }
3119
+ get: function () { return chunkJGUDXRXN_js.offsetToReveal; }
2799
3120
  });
2800
3121
  Object.defineProperty(exports, "resolveLocale", {
2801
3122
  enumerable: true,
2802
- get: function () { return chunkAJDHZRBN_js.resolveLocale; }
3123
+ get: function () { return chunkJGUDXRXN_js.resolveLocale; }
2803
3124
  });
2804
3125
  Object.defineProperty(exports, "revealTarget", {
2805
3126
  enumerable: true,
2806
- get: function () { return chunkAJDHZRBN_js.revealTarget; }
3127
+ get: function () { return chunkJGUDXRXN_js.revealTarget; }
2807
3128
  });
2808
3129
  Object.defineProperty(exports, "setSpotlightMode", {
2809
3130
  enumerable: true,
2810
- get: function () { return chunkAJDHZRBN_js.setSpotlightMode; }
3131
+ get: function () { return chunkJGUDXRXN_js.setSpotlightMode; }
2811
3132
  });
2812
3133
  Object.defineProperty(exports, "setSpotlightTarget", {
2813
3134
  enumerable: true,
2814
- get: function () { return chunkAJDHZRBN_js.setSpotlightTarget; }
3135
+ get: function () { return chunkJGUDXRXN_js.setSpotlightTarget; }
2815
3136
  });
2816
3137
  Object.defineProperty(exports, "subscribeSpotlight", {
2817
3138
  enumerable: true,
2818
- get: function () { return chunkAJDHZRBN_js.subscribeSpotlight; }
3139
+ get: function () { return chunkJGUDXRXN_js.subscribeSpotlight; }
2819
3140
  });
2820
3141
  Object.defineProperty(exports, "useAppilots", {
2821
3142
  enumerable: true,
2822
- get: function () { return chunkAJDHZRBN_js.useAppilots; }
3143
+ get: function () { return chunkJGUDXRXN_js.useAppilots; }
2823
3144
  });
2824
3145
  Object.defineProperty(exports, "useAppilotsActions", {
2825
3146
  enumerable: true,
2826
- get: function () { return chunkAJDHZRBN_js.useAppilotsActions; }
3147
+ get: function () { return chunkJGUDXRXN_js.useAppilotsActions; }
2827
3148
  });
2828
3149
  Object.defineProperty(exports, "useAppilotsChat", {
2829
3150
  enumerable: true,
2830
- get: function () { return chunkAJDHZRBN_js.useAppilotsChat; }
3151
+ get: function () { return chunkJGUDXRXN_js.useAppilotsChat; }
2831
3152
  });
2832
3153
  Object.defineProperty(exports, "useAppilotsField", {
2833
3154
  enumerable: true,
2834
- get: function () { return chunkAJDHZRBN_js.useAppilotsField; }
3155
+ get: function () { return chunkJGUDXRXN_js.useAppilotsField; }
2835
3156
  });
2836
3157
  Object.defineProperty(exports, "useAppilotsI18n", {
2837
3158
  enumerable: true,
2838
- get: function () { return chunkAJDHZRBN_js.useAppilotsI18n; }
3159
+ get: function () { return chunkJGUDXRXN_js.useAppilotsI18n; }
2839
3160
  });
2840
3161
  Object.defineProperty(exports, "useAppilotsNavigation", {
2841
3162
  enumerable: true,
2842
- get: function () { return chunkAJDHZRBN_js.useAppilotsNavigation; }
3163
+ get: function () { return chunkJGUDXRXN_js.useAppilotsNavigation; }
2843
3164
  });
2844
3165
  Object.defineProperty(exports, "useAppilotsSlider", {
2845
3166
  enumerable: true,
2846
- get: function () { return chunkAJDHZRBN_js.useAppilotsSlider; }
3167
+ get: function () { return chunkJGUDXRXN_js.useAppilotsSlider; }
2847
3168
  });
2848
3169
  Object.defineProperty(exports, "useAppilotsTarget", {
2849
3170
  enumerable: true,
2850
- get: function () { return chunkAJDHZRBN_js.useAppilotsTarget; }
3171
+ get: function () { return chunkJGUDXRXN_js.useAppilotsTarget; }
2851
3172
  });
2852
3173
  Object.defineProperty(exports, "useAppilotsToggle", {
2853
3174
  enumerable: true,
2854
- get: function () { return chunkAJDHZRBN_js.useAppilotsToggle; }
3175
+ get: function () { return chunkJGUDXRXN_js.useAppilotsToggle; }
2855
3176
  });
2856
3177
  Object.defineProperty(exports, "useSuggestedPrompts", {
2857
3178
  enumerable: true,
2858
- get: function () { return chunkAJDHZRBN_js.useSuggestedPrompts; }
3179
+ get: function () { return chunkJGUDXRXN_js.useSuggestedPrompts; }
2859
3180
  });
2860
3181
  Object.defineProperty(exports, "AppilotsClient", {
2861
3182
  enumerable: true,
2862
- get: function () { return chunkUZ2D4BVX_js.AppilotsClient; }
3183
+ get: function () { return chunkQAZ4TN3Z_js.AppilotsClient; }
2863
3184
  });
2864
3185
  Object.defineProperty(exports, "AppilotsProvider", {
2865
3186
  enumerable: true,
2866
- get: function () { return chunkUZ2D4BVX_js.AppilotsProvider; }
3187
+ get: function () { return chunkQAZ4TN3Z_js.AppilotsProvider; }
2867
3188
  });
2868
3189
  Object.defineProperty(exports, "AppilotsRegistryProvider", {
2869
3190
  enumerable: true,
2870
- get: function () { return chunkUZ2D4BVX_js.AppilotsRegistryProvider; }
3191
+ get: function () { return chunkQAZ4TN3Z_js.AppilotsRegistryProvider; }
2871
3192
  });
2872
3193
  Object.defineProperty(exports, "RateLimitedError", {
2873
3194
  enumerable: true,
2874
- get: function () { return chunkUZ2D4BVX_js.RateLimitedError; }
3195
+ get: function () { return chunkQAZ4TN3Z_js.RateLimitedError; }
2875
3196
  });
2876
3197
  Object.defineProperty(exports, "SDK_VERSION", {
2877
3198
  enumerable: true,
2878
- get: function () { return chunkUZ2D4BVX_js.SDK_VERSION; }
3199
+ get: function () { return chunkQAZ4TN3Z_js.SDK_VERSION; }
2879
3200
  });
2880
3201
  Object.defineProperty(exports, "_patchJsxRuntimes", {
2881
3202
  enumerable: true,
2882
- get: function () { return chunkUZ2D4BVX_js._patchJsxRuntimes; }
3203
+ get: function () { return chunkQAZ4TN3Z_js._patchJsxRuntimes; }
2883
3204
  });
2884
3205
  Object.defineProperty(exports, "clearAppilotsDebugTraces", {
2885
3206
  enumerable: true,
2886
- get: function () { return chunkUZ2D4BVX_js.clearAppilotsDebugTraces; }
3207
+ get: function () { return chunkQAZ4TN3Z_js.clearAppilotsDebugTraces; }
2887
3208
  });
2888
3209
  Object.defineProperty(exports, "componentRegistry", {
2889
3210
  enumerable: true,
2890
- get: function () { return chunkUZ2D4BVX_js.componentRegistry; }
3211
+ get: function () { return chunkQAZ4TN3Z_js.componentRegistry; }
2891
3212
  });
2892
3213
  Object.defineProperty(exports, "createComponentRegistry", {
2893
3214
  enumerable: true,
2894
- get: function () { return chunkUZ2D4BVX_js.createComponentRegistry; }
3215
+ get: function () { return chunkQAZ4TN3Z_js.createComponentRegistry; }
2895
3216
  });
2896
3217
  Object.defineProperty(exports, "createElementRegistry", {
2897
3218
  enumerable: true,
2898
- get: function () { return chunkUZ2D4BVX_js.createElementRegistry; }
3219
+ get: function () { return chunkQAZ4TN3Z_js.createElementRegistry; }
2899
3220
  });
2900
3221
  Object.defineProperty(exports, "createListRegistry", {
2901
3222
  enumerable: true,
2902
- get: function () { return chunkUZ2D4BVX_js.createListRegistry; }
3223
+ get: function () { return chunkQAZ4TN3Z_js.createListRegistry; }
2903
3224
  });
2904
3225
  Object.defineProperty(exports, "defaultDarkTheme", {
2905
3226
  enumerable: true,
2906
- get: function () { return chunkUZ2D4BVX_js.defaultDarkTheme; }
3227
+ get: function () { return chunkQAZ4TN3Z_js.defaultDarkTheme; }
2907
3228
  });
2908
3229
  Object.defineProperty(exports, "defaultLightTheme", {
2909
3230
  enumerable: true,
2910
- get: function () { return chunkUZ2D4BVX_js.defaultLightTheme; }
3231
+ get: function () { return chunkQAZ4TN3Z_js.defaultLightTheme; }
2911
3232
  });
2912
3233
  Object.defineProperty(exports, "describeAction", {
2913
3234
  enumerable: true,
2914
- get: function () { return chunkUZ2D4BVX_js.describeAction; }
3235
+ get: function () { return chunkQAZ4TN3Z_js.describeAction; }
2915
3236
  });
2916
3237
  Object.defineProperty(exports, "elementRegistry", {
2917
3238
  enumerable: true,
2918
- get: function () { return chunkUZ2D4BVX_js.elementRegistry; }
3239
+ get: function () { return chunkQAZ4TN3Z_js.elementRegistry; }
2919
3240
  });
2920
3241
  Object.defineProperty(exports, "enableAppilotsAutoTracking", {
2921
3242
  enumerable: true,
2922
- get: function () { return chunkUZ2D4BVX_js.enableAppilotsAutoTracking; }
3243
+ get: function () { return chunkQAZ4TN3Z_js.enableAppilotsAutoTracking; }
2923
3244
  });
2924
3245
  Object.defineProperty(exports, "getAppilotsDebugTraces", {
2925
3246
  enumerable: true,
2926
- get: function () { return chunkUZ2D4BVX_js.getAppilotsDebugTraces; }
3247
+ get: function () { return chunkQAZ4TN3Z_js.getAppilotsDebugTraces; }
2927
3248
  });
2928
3249
  Object.defineProperty(exports, "getAutoTrackingState", {
2929
3250
  enumerable: true,
2930
- get: function () { return chunkUZ2D4BVX_js.getAutoTrackingState; }
3251
+ get: function () { return chunkQAZ4TN3Z_js.getAutoTrackingState; }
2931
3252
  });
2932
3253
  Object.defineProperty(exports, "getGlobalConfig", {
2933
3254
  enumerable: true,
2934
- get: function () { return chunkUZ2D4BVX_js.getGlobalConfig; }
3255
+ get: function () { return chunkQAZ4TN3Z_js.getGlobalConfig; }
2935
3256
  });
2936
3257
  Object.defineProperty(exports, "getIntrospectionDiagnostics", {
2937
3258
  enumerable: true,
2938
- get: function () { return chunkUZ2D4BVX_js.getIntrospectionDiagnostics; }
3259
+ get: function () { return chunkQAZ4TN3Z_js.getIntrospectionDiagnostics; }
2939
3260
  });
2940
3261
  Object.defineProperty(exports, "humanizeError", {
2941
3262
  enumerable: true,
2942
- get: function () { return chunkUZ2D4BVX_js.humanizeError; }
3263
+ get: function () { return chunkQAZ4TN3Z_js.humanizeError; }
2943
3264
  });
2944
3265
  Object.defineProperty(exports, "initAppilots", {
2945
3266
  enumerable: true,
2946
- get: function () { return chunkUZ2D4BVX_js.initAppilots; }
3267
+ get: function () { return chunkQAZ4TN3Z_js.initAppilots; }
2947
3268
  });
2948
3269
  Object.defineProperty(exports, "isAutoTrackingEnabled", {
2949
3270
  enumerable: true,
2950
- get: function () { return chunkUZ2D4BVX_js.isAutoTrackingEnabled; }
3271
+ get: function () { return chunkQAZ4TN3Z_js.isAutoTrackingEnabled; }
3272
+ });
3273
+ Object.defineProperty(exports, "isSpeechHost", {
3274
+ enumerable: true,
3275
+ get: function () { return chunkQAZ4TN3Z_js.isSpeechHost; }
2951
3276
  });
2952
3277
  Object.defineProperty(exports, "listRegistry", {
2953
3278
  enumerable: true,
2954
- get: function () { return chunkUZ2D4BVX_js.listRegistry; }
3279
+ get: function () { return chunkQAZ4TN3Z_js.listRegistry; }
2955
3280
  });
2956
3281
  Object.defineProperty(exports, "mergeThemeTokens", {
2957
3282
  enumerable: true,
2958
- get: function () { return chunkUZ2D4BVX_js.mergeThemeTokens; }
3283
+ get: function () { return chunkQAZ4TN3Z_js.mergeThemeTokens; }
2959
3284
  });
2960
3285
  Object.defineProperty(exports, "recordAppilotsDebugTrace", {
2961
3286
  enumerable: true,
2962
- get: function () { return chunkUZ2D4BVX_js.recordAppilotsDebugTrace; }
3287
+ get: function () { return chunkQAZ4TN3Z_js.recordAppilotsDebugTrace; }
2963
3288
  });
2964
3289
  Object.defineProperty(exports, "registerScreen", {
2965
3290
  enumerable: true,
2966
- get: function () { return chunkUZ2D4BVX_js.registerScreen; }
3291
+ get: function () { return chunkQAZ4TN3Z_js.registerScreen; }
2967
3292
  });
2968
3293
  Object.defineProperty(exports, "setCurrentScreen", {
2969
3294
  enumerable: true,
2970
- get: function () { return chunkUZ2D4BVX_js.setCurrentScreen; }
3295
+ get: function () { return chunkQAZ4TN3Z_js.setCurrentScreen; }
2971
3296
  });
2972
3297
  Object.defineProperty(exports, "subscribeAppilotsDebugTraces", {
2973
3298
  enumerable: true,
2974
- get: function () { return chunkUZ2D4BVX_js.subscribeAppilotsDebugTraces; }
3299
+ get: function () { return chunkQAZ4TN3Z_js.subscribeAppilotsDebugTraces; }
2975
3300
  });
2976
3301
  Object.defineProperty(exports, "useAppilotsContext", {
2977
3302
  enumerable: true,
2978
- get: function () { return chunkUZ2D4BVX_js.useAppilotsContext; }
3303
+ get: function () { return chunkQAZ4TN3Z_js.useAppilotsContext; }
2979
3304
  });
2980
3305
  Object.defineProperty(exports, "useResolvedRegistry", {
2981
3306
  enumerable: true,
2982
- get: function () { return chunkUZ2D4BVX_js.useResolvedRegistry; }
3307
+ get: function () { return chunkQAZ4TN3Z_js.useResolvedRegistry; }
2983
3308
  });
2984
3309
  exports.ActionBreadcrumb = ActionBreadcrumb;
2985
3310
  exports.AgentPill = AgentPill;