@ateam-ai-mobile/ui 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/AdasChatScreen.tsx","../src/chat/MessageBubble.tsx","../src/chat/JobProgressBar.tsx","../src/chat/UIActionsRow.tsx","../src/providers.ts","../src/plugin/WidgetHost.tsx","../src/plugin/PluginSurface.tsx","../src/plugin/Plugin.tsx","../src/plugin/EmbeddedPluginWebView.tsx","../src/plugin/usePluginBridge.ts","../src/chat/TableCardBlock.tsx","../src/stores/lightboxStore.ts","../src/chat/TypingIndicator.tsx","../src/chat/ChatInput.tsx","../src/Lightbox.tsx","../src/widgets/WidgetWebView.tsx","../src/TenantPicker.tsx","../src/voice/VoiceCallSheet.tsx","../src/voice/useVoiceCall.ts"],"sourcesContent":["/**\n * AdasChatScreen — the drop-in ADAS chat experience.\n *\n * Push it as a screen or mount it full-flex anywhere: message history with\n * live agent progress, day separators, UI-action chips, table cards,\n * attachment previews, pull-to-refresh, and the composer. Built ONLY on the\n * public @ateam-ai-mobile/core + @ateam-ai-mobile/plugin-runtime APIs.\n *\n * The host must call initAdas() first, and typically:\n * setUIActionNavigator(route => router.push(...)) // chips → plugin screen\n * setupExpoProviders() // Expo hosts\n *\n * Also mount <SurfaceDispatcher /> once at the app root so engine-summoned\n * plugin surfaces (drawers/fullscreens) can appear over the chat.\n */\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n FlatList,\n KeyboardAvoidingView,\n Platform,\n RefreshControl,\n StyleSheet,\n View,\n} from 'react-native';\nimport { ada, useChatStore, pluginCommandEmitter } from '@ateam-ai-mobile/core';\nimport type { Message } from '@ateam-ai-mobile/core';\nimport MessageBubble, { DaySeparator } from './chat/MessageBubble';\nimport TypingIndicator from './chat/TypingIndicator';\nimport ChatInput from './chat/ChatInput';\nimport Lightbox from './Lightbox';\nimport WidgetHost from './plugin/WidgetHost';\n\nexport interface AdasChatScreenProps {\n /** Called when the user taps the call button; omit to hide it. */\n onCallStart?: () => void;\n /** Composer placeholder. */\n placeholder?: string;\n /** Extra element rendered above the composer (e.g. suggestion chips). */\n footerAccessory?: React.ReactNode;\n /** Mount the fullscreen image viewer here. Default true — set false if\n * the host already mounts <Lightbox /> at its root. */\n withLightbox?: boolean;\n}\n\nfunction isSameDay(a: Date, b: Date): boolean {\n return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();\n}\n\nexport default function AdasChatScreen({\n onCallStart,\n placeholder,\n footerAccessory,\n withLightbox = true,\n}: AdasChatScreenProps) {\n const messages = useChatStore(s => s.messages);\n const loading = useChatStore(s => s.loading);\n const conversationLoaded = useChatStore(s => s.conversationLoaded);\n const loadConversation = useChatStore(s => s.loadConversation);\n const sendMessage = useChatStore(s => s.sendMessage);\n\n const listRef = useRef<FlatList<Message>>(null);\n const [refreshing, setRefreshing] = useState(false);\n const [prefill, setPrefill] = useState('');\n\n // Initial history load.\n useEffect(() => {\n if (!conversationLoaded) loadConversation();\n }, [conversationLoaded, loadConversation]);\n\n // bridge.prepareMessage(text) → pre-fill the composer without sending.\n useEffect(() => {\n const unsub = pluginCommandEmitter.on('prepare-chat-message', ({ text }: { text?: string }) => {\n if (text) setPrefill(text);\n });\n return unsub;\n }, []);\n\n // Inverted list — newest at the bottom without scroll management. On WEB\n // `inverted` is a scaleY(-1) transform that react-native-web applies to the\n // container but not reliably to items — content renders upside-down. Use a\n // normal list there and scroll to the end instead.\n const useInverted = Platform.OS !== 'web';\n const listData = useMemo(\n () => (useInverted ? [...messages].reverse() : messages),\n [messages, useInverted],\n );\n\n const scrollToLatest = useCallback((animated: boolean) => {\n if (useInverted) listRef.current?.scrollToOffset({ offset: 0, animated });\n else listRef.current?.scrollToEnd({ animated });\n }, [useInverted]);\n\n const handleSend = useCallback((text: string) => {\n setPrefill('');\n sendMessage(text);\n scrollToLatest(true);\n }, [sendMessage, scrollToLatest]);\n\n const handleRefresh = useCallback(async () => {\n setRefreshing(true);\n try { await loadConversation(); } catch {}\n setRefreshing(false);\n }, [loadConversation]);\n\n const renderItem = useCallback(({ item, index }: { item: Message; index: number }) => {\n // The \"previous\" (older) message is the NEXT array item when inverted,\n // the previous one otherwise.\n const older = useInverted ? listData[index + 1] : listData[index - 1];\n const showDaySep = !older || !isSameDay(older.timestamp, item.timestamp);\n return (\n <View>\n {showDaySep && <DaySeparator date={item.timestamp} />}\n <MessageBubble message={item} />\n </View>\n );\n }, [listData, useInverted]);\n\n const typingIndicator =\n loading && !(useInverted ? listData[0] : listData[listData.length - 1])?.jobProgress\n ? <TypingIndicator />\n : null;\n\n return (\n <KeyboardAvoidingView\n style={styles.root}\n behavior={Platform.OS === 'ios' ? 'padding' : undefined}\n >\n <FlatList\n ref={listRef}\n style={styles.list}\n data={listData}\n inverted={useInverted}\n keyExtractor={m => m.id}\n renderItem={renderItem}\n // In an inverted list the header renders at the visual BOTTOM — where\n // the typing indicator belongs; on web (non-inverted) it's the footer.\n // Suppressed when the newest bubble already shows its progress pill.\n ListHeaderComponent={useInverted ? typingIndicator : null}\n ListFooterComponent={useInverted ? null : typingIndicator}\n onContentSizeChange={useInverted ? undefined : () => scrollToLatest(false)}\n refreshControl={\n <RefreshControl refreshing={refreshing} onRefresh={handleRefresh} tintColor={ada.orange} />\n }\n keyboardShouldPersistTaps=\"handled\"\n contentContainerStyle={styles.listContent}\n />\n {footerAccessory}\n <ChatInput\n onSend={handleSend}\n onCallStart={onCallStart}\n loading={loading}\n prefill={prefill}\n placeholder={placeholder}\n />\n {withLightbox && <Lightbox />}\n {/* Built-in widget presenter: chips without a host navigator and\n agent-driven focus-plugin events open widgets here — zero wiring. */}\n <WidgetHost />\n </KeyboardAvoidingView>\n );\n}\n\nconst styles = StyleSheet.create({\n root: {\n flex: 1,\n backgroundColor: ada.paper,\n },\n list: {\n flex: 1,\n },\n listContent: {\n paddingVertical: 12,\n },\n});\n","import { useState, useCallback } from 'react';\nimport { View, Text, Pressable, StyleSheet, Image, Platform } from 'react-native';\nimport Markdown from 'react-native-markdown-display';\nimport type { Message, ToolCall } from '@ateam-ai-mobile/core';\nimport { TABLE_BLOCK_OPEN, TABLE_BLOCK_CLOSE, getConfig, ada, borderRadius, fontSize } from '@ateam-ai-mobile/core';\nimport { AdaOrb, getHaptics } from '@ateam-ai-mobile/plugin-runtime';\nimport JobProgressBar from './JobProgressBar';\nimport UIActionsRow from './UIActionsRow';\nimport TableCardBlock from './TableCardBlock';\nimport { useLightboxStore } from '../stores/lightboxStore';\nimport { getClipboard } from '../providers';\n\nconst fontFam = Platform.OS === 'ios' ? 'SF Pro Rounded' : undefined;\n\ninterface Props {\n message: Message;\n}\n\nfunction formatTime(date: Date): string {\n const h = date.getHours();\n const m = date.getMinutes().toString().padStart(2, '0');\n return `${h}:${m}`;\n}\n\nexport function DaySeparator({ date }: { date: Date }) {\n const today = new Date();\n const yesterday = new Date(today);\n yesterday.setDate(yesterday.getDate() - 1);\n\n let label: string;\n if (isSameDay(date, today)) {\n label = 'Today';\n } else if (isSameDay(date, yesterday)) {\n label = 'Yesterday';\n } else {\n label = date.toLocaleDateString(undefined, { weekday: 'long', month: 'short', day: 'numeric' });\n }\n\n return (\n <View style={separatorStyles.container}>\n <View style={separatorStyles.pill}>\n <Text style={separatorStyles.text}>{label}</Text>\n </View>\n </View>\n );\n}\n\nfunction isSameDay(a: Date, b: Date): boolean {\n return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();\n}\n\nconst separatorStyles = StyleSheet.create({\n container: {\n alignItems: 'center',\n marginVertical: 14,\n },\n pill: {\n backgroundColor: ada.paperSoft,\n paddingHorizontal: 14,\n paddingVertical: 5,\n borderRadius: 999,\n },\n text: {\n fontSize: 12,\n fontWeight: '600',\n color: ada.inkMuted,\n letterSpacing: 0.4,\n fontFamily: fontFam,\n },\n});\n\nexport default function MessageBubble({ message }: Props) {\n const isUser = message.role === 'user';\n const isSystem = message.role === 'system';\n const isNotification = !isUser && message.kind === 'notification';\n // A \"working on it\" placeholder — just the live chain indicator, no real\n // answer yet. Render it near-transparent so it floats over the background\n // instead of looking like a solid message bubble.\n const st = message.jobProgress?.status;\n const isProgressOnly =\n !isUser &&\n (st === 'running' || st === 'paused') &&\n (!message.content?.trim() || message.content === 'Working on it...');\n const [copied, setCopied] = useState('');\n\n const showCopied = useCallback((label: string) => {\n setCopied(label);\n getHaptics()?.notification('success');\n setTimeout(() => setCopied(''), 1500);\n }, []);\n\n const copyText = useCallback(async (text: string) => {\n const clipboard = getClipboard();\n if (!clipboard) return; // no provider — silently skip (no false \"Copied!\")\n await clipboard.setString(text);\n showCopied('Copied!');\n }, [showCopied]);\n\n const handleLongPress = useCallback(() => {\n copyText(message.content);\n }, [message.content, copyText]);\n\n return (\n <View style={[styles.row, isUser && styles.rowUser]}>\n {!isUser && !isNotification && (\n <View style={styles.avatarOrb}>\n <AdaOrb\n size={28}\n state={message.jobProgress?.status === 'running' ? 'thinking' : 'idle'}\n />\n </View>\n )}\n {isNotification && <View style={styles.notificationLeftStripe} />}\n <Pressable\n accessibilityRole=\"text\"\n accessibilityLabel={`${isUser ? 'You' : isNotification ? 'Notification' : 'Ada'}: ${message.content}`}\n accessibilityHint=\"Long-press to copy\"\n onLongPress={handleLongPress}\n style={[\n styles.bubble,\n isUser && styles.bubbleUser,\n isSystem && styles.bubbleSystem,\n isNotification && styles.bubbleNotification,\n isProgressOnly && styles.bubbleProgress,\n ]}\n >\n {isNotification && (\n <View style={styles.notificationHeader}>\n <Text style={styles.notificationHeaderIcon}>🔔</Text>\n <Text style={styles.notificationHeaderText}>Notification</Text>\n </View>\n )}\n {/* Attachment thumbnails */}\n {message.attachments && message.attachments.length > 0 && (\n <View style={styles.attachments}>\n {message.attachments.map((att, i) => (\n att.previewUri ? (\n <Pressable\n key={i}\n accessibilityRole=\"imagebutton\"\n accessibilityLabel={`Photo${att.name ? `: ${att.name}` : ''}. Tap to enlarge.`}\n onPress={() => useLightboxStore.getState().show(att.previewUri!)}\n >\n <Image\n source={{\n uri: att.previewUri,\n ...(att.previewUri.startsWith('http') ? {\n headers: { Authorization: `Bearer ${getConfig().tokenProvider.getToken()}` },\n } : {}),\n }}\n style={styles.attachmentImage}\n resizeMode=\"cover\"\n onError={(e) => console.warn('[Image] Failed to load:', att.previewUri?.slice(0, 100), e.nativeEvent.error)}\n />\n </Pressable>\n ) : (\n <View key={i} style={styles.attachmentFile}>\n <Text style={styles.attachmentFileName} numberOfLines={1}>{att.name}</Text>\n </View>\n )\n ))}\n </View>\n )}\n {isUser ? (\n // Hide the \"See attachment\" placeholder when the bubble already shows the photo.\n message.content && !(message.content === 'See attachment' && message.attachments?.length) ? (\n <Text selectable style={styles.userText}>{message.content}</Text>\n ) : null\n ) : isProgressOnly ? (\n // No \"Working on it…\" text — the indicator below is the whole message.\n null\n ) : (\n renderAssistantContent(message.content, copyText)\n )}\n {!!copied && (\n <View style={styles.copiedBadge}>\n <Text style={styles.copiedText}>{copied}</Text>\n </View>\n )}\n {message.toolCalls && message.toolCalls.length > 0 && (\n <ToolCallsBadge calls={message.toolCalls} />\n )}\n {message.jobProgress && (\n <JobProgressBar progress={message.jobProgress} standalone={isProgressOnly} />\n )}\n {!isUser && message.actions && message.actions.length > 0 && (\n <UIActionsRow actions={message.actions} />\n )}\n {!isProgressOnly && (\n <Text style={[styles.timeText, isUser && styles.timeTextUser]}>\n {formatTime(message.timestamp)}\n </Text>\n )}\n </Pressable>\n {isUser && <View style={styles.avatarSpacer} />}\n </View>\n );\n}\n\n/**\n * Split assistant content on table-block sentinels and render each segment:\n * markdown text → <Markdown>, table payload → <TableCardBlock>. Falls back\n * to plain markdown when no sentinels are present (the common case).\n */\nfunction renderAssistantContent(content: string, copyText: (s: string) => void) {\n if (!content) return null;\n if (!content.includes(TABLE_BLOCK_OPEN)) {\n return <MarkdownBubble content={content} copyText={copyText} />;\n }\n\n const segments: Array<{ kind: 'md' | 'table'; content: string }> = [];\n let cursor = 0;\n while (cursor < content.length) {\n const open = content.indexOf(TABLE_BLOCK_OPEN, cursor);\n if (open === -1) {\n segments.push({ kind: 'md', content: content.slice(cursor) });\n break;\n }\n if (open > cursor) {\n segments.push({ kind: 'md', content: content.slice(cursor, open) });\n }\n const close = content.indexOf(TABLE_BLOCK_CLOSE, open + TABLE_BLOCK_OPEN.length);\n if (close === -1) {\n // Unterminated marker — render the rest as markdown so we don't lose data.\n segments.push({ kind: 'md', content: content.slice(open) });\n break;\n }\n const payload = content.slice(open + TABLE_BLOCK_OPEN.length, close);\n segments.push({ kind: 'table', content: payload });\n cursor = close + TABLE_BLOCK_CLOSE.length;\n }\n\n return (\n <>\n {segments.map((seg, i) => {\n if (seg.kind === 'md') {\n const trimmed = seg.content.trim();\n if (!trimmed) return null;\n return <MarkdownBubble key={i} content={seg.content} copyText={copyText} />;\n }\n try {\n const data = JSON.parse(decodeURIComponent(seg.content));\n return <TableCardBlock key={i} columns={data.columns} rows={data.rows} />;\n } catch {\n return null;\n }\n })}\n </>\n );\n}\n\nfunction MarkdownBubble({ content, copyText }: { content: string; copyText: (s: string) => void }) {\n return (\n <Markdown\n style={markdownStyles}\n rules={{\n code_inline: (node) => (\n <Text\n key={node.key}\n style={markdownStyles.code_inline}\n onPress={() => copyText(node.content)}\n >\n {node.content}\n </Text>\n ),\n fence: (node) => (\n <Pressable\n key={node.key}\n onPress={() => copyText(node.content)}\n style={markdownStyles.fence}\n >\n <Text style={markdownStyles.fenceText}>{node.content}</Text>\n </Pressable>\n ),\n }}\n >\n {content}\n </Markdown>\n );\n}\n\nfunction ToolCallsBadge({ calls }: { calls: ToolCall[] }) {\n const [expanded, setExpanded] = useState(false);\n const label = calls\n .filter(c => c.name === 'send_message_to_skill')\n .map(c => (c.args as any).skill_name || c.skill)\n .filter(Boolean)\n .join(', ') || 'Tool call';\n\n return (\n <View style={styles.toolCalls}>\n <Pressable style={styles.toolToggle} onPress={() => setExpanded(!expanded)}>\n <Text style={styles.toolLabel}>{label}</Text>\n <Text style={styles.toolChevron}>{expanded ? '▲' : '▼'}</Text>\n </Pressable>\n {expanded && calls.map((tc, i) => (\n <View key={i} style={styles.toolItem}>\n <Text style={styles.toolName}>{tc.name}</Text>\n {tc.skill && <Text style={styles.toolSkill}>{tc.skill}</Text>}\n </View>\n ))}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n row: {\n flexDirection: 'row',\n alignItems: 'flex-end',\n marginBottom: 12,\n paddingHorizontal: 12,\n gap: 8,\n },\n rowUser: {\n justifyContent: 'flex-end',\n },\n avatarOrb: {\n width: 28,\n height: 28,\n justifyContent: 'center',\n alignItems: 'center',\n },\n avatarSpacer: {\n width: 28,\n height: 28,\n },\n bubble: {\n maxWidth: '78%',\n backgroundColor: ada.botBubble,\n borderWidth: 1,\n borderColor: ada.botBubbleBorder,\n borderRadius: borderRadius.xl,\n paddingHorizontal: 16,\n paddingVertical: 12,\n },\n bubbleUser: {\n backgroundColor: ada.userBubble,\n borderColor: 'transparent',\n },\n // Live-chain placeholder: no fill, no border, tighter padding — the\n // indicator floats over the background instead of sitting in a bubble.\n bubbleProgress: {\n backgroundColor: 'transparent',\n borderColor: 'transparent',\n paddingHorizontal: 4,\n paddingVertical: 2,\n },\n bubbleSystem: {\n backgroundColor: ada.orangeSoft,\n borderColor: ada.orange,\n maxWidth: '90%',\n },\n bubbleNotification: {\n backgroundColor: ada.orangeSoft,\n borderColor: 'rgba(255, 122, 40, 0.35)',\n borderRadius: borderRadius.lg,\n maxWidth: '90%',\n },\n notificationLeftStripe: {\n width: 3,\n alignSelf: 'stretch',\n backgroundColor: ada.orange,\n borderRadius: 2,\n marginRight: 4,\n },\n notificationHeader: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 6,\n marginBottom: 6,\n },\n notificationHeaderIcon: {\n fontSize: 12,\n },\n notificationHeaderText: {\n color: ada.orangeDeep,\n fontSize: 11,\n fontWeight: '700',\n letterSpacing: 0.6,\n textTransform: 'uppercase',\n fontFamily: fontFam,\n },\n userText: {\n color: ada.userBubbleText,\n fontSize: fontSize.md,\n lineHeight: 22,\n fontFamily: fontFam,\n },\n timeText: {\n fontSize: 11,\n color: ada.inkMuted,\n alignSelf: 'flex-end',\n marginTop: 4,\n fontFamily: fontFam,\n },\n timeTextUser: {\n color: 'rgba(250,246,238,0.55)',\n },\n attachments: {\n flexDirection: 'row',\n flexWrap: 'wrap',\n gap: 6,\n marginBottom: 8,\n },\n attachmentImage: {\n width: 120,\n height: 90,\n borderRadius: 8,\n },\n attachmentFile: {\n backgroundColor: 'rgba(255,255,255,0.15)',\n borderRadius: 8,\n paddingHorizontal: 10,\n paddingVertical: 6,\n },\n attachmentFileName: {\n color: 'rgba(255,255,255,0.8)',\n fontSize: 11,\n maxWidth: 100,\n },\n copiedBadge: {\n position: 'absolute',\n top: 6,\n right: 6,\n backgroundColor: '#5A8A5C',\n paddingHorizontal: 8,\n paddingVertical: 2,\n borderRadius: borderRadius.sm,\n },\n copiedText: {\n color: '#fff',\n fontSize: fontSize.xs,\n fontWeight: '600',\n },\n toolCalls: {\n marginTop: 8,\n borderTopWidth: 1,\n borderTopColor: ada.border,\n paddingTop: 6,\n },\n toolToggle: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 6,\n },\n toolLabel: {\n color: ada.inkSoft,\n fontSize: fontSize.xs,\n fontWeight: '500',\n },\n toolChevron: {\n color: ada.inkMuted,\n fontSize: 8,\n },\n toolItem: {\n marginTop: 4,\n paddingLeft: 8,\n },\n toolName: {\n color: ada.inkSoft,\n fontSize: fontSize.xs,\n fontFamily: 'monospace',\n },\n toolSkill: {\n color: ada.orangeDeep,\n fontSize: fontSize.xs,\n },\n});\n\nconst markdownStyles = StyleSheet.create({\n body: {\n color: ada.botBubbleText,\n fontSize: fontSize.md,\n lineHeight: 22,\n fontFamily: fontFam,\n },\n paragraph: {\n marginTop: 0,\n marginBottom: 4,\n },\n strong: {\n fontWeight: '700',\n color: ada.botBubbleText,\n },\n em: {\n fontStyle: 'italic',\n },\n code_inline: {\n backgroundColor: ada.paperDeep,\n color: ada.orangeDeep,\n paddingHorizontal: 5,\n paddingVertical: 1,\n borderRadius: 4,\n fontFamily: 'monospace',\n fontSize: fontSize.sm,\n },\n fence: {\n backgroundColor: ada.paperDeep,\n padding: 10,\n borderRadius: 10,\n },\n fenceText: {\n fontFamily: 'monospace',\n fontSize: fontSize.sm,\n color: ada.ink,\n },\n link: {\n color: ada.orangeDeep,\n },\n list_item: {\n color: ada.botBubbleText,\n },\n bullet_list: {\n marginVertical: 4,\n },\n});\n","import { useEffect, useRef, useState } from 'react';\nimport { View, Text, Animated, StyleSheet } from 'react-native';\nimport type { JobProgress } from '@ateam-ai-mobile/core';\nimport { ada, fontSize } from '@ateam-ai-mobile/core';\n\n// Semantic warm-palette colors for terminal states (kept local — Ada palette\n// is mostly orange/ink, but progress states need a small warm green/red/amber\n// vocabulary to stay readable).\nconst WARM_GREEN = '#5A8A5C';\nconst WARM_GREEN_SOFT = 'rgba(90, 138, 92, 0.14)';\nconst WARM_RED = '#C15545';\nconst WARM_RED_SOFT = 'rgba(193, 85, 69, 0.14)';\nconst WARM_AMBER = '#D49A4E';\nconst WARM_AMBER_SOFT = 'rgba(212, 154, 78, 0.16)';\n\ninterface Props {\n progress: JobProgress;\n /** Standalone placeholder (transparent bubble) — drop the top divider so it\n * floats cleanly over the background. */\n standalone?: boolean;\n}\n\nexport default function JobProgressBar({ progress, standalone }: Props) {\n const pulseAnim = useRef(new Animated.Value(0.5)).current;\n const [elapsed, setElapsed] = useState(0);\n\n const isRunning = progress.status === 'running';\n const isDone = progress.status === 'done';\n const isError = progress.status === 'error';\n const isPaused = progress.status === 'paused';\n\n // Pulse animation while running\n useEffect(() => {\n if (!isRunning) {\n pulseAnim.setValue(1);\n return;\n }\n const anim = Animated.loop(\n Animated.sequence([\n // Gentle breath — a soft fade rather than a hard blink, so the running\n // indicator recedes into the bubble instead of demanding attention.\n Animated.timing(pulseAnim, { toValue: 0.55, duration: 1100, useNativeDriver: true }),\n Animated.timing(pulseAnim, { toValue: 0.22, duration: 1100, useNativeDriver: true }),\n ]),\n );\n anim.start();\n return () => anim.stop();\n }, [isRunning, pulseAnim]);\n\n // Elapsed timer — ticks every second while running, clears on terminal state\n useEffect(() => {\n if (!isRunning || !progress.chainStartedAt) {\n setElapsed(0);\n return;\n }\n const start = progress.chainStartedAt;\n setElapsed(Math.floor((Date.now() - start) / 1000));\n const id = setInterval(() => {\n setElapsed(Math.floor((Date.now() - start) / 1000));\n }, 1000);\n return () => clearInterval(id);\n }, [isRunning, progress.chainStartedAt]);\n\n const statusColor = isDone\n ? WARM_GREEN\n : isError\n ? WARM_RED\n : isPaused\n ? WARM_AMBER\n : ada.orange;\n\n const statusBg = isDone\n ? WARM_GREEN_SOFT\n : isError\n ? WARM_RED_SOFT\n : isPaused\n ? WARM_AMBER_SOFT\n : ada.orangeSoft;\n\n // Terminal states — simple one-liner\n if (isDone || isError) {\n return (\n <View style={[styles.container, standalone && styles.containerStandalone]}>\n <View style={styles.row}>\n <View style={[styles.dot, { backgroundColor: statusColor }]} />\n <Text style={[styles.label, { color: statusColor }]}>\n {isDone ? 'Completed' : 'Failed'}\n </Text>\n </View>\n </View>\n );\n }\n\n if (isPaused) {\n return (\n <View style={[styles.container, standalone && styles.containerStandalone]}>\n <View style={styles.row}>\n <View style={[styles.dot, { backgroundColor: statusColor }]} />\n <Text style={[styles.label, { color: statusColor }]}>\n Waiting for your reply\n </Text>\n </View>\n </View>\n );\n }\n\n // Running. Prefer the backend's warm, localized humanStatus; fall back to\n // the raw skill/tool tokens (translated via humanLabels when available).\n // Elapsed shows in human units: \"3s\", \"1m 20s\". (Docs/STATUS_I18N_MOBILE_API)\n const elapsedStr = progress.chainStartedAt\n ? elapsed < 60\n ? `${elapsed}s`\n : `${Math.floor(elapsed / 60)}m ${elapsed % 60}s`\n : null;\n\n const metaParts = [\n progress.iteration != null && progress.iteration > 0 ? `iter ${progress.iteration}` : null,\n elapsedStr,\n ].filter(Boolean) as string[];\n\n const labels = progress.humanLabels;\n const label = (t?: string) => (t && labels?.[t]) || t;\n const headline = progress.humanStatus || label(progress.skillSlug) || 'Processing...';\n // When we already have a warm headline, don't also show the raw \"→ tool\".\n const showRawTool = !progress.humanStatus && !!progress.currentTool;\n\n const lp = progress.liveProgress;\n\n return (\n <View style={[styles.container, standalone && styles.containerStandalone]}>\n <View style={styles.row}>\n <Animated.View\n style={[styles.dot, styles.dotRunning, { opacity: pulseAnim }]}\n />\n <Text style={styles.skill} numberOfLines={1}>\n {headline}\n </Text>\n {showRawTool && (\n <Text style={styles.tool} numberOfLines={1}>\n {` → ${label(progress.currentTool)}`}\n </Text>\n )}\n {metaParts.length > 0 && (\n <Text style={styles.meta} numberOfLines={1}>\n {` · ${metaParts.join(' · ')}`}\n </Text>\n )}\n </View>\n {/* Live progress from adas_emit_progress() — shown during fat tool execution */}\n {!!lp?.message && (\n <View style={styles.liveProgressRow}>\n {lp.step != null && lp.total != null && (\n <Text style={styles.liveProgressStep}>[{lp.step}/{lp.total}]</Text>\n )}\n <Text style={styles.liveProgressMsg} numberOfLines={1}>{lp.message}</Text>\n </View>\n )}\n <View style={styles.progressTrack}>\n <Animated.View\n style={[styles.progressFill, { opacity: pulseAnim }]}\n />\n </View>\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n marginTop: 8,\n paddingTop: 8,\n borderTopWidth: 1,\n borderTopColor: ada.border,\n },\n // Standalone (transparent-bubble) placeholder — no divider/top spacing.\n containerStandalone: {\n marginTop: 0,\n paddingTop: 0,\n borderTopWidth: 0,\n },\n row: {\n flexDirection: 'row',\n alignItems: 'center',\n flexWrap: 'nowrap',\n overflow: 'hidden',\n },\n dot: {\n width: 6,\n height: 6,\n borderRadius: 3,\n marginRight: 6,\n flexShrink: 0,\n },\n // Running dot: soft orange, not the full-saturation accent.\n dotRunning: {\n backgroundColor: 'rgba(255, 122, 40, 0.6)',\n },\n label: {\n fontSize: fontSize.xs,\n fontWeight: '600',\n },\n // Running state text segments — muted so the indicator blends into the\n // bubble rather than shouting in orange.\n skill: {\n fontSize: fontSize.xs,\n fontWeight: '500',\n color: ada.inkSoft,\n flexShrink: 1,\n },\n tool: {\n fontSize: fontSize.xs,\n color: ada.inkMuted,\n flexShrink: 2,\n },\n meta: {\n fontSize: fontSize.xs,\n color: ada.inkMuted,\n flexShrink: 0,\n },\n liveProgressRow: {\n flexDirection: 'row',\n alignItems: 'center',\n marginTop: 4,\n gap: 4,\n },\n liveProgressStep: {\n fontSize: fontSize.xs,\n fontWeight: '600',\n color: ada.inkMuted,\n },\n liveProgressMsg: {\n fontSize: fontSize.xs,\n color: ada.inkSoft,\n flex: 1,\n },\n progressTrack: {\n height: 2,\n borderRadius: 1,\n marginTop: 8,\n overflow: 'hidden',\n // Barely-there rail so the bar reads as a hint, not a status meter.\n backgroundColor: 'rgba(26, 20, 16, 0.05)',\n },\n progressFill: {\n height: '100%',\n width: '55%',\n borderRadius: 1,\n // Muted orange — present but recessive.\n backgroundColor: 'rgba(255, 122, 40, 0.4)',\n },\n});\n","// Renders the row of UI Action chips beneath an assistant bubble.\n// Payload comes from `message.actions[]` produced by the polisher and\n// validated by Core's `cp.uiActions_api`.\n//\n// Chips targeting a registered surface mount it directly via the surface\n// store. Everything else goes through the navigator registered with\n// setUIActionNavigator() when the host provided one (no router imports\n// here), or falls back to the built-in WidgetHost presenter — so chips open\n// widgets with zero host wiring.\n\nimport { View, Text, Pressable, StyleSheet, Platform } from 'react-native';\nimport { ada, fontSize } from '@ateam-ai-mobile/core';\nimport type { UIAction } from '@ateam-ai-mobile/core';\nimport { useSurfaceStore, getHaptics } from '@ateam-ai-mobile/plugin-runtime';\nimport { getUIActionNavigator } from '../providers';\nimport { openWidget } from '../plugin/WidgetHost';\n\nconst fontFam = Platform.OS === 'ios' ? 'SF Pro Rounded' : undefined;\n\nconst ICON_MAP: Record<string, string> = {\n timer: '⏱',\n memory: '🧠',\n calendar: '📅',\n home: '🏠',\n bell: '🔔',\n star: '⭐',\n bolt: '⚡',\n};\n\ninterface Props {\n actions: UIAction[];\n}\n\nexport default function UIActionsRow({ actions }: Props) {\n if (!Array.isArray(actions) || actions.length === 0) return null;\n\n const handlePress = (a: UIAction) => {\n getHaptics()?.selection();\n // Validator returns pluginId as the full id (\"mcp:connector:plugin\" for\n // solution plugins, \"platform:<name>\" for host platform screens). Fall\n // back to target (short id) only for debugging.\n const id = a.pluginId || a.target;\n if (!id) return;\n\n // Compute focus once; both branches use it.\n const focus = a.payload?.id || a.payload?.entity_id || a.payload?.focusId;\n\n // Host-rendered platform surfaces live in the surface store, not in the\n // dynamic plugin registry. Mount the registered drawer/fullscreen\n // directly — skip navigation (which would try getPlugin() and fail).\n const surface = useSurfaceStore.getState().manifests[id];\n if (surface) {\n useSurfaceStore.getState().show(id, focus ? { focus } : undefined);\n return;\n }\n\n // Pass payload fields as params so the plugin can focus the relevant\n // entity on load (e.g. ?focus=rem_abc).\n const params: Record<string, string> = {};\n if (focus) params.focus = String(focus);\n if (a.intent === 'suggested_action' && a.payload?.tool) {\n params.tool = String(a.payload.tool);\n if (a.payload?.args) {\n try { params.args = JSON.stringify(a.payload.args); } catch {}\n }\n }\n if (a.intent === 'quick_toggle' && a.payload?.verb) {\n params.verb = String(a.payload.verb);\n }\n\n const navigate = getUIActionNavigator();\n if (navigate) {\n navigate({ pluginId: id, params });\n return;\n }\n // No host navigator — present via the built-in WidgetHost (mounted by\n // AdasChatScreen). Params ride along as engine props.\n openWidget(id, Object.keys(params).length ? params : undefined);\n };\n\n return (\n <View style={styles.row}>\n {actions.map((a, i) => {\n const icon = a.icon ? ICON_MAP[a.icon.toLowerCase()] : null;\n return (\n <Pressable\n key={`${a.target || 'a'}-${i}`}\n accessibilityRole=\"button\"\n accessibilityLabel={a.description || a.label}\n onPress={() => handlePress(a)}\n style={({ pressed }) => [styles.chip, pressed && styles.chipPressed]}\n >\n {icon ? <Text style={styles.icon}>{icon}</Text> : null}\n <Text style={styles.label} numberOfLines={1}>{a.label}</Text>\n </Pressable>\n );\n })}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n row: {\n flexDirection: 'row',\n flexWrap: 'wrap',\n gap: 6,\n marginTop: 10,\n },\n chip: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 6,\n paddingHorizontal: 12,\n paddingVertical: 6,\n backgroundColor: ada.orangeSoft,\n borderColor: ada.orange,\n borderWidth: 1,\n borderRadius: 14,\n },\n chipPressed: {\n backgroundColor: ada.orange,\n },\n icon: {\n fontSize: 12,\n lineHeight: 14,\n },\n label: {\n color: ada.orangeDeep,\n fontSize: fontSize.xs,\n fontWeight: '600',\n fontFamily: fontFam,\n },\n});\n","/**\n * Host integration points for @ateam-ai-mobile/ui — same DI pattern as\n * @ateam-ai-mobile/plugin-runtime's host.ts. Everything has a safe default; the host\n * (or @ateam-ai-mobile/expo) wires real implementations at startup.\n */\n\n// ── Clipboard ──────────────────────────────────────────────────────────────\n\nexport interface ClipboardProvider {\n setString(text: string): Promise<void>;\n}\n\nlet _clipboard: ClipboardProvider | null = null;\n\n/** Register a clipboard implementation (e.g. expo-clipboard via @ateam-ai-mobile/expo). */\nexport function setClipboardProvider(clipboard: ClipboardProvider | null): void {\n _clipboard = clipboard;\n}\n\nexport function getClipboard(): ClipboardProvider | null {\n return _clipboard;\n}\n\n// ── UI-action navigation ───────────────────────────────────────────────────\n// Chips with a plugin target need to open the host's plugin screen. The SDK\n// never imports a router — the HOST owns navigation and registers a handler\n// (e.g. Expo Router: router.push({ pathname: '/plugin/[id]', params })).\n\nexport interface UIActionRoute {\n /** Full plugin id, e.g. \"mcp:connector:plugin\" or \"platform:<name>\". */\n pluginId: string;\n /** Query params the plugin reads on load (focus, tool, args, verb). */\n params: Record<string, string>;\n}\n\ntype UIActionNavigator = (route: UIActionRoute) => void;\n\nlet _navigator: UIActionNavigator | null = null;\n\nexport function setUIActionNavigator(navigate: UIActionNavigator | null): void {\n _navigator = navigate;\n}\n\nexport function getUIActionNavigator(): UIActionNavigator | null {\n return _navigator;\n}\n\n// ── Plugin WebView extra allowed hosts ─────────────────────────────────────\n// The plugin WebView allow-list is derived from the SDK config (core + voice\n// URLs). Hosts with additional trusted services plugins navigate to (e.g. a\n// relay) register a getter returning extra URLs; resolved live per check.\n\ntype ExtraHostsGetter = () => string[];\n\nlet _extraHosts: ExtraHostsGetter | null = null;\n\nexport function setPluginWebViewExtraHosts(getter: ExtraHostsGetter | null): void {\n _extraHosts = getter;\n}\n\nexport function getPluginWebViewExtraHosts(): ExtraHostsGetter | null {\n return _extraHosts;\n}\n","/**\n * WidgetHost — zero-config widget presenter.\n *\n * The glue that makes chips and the agent able to open widgets without any\n * host wiring:\n *\n * - `openWidget(pluginId, opts)` — imperative open from anywhere. Surfaces\n * registered in the surface store (host surfaces, platform-declared\n * surfaces) mount through the surface registry; everything else is\n * presented here as a fullscreen PluginSurface (manifest fetched lazily).\n * - Chip taps: UIActionsRow falls back to openWidget() when the host hasn't\n * registered a custom navigator via setUIActionNavigator().\n * - Server/agent proactive open: listens for the chat stream's\n * `focus-plugin` event (sys.focusUiPlugin(pluginId, props) on the engine\n * side) and presents the widget, forwarding the engine props.\n *\n * <AdasChatScreen /> mounts a WidgetHost automatically — drop-in hosts get\n * the full chips→widgets and agent→widgets experience for free. Custom\n * layouts render <WidgetHost /> once near the app root (mounting it twice is\n * safe: both instances read the same store, last-closed wins).\n */\nimport { useEffect } from 'react';\nimport { create } from 'zustand';\nimport { pluginCommandEmitter } from '@ateam-ai-mobile/core';\nimport { useSurfaceStore } from '@ateam-ai-mobile/plugin-runtime';\nimport PluginSurface from './PluginSurface';\n\ninterface WidgetHostState {\n pluginId: string | null;\n /** Engine/chip-supplied props forwarded to the plugin as PluginProps.props. */\n props?: any;\n open: (pluginId: string, props?: any) => void;\n close: () => void;\n}\n\nexport const useWidgetHostStore = create<WidgetHostState>((set) => ({\n pluginId: null,\n props: undefined,\n open: (pluginId, props) => set({ pluginId, props }),\n close: () => set({ pluginId: null, props: undefined }),\n}));\n\n/**\n * Open a widget by plugin id. Host surfaces registered in the surface store\n * take priority (they own their chrome); everything else is presented as a\n * fullscreen PluginSurface by the mounted <WidgetHost />.\n */\nexport function openWidget(pluginId: string, props?: any): void {\n const surfaces = useSurfaceStore.getState();\n if (surfaces.manifests[pluginId]) {\n surfaces.show(pluginId, props);\n return;\n }\n useWidgetHostStore.getState().open(pluginId, props);\n}\n\nexport default function WidgetHost() {\n const pluginId = useWidgetHostStore(s => s.pluginId);\n const props = useWidgetHostStore(s => s.props);\n const close = useWidgetHostStore(s => s.close);\n\n // Agent-driven proactive open: sys.focusUiPlugin(pluginId, props) flows\n // through the chat stream → core emits 'focus-plugin' → present it.\n useEffect(() => {\n return pluginCommandEmitter.on('focus-plugin', (data: any) => {\n if (data?.pluginId) openWidget(String(data.pluginId), data.props);\n });\n }, []);\n\n if (!pluginId) return null;\n\n return (\n <PluginSurface\n key={pluginId}\n pluginId={pluginId}\n surface={{ type: 'fullscreen' }}\n dismiss={close}\n props={props}\n />\n );\n}\n","/**\n * PluginSurface — universal mount that wraps any platform-declared plugin\n * (iframe or React Native) inside the right Ada-themed surface container.\n *\n * Mounted when an `engine` or `user` event activates a platform plugin that\n * declared a `surface` field in its manifest. Picks SurfaceDrawer or\n * SurfaceFullscreen based on `surface.type`, fetches the full PluginManifest\n * lazily, and renders <Plugin /> inside the body.\n */\nimport { useEffect, useState } from 'react';\nimport { View, ActivityIndicator } from 'react-native';\nimport { ada } from '@ateam-ai-mobile/core';\nimport {\n getPlugin,\n SurfaceDrawer,\n SurfaceFullscreen,\n type PluginSurfaceMeta,\n} from '@ateam-ai-mobile/plugin-runtime';\nimport type { PlatformPluginManifest as PluginManifest } from '@ateam-ai-mobile/plugin-runtime';\nimport Plugin from './Plugin';\n\ninterface Props {\n pluginId: string;\n surface: PluginSurfaceMeta;\n dismiss: () => void;\n /** Engine-supplied props forwarded from sys.focusUiPlugin(id, props). */\n props?: any;\n}\n\nexport default function PluginSurface({ pluginId, surface, dismiss, props }: Props) {\n const [manifest, setManifest] = useState<PluginManifest | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n getPlugin(pluginId)\n .then(m => { if (!cancelled) m ? setManifest(m) : setError('Plugin not found'); })\n .catch(e => { if (!cancelled) setError(e?.message || 'Failed to load'); });\n return () => { cancelled = true; };\n }, [pluginId]);\n\n const body = manifest ? (\n <Plugin id={pluginId} manifest={manifest as any} props={props} />\n ) : (\n <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', padding: 24 }}>\n {error ? null : <ActivityIndicator color={ada.orange} />}\n </View>\n );\n\n if (surface.type === 'fullscreen') {\n return (\n <SurfaceFullscreen\n visible={true}\n onClose={dismiss}\n status={surface.title}\n showWordmark\n closeIcon=\"x\"\n closeLabel=\"Close\"\n >\n {body}\n </SurfaceFullscreen>\n );\n }\n\n // Default: drawer\n return (\n <SurfaceDrawer\n visible={true}\n onClose={dismiss}\n title={surface.title || pluginId}\n subtitle={surface.subtitle}\n privacy={!!surface.privacy}\n >\n {body}\n </SurfaceDrawer>\n );\n}\n","/**\n * <Plugin /> — unified plugin renderer.\n *\n * Auto-detects native vs webview, provides bridge/theme/context, wraps in an\n * error boundary.\n *\n * Usage:\n * <Plugin id=\"mcp:connector:plugin-name\" manifest={manifest} />\n */\nimport React, { useMemo } from 'react';\nimport { View, Text, Pressable, ActivityIndicator, StyleSheet } from 'react-native';\nimport { getTenant, getUser, colors } from '@ateam-ai-mobile/core';\nimport {\n usePlugin,\n useNativeBridge,\n usePluginTheme,\n getPluginNative,\n gatePluginNative,\n type PluginContext,\n} from '@ateam-ai-mobile/plugin-runtime';\nimport EmbeddedPluginWebView from './EmbeddedPluginWebView';\n\n// ── Error Boundary ──────────────────────────────────────────\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n}\n\nclass PluginErrorBoundary extends React.Component<\n { pluginId: string; children: React.ReactNode },\n ErrorBoundaryState\n> {\n state: ErrorBoundaryState = { hasError: false, error: null };\n\n static getDerivedStateFromError(error: Error) {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, info: React.ErrorInfo) {\n console.error(`[Plugin:${this.props.pluginId}] Crash:`, error, info.componentStack);\n }\n\n render() {\n if (this.state.hasError) {\n return (\n <View style={styles.error}>\n <Text style={styles.errorTitle}>Plugin Error</Text>\n <Text style={styles.errorMessage}>\n {this.state.error?.message || 'An unexpected error occurred'}\n </Text>\n <Pressable\n style={styles.retryBtn}\n onPress={() => this.setState({ hasError: false, error: null })}\n >\n <Text style={styles.retryText}>Retry</Text>\n </Pressable>\n </View>\n );\n }\n return this.props.children;\n }\n}\n\n// ── Plugin Component ─────────────────────────────────────────\n\ninterface PluginRendererProps {\n /** Full plugin ID, e.g. \"mcp:connector-id:plugin-name\" */\n id: string;\n /** Plugin manifest (from API) */\n manifest: any;\n /** Shared command buffer from parent — captures commands before plugin mounts */\n commandBufferRef?: React.MutableRefObject<any[]>;\n /** Engine-supplied props from sys.focusUiPlugin(id, props) — forwarded to\n * the plugin Component as `PluginProps.props`. */\n props?: any;\n}\n\nexport default function Plugin({ id, manifest, commandBufferRef, props: engineProps }: PluginRendererProps) {\n // Load the plugin component (handles cache, download, eval)\n const { plugin, loading, error, bundleMissing } = usePlugin(id, manifest);\n\n // Extract connectorId from MCP plugin ID: mcp:<connector>:<plugin>\n const connectorId = id.startsWith('mcp:') ? id.split(':')[1] : manifest._connectorId;\n\n // Wire up bridge, capabilities, theme\n const bridge = useNativeBridge(id, connectorId, commandBufferRef);\n // Per-plugin capability gate: undeclared native APIs become warn-and-ignore\n // proxies. Memoized so the plugin Component doesn't re-render on a fresh\n // object every pass (useApi effects key off prop identity).\n const declaredCaps = manifest?.native;\n const native = useMemo(() => gatePluginNative(getPluginNative(), declaredCaps), [declaredCaps]);\n const theme = usePluginTheme();\n\n // Build context from the host-owned identity\n const user = getUser();\n const context = useMemo<PluginContext>(() => ({\n tenant: getTenant(),\n pluginId: id,\n connectorId,\n user: user ? { id: user.actorId || '', name: user.name || '', roles: user.roles || [] } : undefined,\n }), [id, connectorId, user?.actorId, user?.name, user?.roles]);\n\n // Fallback: connector declared an RN component but didn't ship the bundle.\n // When the manifest also has an iframeUrl (adaptive mode), render the\n // WebView instead of an error screen. Must run AFTER all hook calls above\n // to keep hook order stable across renders.\n const iframeUrl = manifest?.render?.iframeUrl;\n if (bundleMissing && iframeUrl) {\n return <EmbeddedPluginWebView pluginId={id} manifest={manifest} commandBufferRef={commandBufferRef} />;\n }\n\n if (loading) {\n return (\n <View style={styles.center}>\n <ActivityIndicator size=\"small\" color={colors.dark.accent} />\n <Text style={styles.loadingText}>Loading plugin...</Text>\n </View>\n );\n }\n\n if (error || !plugin) {\n return (\n <View style={styles.center}>\n <Text style={styles.errorMessage}>{error || 'Plugin not found'}</Text>\n </View>\n );\n }\n\n const { Component } = plugin;\n return (\n <PluginErrorBoundary pluginId={id}>\n <Component bridge={bridge} native={native} theme={theme} context={context} props={engineProps} />\n </PluginErrorBoundary>\n );\n}\n\n// ── Styles ───────────────────────────────────────────────────\n\nconst styles = StyleSheet.create({\n center: {\n flex: 1,\n justifyContent: 'center',\n alignItems: 'center',\n backgroundColor: colors.dark.bgPrimary,\n paddingHorizontal: 32,\n gap: 12,\n },\n loadingText: {\n color: colors.dark.textSecondary,\n fontSize: 14,\n },\n error: {\n flex: 1,\n justifyContent: 'center',\n alignItems: 'center',\n backgroundColor: colors.dark.bgPrimary,\n paddingHorizontal: 32,\n gap: 8,\n },\n errorTitle: {\n color: colors.dark.red,\n fontSize: 16,\n fontWeight: '600',\n },\n errorMessage: {\n color: colors.dark.textSecondary,\n fontSize: 14,\n textAlign: 'center',\n },\n retryBtn: {\n marginTop: 12,\n paddingHorizontal: 20,\n paddingVertical: 10,\n backgroundColor: colors.dark.accentSoft,\n borderRadius: 8,\n },\n retryText: {\n color: colors.dark.accent,\n fontSize: 14,\n fontWeight: '600',\n },\n});\n","import { useState, useMemo, useCallback } from 'react';\nimport { View, Text, ActivityIndicator, StyleSheet, Platform } from 'react-native';\nimport { WebView } from 'react-native-webview';\nimport { getConfig, getCoreApiUrl, getVoiceApiUrl, getTenant, getToken, ada } from '@ateam-ai-mobile/core';\nimport { resolvePluginUrl, type PlatformPluginManifest as PluginManifest } from '@ateam-ai-mobile/plugin-runtime';\nimport { usePluginBridge, buildPluginBridgeJS } from './usePluginBridge';\nimport { getPluginWebViewExtraHosts } from '../providers';\n\ninterface Props {\n pluginId: string;\n manifest: PluginManifest;\n commandBufferRef?: React.MutableRefObject<any[]>;\n}\n\n/**\n * WebView renderer for iframe-mode plugins. The injected bridge JS makes\n * existing web plugins work unmodified; the origin guards below make sure\n * the JWT seeded into localStorage can never leave the trusted hosts.\n */\nexport default function EmbeddedPluginWebView({ pluginId, manifest, commandBufferRef }: Props) {\n const [error, setError] = useState<string | null>(null);\n\n const token = getToken();\n const tenant = getTenant();\n\n // _connectorId from the manifest (set by cp.getContextPlugin) — same as\n // what the web PluginHost sends in init.\n const { webViewRef, sendInit, handleMessage } = usePluginBridge(pluginId, manifest._connectorId, commandBufferRef);\n\n const url = resolvePluginUrl(manifest, tenant || undefined);\n const bridgeJS = buildPluginBridgeJS(token || '', tenant || '');\n\n // Hosts the plugin may navigate to — derived from the SDK config plus any\n // host-registered extras (e.g. a relay service). Resolved LIVE on every\n // read, never frozen at mount: config URLs can change after hydration and a\n // stale whitelist silently bounces plugin URLs out to the system browser\n // (a documented regression in the reference app).\n const computeAllowedHosts = useCallback((): Set<string> => {\n const hosts = new Set<string>();\n const urls = [getCoreApiUrl()];\n // voiceUrl is optional and may be a getter — resolve via getVoiceApiUrl()\n // (which throws when unset, so gate on the raw config first).\n if (getConfig().voiceUrl) urls.push(getVoiceApiUrl());\n try { urls.push(...(getPluginWebViewExtraHosts()?.() || [])); } catch { /* host getter threw */ }\n for (const u of urls) {\n try { hosts.add(new URL(u).hostname); } catch { /* ignore bad URL */ }\n }\n return hosts;\n }, []);\n\n const isAllowedPluginUrl = useCallback((rawUrl: string | undefined | null): boolean => {\n if (!rawUrl) return false;\n // about:blank, data:, file: — never allow off-origin navigation\n let parsed: URL;\n try { parsed = new URL(rawUrl); } catch { return false; }\n if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') return false;\n if (parsed.protocol === 'http:') return false; // belt-and-suspenders with mixedContentMode=never\n return computeAllowedHosts().has(parsed.hostname);\n }, [computeAllowedHosts]);\n\n const originWhitelist = useMemo(\n () => Array.from(computeAllowedHosts()).map(h => `https://${h}`),\n [computeAllowedHosts],\n );\n\n if (error) {\n return (\n <View style={styles.center}>\n <Text style={styles.errorText}>{error}</Text>\n </View>\n );\n }\n\n return (\n <View style={styles.container}>\n <WebView\n ref={webViewRef}\n source={{ uri: url }}\n style={styles.webview}\n javaScriptEnabled\n domStorageEnabled\n allowsInlineMediaPlayback\n mediaPlaybackRequiresUserAction={false}\n // SECURITY:\n // mixedContentMode=never → block any plain HTTP load inside the WebView.\n // originWhitelist → only the ADAS-owned hosts.\n // onShouldStartLoadWithRequest → reject navigation off allowlisted hosts.\n // setSupportMultipleWindows / javaScriptCanOpenWindowsAutomatically\n // → prevent window.open() from spawning a WebView that inherits\n // the bridge but skips the origin guard.\n // allowsBackForwardNavigationGestures=false\n // → a user gesture must not be a way out of the sandbox.\n // The bridge writes the JWT into the WebView's localStorage; these\n // guards make sure it can never leave the trusted origins.\n mixedContentMode=\"never\"\n originWhitelist={originWhitelist}\n allowsBackForwardNavigationGestures={false}\n setSupportMultipleWindows={false}\n javaScriptCanOpenWindowsAutomatically={false}\n onShouldStartLoadWithRequest={(req) => {\n if (!isAllowedPluginUrl(req.url)) {\n console.warn(`[EmbeddedPluginWebView] BLOCKED nav to disallowed origin: ${req.url}`);\n return false;\n }\n return true;\n }}\n injectedJavaScriptBeforeContentLoaded={bridgeJS}\n onMessage={handleMessage}\n onLoad={() => {\n // Send init with retries to beat the race condition\n setTimeout(sendInit, 100);\n setTimeout(sendInit, 500);\n setTimeout(sendInit, 1200);\n }}\n onError={(syntheticEvent) => {\n const { nativeEvent } = syntheticEvent;\n console.warn('[EmbeddedPluginWebView] Error:', nativeEvent.description);\n setError(`WebView error: ${nativeEvent.description}`);\n }}\n onHttpError={(syntheticEvent) => {\n const { nativeEvent } = syntheticEvent;\n console.warn('[EmbeddedPluginWebView] HTTP error:', nativeEvent.statusCode, nativeEvent.url);\n if (nativeEvent.statusCode >= 400) {\n setError(`HTTP ${nativeEvent.statusCode}: Failed to load plugin`);\n }\n }}\n startInLoadingState\n renderLoading={() => (\n <View style={styles.webviewLoading}>\n <ActivityIndicator size=\"small\" color={ada.orange} />\n <Text style={styles.loadingText}>Loading plugin...</Text>\n </View>\n )}\n {...(Platform.OS === 'ios' ? { bounces: false } : {})}\n />\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n backgroundColor: ada.paper,\n },\n center: {\n flex: 1,\n justifyContent: 'center',\n alignItems: 'center',\n backgroundColor: ada.paper,\n paddingHorizontal: 32,\n },\n errorText: {\n color: '#C15545',\n fontSize: 16,\n textAlign: 'center',\n },\n webview: {\n flex: 1,\n backgroundColor: ada.paper,\n },\n webviewLoading: {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n justifyContent: 'center',\n alignItems: 'center',\n backgroundColor: ada.paper,\n gap: 12,\n },\n loadingText: {\n color: ada.inkSoft,\n fontSize: 14,\n },\n});\n","import { useCallback, useEffect, useRef } from 'react';\nimport {\n getTenant,\n connectorCall,\n mcpFetch,\n mcpToolCall,\n postCommandResult,\n pluginCommandEmitter,\n} from '@ateam-ai-mobile/core';\n\n/**\n * PostMessage bridge between the React Native host and a plugin WebView.\n * Implements the same protocol as PluginHost.jsx in the web frontend.\n *\n * Handles THREE communication paths:\n * 1. fetch(\"/mcp\") — intercepted in bridge JS, proxied through postMessage\n * 2. postMessage mcp-call — direct postMessage from plugin SDK\n * 3. plugin commands — routed from the job stream to the WebView\n */\nexport function usePluginBridge(\n pluginId: string,\n connectorId?: string,\n commandBufferRef?: React.MutableRefObject<any[]>,\n wsRef?: { current: WebSocket | null },\n) {\n // Loosely typed on purpose: react-native-webview's generic class type\n // resolves JSX props to `never` under React 19 typings when used as a\n // useRef parameter. Runtime shape is the WebView instance (postMessage).\n const webViewRef = useRef<any>(null);\n\n // Send init message to plugin (mirrors web PluginHost sendInit)\n const sendInit = useCallback(() => {\n const msg = JSON.stringify({\n source: 'adas-host',\n pluginId,\n message: {\n type: 'init',\n payload: {\n tenant: getTenant(),\n connectorId: connectorId || null,\n mcpEndpoint: null,\n slug: null,\n skillSlug: null,\n },\n },\n });\n webViewRef.current?.postMessage(msg);\n }, [pluginId, connectorId]);\n\n // Send result back to plugin WebView\n const sendToPlugin = useCallback(\n (type: string, payload: any) => {\n const msg = JSON.stringify({\n source: 'adas-host',\n message: { type, payload },\n });\n webViewRef.current?.postMessage(msg);\n },\n [],\n );\n\n // Helper to dispatch a command to the WebView plugin\n const dispatchToWebView = useCallback((cmd: any) => {\n if (cmd.command === '__focus') return; // Focus-only, handled by the host screen\n const msg = JSON.stringify({\n source: 'adas-host',\n pluginId,\n message: {\n type: 'plugin.command',\n payload: {\n command: cmd.command,\n args: cmd.args,\n correlationId: cmd.correlationId,\n },\n },\n });\n webViewRef.current?.postMessage(msg);\n }, [pluginId]);\n\n // ── Listen for live plugin commands from the job stream ──\n useEffect(() => {\n const unsub = pluginCommandEmitter.on('plugin-command', (cmd: any) => {\n if (cmd.pluginId !== pluginId) return;\n dispatchToWebView(cmd);\n });\n return unsub;\n }, [pluginId, dispatchToWebView]);\n\n // ── Flush buffered commands when the WebView loads ──\n useEffect(() => {\n if (!commandBufferRef) return;\n // Flush after a delay to let the iframe initialize\n const timer = setTimeout(() => {\n const buf = commandBufferRef.current;\n const remaining: any[] = [];\n for (const cmd of buf) {\n if (cmd.pluginId === pluginId) {\n dispatchToWebView(cmd);\n } else {\n remaining.push(cmd);\n }\n }\n commandBufferRef.current = remaining;\n }, 1000);\n return () => clearTimeout(timer);\n }, [pluginId, commandBufferRef, dispatchToWebView]);\n\n // Handle messages from plugin WebView\n const handleMessage = useCallback(\n async (event: { nativeEvent: { data: string } }) => {\n let data: any;\n try {\n data = JSON.parse(event.nativeEvent.data);\n } catch {\n return;\n }\n\n if (data.source !== 'adas-plugin') return;\n\n const action = data.message?.action || data.action;\n const payload = data.message?.payload || data.payload;\n const type = data.message?.type || data.type;\n\n // -----------------------------------------------------------------\n // 1. Intercepted fetch(\"/mcp\") — proxy to Core backend\n // -----------------------------------------------------------------\n if (action === 'mcp-fetch' && payload?.requestId) {\n const { requestId, body } = payload;\n try {\n const result = await mcpFetch(body);\n sendToPlugin('mcp-fetch-result', { requestId, result, error: null });\n } catch (err: any) {\n console.warn('[PluginBridge] mcp-fetch ERROR:', err.message);\n sendToPlugin('mcp-fetch-result', { requestId, result: null, error: err.message });\n }\n return;\n }\n\n // -----------------------------------------------------------------\n // 2. PostMessage mcp-call — plugin SDK's callTool()\n // a) toolName present (e.g. \"cp.fe_api\") → JSON-RPC to /mcp\n // b) direct connectorId/tool → /api/connectors/:id/call\n // -----------------------------------------------------------------\n if (action === 'mcp-call' && payload?.requestId) {\n const { requestId, toolName, args: callArgs } = payload;\n\n // Path A: JSON-RPC tool call (cp.fe_api, cp.admin_api, etc.)\n if (toolName) {\n try {\n const rpcResponse = await mcpToolCall(toolName, callArgs || {});\n // Unwrap the JSON-RPC envelope — plugin expects { content: [...] }\n const result = rpcResponse?.result ?? rpcResponse;\n sendToPlugin('mcp-result', { requestId, result, error: null });\n } catch (err: any) {\n sendToPlugin('mcp-result', { requestId, result: null, error: err.message });\n }\n return;\n }\n\n // Path B: direct connector call (connectorId + tool). The plugin may\n // send connectorId/tool at payload level OR nested in args.\n const cId = payload.connectorId || callArgs?.connectorId || callArgs?.params?.connectorId;\n const tool = payload.tool || callArgs?.tool || callArgs?.params?.tool;\n const toolArgs = payload.args || callArgs?.args || callArgs?.params?.args || {};\n\n if (!cId || !tool) {\n console.error(`[PluginBridge] mcp-call missing params — connectorId: ${cId}, tool: ${tool}`);\n sendToPlugin('mcp-result', { requestId, result: null, error: `Missing connectorId or tool in mcp-call. Got connectorId=${cId}, tool=${tool}` });\n return;\n }\n\n try {\n const data = await connectorCall(cId, tool, toolArgs);\n if (data.ok) {\n sendToPlugin('mcp-result', { requestId, result: data.result, error: null });\n } else {\n sendToPlugin('mcp-result', { requestId, result: null, error: data.error || 'MCP call failed' });\n }\n } catch (err: any) {\n sendToPlugin('mcp-result', { requestId, result: null, error: err.message });\n }\n return;\n }\n\n // -----------------------------------------------------------------\n // 3. Plugin self-close — return to chat\n // -----------------------------------------------------------------\n if (action === 'close') {\n pluginCommandEmitter.emit('plugin-close', { pluginId });\n return;\n }\n\n // -----------------------------------------------------------------\n // 4. Plugin command result — WebSocket (preferred) or HTTP POST\n // -----------------------------------------------------------------\n if (type === 'plugin.command.result' && payload?.correlationId) {\n const ws = wsRef?.current;\n if (ws && ws.readyState === WebSocket.OPEN) {\n try {\n ws.send(JSON.stringify({\n type: 'plugin-command-result',\n correlationId: payload.correlationId,\n result: payload.result,\n error: payload.error,\n }));\n } catch (err: any) {\n console.warn('[PluginBridge] WS send failed, falling back to POST:', err.message);\n await postCommandResult(payload.correlationId, payload.result, payload.error).catch(() => {});\n }\n } else {\n try {\n await postCommandResult(payload.correlationId, payload.result, payload.error);\n } catch (err: any) {\n console.warn('[PluginBridge] Failed to send command result:', err.message);\n }\n }\n return;\n }\n },\n [sendToPlugin],\n );\n\n return {\n webViewRef,\n sendInit,\n handleMessage,\n };\n}\n\n/**\n * Build injected JavaScript that:\n * 1. Seeds localStorage with JWT + tenant (plugins read from localStorage)\n * 2. Intercepts fetch(\"/mcp\") and proxies through the postMessage bridge\n * 3. Bridges iframe postMessage API to React Native WebView\n *\n * This makes existing web plugins work on mobile WITHOUT modification.\n */\nexport function buildPluginBridgeJS(jwt: string, tenant: string): string {\n return `\n(function() {\n function _dbg(msg) {\n console.log('[PluginBridge] ' + msg);\n }\n\n // 1. Seed localStorage. JWT is required by web-shared plugin code\n // (cpFeApi.ts etc. read localStorage.adas.jwt directly). Origin lockdown\n // lives in EmbeddedPluginWebView (originWhitelist +\n // onShouldStartLoadWithRequest) — not here. Never log the token.\n try {\n localStorage.setItem('adas.jwt', ${JSON.stringify(jwt)});\n localStorage.setItem('adas.tenant', ${JSON.stringify(tenant)});\n _dbg('localStorage seeded: jwt=' + (${JSON.stringify(jwt)} ? '[present]' : '[absent]') + ' tenant=' + ${JSON.stringify(tenant)});\n } catch(e) { _dbg('localStorage ERROR: ' + e.message); }\n\n // 2. Intercept ALL fetch calls — proxy /mcp through the RN bridge\n var _origFetch = window.fetch.bind(window);\n var _mcpReqId = 0;\n var _pendingMcp = {};\n\n window.fetch = function(url, opts) {\n var urlStr = (typeof url === 'string') ? url : (url && url.url) || '';\n var method = (opts && opts.method) || 'GET';\n\n _dbg('FETCH ' + method + ' ' + urlStr.substring(0, 80));\n\n // Intercept /mcp calls\n if (urlStr === '/mcp' || urlStr.endsWith('/mcp')) {\n _dbg(' -> INTERCEPTED /mcp, proxying via RN bridge');\n return new Promise(function(resolve, reject) {\n var requestId = 'mcp-f-' + (++_mcpReqId) + '-' + Date.now();\n _pendingMcp[requestId] = { resolve: resolve, reject: reject };\n window.ReactNativeWebView.postMessage(JSON.stringify({\n source: 'adas-plugin',\n action: 'mcp-fetch',\n payload: { requestId: requestId, body: opts && opts.body ? opts.body : null }\n }));\n setTimeout(function() {\n if (_pendingMcp[requestId]) {\n delete _pendingMcp[requestId];\n _dbg('TIMEOUT mcp-fetch ' + requestId);\n reject(new Error('MCP fetch timeout (30s)'));\n }\n }, 30000);\n });\n }\n\n // Inject Authorization header ONLY for same-origin requests. A relative\n // path resolves against window.location.origin; an absolute URL must\n // literally match. This stops a plugin from leaking the JWT to a foreign\n // host via fetch('https://attacker.com/x') or via <base href>.\n var sameOrigin = false;\n try {\n var resolved = new URL(urlStr, window.location.origin);\n sameOrigin = (resolved.origin === window.location.origin);\n } catch (_) { sameOrigin = false; }\n if (sameOrigin) {\n opts = Object.assign({}, opts || {});\n var h = opts.headers;\n if (h instanceof Headers) {\n if (!h.has('Authorization')) { var jwt = localStorage.getItem('adas.jwt'); if (jwt) h.set('Authorization', 'Bearer ' + jwt); }\n } else {\n h = Object.assign({}, h || {});\n if (!h['Authorization'] && !h['authorization']) { var jwt2 = localStorage.getItem('adas.jwt'); if (jwt2) h['Authorization'] = 'Bearer ' + jwt2; }\n opts.headers = h;\n }\n }\n\n return _origFetch(url, opts).then(function(res) {\n _dbg(' <- ' + res.status + ' ' + urlStr.substring(0, 60));\n return res;\n }).catch(function(err) {\n _dbg(' <- FETCH ERR: ' + err.message + ' ' + urlStr.substring(0, 40));\n throw err;\n });\n };\n\n // Handle results from RN host\n function _handleHostMessage(d) {\n if (!d || d.source !== 'adas-host') return;\n var msg = d.message || {};\n\n // mcp-fetch-result: response to intercepted fetch(\"/mcp\")\n if (msg.type === 'mcp-fetch-result' && msg.payload) {\n var p = msg.payload;\n var pending = _pendingMcp[p.requestId];\n if (pending) {\n delete _pendingMcp[p.requestId];\n if (p.error) {\n pending.reject(new Error(p.error));\n } else {\n pending.resolve(new Response(JSON.stringify(p.result), {\n status: 200,\n headers: { 'Content-Type': 'application/json' }\n }));\n }\n }\n }\n }\n\n // 3. Override window.parent.postMessage (plugins use this in iframes)\n window.parent = window.parent || {};\n window.parent.postMessage = function(data, origin) {\n if (data && data.source === 'adas-plugin') {\n window.ReactNativeWebView.postMessage(JSON.stringify(data));\n }\n };\n\n // 4. Also intercept direct window.postMessage\n var origPost = window.postMessage.bind(window);\n window.postMessage = function(data, origin) {\n if (data && data.source === 'adas-plugin') {\n window.ReactNativeWebView.postMessage(JSON.stringify(data));\n }\n origPost(data, origin);\n };\n\n // 5. Forward messages from RN host -> plugin\n // iOS: window 'message' event, Android: document 'message' event\n window.addEventListener('message', function(e) {\n try {\n var d = typeof e.data === 'string' ? JSON.parse(e.data) : e.data;\n if (d && d.source === 'adas-host') {\n _handleHostMessage(d);\n if (typeof e.data === 'string') {\n window.dispatchEvent(new MessageEvent('message', { data: d }));\n }\n }\n } catch(_) {}\n });\n\n document.addEventListener('message', function(e) {\n try {\n var d = typeof e.data === 'string' ? JSON.parse(e.data) : e.data;\n _handleHostMessage(d);\n window.dispatchEvent(new MessageEvent('message', { data: d }));\n } catch(_) {}\n });\n\n _dbg('Bridge JS loaded. Waiting for plugin...');\n true;\n})();\n`;\n}\n","import { View, Text, StyleSheet, Platform } from 'react-native';\nimport { ada, borderRadius, fontSize, spacing } from '@ateam-ai-mobile/core';\n\nconst fontFam = Platform.OS === 'ios' ? 'SF Pro Rounded' : undefined;\n\ninterface Props {\n columns: string[];\n rows: any[][];\n}\n\n/**\n * Renders tabular data as a vertical stack of cards — one card per row.\n * The first column becomes the card title; remaining columns become\n * key:value rows inside the card. Built specifically for narrow phone\n * screens where horizontal markdown tables become unreadable.\n */\nexport default function TableCardBlock({ columns, rows }: Props) {\n if (!columns?.length || !rows?.length) return null;\n\n const [titleCol, ...detailCols] = columns;\n\n return (\n <View style={styles.wrap}>\n {rows.map((row, i) => {\n const cells = Array.isArray(row) ? row : [row];\n const title = cells[0];\n return (\n <View key={i} style={styles.card}>\n <Text style={styles.title}>{String(title ?? '')}</Text>\n {detailCols.length > 0 && (\n <View style={styles.details}>\n {detailCols.map((col, ci) => {\n const value = cells[ci + 1];\n if (value == null || value === '') return null;\n return (\n <View key={ci} style={styles.row}>\n <Text style={styles.label}>{String(col)}</Text>\n <Text style={styles.value}>{String(value)}</Text>\n </View>\n );\n })}\n </View>\n )}\n </View>\n );\n })}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n wrap: {\n marginVertical: 6,\n gap: 8,\n },\n card: {\n backgroundColor: ada.paper,\n borderRadius: borderRadius.md,\n borderWidth: 1,\n borderColor: ada.border,\n padding: spacing.md,\n },\n title: {\n color: ada.ink,\n fontSize: fontSize.md,\n fontWeight: '600',\n fontFamily: fontFam,\n letterSpacing: -0.2,\n marginBottom: 6,\n },\n details: {\n gap: 4,\n },\n row: {\n flexDirection: 'row',\n alignItems: 'flex-start',\n gap: 8,\n },\n label: {\n color: ada.inkMuted,\n fontSize: fontSize.xs,\n fontFamily: fontFam,\n fontWeight: '500',\n width: 84,\n textTransform: 'uppercase',\n letterSpacing: 0.6,\n paddingTop: 2,\n },\n value: {\n flex: 1,\n color: ada.inkSoft,\n fontSize: fontSize.sm,\n fontFamily: fontFam,\n lineHeight: 18,\n },\n});\n","/**\n * Lightbox store — any component can open a fullscreen image viewer\n * by calling `useLightboxStore.getState().show(uri)`. The lightbox is\n * mounted once at the app root.\n */\nimport { create } from 'zustand';\n\ninterface LightboxState {\n uri: string | null;\n show: (uri: string) => void;\n hide: () => void;\n}\n\nexport const useLightboxStore = create<LightboxState>((set) => ({\n uri: null,\n show: (uri) => set({ uri }),\n hide: () => set({ uri: null }),\n}));\n","import { View, StyleSheet } from 'react-native';\nimport { AdaOrb } from '@ateam-ai-mobile/plugin-runtime';\n\nexport default function TypingIndicator() {\n return (\n <View style={styles.row}>\n <AdaOrb size={32} state=\"thinking\" />\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n row: {\n flexDirection: 'row',\n alignItems: 'center',\n marginBottom: 12,\n paddingHorizontal: 16,\n paddingVertical: 4,\n },\n});\n","import { useState, useRef, useCallback, useEffect } from 'react';\nimport {\n View,\n TextInput,\n Pressable,\n StyleSheet,\n Platform,\n} from 'react-native';\nimport Svg, { Path, Line, Polygon } from 'react-native-svg';\nimport { colors, borderRadius } from '@ateam-ai-mobile/core';\nimport { getHaptics } from '@ateam-ai-mobile/plugin-runtime';\n\ninterface Props {\n onSend: (text: string) => void;\n onCallStart?: () => void;\n loading: boolean;\n /** Pre-fill the composer (e.g. from bridge.prepareMessage). The text is\n * placed in the input and focused — not sent. */\n prefill?: string;\n placeholder?: string;\n}\n\nexport default function ChatInput({ onSend, onCallStart, loading, prefill, placeholder }: Props) {\n const [text, setText] = useState('');\n const [height, setHeight] = useState(40);\n const inputRef = useRef<TextInput>(null);\n\n useEffect(() => {\n if (prefill) {\n setText(prefill);\n inputRef.current?.focus();\n }\n }, [prefill]);\n\n // NOTE: no `loading` guard and no editable={!loading} — sending WHILE a\n // chain runs is a feature (backend Chain Additions router decides\n // attach/cancel/new), and the input must never be disabled mid-run.\n const handleSend = useCallback(() => {\n const trimmed = text.trim();\n if (!trimmed) return;\n getHaptics()?.impact('light');\n onSend(trimmed);\n setText('');\n setHeight(40);\n }, [text, loading, onSend]);\n\n const canSend = text.trim().length > 0;\n\n return (\n <View style={styles.dock}>\n <View style={styles.inputRow}>\n {onCallStart && (\n <Pressable style={styles.callBtn} onPress={onCallStart}>\n <Svg width={20} height={20} viewBox=\"0 0 24 24\" fill=\"none\" stroke={colors.light.accent} strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <Path d=\"M22 16.92v3a2 2 0 01-2.18 2 19.79 19.79 0 01-8.63-3.07 19.5 19.5 0 01-6-6 19.79 19.79 0 01-3.07-8.63A2 2 0 014.11 2h3a2 2 0 012 1.72 12.84 12.84 0 00.7 2.81 2 2 0 01-.45 2.11L8.09 9.91a16 16 0 006 6l1.27-1.27a2 2 0 012.11-.45 12.84 12.84 0 002.81.7A2 2 0 0122 16.92z\" />\n </Svg>\n </Pressable>\n )}\n <TextInput\n ref={inputRef}\n style={[styles.input, { height: Math.min(Math.max(40, height), 120) }]}\n value={text}\n onChangeText={setText}\n onContentSizeChange={e => setHeight(e.nativeEvent.contentSize.height)}\n placeholder={placeholder || 'Message A-Team...'}\n placeholderTextColor={colors.light.textMuted}\n multiline\n returnKeyType=\"default\"\n blurOnSubmit={false}\n onSubmitEditing={() => {\n if (Platform.OS === 'web') handleSend();\n }}\n />\n <Pressable\n style={[styles.sendBtn, canSend && styles.sendBtnActive]}\n onPress={handleSend}\n disabled={!canSend}\n >\n <Svg width={18} height={18} viewBox=\"0 0 24 24\" fill=\"none\" stroke={canSend ? '#fff' : colors.light.textMuted} strokeWidth={2}>\n <Line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" />\n <Polygon points=\"22 2 15 22 11 13 2 9 22 2\" />\n </Svg>\n </Pressable>\n </View>\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n dock: {\n paddingHorizontal: 12,\n paddingVertical: 8,\n backgroundColor: colors.light.bgPrimary,\n borderTopWidth: 0.5,\n borderTopColor: colors.light.border,\n },\n inputRow: {\n flexDirection: 'row',\n alignItems: 'flex-end',\n backgroundColor: colors.light.bgInput,\n borderRadius: borderRadius.xl,\n borderWidth: 1,\n borderColor: colors.light.border,\n paddingHorizontal: 4,\n paddingVertical: 4,\n gap: 4,\n },\n callBtn: {\n width: 36,\n height: 36,\n borderRadius: 18,\n justifyContent: 'center',\n alignItems: 'center',\n },\n input: {\n flex: 1,\n fontSize: 16,\n color: colors.light.textPrimary,\n paddingHorizontal: 8,\n paddingVertical: 8,\n maxHeight: 120,\n },\n sendBtn: {\n width: 36,\n height: 36,\n borderRadius: 18,\n justifyContent: 'center',\n alignItems: 'center',\n backgroundColor: colors.light.bgTertiary,\n },\n sendBtnActive: {\n backgroundColor: colors.light.accent,\n },\n});\n","/**\n * Fullscreen image viewer — mounted once inside AdasChatScreen (or at the\n * host root). Any component opens it via useLightboxStore.getState().show(uri).\n */\nimport { Modal, View, Image, Pressable, Text, StyleSheet } from 'react-native';\nimport { getConfig } from '@ateam-ai-mobile/core';\nimport { useLightboxStore } from './stores/lightboxStore';\n\nexport default function Lightbox() {\n const uri = useLightboxStore(s => s.uri);\n const hide = useLightboxStore(s => s.hide);\n\n if (!uri) return null;\n\n return (\n <Modal visible transparent animationType=\"fade\" onRequestClose={hide}>\n <Pressable style={styles.backdrop} onPress={hide}>\n <Image\n source={{\n uri,\n ...(uri.startsWith('http') ? {\n headers: { Authorization: `Bearer ${getConfig().tokenProvider.getToken()}` },\n } : {}),\n }}\n style={styles.image}\n resizeMode=\"contain\"\n />\n <View style={styles.closeHint}>\n <Text style={styles.closeHintText}>Tap to close</Text>\n </View>\n </Pressable>\n </Modal>\n );\n}\n\nconst styles = StyleSheet.create({\n backdrop: {\n flex: 1,\n backgroundColor: 'rgba(0,0,0,0.92)',\n justifyContent: 'center',\n },\n image: {\n width: '100%',\n height: '85%',\n },\n closeHint: {\n position: 'absolute',\n bottom: 40,\n alignSelf: 'center',\n },\n closeHintText: {\n color: 'rgba(255,255,255,0.6)',\n fontSize: 13,\n },\n});\n","// src/components/widgets/WidgetWebView.tsx\n//\n// Fullscreen modal that renders an ACS widget bundle in a WebView.\n//\n// The bundleUrl on each /surface item is a signed URL minted by the backend\n// proxy (apps/backend/routes/acsProxy.js → signItemBundleUrl). The URL\n// self-authenticates — the bundle endpoint verifies sig/exp/tenant/actor on\n// the server side — so the WebView doesn't need to pass auth headers.\n//\n// Relative URLs (e.g. `/api/acs/artifacts/.../bundle/1?sig=…`) are prepended\n// with the current core URL from configStore.\n//\n// Strict CSP is set on the response by the bundle endpoint. We additionally\n// disable JS injection paths we don't need (no onMessage handlers wired,\n// no injectedJavaScriptBeforeContentLoaded).\n\nimport { useMemo, useState } from 'react';\nimport {\n Modal,\n View,\n Text,\n Pressable,\n StyleSheet,\n ActivityIndicator,\n Platform,\n} from 'react-native';\nimport { WebView } from 'react-native-webview';\nimport { ada } from '@ateam-ai-mobile/core';\nimport { getCoreApiUrl } from '@ateam-ai-mobile/core';\n\nconst fontFam = Platform.OS === 'ios' ? 'SF Pro Rounded' : undefined;\n\ninterface Props {\n visible: boolean;\n /** Display title shown in the top bar. */\n title?: string;\n /** Signed bundle URL from a /surface item. Relative or absolute. */\n bundleUrl?: string;\n onClose: () => void;\n}\n\nexport default function WidgetWebView({ visible, title, bundleUrl, onClose }: Props) {\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n // Absolute URL — prepend the resolved core if backend returned a relative path.\n const uri = useMemo(() => {\n if (!bundleUrl) return null;\n if (/^https?:\\/\\//i.test(bundleUrl)) return bundleUrl;\n return `${getCoreApiUrl()}${bundleUrl}`;\n }, [bundleUrl]);\n\n return (\n <Modal\n visible={visible}\n animationType=\"slide\"\n presentationStyle=\"pageSheet\"\n onRequestClose={onClose}\n >\n <View style={styles.root}>\n <View style={styles.bar}>\n <Pressable onPress={onClose} hitSlop={12} style={styles.closeBtn}>\n <Text style={styles.closeIcon}>{'✕'}</Text>\n </Pressable>\n <Text style={styles.title} numberOfLines={1}>{title || 'Widget'}</Text>\n {/* Spacer matches closeBtn width so the title stays centered */}\n <View style={styles.closeBtn} />\n </View>\n {!uri ? (\n <View style={styles.errorWrap}>\n <Text style={styles.errorText}>No bundle available for this widget.</Text>\n </View>\n ) : error ? (\n <View style={styles.errorWrap}>\n <Text style={styles.errorText}>Couldn't load widget</Text>\n <Text style={styles.errorSub}>{error}</Text>\n </View>\n ) : (\n <>\n <WebView\n source={{ uri }}\n style={styles.web}\n onLoadStart={() => { setLoading(true); setError(null); }}\n onLoadEnd={() => setLoading(false)}\n onError={(e) => {\n setLoading(false);\n setError(e.nativeEvent.description || 'Unknown error');\n }}\n onHttpError={(e) => {\n setLoading(false);\n setError(`HTTP ${e.nativeEvent.statusCode}`);\n }}\n // The bundle is the only thing this WebView should render.\n // Block navigation away from it (prevents accidental browse\n // out of the widget sandbox into arbitrary URLs).\n originWhitelist={['https://*']}\n setSupportMultipleWindows={false}\n />\n {loading && (\n <View pointerEvents=\"none\" style={styles.spinner}>\n <ActivityIndicator color={ada.orange} />\n </View>\n )}\n </>\n )}\n </View>\n </Modal>\n );\n}\n\nconst styles = StyleSheet.create({\n root: {\n flex: 1,\n backgroundColor: ada.paper,\n },\n bar: {\n flexDirection: 'row',\n alignItems: 'center',\n paddingHorizontal: 14,\n paddingVertical: 12,\n borderBottomWidth: 1,\n borderBottomColor: ada.border,\n backgroundColor: ada.paperSoft,\n },\n closeBtn: {\n width: 32,\n height: 32,\n alignItems: 'center',\n justifyContent: 'center',\n },\n closeIcon: {\n fontSize: 18,\n color: ada.ink,\n fontWeight: '500',\n },\n title: {\n flex: 1,\n textAlign: 'center',\n fontSize: 16,\n fontWeight: '600',\n color: ada.ink,\n fontFamily: fontFam,\n letterSpacing: -0.2,\n },\n web: {\n flex: 1,\n backgroundColor: ada.paper,\n },\n spinner: {\n position: 'absolute',\n top: 80,\n left: 0,\n right: 0,\n alignItems: 'center',\n },\n errorWrap: {\n flex: 1,\n alignItems: 'center',\n justifyContent: 'center',\n paddingHorizontal: 24,\n },\n errorText: {\n fontSize: 15,\n color: ada.ink,\n fontWeight: '600',\n marginBottom: 6,\n },\n errorSub: {\n fontSize: 13,\n color: ada.inkMuted,\n textAlign: 'center',\n },\n});\n","/**\n * TenantPicker — prebuilt team switcher, fully SDK-driven.\n *\n * Lists the user's REAL memberships via core's listMyTenants() and, on tap,\n * re-scopes the whole session with core's switchTenant() (which mints the new\n * tenant JWT, persists it through config.onSession, and reconnects chat). The\n * host only reacts via onSwitched (e.g. navigate home). Single-tenant hosts\n * simply never render it.\n *\n * For custom flows, pass `onSelect` to intercept the tap instead of switching.\n */\nimport { useEffect, useState } from 'react';\nimport { View, Text, Pressable, ActivityIndicator, StyleSheet, Platform } from 'react-native';\nimport { ada, fontSize, borderRadius, listMyTenants, switchTenant, getTenant } from '@ateam-ai-mobile/core';\nimport type { TenantMembership, AdasSession } from '@ateam-ai-mobile/core';\n\nconst fontFam = Platform.OS === 'ios' ? 'SF Pro Rounded' : undefined;\n\nexport interface TenantPickerProps {\n /** Called after a successful SDK-driven switch (host navigates/refreshes). */\n onSwitched?: (session: AdasSession) => void;\n /** Intercept the tap instead of switching — for fully custom host flows.\n * When provided, the SDK does NOT call switchTenant(). */\n onSelect?: (tenant: TenantMembership) => void;\n /** Highlight the active tenant. Defaults to the SDK config's tenant. */\n currentTenantId?: string;\n}\n\nexport default function TenantPicker({ onSwitched, onSelect, currentTenantId }: TenantPickerProps) {\n const [tenants, setTenants] = useState<TenantMembership[] | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [switching, setSwitching] = useState<string | null>(null);\n const active = currentTenantId ?? getTenant();\n\n useEffect(() => {\n let cancelled = false;\n listMyTenants()\n .then(list => { if (!cancelled) setTenants(list); })\n .catch(e => { if (!cancelled) setError(e?.message || 'Failed to load teams'); });\n return () => { cancelled = true; };\n }, []);\n\n const handlePress = async (t: TenantMembership) => {\n if (t.id === active || switching) return;\n if (onSelect) { onSelect(t); return; }\n setError(null);\n setSwitching(t.id);\n try {\n const session = await switchTenant(t.id);\n onSwitched?.(session);\n } catch (e: any) {\n setError(e?.message || 'Could not switch team');\n } finally {\n setSwitching(null);\n }\n };\n\n if (error) return <Text style={styles.error}>{error}</Text>;\n if (!tenants) {\n return (\n <View style={styles.loading}>\n <ActivityIndicator color={ada.orange} />\n </View>\n );\n }\n if (tenants.length === 0) return <Text style={styles.empty}>No teams found for this account.</Text>;\n\n return (\n <View style={styles.list}>\n {tenants.map(t => {\n const isActive = t.id === active;\n const isSwitching = switching === t.id;\n return (\n <Pressable\n key={t.id}\n accessibilityRole=\"button\"\n accessibilityLabel={`Team ${t.name}${isActive ? ', current' : ''}`}\n disabled={!!switching}\n onPress={() => handlePress(t)}\n style={[styles.row, isActive && styles.rowActive]}\n >\n <View style={styles.dot} />\n <View style={styles.rowText}>\n <Text style={styles.name}>{t.name}</Text>\n <Text style={styles.slug}>{t.id}</Text>\n </View>\n {isSwitching ? <ActivityIndicator color={ada.orange} /> : isActive ? <Text style={styles.check}>✓</Text> : null}\n </Pressable>\n );\n })}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n list: {\n gap: 10,\n },\n row: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 12,\n backgroundColor: ada.paperSoft,\n borderRadius: borderRadius.lg,\n borderWidth: 1,\n borderColor: 'transparent',\n paddingHorizontal: 16,\n paddingVertical: 14,\n },\n rowActive: {\n backgroundColor: ada.orangeSoft,\n borderColor: ada.orange,\n },\n dot: {\n width: 10,\n height: 10,\n borderRadius: 5,\n backgroundColor: ada.orange,\n },\n rowText: {\n flex: 1,\n },\n name: {\n color: ada.ink,\n fontSize: fontSize.lg,\n fontWeight: '600',\n fontFamily: fontFam,\n },\n slug: {\n color: ada.inkMuted,\n fontSize: fontSize.sm,\n fontFamily: 'monospace',\n },\n check: {\n color: ada.orangeDeep,\n fontSize: fontSize.lg,\n fontWeight: '700',\n },\n loading: {\n paddingVertical: 24,\n alignItems: 'center',\n },\n empty: {\n color: ada.inkMuted,\n fontSize: fontSize.md,\n textAlign: 'center',\n paddingVertical: 16,\n },\n error: {\n color: '#C15545',\n fontSize: fontSize.md,\n textAlign: 'center',\n paddingVertical: 16,\n },\n});\n","/**\n * VoiceCallSheet — the full-screen voice call experience.\n *\n * AdaOrb hero + live transcript (with important-data highlighting) + mute\n * control + an offscreen WebView that runs the actual WebRTC session (see\n * useVoiceCall). Requires `voiceUrl` in the initAdas() config.\n */\nimport { useEffect, useRef, useMemo } from 'react';\nimport {\n View,\n Text,\n StyleSheet,\n Platform,\n Pressable,\n ScrollView,\n} from 'react-native';\nimport Svg, { Path, Line } from 'react-native-svg';\nimport { WebView } from 'react-native-webview';\nimport { ada } from '@ateam-ai-mobile/core';\nimport { AdaOrb, SurfaceFullscreen, type AdaOrbState } from '@ateam-ai-mobile/plugin-runtime';\nimport useVoiceCall from './useVoiceCall';\n\ninterface Props {\n visible: boolean;\n onClose: () => void;\n}\n\nconst fontFam = Platform.OS === 'ios' ? 'SF Pro Rounded' : undefined;\n\n// Detect important data in voice transcripts so the user can verify it visually.\nconst HIGHLIGHT_PATTERNS = [\n /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}/g,\n /(?:\\+?\\d[\\s\\-().]?){7,}\\d/g,\n /\\$\\d[\\d,]*(?:\\.\\d{1,2})?/g,\n /\\b\\d{1,2}:\\d{2}\\s?(?:am|pm|AM|PM)?\\b/g,\n /\\bhttps?:\\/\\/\\S+/g,\n /\\b\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}\\b/g,\n];\n\nfunction highlightSegments(text: string): Array<{ text: string; important: boolean }> {\n const ranges: Array<[number, number]> = [];\n for (const p of HIGHLIGHT_PATTERNS) {\n p.lastIndex = 0;\n let m;\n while ((m = p.exec(text)) !== null) {\n ranges.push([m.index, m.index + m[0].length]);\n }\n }\n if (!ranges.length) return [{ text, important: false }];\n ranges.sort((a, b) => a[0] - b[0]);\n const merged: Array<[number, number]> = [];\n for (const r of ranges) {\n if (merged.length && r[0] <= merged[merged.length - 1][1]) {\n merged[merged.length - 1][1] = Math.max(merged[merged.length - 1][1], r[1]);\n } else {\n merged.push([r[0], r[1]]);\n }\n }\n const segments: Array<{ text: string; important: boolean }> = [];\n let cursor = 0;\n for (const [start, end] of merged) {\n if (start > cursor) segments.push({ text: text.slice(cursor, start), important: false });\n segments.push({ text: text.slice(start, end), important: true });\n cursor = end;\n }\n if (cursor < text.length) segments.push({ text: text.slice(cursor), important: false });\n return segments;\n}\n\nfunction HighlightedText({\n text,\n baseStyle,\n importantStyle,\n}: {\n text: string;\n baseStyle: any;\n importantStyle: any;\n}) {\n const segments = useMemo(() => highlightSegments(text), [text]);\n return (\n <Text style={baseStyle}>\n {segments.map((seg, i) => (\n <Text key={i} style={seg.important ? importantStyle : undefined}>\n {seg.text}\n </Text>\n ))}\n </Text>\n );\n}\n\nexport default function VoiceCallSheet({ visible, onClose }: Props) {\n const {\n callState, aiPartial, userPartial, transcript, error, muted,\n startCall, stopCall, toggleMute, handleWebViewMessage, getWebViewSource, webViewRef,\n injectedTrackHook,\n } = useVoiceCall();\n\n const scrollRef = useRef<ScrollView>(null);\n\n useEffect(() => {\n if (visible && callState === 'idle') startCall();\n }, [visible]); // eslint-disable-line react-hooks/exhaustive-deps\n\n useEffect(() => {\n scrollRef.current?.scrollToEnd?.({ animated: true });\n }, [transcript.length, aiPartial, userPartial]);\n\n const handleHangUp = () => {\n stopCall();\n onClose();\n };\n\n const orbState: AdaOrbState = useMemo(() => {\n if (callState === 'connecting') return 'thinking';\n if (callState === 'error') return 'idle';\n if (aiPartial) return 'speaking';\n if (userPartial) return 'listening';\n return 'idle';\n }, [callState, aiPartial, userPartial]);\n\n const statusLabel = useMemo(() => {\n if (callState === 'connecting') return 'Connecting…';\n if (callState === 'error') return error || 'Couldn’t connect';\n if (aiPartial) return 'Ada is speaking';\n if (userPartial) return 'Listening';\n if (callState === 'connected') return 'Go ahead, I’m here.';\n return '';\n }, [callState, aiPartial, userPartial, error]);\n\n if (!visible) return null;\n\n const visibleEntries = transcript.filter(e => e.role === 'user' || e.role === 'ai');\n\n return (\n <SurfaceFullscreen\n visible={visible}\n onClose={handleHangUp}\n status={statusLabel}\n hero={<AdaOrb size={180} state={orbState} />}\n closeIcon=\"hangup\"\n closeLabel=\"End\"\n >\n <ScrollView\n ref={scrollRef}\n style={styles.transcript}\n contentContainerStyle={styles.transcriptContent}\n showsVerticalScrollIndicator={false}\n >\n {callState === 'error' && error ? (\n <View style={styles.errorBox}>\n <Text style={styles.errorText}>{error}</Text>\n </View>\n ) : null}\n {visibleEntries.map((entry, i) => (\n <View key={`${entry.ts}-${i}`} style={styles.entry}>\n <Text style={styles.role}>\n {entry.role === 'user' ? 'YOU' : 'ADA'}\n </Text>\n <HighlightedText\n text={entry.text}\n baseStyle={styles.entryText}\n importantStyle={styles.important}\n />\n </View>\n ))}\n {(userPartial || aiPartial) ? (\n <View style={styles.entry}>\n <Text style={styles.role}>\n {userPartial ? 'YOU' : 'ADA'}\n </Text>\n <HighlightedText\n text={userPartial || aiPartial}\n baseStyle={styles.entryTextLive}\n importantStyle={styles.important}\n />\n </View>\n ) : null}\n </ScrollView>\n\n {/* Mute control — floating above transcript, only when call is live */}\n {callState === 'connected' || callState === 'connecting' ? (\n <View style={styles.muteWrap} pointerEvents=\"box-none\">\n <Pressable\n onPress={toggleMute}\n accessibilityRole=\"button\"\n accessibilityLabel={muted ? 'Unmute microphone' : 'Mute microphone'}\n accessibilityState={{ selected: muted }}\n style={[styles.muteBtn, muted && styles.muteBtnActive]}\n hitSlop={12}\n >\n <Svg width={22} height={22} viewBox=\"0 0 24 24\" fill=\"none\" stroke={muted ? ada.paper : ada.ink} strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <Path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z\" />\n <Path d=\"M19 10v2a7 7 0 0 1-14 0v-2\" />\n <Line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\" />\n <Line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\" />\n {muted ? <Line x1=\"3\" y1=\"3\" x2=\"21\" y2=\"21\" stroke={ada.paper} strokeWidth={2.4} /> : null}\n </Svg>\n </Pressable>\n <Text style={styles.muteLabel}>{muted ? 'Muted' : 'Mute'}</Text>\n </View>\n ) : null}\n\n {/* WebView mounted offscreen — runs WebRTC silently */}\n {callState !== 'idle' && (\n <View style={styles.hiddenWebView} pointerEvents=\"none\">\n <WebView\n ref={webViewRef}\n source={getWebViewSource()}\n style={{ flex: 1, backgroundColor: 'transparent' }}\n onMessage={handleWebViewMessage}\n onError={(e: any) => console.log('[VoiceWebView] error:', e.nativeEvent?.description)}\n injectedJavaScriptBeforeContentLoaded={injectedTrackHook}\n mediaPlaybackRequiresUserAction={false}\n allowsInlineMediaPlayback={true}\n mediaCapturePermissionGrantType=\"grant\"\n javaScriptEnabled={true}\n originWhitelist={['*']}\n />\n </View>\n )}\n </SurfaceFullscreen>\n );\n}\n\nconst styles = StyleSheet.create({\n transcript: {\n flex: 1,\n paddingHorizontal: 28,\n },\n transcriptContent: {\n paddingTop: 8,\n paddingBottom: 16,\n gap: 14,\n },\n entry: {\n flexDirection: 'row',\n gap: 10,\n alignItems: 'flex-start',\n },\n role: {\n fontSize: 10,\n fontFamily: fontFam,\n fontWeight: '700',\n color: ada.inkMuted,\n letterSpacing: 1.4,\n minWidth: 32,\n paddingTop: 3,\n opacity: 0.55,\n },\n entryText: {\n flex: 1,\n fontSize: 14,\n fontFamily: fontFam,\n fontWeight: '400',\n color: ada.inkSoft,\n lineHeight: 20,\n letterSpacing: -0.1,\n opacity: 0.42,\n },\n entryTextLive: {\n flex: 1,\n fontSize: 14,\n fontFamily: fontFam,\n fontWeight: '400',\n color: ada.inkSoft,\n lineHeight: 20,\n letterSpacing: -0.1,\n opacity: 0.7,\n },\n important: {\n fontSize: 17,\n fontFamily: fontFam,\n fontWeight: '700',\n color: ada.ink,\n letterSpacing: -0.1,\n opacity: 1,\n },\n errorBox: {\n backgroundColor: 'rgba(239,68,68,0.12)',\n borderColor: 'rgba(239,68,68,0.45)',\n borderWidth: 1,\n borderRadius: 10,\n paddingVertical: 10,\n paddingHorizontal: 14,\n marginBottom: 12,\n },\n errorText: {\n fontSize: 13,\n fontFamily: fontFam,\n fontWeight: '500',\n color: '#fca5a5',\n lineHeight: 18,\n },\n muteWrap: {\n position: 'absolute',\n bottom: Platform.OS === 'ios' ? 56 : 40,\n left: 28,\n alignItems: 'center',\n gap: 6,\n },\n muteBtn: {\n width: 56,\n height: 56,\n borderRadius: 28,\n backgroundColor: ada.paperSoft,\n borderWidth: 1,\n borderColor: ada.border,\n justifyContent: 'center',\n alignItems: 'center',\n },\n muteBtnActive: {\n backgroundColor: '#C15545',\n borderColor: '#C15545',\n },\n muteLabel: {\n fontSize: 12,\n fontFamily: fontFam,\n fontWeight: '500',\n color: ada.inkMuted,\n letterSpacing: 0.3,\n },\n hiddenWebView: {\n position: 'absolute',\n width: 1,\n height: 1,\n top: -100,\n left: -100,\n opacity: 0,\n },\n});\n","/**\n * useVoiceCall — WebView-based voice hook.\n *\n * The WebView runs WebRTC + OpenAI Realtime internally (iOS WebView supports\n * WebRTC); communication is postMessage (transcript/state events → RN).\n * Requires `voiceUrl` in the initAdas() config — getWebViewSource() throws\n * without it. Identity (token/tenant/actor) comes from the host-owned config.\n */\nimport { useState, useRef, useCallback } from 'react';\nimport { getVoiceApiUrl, getToken, getTenant, getUser } from '@ateam-ai-mobile/core';\n\nexport interface TranscriptEntry {\n role: 'user' | 'ai' | 'tool';\n text: string;\n ts: number;\n}\n\nexport type CallState = 'idle' | 'connecting' | 'connected' | 'error';\n\n// Installed BEFORE the voice app loads. Captures every audio track that\n// could possibly be sent to the peer connection so the mute button can flip\n// enabled=false on all of them, regardless of how the voice app obtained or\n// added the track.\nconst INJECT_TRACK_HOOK = `\n(function() {\n if (window._adaTrackHookInstalled) return;\n window._adaTrackHookInstalled = true;\n window._allAudioTracks = [];\n window._adaPeerConnections = [];\n\n function track(t) {\n if (t && t.kind === 'audio' && window._allAudioTracks.indexOf(t) === -1) {\n window._allAudioTracks.push(t);\n }\n }\n\n // 1) Hook getUserMedia — captures mic streams at request time.\n try {\n if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {\n const origGUM = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);\n navigator.mediaDevices.getUserMedia = async function(constraints) {\n const stream = await origGUM(constraints);\n if (constraints && constraints.audio) {\n try { stream.getAudioTracks().forEach(track); } catch (e) {}\n }\n return stream;\n };\n }\n } catch (e) {}\n\n // 2) Hook RTCPeerConnection.addTrack — catches whatever the app sends.\n try {\n if (window.RTCPeerConnection) {\n const origPC = window.RTCPeerConnection;\n const origAddTrack = origPC.prototype.addTrack;\n const origAddStream = origPC.prototype.addStream;\n const origAddTransceiver = origPC.prototype.addTransceiver;\n\n origPC.prototype.addTrack = function(t) {\n if (t && t.kind === 'audio') track(t);\n return origAddTrack.apply(this, arguments);\n };\n if (origAddStream) {\n origPC.prototype.addStream = function(stream) {\n try { stream.getAudioTracks().forEach(track); } catch (e) {}\n return origAddStream.apply(this, arguments);\n };\n }\n if (origAddTransceiver) {\n origPC.prototype.addTransceiver = function(arg) {\n if (arg && arg.kind === 'audio') {\n // Transceiver created with kind 'audio' — sender track set later.\n } else if (arg && arg.kind === undefined && arg.track && arg.track.kind === 'audio') {\n track(arg.track);\n }\n const tx = origAddTransceiver.apply(this, arguments);\n try {\n if (tx && tx.sender && tx.sender.track && tx.sender.track.kind === 'audio') track(tx.sender.track);\n } catch (e) {}\n return tx;\n };\n }\n }\n } catch (e) {}\n\n // 3) Helper exposed for direct calls.\n window._adaSetMuted = function(muted) {\n let n = 0;\n if (Array.isArray(window._allAudioTracks)) {\n window._allAudioTracks.forEach(function(t) {\n try { t.enabled = !muted; n++; } catch (e) {}\n });\n }\n return n;\n };\n})(); true;\n`;\n\nconst buildMuteScript = (muted: boolean) => `\n(function(muted) {\n if (typeof window.setMuted === 'function') { window.setMuted(muted); }\n let n = 0;\n if (typeof window._adaSetMuted === 'function') {\n n = window._adaSetMuted(muted);\n }\n // Last-resort scan if hook somehow missed.\n if (n === 0 && Array.isArray(window._allAudioTracks)) {\n window._allAudioTracks.forEach(function(t) {\n try { t.enabled = !muted; n++; } catch (e) {}\n });\n }\n console.log('[ada-mute]', muted ? 'MUTED' : 'UNMUTED', 'tracks=', n);\n})(${muted}); true;\n`;\n\nexport default function useVoiceCall() {\n const [callState, setCallState] = useState<CallState>('idle');\n const [sessionId, setSessionId] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [transcript, setTranscript] = useState<TranscriptEntry[]>([]);\n const [aiPartial, setAiPartial] = useState('');\n const [userPartial, setUserPartial] = useState('');\n const [muted, setMuted] = useState(false);\n const webViewRef = useRef<any>(null);\n\n /** Handle postMessage events from the WebView */\n const handleWebViewMessage = useCallback((event: any) => {\n try {\n const data = JSON.parse(event.nativeEvent.data);\n console.log('[VoiceWebView] message:', data.type, data.text?.slice?.(0, 50) || data.state || '');\n switch (data.type) {\n case 'callState':\n case 'call-state':\n setCallState(data.state);\n if (data.sessionId) setSessionId(data.sessionId);\n if (data.error) setError(data.error);\n break;\n case 'transcript':\n setTranscript(prev => [...prev, { role: data.role, text: data.text, ts: Date.now() }]);\n break;\n case 'aiPartial':\n setAiPartial(data.text);\n break;\n case 'userPartial':\n setUserPartial(data.text);\n break;\n case 'clearPartials':\n setAiPartial('');\n setUserPartial('');\n break;\n case 'error':\n setError(data.message);\n setCallState('error');\n break;\n }\n } catch {}\n }, []);\n\n const startCall = useCallback(() => {\n setCallState('connecting');\n setError(null);\n setTranscript([]);\n setAiPartial('');\n setUserPartial('');\n }, []);\n\n const stopCall = useCallback(() => {\n // Tell WebView to hang up\n webViewRef.current?.injectJavaScript?.('window.hangUp && window.hangUp(); true;');\n setCallState('idle');\n setAiPartial('');\n setUserPartial('');\n setMuted(false);\n }, []);\n\n const toggleMute = useCallback(() => {\n setMuted(prev => {\n const next = !prev;\n webViewRef.current?.injectJavaScript?.(buildMuteScript(next));\n return next;\n });\n }, []);\n\n /** Build the WebView source. Identity comes from the SDK config (host-owned\n * auth) — token, tenant, actorId are passed to the voice mini-app. */\n const getWebViewSource = useCallback(() => {\n const token = getToken();\n const tenant = getTenant();\n const actorId = getUser()?.actorId || '';\n return {\n uri: `${getVoiceApiUrl()}/app?mode=mini&embedded=rn&authToken=${encodeURIComponent(token || '')}&tenant=${encodeURIComponent(tenant)}&actorId=${encodeURIComponent(actorId)}`,\n };\n }, []);\n\n return {\n callState, sessionId, error, transcript, aiPartial, userPartial, muted,\n startCall, stopCall, toggleMute, handleWebViewMessage, getWebViewSource, webViewRef,\n injectedTrackHook: INJECT_TRACK_HOOK,\n };\n}\n"],"mappings":"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","names":["useCallback","useEffect","useMemo","useRef","useState","Platform","StyleSheet","View","ada","pluginCommandEmitter","useState","useCallback","View","Text","Pressable","StyleSheet","Platform","getConfig","ada","borderRadius","fontSize","getHaptics","View","Text","Pressable","StyleSheet","Platform","ada","fontSize","useSurfaceStore","useEffect","pluginCommandEmitter","useEffect","useState","View","ActivityIndicator","ada","useMemo","View","Text","ActivityIndicator","StyleSheet","getTenant","useState","useCallback","View","Text","StyleSheet","getTenant","ada","useEffect","useRef","data","jsx","jsxs","useState","getTenant","useCallback","View","styles","Text","ada","StyleSheet","jsx","jsxs","View","styles","Text","useMemo","getTenant","ActivityIndicator","StyleSheet","jsx","useState","useEffect","View","ActivityIndicator","ada","jsx","useEffect","pluginCommandEmitter","jsx","jsxs","Platform","useSurfaceStore","View","styles","Pressable","Text","StyleSheet","ada","fontSize","View","Text","StyleSheet","Platform","ada","fontSize","jsx","jsxs","fontFam","styles","create","jsx","jsxs","fontFam","Platform","View","Text","StyleSheet","ada","useState","useCallback","getHaptics","styles","Pressable","getConfig","borderRadius","fontSize","View","StyleSheet","AdaOrb","jsx","styles","useState","useRef","useCallback","useEffect","View","Pressable","StyleSheet","Platform","colors","borderRadius","getHaptics","jsx","jsxs","styles","View","Image","Pressable","Text","StyleSheet","getConfig","jsx","jsxs","Pressable","styles","Image","getConfig","View","Text","StyleSheet","jsx","jsxs","isSameDay","useRef","useState","useEffect","pluginCommandEmitter","Platform","useMemo","useCallback","View","styles","ada","StyleSheet","useMemo","useState","Modal","View","Text","Pressable","StyleSheet","ActivityIndicator","Platform","WebView","ada","getCoreApiUrl","Fragment","jsx","jsxs","fontFam","styles","useEffect","useState","View","Text","Pressable","ActivityIndicator","StyleSheet","Platform","ada","fontSize","borderRadius","getTenant","jsx","jsxs","fontFam","styles","useEffect","useRef","useMemo","View","Text","StyleSheet","Platform","Pressable","Svg","Path","Line","WebView","ada","AdaOrb","SurfaceFullscreen","useState","useRef","useCallback","getVoiceApiUrl","getToken","getTenant","getUser","jsx","jsxs","fontFam","Platform","useMemo","Text","useRef","useEffect","SurfaceFullscreen","AdaOrb","styles","View","Pressable","Svg","ada","Path","Line","WebView","StyleSheet"]}
1
+ {"version":3,"sources":["../src/AdasChatScreen.tsx","../src/chat/MessageBubble.tsx","../src/chat/JobProgressBar.tsx","../src/chat/UIActionsRow.tsx","../src/providers.ts","../src/plugin/WidgetHost.tsx","../src/plugin/PluginSurface.tsx","../src/plugin/Plugin.tsx","../src/plugin/EmbeddedPluginWebView.tsx","../src/plugin/usePluginBridge.ts","../src/chat/TableCardBlock.tsx","../src/stores/lightboxStore.ts","../src/chat/TypingIndicator.tsx","../src/chat/ChatInput.tsx","../src/Lightbox.tsx","../src/widgets/WidgetWebView.tsx","../src/TenantPicker.tsx","../src/voice/VoiceCallSheet.tsx","../src/voice/useVoiceCall.ts"],"sourcesContent":["/**\n * AdasChatScreen — the drop-in ADAS chat experience.\n *\n * Push it as a screen or mount it full-flex anywhere: message history with\n * live agent progress, day separators, UI-action chips, table cards,\n * attachment previews, pull-to-refresh, and the composer. Built ONLY on the\n * public @ateam-ai-mobile/core + @ateam-ai-mobile/plugin-runtime APIs.\n *\n * The host must call initAdas() first, and typically:\n * setUIActionNavigator(route => router.push(...)) // chips → plugin screen\n * setupExpoProviders() // Expo hosts\n *\n * Also mount <SurfaceDispatcher /> once at the app root so engine-summoned\n * plugin surfaces (drawers/fullscreens) can appear over the chat.\n */\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n FlatList,\n KeyboardAvoidingView,\n Platform,\n RefreshControl,\n StyleSheet,\n View,\n} from 'react-native';\nimport { ada, useChatStore, pluginCommandEmitter } from '@ateam-ai-mobile/core';\nimport type { Message } from '@ateam-ai-mobile/core';\nimport MessageBubble, { DaySeparator } from './chat/MessageBubble';\nimport TypingIndicator from './chat/TypingIndicator';\nimport ChatInput from './chat/ChatInput';\nimport Lightbox from './Lightbox';\nimport WidgetHost from './plugin/WidgetHost';\n\nexport interface AdasChatScreenProps {\n /** Called when the user taps the call button; omit to hide it. */\n onCallStart?: () => void;\n /** Composer placeholder. */\n placeholder?: string;\n /** Extra element rendered above the composer (e.g. suggestion chips). */\n footerAccessory?: React.ReactNode;\n /** Mount the fullscreen image viewer here. Default true — set false if\n * the host already mounts <Lightbox /> at its root. */\n withLightbox?: boolean;\n}\n\nfunction isSameDay(a: Date, b: Date): boolean {\n return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();\n}\n\nexport default function AdasChatScreen({\n onCallStart,\n placeholder,\n footerAccessory,\n withLightbox = true,\n}: AdasChatScreenProps) {\n const messages = useChatStore(s => s.messages);\n const loading = useChatStore(s => s.loading);\n const conversationLoaded = useChatStore(s => s.conversationLoaded);\n const loadConversation = useChatStore(s => s.loadConversation);\n const sendMessage = useChatStore(s => s.sendMessage);\n\n const listRef = useRef<FlatList<Message>>(null);\n const [refreshing, setRefreshing] = useState(false);\n const [prefill, setPrefill] = useState('');\n\n // Initial history load.\n useEffect(() => {\n if (!conversationLoaded) loadConversation();\n }, [conversationLoaded, loadConversation]);\n\n // bridge.prepareMessage(text) → pre-fill the composer without sending.\n useEffect(() => {\n const unsub = pluginCommandEmitter.on('prepare-chat-message', ({ text }: { text?: string }) => {\n if (text) setPrefill(text);\n });\n return unsub;\n }, []);\n\n // Inverted list — newest at the bottom without scroll management. On WEB\n // `inverted` is a scaleY(-1) transform that react-native-web applies to the\n // container but not reliably to items — content renders upside-down. Use a\n // normal list there and scroll to the end instead.\n const useInverted = Platform.OS !== 'web';\n const listData = useMemo(\n () => (useInverted ? [...messages].reverse() : messages),\n [messages, useInverted],\n );\n\n const scrollToLatest = useCallback((animated: boolean) => {\n if (useInverted) listRef.current?.scrollToOffset({ offset: 0, animated });\n else listRef.current?.scrollToEnd({ animated });\n }, [useInverted]);\n\n const handleSend = useCallback((text: string) => {\n setPrefill('');\n sendMessage(text);\n scrollToLatest(true);\n }, [sendMessage, scrollToLatest]);\n\n const handleRefresh = useCallback(async () => {\n setRefreshing(true);\n try { await loadConversation(); } catch {}\n setRefreshing(false);\n }, [loadConversation]);\n\n const renderItem = useCallback(({ item, index }: { item: Message; index: number }) => {\n // The \"previous\" (older) message is the NEXT array item when inverted,\n // the previous one otherwise.\n const older = useInverted ? listData[index + 1] : listData[index - 1];\n const showDaySep = !older || !isSameDay(older.timestamp, item.timestamp);\n return (\n <View>\n {showDaySep && <DaySeparator date={item.timestamp} />}\n <MessageBubble message={item} />\n </View>\n );\n }, [listData, useInverted]);\n\n const typingIndicator =\n loading && !(useInverted ? listData[0] : listData[listData.length - 1])?.jobProgress\n ? <TypingIndicator />\n : null;\n\n return (\n <KeyboardAvoidingView\n style={styles.root}\n behavior={Platform.OS === 'ios' ? 'padding' : undefined}\n >\n <FlatList\n ref={listRef}\n style={styles.list}\n data={listData}\n inverted={useInverted}\n keyExtractor={m => m.id}\n renderItem={renderItem}\n // In an inverted list the header renders at the visual BOTTOM — where\n // the typing indicator belongs; on web (non-inverted) it's the footer.\n // Suppressed when the newest bubble already shows its progress pill.\n ListHeaderComponent={useInverted ? typingIndicator : null}\n ListFooterComponent={useInverted ? null : typingIndicator}\n onContentSizeChange={useInverted ? undefined : () => scrollToLatest(false)}\n refreshControl={\n <RefreshControl refreshing={refreshing} onRefresh={handleRefresh} tintColor={ada.orange} />\n }\n keyboardShouldPersistTaps=\"handled\"\n contentContainerStyle={styles.listContent}\n />\n {footerAccessory}\n <ChatInput\n onSend={handleSend}\n onCallStart={onCallStart}\n loading={loading}\n prefill={prefill}\n placeholder={placeholder}\n />\n {withLightbox && <Lightbox />}\n {/* Built-in widget presenter: chips without a host navigator and\n agent-driven focus-plugin events open widgets here — zero wiring. */}\n <WidgetHost />\n </KeyboardAvoidingView>\n );\n}\n\nconst styles = StyleSheet.create({\n root: {\n flex: 1,\n backgroundColor: ada.paper,\n },\n list: {\n flex: 1,\n },\n listContent: {\n paddingVertical: 12,\n },\n});\n","import { useState, useCallback } from 'react';\nimport { View, Text, Pressable, StyleSheet, Image, Platform } from 'react-native';\nimport Markdown from 'react-native-markdown-display';\nimport type { Message, ToolCall } from '@ateam-ai-mobile/core';\nimport { TABLE_BLOCK_OPEN, TABLE_BLOCK_CLOSE, getConfig, ada, borderRadius, fontSize } from '@ateam-ai-mobile/core';\nimport { AdaOrb, getHaptics } from '@ateam-ai-mobile/plugin-runtime';\nimport JobProgressBar from './JobProgressBar';\nimport UIActionsRow from './UIActionsRow';\nimport TableCardBlock from './TableCardBlock';\nimport { useLightboxStore } from '../stores/lightboxStore';\nimport { getClipboard } from '../providers';\n\nconst fontFam = Platform.OS === 'ios' ? 'SF Pro Rounded' : undefined;\n\ninterface Props {\n message: Message;\n}\n\nfunction formatTime(date: Date): string {\n const h = date.getHours();\n const m = date.getMinutes().toString().padStart(2, '0');\n return `${h}:${m}`;\n}\n\nexport function DaySeparator({ date }: { date: Date }) {\n const today = new Date();\n const yesterday = new Date(today);\n yesterday.setDate(yesterday.getDate() - 1);\n\n let label: string;\n if (isSameDay(date, today)) {\n label = 'Today';\n } else if (isSameDay(date, yesterday)) {\n label = 'Yesterday';\n } else {\n label = date.toLocaleDateString(undefined, { weekday: 'long', month: 'short', day: 'numeric' });\n }\n\n return (\n <View style={separatorStyles.container}>\n <View style={separatorStyles.pill}>\n <Text style={separatorStyles.text}>{label}</Text>\n </View>\n </View>\n );\n}\n\nfunction isSameDay(a: Date, b: Date): boolean {\n return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();\n}\n\nconst separatorStyles = StyleSheet.create({\n container: {\n alignItems: 'center',\n marginVertical: 14,\n },\n pill: {\n backgroundColor: ada.paperSoft,\n paddingHorizontal: 14,\n paddingVertical: 5,\n borderRadius: 999,\n },\n text: {\n fontSize: 12,\n fontWeight: '600',\n color: ada.inkMuted,\n letterSpacing: 0.4,\n fontFamily: fontFam,\n },\n});\n\nexport default function MessageBubble({ message }: Props) {\n const isUser = message.role === 'user';\n const isSystem = message.role === 'system';\n const isNotification = !isUser && message.kind === 'notification';\n // A \"working on it\" placeholder — just the live chain indicator, no real\n // answer yet. Render it near-transparent so it floats over the background\n // instead of looking like a solid message bubble.\n const st = message.jobProgress?.status;\n const isProgressOnly =\n !isUser &&\n (st === 'running' || st === 'paused') &&\n (!message.content?.trim() || message.content === 'Working on it...');\n const [copied, setCopied] = useState('');\n\n const showCopied = useCallback((label: string) => {\n setCopied(label);\n getHaptics()?.notification('success');\n setTimeout(() => setCopied(''), 1500);\n }, []);\n\n const copyText = useCallback(async (text: string) => {\n const clipboard = getClipboard();\n if (!clipboard) return; // no provider — silently skip (no false \"Copied!\")\n await clipboard.setString(text);\n showCopied('Copied!');\n }, [showCopied]);\n\n const handleLongPress = useCallback(() => {\n copyText(message.content);\n }, [message.content, copyText]);\n\n return (\n <View style={[styles.row, isUser && styles.rowUser]}>\n {!isUser && !isNotification && (\n <View style={styles.avatarOrb}>\n <AdaOrb\n size={28}\n state={message.jobProgress?.status === 'running' ? 'thinking' : 'idle'}\n />\n </View>\n )}\n {isNotification && <View style={styles.notificationLeftStripe} />}\n <Pressable\n accessibilityRole=\"text\"\n accessibilityLabel={`${isUser ? 'You' : isNotification ? 'Notification' : 'Ada'}: ${message.content}`}\n accessibilityHint=\"Long-press to copy\"\n onLongPress={handleLongPress}\n style={[\n styles.bubble,\n isUser && styles.bubbleUser,\n isSystem && styles.bubbleSystem,\n isNotification && styles.bubbleNotification,\n isProgressOnly && styles.bubbleProgress,\n ]}\n >\n {isNotification && (\n <View style={styles.notificationHeader}>\n <Text style={styles.notificationHeaderIcon}>🔔</Text>\n <Text style={styles.notificationHeaderText}>Notification</Text>\n </View>\n )}\n {/* Attachment thumbnails */}\n {message.attachments && message.attachments.length > 0 && (\n <View style={styles.attachments}>\n {message.attachments.map((att, i) => (\n att.previewUri ? (\n <Pressable\n key={i}\n accessibilityRole=\"imagebutton\"\n accessibilityLabel={`Photo${att.name ? `: ${att.name}` : ''}. Tap to enlarge.`}\n onPress={() => useLightboxStore.getState().show(att.previewUri!)}\n >\n <Image\n source={{\n uri: att.previewUri,\n ...(att.previewUri.startsWith('http') ? {\n headers: { Authorization: `Bearer ${getConfig().tokenProvider.getToken()}` },\n } : {}),\n }}\n style={styles.attachmentImage}\n resizeMode=\"cover\"\n onError={(e) => console.warn('[Image] Failed to load:', att.previewUri?.slice(0, 100), e.nativeEvent.error)}\n />\n </Pressable>\n ) : (\n <View key={i} style={styles.attachmentFile}>\n <Text style={styles.attachmentFileName} numberOfLines={1}>{att.name}</Text>\n </View>\n )\n ))}\n </View>\n )}\n {isUser ? (\n // Hide the \"See attachment\" placeholder when the bubble already shows the photo.\n message.content && !(message.content === 'See attachment' && message.attachments?.length) ? (\n <Text selectable style={styles.userText}>{message.content}</Text>\n ) : null\n ) : isProgressOnly ? (\n // No \"Working on it…\" text — the indicator below is the whole message.\n null\n ) : (\n renderAssistantContent(message.content, copyText)\n )}\n {!!copied && (\n <View style={styles.copiedBadge}>\n <Text style={styles.copiedText}>{copied}</Text>\n </View>\n )}\n {message.toolCalls && message.toolCalls.length > 0 && (\n <ToolCallsBadge calls={message.toolCalls} />\n )}\n {message.jobProgress && (\n <JobProgressBar progress={message.jobProgress} standalone={isProgressOnly} />\n )}\n {!isUser && message.actions && message.actions.length > 0 && (\n <UIActionsRow actions={message.actions} />\n )}\n {!isProgressOnly && (\n <Text style={[styles.timeText, isUser && styles.timeTextUser]}>\n {formatTime(message.timestamp)}\n </Text>\n )}\n </Pressable>\n {isUser && <View style={styles.avatarSpacer} />}\n </View>\n );\n}\n\n/**\n * Split assistant content on table-block sentinels and render each segment:\n * markdown text → <Markdown>, table payload → <TableCardBlock>. Falls back\n * to plain markdown when no sentinels are present (the common case).\n */\nfunction renderAssistantContent(content: string, copyText: (s: string) => void) {\n if (!content) return null;\n if (!content.includes(TABLE_BLOCK_OPEN)) {\n return <MarkdownBubble content={content} copyText={copyText} />;\n }\n\n const segments: Array<{ kind: 'md' | 'table'; content: string }> = [];\n let cursor = 0;\n while (cursor < content.length) {\n const open = content.indexOf(TABLE_BLOCK_OPEN, cursor);\n if (open === -1) {\n segments.push({ kind: 'md', content: content.slice(cursor) });\n break;\n }\n if (open > cursor) {\n segments.push({ kind: 'md', content: content.slice(cursor, open) });\n }\n const close = content.indexOf(TABLE_BLOCK_CLOSE, open + TABLE_BLOCK_OPEN.length);\n if (close === -1) {\n // Unterminated marker — render the rest as markdown so we don't lose data.\n segments.push({ kind: 'md', content: content.slice(open) });\n break;\n }\n const payload = content.slice(open + TABLE_BLOCK_OPEN.length, close);\n segments.push({ kind: 'table', content: payload });\n cursor = close + TABLE_BLOCK_CLOSE.length;\n }\n\n return (\n <>\n {segments.map((seg, i) => {\n if (seg.kind === 'md') {\n const trimmed = seg.content.trim();\n if (!trimmed) return null;\n return <MarkdownBubble key={i} content={seg.content} copyText={copyText} />;\n }\n try {\n const data = JSON.parse(decodeURIComponent(seg.content));\n return <TableCardBlock key={i} columns={data.columns} rows={data.rows} />;\n } catch {\n return null;\n }\n })}\n </>\n );\n}\n\nfunction MarkdownBubble({ content, copyText }: { content: string; copyText: (s: string) => void }) {\n return (\n <Markdown\n style={markdownStyles}\n rules={{\n code_inline: (node) => (\n <Text\n key={node.key}\n style={markdownStyles.code_inline}\n onPress={() => copyText(node.content)}\n >\n {node.content}\n </Text>\n ),\n fence: (node) => (\n <Pressable\n key={node.key}\n onPress={() => copyText(node.content)}\n style={markdownStyles.fence}\n >\n <Text style={markdownStyles.fenceText}>{node.content}</Text>\n </Pressable>\n ),\n }}\n >\n {content}\n </Markdown>\n );\n}\n\nfunction ToolCallsBadge({ calls }: { calls: ToolCall[] }) {\n const [expanded, setExpanded] = useState(false);\n const label = calls\n .filter(c => c.name === 'send_message_to_skill')\n .map(c => (c.args as any).skill_name || c.skill)\n .filter(Boolean)\n .join(', ') || 'Tool call';\n\n return (\n <View style={styles.toolCalls}>\n <Pressable style={styles.toolToggle} onPress={() => setExpanded(!expanded)}>\n <Text style={styles.toolLabel}>{label}</Text>\n <Text style={styles.toolChevron}>{expanded ? '▲' : '▼'}</Text>\n </Pressable>\n {expanded && calls.map((tc, i) => (\n <View key={i} style={styles.toolItem}>\n <Text style={styles.toolName}>{tc.name}</Text>\n {tc.skill && <Text style={styles.toolSkill}>{tc.skill}</Text>}\n </View>\n ))}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n row: {\n flexDirection: 'row',\n alignItems: 'flex-end',\n marginBottom: 12,\n paddingHorizontal: 12,\n gap: 8,\n },\n rowUser: {\n justifyContent: 'flex-end',\n },\n avatarOrb: {\n width: 28,\n height: 28,\n justifyContent: 'center',\n alignItems: 'center',\n },\n avatarSpacer: {\n width: 28,\n height: 28,\n },\n bubble: {\n maxWidth: '78%',\n backgroundColor: ada.botBubble,\n borderWidth: 1,\n borderColor: ada.botBubbleBorder,\n borderRadius: borderRadius.xl,\n paddingHorizontal: 16,\n paddingVertical: 12,\n },\n bubbleUser: {\n backgroundColor: ada.userBubble,\n borderColor: 'transparent',\n },\n // Live-chain placeholder: no fill, no border, tighter padding — the\n // indicator floats over the background instead of sitting in a bubble.\n bubbleProgress: {\n backgroundColor: 'transparent',\n borderColor: 'transparent',\n paddingHorizontal: 4,\n paddingVertical: 2,\n },\n bubbleSystem: {\n backgroundColor: ada.orangeSoft,\n borderColor: ada.orange,\n maxWidth: '90%',\n },\n bubbleNotification: {\n backgroundColor: ada.orangeSoft,\n borderColor: 'rgba(255, 122, 40, 0.35)',\n borderRadius: borderRadius.lg,\n maxWidth: '90%',\n },\n notificationLeftStripe: {\n width: 3,\n alignSelf: 'stretch',\n backgroundColor: ada.orange,\n borderRadius: 2,\n marginRight: 4,\n },\n notificationHeader: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 6,\n marginBottom: 6,\n },\n notificationHeaderIcon: {\n fontSize: 12,\n },\n notificationHeaderText: {\n color: ada.orangeDeep,\n fontSize: 11,\n fontWeight: '700',\n letterSpacing: 0.6,\n textTransform: 'uppercase',\n fontFamily: fontFam,\n },\n userText: {\n color: ada.userBubbleText,\n fontSize: fontSize.md,\n lineHeight: 22,\n fontFamily: fontFam,\n },\n timeText: {\n fontSize: 11,\n color: ada.inkMuted,\n alignSelf: 'flex-end',\n marginTop: 4,\n fontFamily: fontFam,\n },\n timeTextUser: {\n color: 'rgba(250,246,238,0.55)',\n },\n attachments: {\n flexDirection: 'row',\n flexWrap: 'wrap',\n gap: 6,\n marginBottom: 8,\n },\n attachmentImage: {\n width: 120,\n height: 90,\n borderRadius: 8,\n },\n attachmentFile: {\n backgroundColor: 'rgba(255,255,255,0.15)',\n borderRadius: 8,\n paddingHorizontal: 10,\n paddingVertical: 6,\n },\n attachmentFileName: {\n color: 'rgba(255,255,255,0.8)',\n fontSize: 11,\n maxWidth: 100,\n },\n copiedBadge: {\n position: 'absolute',\n top: 6,\n right: 6,\n backgroundColor: '#5A8A5C',\n paddingHorizontal: 8,\n paddingVertical: 2,\n borderRadius: borderRadius.sm,\n },\n copiedText: {\n color: '#fff',\n fontSize: fontSize.xs,\n fontWeight: '600',\n },\n toolCalls: {\n marginTop: 8,\n borderTopWidth: 1,\n borderTopColor: ada.border,\n paddingTop: 6,\n },\n toolToggle: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 6,\n },\n toolLabel: {\n color: ada.inkSoft,\n fontSize: fontSize.xs,\n fontWeight: '500',\n },\n toolChevron: {\n color: ada.inkMuted,\n fontSize: 8,\n },\n toolItem: {\n marginTop: 4,\n paddingLeft: 8,\n },\n toolName: {\n color: ada.inkSoft,\n fontSize: fontSize.xs,\n fontFamily: 'monospace',\n },\n toolSkill: {\n color: ada.orangeDeep,\n fontSize: fontSize.xs,\n },\n});\n\nconst markdownStyles = StyleSheet.create({\n body: {\n color: ada.botBubbleText,\n fontSize: fontSize.md,\n lineHeight: 22,\n fontFamily: fontFam,\n },\n paragraph: {\n marginTop: 0,\n marginBottom: 4,\n },\n strong: {\n fontWeight: '700',\n color: ada.botBubbleText,\n },\n em: {\n fontStyle: 'italic',\n },\n code_inline: {\n backgroundColor: ada.paperDeep,\n color: ada.orangeDeep,\n paddingHorizontal: 5,\n paddingVertical: 1,\n borderRadius: 4,\n fontFamily: 'monospace',\n fontSize: fontSize.sm,\n },\n fence: {\n backgroundColor: ada.paperDeep,\n padding: 10,\n borderRadius: 10,\n },\n fenceText: {\n fontFamily: 'monospace',\n fontSize: fontSize.sm,\n color: ada.ink,\n },\n link: {\n color: ada.orangeDeep,\n },\n list_item: {\n color: ada.botBubbleText,\n },\n bullet_list: {\n marginVertical: 4,\n },\n});\n","import { useEffect, useRef, useState } from 'react';\nimport { View, Text, Animated, StyleSheet } from 'react-native';\nimport type { JobProgress } from '@ateam-ai-mobile/core';\nimport { ada, fontSize } from '@ateam-ai-mobile/core';\n\n// Semantic warm-palette colors for terminal states (kept local — Ada palette\n// is mostly orange/ink, but progress states need a small warm green/red/amber\n// vocabulary to stay readable).\nconst WARM_GREEN = '#5A8A5C';\nconst WARM_GREEN_SOFT = 'rgba(90, 138, 92, 0.14)';\nconst WARM_RED = '#C15545';\nconst WARM_RED_SOFT = 'rgba(193, 85, 69, 0.14)';\nconst WARM_AMBER = '#D49A4E';\nconst WARM_AMBER_SOFT = 'rgba(212, 154, 78, 0.16)';\n\ninterface Props {\n progress: JobProgress;\n /** Standalone placeholder (transparent bubble) — drop the top divider so it\n * floats cleanly over the background. */\n standalone?: boolean;\n}\n\nexport default function JobProgressBar({ progress, standalone }: Props) {\n const pulseAnim = useRef(new Animated.Value(0.5)).current;\n const [elapsed, setElapsed] = useState(0);\n\n const isRunning = progress.status === 'running';\n const isDone = progress.status === 'done';\n const isError = progress.status === 'error';\n const isPaused = progress.status === 'paused';\n\n // Pulse animation while running\n useEffect(() => {\n if (!isRunning) {\n pulseAnim.setValue(1);\n return;\n }\n const anim = Animated.loop(\n Animated.sequence([\n // Gentle breath — a soft fade rather than a hard blink, so the running\n // indicator recedes into the bubble instead of demanding attention.\n Animated.timing(pulseAnim, { toValue: 0.55, duration: 1100, useNativeDriver: true }),\n Animated.timing(pulseAnim, { toValue: 0.22, duration: 1100, useNativeDriver: true }),\n ]),\n );\n anim.start();\n return () => anim.stop();\n }, [isRunning, pulseAnim]);\n\n // Elapsed timer — ticks every second while running, clears on terminal state\n useEffect(() => {\n if (!isRunning || !progress.chainStartedAt) {\n setElapsed(0);\n return;\n }\n const start = progress.chainStartedAt;\n setElapsed(Math.floor((Date.now() - start) / 1000));\n const id = setInterval(() => {\n setElapsed(Math.floor((Date.now() - start) / 1000));\n }, 1000);\n return () => clearInterval(id);\n }, [isRunning, progress.chainStartedAt]);\n\n const statusColor = isDone\n ? WARM_GREEN\n : isError\n ? WARM_RED\n : isPaused\n ? WARM_AMBER\n : ada.orange;\n\n const statusBg = isDone\n ? WARM_GREEN_SOFT\n : isError\n ? WARM_RED_SOFT\n : isPaused\n ? WARM_AMBER_SOFT\n : ada.orangeSoft;\n\n // Terminal states — simple one-liner\n if (isDone || isError) {\n return (\n <View style={[styles.container, standalone && styles.containerStandalone]}>\n <View style={styles.row}>\n <View style={[styles.dot, { backgroundColor: statusColor }]} />\n <Text style={[styles.label, { color: statusColor }]}>\n {isDone ? 'Completed' : 'Failed'}\n </Text>\n </View>\n </View>\n );\n }\n\n if (isPaused) {\n return (\n <View style={[styles.container, standalone && styles.containerStandalone]}>\n <View style={styles.row}>\n <View style={[styles.dot, { backgroundColor: statusColor }]} />\n <Text style={[styles.label, { color: statusColor }]}>\n Waiting for your reply\n </Text>\n </View>\n </View>\n );\n }\n\n // Running. Prefer the backend's warm, localized humanStatus; fall back to\n // the raw skill/tool tokens (translated via humanLabels when available).\n // Elapsed shows in human units: \"3s\", \"1m 20s\". (Docs/STATUS_I18N_MOBILE_API)\n const elapsedStr = progress.chainStartedAt\n ? elapsed < 60\n ? `${elapsed}s`\n : `${Math.floor(elapsed / 60)}m ${elapsed % 60}s`\n : null;\n\n const metaParts = [\n progress.iteration != null && progress.iteration > 0 ? `iter ${progress.iteration}` : null,\n elapsedStr,\n ].filter(Boolean) as string[];\n\n const labels = progress.humanLabels;\n const label = (t?: string) => (t && labels?.[t]) || t;\n const headline = progress.humanStatus || label(progress.skillSlug) || 'Processing...';\n // When we already have a warm headline, don't also show the raw \"→ tool\".\n const showRawTool = !progress.humanStatus && !!progress.currentTool;\n\n const lp = progress.liveProgress;\n\n return (\n <View style={[styles.container, standalone && styles.containerStandalone]}>\n <View style={styles.row}>\n <Animated.View\n style={[styles.dot, styles.dotRunning, { opacity: pulseAnim }]}\n />\n <Text style={styles.skill} numberOfLines={1}>\n {headline}\n </Text>\n {showRawTool && (\n <Text style={styles.tool} numberOfLines={1}>\n {` → ${label(progress.currentTool)}`}\n </Text>\n )}\n {metaParts.length > 0 && (\n <Text style={styles.meta} numberOfLines={1}>\n {` · ${metaParts.join(' · ')}`}\n </Text>\n )}\n </View>\n {/* Live progress from adas_emit_progress() — shown during fat tool execution */}\n {!!lp?.message && (\n <View style={styles.liveProgressRow}>\n {lp.step != null && lp.total != null && (\n <Text style={styles.liveProgressStep}>[{lp.step}/{lp.total}]</Text>\n )}\n <Text style={styles.liveProgressMsg} numberOfLines={1}>{lp.message}</Text>\n </View>\n )}\n <View style={styles.progressTrack}>\n <Animated.View\n style={[styles.progressFill, { opacity: pulseAnim }]}\n />\n </View>\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n marginTop: 8,\n paddingTop: 8,\n borderTopWidth: 1,\n borderTopColor: ada.border,\n },\n // Standalone (transparent-bubble) placeholder — no divider/top spacing.\n containerStandalone: {\n marginTop: 0,\n paddingTop: 0,\n borderTopWidth: 0,\n },\n row: {\n flexDirection: 'row',\n alignItems: 'center',\n flexWrap: 'nowrap',\n overflow: 'hidden',\n },\n dot: {\n width: 6,\n height: 6,\n borderRadius: 3,\n marginRight: 6,\n flexShrink: 0,\n },\n // Running dot: soft orange, not the full-saturation accent.\n dotRunning: {\n backgroundColor: 'rgba(255, 122, 40, 0.6)',\n },\n label: {\n fontSize: fontSize.xs,\n fontWeight: '600',\n },\n // Running state text segments — muted so the indicator blends into the\n // bubble rather than shouting in orange.\n skill: {\n fontSize: fontSize.xs,\n fontWeight: '500',\n color: ada.inkSoft,\n flexShrink: 1,\n },\n tool: {\n fontSize: fontSize.xs,\n color: ada.inkMuted,\n flexShrink: 2,\n },\n meta: {\n fontSize: fontSize.xs,\n color: ada.inkMuted,\n flexShrink: 0,\n },\n liveProgressRow: {\n flexDirection: 'row',\n alignItems: 'center',\n marginTop: 4,\n gap: 4,\n },\n liveProgressStep: {\n fontSize: fontSize.xs,\n fontWeight: '600',\n color: ada.inkMuted,\n },\n liveProgressMsg: {\n fontSize: fontSize.xs,\n color: ada.inkSoft,\n flex: 1,\n },\n progressTrack: {\n height: 2,\n borderRadius: 1,\n marginTop: 8,\n overflow: 'hidden',\n // Barely-there rail so the bar reads as a hint, not a status meter.\n backgroundColor: 'rgba(26, 20, 16, 0.05)',\n },\n progressFill: {\n height: '100%',\n width: '55%',\n borderRadius: 1,\n // Muted orange — present but recessive.\n backgroundColor: 'rgba(255, 122, 40, 0.4)',\n },\n});\n","// Renders the row of UI Action chips beneath an assistant bubble.\n// Payload comes from `message.actions[]` produced by the polisher and\n// validated by Core's `cp.uiActions_api`.\n//\n// Chips targeting a registered surface mount it directly via the surface\n// store. Everything else goes through the navigator registered with\n// setUIActionNavigator() when the host provided one (no router imports\n// here), or falls back to the built-in WidgetHost presenter — so chips open\n// widgets with zero host wiring.\n\nimport { View, Text, Pressable, StyleSheet, Platform } from 'react-native';\nimport { ada, fontSize } from '@ateam-ai-mobile/core';\nimport type { UIAction } from '@ateam-ai-mobile/core';\nimport { useSurfaceStore, getHaptics } from '@ateam-ai-mobile/plugin-runtime';\nimport { getUIActionNavigator } from '../providers';\nimport { openWidget } from '../plugin/WidgetHost';\n\nconst fontFam = Platform.OS === 'ios' ? 'SF Pro Rounded' : undefined;\n\nconst ICON_MAP: Record<string, string> = {\n timer: '⏱',\n memory: '🧠',\n calendar: '📅',\n home: '🏠',\n bell: '🔔',\n star: '⭐',\n bolt: '⚡',\n};\n\ninterface Props {\n actions: UIAction[];\n}\n\nexport default function UIActionsRow({ actions }: Props) {\n if (!Array.isArray(actions) || actions.length === 0) return null;\n\n const handlePress = (a: UIAction) => {\n getHaptics()?.selection();\n // Validator returns pluginId as the full id (\"mcp:connector:plugin\" for\n // solution plugins, \"platform:<name>\" for host platform screens). Fall\n // back to target (short id) only for debugging.\n const id = a.pluginId || a.target;\n if (!id) return;\n\n // Compute focus once; both branches use it.\n const focus = a.payload?.id || a.payload?.entity_id || a.payload?.focusId;\n\n // Host-rendered platform surfaces live in the surface store, not in the\n // dynamic plugin registry. Mount the registered drawer/fullscreen\n // directly — skip navigation (which would try getPlugin() and fail).\n const surface = useSurfaceStore.getState().manifests[id];\n if (surface) {\n useSurfaceStore.getState().show(id, focus ? { focus } : undefined);\n return;\n }\n\n // Pass payload fields as params so the plugin can focus the relevant\n // entity on load (e.g. ?focus=rem_abc).\n const params: Record<string, string> = {};\n if (focus) params.focus = String(focus);\n if (a.intent === 'suggested_action' && a.payload?.tool) {\n params.tool = String(a.payload.tool);\n if (a.payload?.args) {\n try { params.args = JSON.stringify(a.payload.args); } catch {}\n }\n }\n if (a.intent === 'quick_toggle' && a.payload?.verb) {\n params.verb = String(a.payload.verb);\n }\n\n const navigate = getUIActionNavigator();\n if (navigate) {\n navigate({ pluginId: id, params });\n return;\n }\n // No host navigator — present via the built-in WidgetHost (mounted by\n // AdasChatScreen). Params ride along as engine props.\n openWidget(id, Object.keys(params).length ? params : undefined);\n };\n\n return (\n <View style={styles.row}>\n {actions.map((a, i) => {\n const icon = a.icon ? ICON_MAP[a.icon.toLowerCase()] : null;\n return (\n <Pressable\n key={`${a.target || 'a'}-${i}`}\n accessibilityRole=\"button\"\n accessibilityLabel={a.description || a.label}\n onPress={() => handlePress(a)}\n style={({ pressed }) => [styles.chip, pressed && styles.chipPressed]}\n >\n {icon ? <Text style={styles.icon}>{icon}</Text> : null}\n <Text style={styles.label} numberOfLines={1}>{a.label}</Text>\n </Pressable>\n );\n })}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n row: {\n flexDirection: 'row',\n flexWrap: 'wrap',\n gap: 6,\n marginTop: 10,\n },\n chip: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 6,\n paddingHorizontal: 12,\n paddingVertical: 6,\n backgroundColor: ada.orangeSoft,\n borderColor: ada.orange,\n borderWidth: 1,\n borderRadius: 14,\n },\n chipPressed: {\n backgroundColor: ada.orange,\n },\n icon: {\n fontSize: 12,\n lineHeight: 14,\n },\n label: {\n color: ada.orangeDeep,\n fontSize: fontSize.xs,\n fontWeight: '600',\n fontFamily: fontFam,\n },\n});\n","/**\n * Host integration points for @ateam-ai-mobile/ui — same DI pattern as\n * @ateam-ai-mobile/plugin-runtime's host.ts. Everything has a safe default; the host\n * (or @ateam-ai-mobile/expo) wires real implementations at startup.\n */\n\n// ── Clipboard ──────────────────────────────────────────────────────────────\n\nexport interface ClipboardProvider {\n setString(text: string): Promise<void>;\n}\n\nlet _clipboard: ClipboardProvider | null = null;\n\n/** Register a clipboard implementation (e.g. expo-clipboard via @ateam-ai-mobile/expo). */\nexport function setClipboardProvider(clipboard: ClipboardProvider | null): void {\n _clipboard = clipboard;\n}\n\nexport function getClipboard(): ClipboardProvider | null {\n return _clipboard;\n}\n\n// ── UI-action navigation ───────────────────────────────────────────────────\n// Chips with a plugin target need to open the host's plugin screen. The SDK\n// never imports a router — the HOST owns navigation and registers a handler\n// (e.g. Expo Router: router.push({ pathname: '/plugin/[id]', params })).\n\nexport interface UIActionRoute {\n /** Full plugin id, e.g. \"mcp:connector:plugin\" or \"platform:<name>\". */\n pluginId: string;\n /** Query params the plugin reads on load (focus, tool, args, verb). */\n params: Record<string, string>;\n}\n\ntype UIActionNavigator = (route: UIActionRoute) => void;\n\nlet _navigator: UIActionNavigator | null = null;\n\nexport function setUIActionNavigator(navigate: UIActionNavigator | null): void {\n _navigator = navigate;\n}\n\nexport function getUIActionNavigator(): UIActionNavigator | null {\n return _navigator;\n}\n\n// ── Plugin WebView extra allowed hosts ─────────────────────────────────────\n// The plugin WebView allow-list is derived from the SDK config (core + voice\n// URLs). Hosts with additional trusted services plugins navigate to (e.g. a\n// relay) register a getter returning extra URLs; resolved live per check.\n\ntype ExtraHostsGetter = () => string[];\n\nlet _extraHosts: ExtraHostsGetter | null = null;\n\nexport function setPluginWebViewExtraHosts(getter: ExtraHostsGetter | null): void {\n _extraHosts = getter;\n}\n\nexport function getPluginWebViewExtraHosts(): ExtraHostsGetter | null {\n return _extraHosts;\n}\n","/**\n * WidgetHost — zero-config widget presenter.\n *\n * The glue that makes chips and the agent able to open widgets without any\n * host wiring:\n *\n * - `openWidget(pluginId, opts)` — imperative open from anywhere. Surfaces\n * registered in the surface store (host surfaces, platform-declared\n * surfaces) mount through the surface registry; everything else is\n * presented here as a fullscreen PluginSurface (manifest fetched lazily).\n * - Chip taps: UIActionsRow falls back to openWidget() when the host hasn't\n * registered a custom navigator via setUIActionNavigator().\n * - Server/agent proactive open: listens for the chat stream's\n * `focus-plugin` event (sys.focusUiPlugin(pluginId, props) on the engine\n * side) and presents the widget, forwarding the engine props.\n *\n * <AdasChatScreen /> mounts a WidgetHost automatically — drop-in hosts get\n * the full chips→widgets and agent→widgets experience for free. Custom\n * layouts render <WidgetHost /> once near the app root (mounting it twice is\n * safe: both instances read the same store, last-closed wins).\n */\nimport { useEffect } from 'react';\nimport { create } from 'zustand';\nimport { pluginCommandEmitter } from '@ateam-ai-mobile/core';\nimport { useSurfaceStore } from '@ateam-ai-mobile/plugin-runtime';\nimport PluginSurface from './PluginSurface';\n\ninterface WidgetHostState {\n pluginId: string | null;\n /** Engine/chip-supplied props forwarded to the plugin as PluginProps.props. */\n props?: any;\n open: (pluginId: string, props?: any) => void;\n close: () => void;\n}\n\nexport const useWidgetHostStore = create<WidgetHostState>((set) => ({\n pluginId: null,\n props: undefined,\n open: (pluginId, props) => set({ pluginId, props }),\n close: () => set({ pluginId: null, props: undefined }),\n}));\n\n/**\n * Open a widget by plugin id. Host surfaces registered in the surface store\n * take priority (they own their chrome); everything else is presented as a\n * fullscreen PluginSurface by the mounted <WidgetHost />.\n */\nexport function openWidget(pluginId: string, props?: any): void {\n const surfaces = useSurfaceStore.getState();\n if (surfaces.manifests[pluginId]) {\n surfaces.show(pluginId, props);\n return;\n }\n useWidgetHostStore.getState().open(pluginId, props);\n}\n\nexport default function WidgetHost() {\n const pluginId = useWidgetHostStore(s => s.pluginId);\n const props = useWidgetHostStore(s => s.props);\n const close = useWidgetHostStore(s => s.close);\n\n // Agent-driven proactive open: sys.focusUiPlugin(pluginId, props) flows\n // through the chat stream → core emits 'focus-plugin' → present it.\n useEffect(() => {\n return pluginCommandEmitter.on('focus-plugin', (data: any) => {\n if (data?.pluginId) openWidget(String(data.pluginId), data.props);\n });\n }, []);\n\n if (!pluginId) return null;\n\n return (\n <PluginSurface\n key={pluginId}\n pluginId={pluginId}\n surface={{ type: 'fullscreen' }}\n dismiss={close}\n props={props}\n />\n );\n}\n","/**\n * PluginSurface — universal mount that wraps any platform-declared plugin\n * (iframe or React Native) inside the right Ada-themed surface container.\n *\n * Mounted when an `engine` or `user` event activates a platform plugin that\n * declared a `surface` field in its manifest. Picks SurfaceDrawer or\n * SurfaceFullscreen based on `surface.type`, fetches the full PluginManifest\n * lazily, and renders <Plugin /> inside the body.\n */\nimport { useEffect, useState } from 'react';\nimport { View, ActivityIndicator } from 'react-native';\nimport { ada } from '@ateam-ai-mobile/core';\nimport {\n getPlugin,\n SurfaceDrawer,\n SurfaceFullscreen,\n type PluginSurfaceMeta,\n} from '@ateam-ai-mobile/plugin-runtime';\nimport type { PlatformPluginManifest as PluginManifest } from '@ateam-ai-mobile/plugin-runtime';\nimport Plugin from './Plugin';\n\ninterface Props {\n pluginId: string;\n surface: PluginSurfaceMeta;\n dismiss: () => void;\n /** Engine-supplied props forwarded from sys.focusUiPlugin(id, props). */\n props?: any;\n}\n\nexport default function PluginSurface({ pluginId, surface, dismiss, props }: Props) {\n const [manifest, setManifest] = useState<PluginManifest | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n getPlugin(pluginId)\n .then(m => { if (!cancelled) m ? setManifest(m) : setError('Plugin not found'); })\n .catch(e => { if (!cancelled) setError(e?.message || 'Failed to load'); });\n return () => { cancelled = true; };\n }, [pluginId]);\n\n const body = manifest ? (\n <Plugin id={pluginId} manifest={manifest as any} props={props} />\n ) : (\n <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', padding: 24 }}>\n {error ? null : <ActivityIndicator color={ada.orange} />}\n </View>\n );\n\n if (surface.type === 'fullscreen') {\n return (\n <SurfaceFullscreen\n visible={true}\n onClose={dismiss}\n status={surface.title}\n showWordmark\n closeIcon=\"x\"\n closeLabel=\"Close\"\n >\n {body}\n </SurfaceFullscreen>\n );\n }\n\n // Default: drawer\n return (\n <SurfaceDrawer\n visible={true}\n onClose={dismiss}\n title={surface.title || pluginId}\n subtitle={surface.subtitle}\n privacy={!!surface.privacy}\n >\n {body}\n </SurfaceDrawer>\n );\n}\n","/**\n * <Plugin /> — unified plugin renderer.\n *\n * Auto-detects native vs webview, provides bridge/theme/context, wraps in an\n * error boundary.\n *\n * Usage:\n * <Plugin id=\"mcp:connector:plugin-name\" manifest={manifest} />\n */\nimport React, { useMemo } from 'react';\nimport { View, Text, Pressable, ActivityIndicator, StyleSheet } from 'react-native';\nimport { getTenant, getUser, colors } from '@ateam-ai-mobile/core';\nimport {\n usePlugin,\n useNativeBridge,\n usePluginTheme,\n getPluginNative,\n gatePluginNative,\n type PluginContext,\n} from '@ateam-ai-mobile/plugin-runtime';\nimport EmbeddedPluginWebView from './EmbeddedPluginWebView';\n\n// ── Error Boundary ──────────────────────────────────────────\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n}\n\nclass PluginErrorBoundary extends React.Component<\n { pluginId: string; children: React.ReactNode },\n ErrorBoundaryState\n> {\n state: ErrorBoundaryState = { hasError: false, error: null };\n\n static getDerivedStateFromError(error: Error) {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, info: React.ErrorInfo) {\n console.error(`[Plugin:${this.props.pluginId}] Crash:`, error, info.componentStack);\n }\n\n render() {\n if (this.state.hasError) {\n return (\n <View style={styles.error}>\n <Text style={styles.errorTitle}>Plugin Error</Text>\n <Text style={styles.errorMessage}>\n {this.state.error?.message || 'An unexpected error occurred'}\n </Text>\n <Pressable\n style={styles.retryBtn}\n onPress={() => this.setState({ hasError: false, error: null })}\n >\n <Text style={styles.retryText}>Retry</Text>\n </Pressable>\n </View>\n );\n }\n return this.props.children;\n }\n}\n\n// ── Plugin Component ─────────────────────────────────────────\n\ninterface PluginRendererProps {\n /** Full plugin ID, e.g. \"mcp:connector-id:plugin-name\" */\n id: string;\n /** Plugin manifest (from API) */\n manifest: any;\n /** Shared command buffer from parent — captures commands before plugin mounts */\n commandBufferRef?: React.MutableRefObject<any[]>;\n /** Engine-supplied props from sys.focusUiPlugin(id, props) — forwarded to\n * the plugin Component as `PluginProps.props`. */\n props?: any;\n}\n\nexport default function Plugin({ id, manifest, commandBufferRef, props: engineProps }: PluginRendererProps) {\n // Load the plugin component (handles cache, download, eval)\n const { plugin, loading, error, bundleMissing } = usePlugin(id, manifest);\n\n // Extract connectorId from MCP plugin ID: mcp:<connector>:<plugin>\n const connectorId = id.startsWith('mcp:') ? id.split(':')[1] : manifest._connectorId;\n\n // Wire up bridge, capabilities, theme\n const bridge = useNativeBridge(id, connectorId, commandBufferRef);\n // Per-plugin capability gate: undeclared native APIs become warn-and-ignore\n // proxies. Memoized so the plugin Component doesn't re-render on a fresh\n // object every pass (useApi effects key off prop identity).\n const declaredCaps = manifest?.native;\n const native = useMemo(() => gatePluginNative(getPluginNative(), declaredCaps), [declaredCaps]);\n const theme = usePluginTheme();\n\n // Build context from the host-owned identity\n const user = getUser();\n const context = useMemo<PluginContext>(() => ({\n tenant: getTenant(),\n pluginId: id,\n connectorId,\n user: user ? { id: user.actorId || '', name: user.name || '', roles: user.roles || [] } : undefined,\n }), [id, connectorId, user?.actorId, user?.name, user?.roles]);\n\n // Fallback: connector declared an RN component but didn't ship the bundle.\n // When the manifest also has an iframeUrl (adaptive mode), render the\n // WebView instead of an error screen. Must run AFTER all hook calls above\n // to keep hook order stable across renders.\n const iframeUrl = manifest?.render?.iframeUrl;\n if (bundleMissing && iframeUrl) {\n return <EmbeddedPluginWebView pluginId={id} manifest={manifest} commandBufferRef={commandBufferRef} />;\n }\n\n if (loading) {\n return (\n <View style={styles.center}>\n <ActivityIndicator size=\"small\" color={colors.dark.accent} />\n <Text style={styles.loadingText}>Loading plugin...</Text>\n </View>\n );\n }\n\n if (error || !plugin) {\n return (\n <View style={styles.center}>\n <Text style={styles.errorMessage}>{error || 'Plugin not found'}</Text>\n </View>\n );\n }\n\n const { Component } = plugin;\n return (\n <PluginErrorBoundary pluginId={id}>\n <Component bridge={bridge} native={native} theme={theme} context={context} props={engineProps} />\n </PluginErrorBoundary>\n );\n}\n\n// ── Styles ───────────────────────────────────────────────────\n\nconst styles = StyleSheet.create({\n center: {\n flex: 1,\n justifyContent: 'center',\n alignItems: 'center',\n backgroundColor: colors.dark.bgPrimary,\n paddingHorizontal: 32,\n gap: 12,\n },\n loadingText: {\n color: colors.dark.textSecondary,\n fontSize: 14,\n },\n error: {\n flex: 1,\n justifyContent: 'center',\n alignItems: 'center',\n backgroundColor: colors.dark.bgPrimary,\n paddingHorizontal: 32,\n gap: 8,\n },\n errorTitle: {\n color: colors.dark.red,\n fontSize: 16,\n fontWeight: '600',\n },\n errorMessage: {\n color: colors.dark.textSecondary,\n fontSize: 14,\n textAlign: 'center',\n },\n retryBtn: {\n marginTop: 12,\n paddingHorizontal: 20,\n paddingVertical: 10,\n backgroundColor: colors.dark.accentSoft,\n borderRadius: 8,\n },\n retryText: {\n color: colors.dark.accent,\n fontSize: 14,\n fontWeight: '600',\n },\n});\n","import { useState, useMemo, useCallback } from 'react';\nimport { View, Text, ActivityIndicator, StyleSheet, Platform } from 'react-native';\nimport { WebView } from 'react-native-webview';\nimport { getConfig, getCoreApiUrl, getVoiceApiUrl, getTenant, getToken, ada } from '@ateam-ai-mobile/core';\nimport { resolvePluginUrl, type PlatformPluginManifest as PluginManifest } from '@ateam-ai-mobile/plugin-runtime';\nimport { usePluginBridge, buildPluginBridgeJS } from './usePluginBridge';\nimport { getPluginWebViewExtraHosts } from '../providers';\n\ninterface Props {\n pluginId: string;\n manifest: PluginManifest;\n commandBufferRef?: React.MutableRefObject<any[]>;\n}\n\n/**\n * WebView renderer for iframe-mode plugins. The injected bridge JS makes\n * existing web plugins work unmodified; the origin guards below make sure\n * the JWT seeded into localStorage can never leave the trusted hosts.\n */\nexport default function EmbeddedPluginWebView({ pluginId, manifest, commandBufferRef }: Props) {\n const [error, setError] = useState<string | null>(null);\n\n const token = getToken();\n const tenant = getTenant();\n\n // _connectorId from the manifest (set by cp.getContextPlugin) — same as\n // what the web PluginHost sends in init.\n const { webViewRef, sendInit, handleMessage } = usePluginBridge(pluginId, manifest._connectorId, commandBufferRef);\n\n const url = resolvePluginUrl(manifest, tenant || undefined);\n const bridgeJS = buildPluginBridgeJS(token || '', tenant || '');\n\n // Hosts the plugin may navigate to — derived from the SDK config plus any\n // host-registered extras (e.g. a relay service). Resolved LIVE on every\n // read, never frozen at mount: config URLs can change after hydration and a\n // stale whitelist silently bounces plugin URLs out to the system browser\n // (a documented regression in the reference app).\n const computeAllowedHosts = useCallback((): Set<string> => {\n const hosts = new Set<string>();\n const urls = [getCoreApiUrl()];\n // voiceUrl is optional and may be a getter — resolve via getVoiceApiUrl()\n // (which throws when unset, so gate on the raw config first).\n if (getConfig().voiceUrl) urls.push(getVoiceApiUrl());\n try { urls.push(...(getPluginWebViewExtraHosts()?.() || [])); } catch { /* host getter threw */ }\n for (const u of urls) {\n try { hosts.add(new URL(u).hostname); } catch { /* ignore bad URL */ }\n }\n return hosts;\n }, []);\n\n const isAllowedPluginUrl = useCallback((rawUrl: string | undefined | null): boolean => {\n if (!rawUrl) return false;\n // about:blank, data:, file: — never allow off-origin navigation\n let parsed: URL;\n try { parsed = new URL(rawUrl); } catch { return false; }\n if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') return false;\n if (parsed.protocol === 'http:') return false; // belt-and-suspenders with mixedContentMode=never\n return computeAllowedHosts().has(parsed.hostname);\n }, [computeAllowedHosts]);\n\n const originWhitelist = useMemo(\n () => Array.from(computeAllowedHosts()).map(h => `https://${h}`),\n [computeAllowedHosts],\n );\n\n if (error) {\n return (\n <View style={styles.center}>\n <Text style={styles.errorText}>{error}</Text>\n </View>\n );\n }\n\n return (\n <View style={styles.container}>\n <WebView\n ref={webViewRef}\n source={{ uri: url }}\n style={styles.webview}\n javaScriptEnabled\n domStorageEnabled\n allowsInlineMediaPlayback\n mediaPlaybackRequiresUserAction={false}\n // SECURITY:\n // mixedContentMode=never → block any plain HTTP load inside the WebView.\n // originWhitelist → only the ADAS-owned hosts.\n // onShouldStartLoadWithRequest → reject navigation off allowlisted hosts.\n // setSupportMultipleWindows / javaScriptCanOpenWindowsAutomatically\n // → prevent window.open() from spawning a WebView that inherits\n // the bridge but skips the origin guard.\n // allowsBackForwardNavigationGestures=false\n // → a user gesture must not be a way out of the sandbox.\n // The bridge writes the JWT into the WebView's localStorage; these\n // guards make sure it can never leave the trusted origins.\n mixedContentMode=\"never\"\n originWhitelist={originWhitelist}\n allowsBackForwardNavigationGestures={false}\n setSupportMultipleWindows={false}\n javaScriptCanOpenWindowsAutomatically={false}\n onShouldStartLoadWithRequest={(req) => {\n if (!isAllowedPluginUrl(req.url)) {\n console.warn(`[EmbeddedPluginWebView] BLOCKED nav to disallowed origin: ${req.url}`);\n return false;\n }\n return true;\n }}\n injectedJavaScriptBeforeContentLoaded={bridgeJS}\n onMessage={handleMessage}\n onLoad={() => {\n // Send init with retries to beat the race condition\n setTimeout(sendInit, 100);\n setTimeout(sendInit, 500);\n setTimeout(sendInit, 1200);\n }}\n onError={(syntheticEvent) => {\n const { nativeEvent } = syntheticEvent;\n console.warn('[EmbeddedPluginWebView] Error:', nativeEvent.description);\n setError(`WebView error: ${nativeEvent.description}`);\n }}\n onHttpError={(syntheticEvent) => {\n const { nativeEvent } = syntheticEvent;\n console.warn('[EmbeddedPluginWebView] HTTP error:', nativeEvent.statusCode, nativeEvent.url);\n if (nativeEvent.statusCode >= 400) {\n setError(`HTTP ${nativeEvent.statusCode}: Failed to load plugin`);\n }\n }}\n startInLoadingState\n renderLoading={() => (\n <View style={styles.webviewLoading}>\n <ActivityIndicator size=\"small\" color={ada.orange} />\n <Text style={styles.loadingText}>Loading plugin...</Text>\n </View>\n )}\n {...(Platform.OS === 'ios' ? { bounces: false } : {})}\n />\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n backgroundColor: ada.paper,\n },\n center: {\n flex: 1,\n justifyContent: 'center',\n alignItems: 'center',\n backgroundColor: ada.paper,\n paddingHorizontal: 32,\n },\n errorText: {\n color: '#C15545',\n fontSize: 16,\n textAlign: 'center',\n },\n webview: {\n flex: 1,\n backgroundColor: ada.paper,\n },\n webviewLoading: {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n justifyContent: 'center',\n alignItems: 'center',\n backgroundColor: ada.paper,\n gap: 12,\n },\n loadingText: {\n color: ada.inkSoft,\n fontSize: 14,\n },\n});\n","import { useCallback, useEffect, useRef } from 'react';\nimport {\n getTenant,\n connectorCall,\n mcpFetch,\n mcpToolCall,\n postCommandResult,\n pluginCommandEmitter,\n} from '@ateam-ai-mobile/core';\n\n/**\n * PostMessage bridge between the React Native host and a plugin WebView.\n * Implements the same protocol as PluginHost.jsx in the web frontend.\n *\n * Handles THREE communication paths:\n * 1. fetch(\"/mcp\") — intercepted in bridge JS, proxied through postMessage\n * 2. postMessage mcp-call — direct postMessage from plugin SDK\n * 3. plugin commands — routed from the job stream to the WebView\n */\nexport function usePluginBridge(\n pluginId: string,\n connectorId?: string,\n commandBufferRef?: React.MutableRefObject<any[]>,\n wsRef?: { current: WebSocket | null },\n) {\n // Loosely typed on purpose: react-native-webview's generic class type\n // resolves JSX props to `never` under React 19 typings when used as a\n // useRef parameter. Runtime shape is the WebView instance (postMessage).\n const webViewRef = useRef<any>(null);\n\n // Send init message to plugin (mirrors web PluginHost sendInit)\n const sendInit = useCallback(() => {\n const msg = JSON.stringify({\n source: 'adas-host',\n pluginId,\n message: {\n type: 'init',\n payload: {\n tenant: getTenant(),\n connectorId: connectorId || null,\n mcpEndpoint: null,\n slug: null,\n skillSlug: null,\n },\n },\n });\n webViewRef.current?.postMessage(msg);\n }, [pluginId, connectorId]);\n\n // Send result back to plugin WebView\n const sendToPlugin = useCallback(\n (type: string, payload: any) => {\n const msg = JSON.stringify({\n source: 'adas-host',\n message: { type, payload },\n });\n webViewRef.current?.postMessage(msg);\n },\n [],\n );\n\n // Helper to dispatch a command to the WebView plugin\n const dispatchToWebView = useCallback((cmd: any) => {\n if (cmd.command === '__focus') return; // Focus-only, handled by the host screen\n const msg = JSON.stringify({\n source: 'adas-host',\n pluginId,\n message: {\n type: 'plugin.command',\n payload: {\n command: cmd.command,\n args: cmd.args,\n correlationId: cmd.correlationId,\n },\n },\n });\n webViewRef.current?.postMessage(msg);\n }, [pluginId]);\n\n // ── Listen for live plugin commands from the job stream ──\n useEffect(() => {\n const unsub = pluginCommandEmitter.on('plugin-command', (cmd: any) => {\n if (cmd.pluginId !== pluginId) return;\n dispatchToWebView(cmd);\n });\n return unsub;\n }, [pluginId, dispatchToWebView]);\n\n // ── Flush buffered commands when the WebView loads ──\n useEffect(() => {\n if (!commandBufferRef) return;\n // Flush after a delay to let the iframe initialize\n const timer = setTimeout(() => {\n const buf = commandBufferRef.current;\n const remaining: any[] = [];\n for (const cmd of buf) {\n if (cmd.pluginId === pluginId) {\n dispatchToWebView(cmd);\n } else {\n remaining.push(cmd);\n }\n }\n commandBufferRef.current = remaining;\n }, 1000);\n return () => clearTimeout(timer);\n }, [pluginId, commandBufferRef, dispatchToWebView]);\n\n // Handle messages from plugin WebView\n const handleMessage = useCallback(\n async (event: { nativeEvent: { data: string } }) => {\n let data: any;\n try {\n data = JSON.parse(event.nativeEvent.data);\n } catch {\n return;\n }\n\n if (data.source !== 'adas-plugin') return;\n\n const action = data.message?.action || data.action;\n const payload = data.message?.payload || data.payload;\n const type = data.message?.type || data.type;\n\n // -----------------------------------------------------------------\n // 1. Intercepted fetch(\"/mcp\") — proxy to Core backend\n // -----------------------------------------------------------------\n if (action === 'mcp-fetch' && payload?.requestId) {\n const { requestId, body } = payload;\n try {\n const result = await mcpFetch(body);\n sendToPlugin('mcp-fetch-result', { requestId, result, error: null });\n } catch (err: any) {\n console.warn('[PluginBridge] mcp-fetch ERROR:', err.message);\n sendToPlugin('mcp-fetch-result', { requestId, result: null, error: err.message });\n }\n return;\n }\n\n // -----------------------------------------------------------------\n // 2. PostMessage mcp-call — plugin SDK's callTool()\n // a) toolName present (e.g. \"cp.fe_api\") → JSON-RPC to /mcp\n // b) direct connectorId/tool → /api/connectors/:id/call\n // -----------------------------------------------------------------\n if (action === 'mcp-call' && payload?.requestId) {\n const { requestId, toolName, args: callArgs } = payload;\n\n // Path A: JSON-RPC tool call (cp.fe_api, cp.admin_api, etc.)\n if (toolName) {\n try {\n const rpcResponse = await mcpToolCall(toolName, callArgs || {});\n // Unwrap the JSON-RPC envelope — plugin expects { content: [...] }\n const result = rpcResponse?.result ?? rpcResponse;\n sendToPlugin('mcp-result', { requestId, result, error: null });\n } catch (err: any) {\n sendToPlugin('mcp-result', { requestId, result: null, error: err.message });\n }\n return;\n }\n\n // Path B: direct connector call (connectorId + tool). The plugin may\n // send connectorId/tool at payload level OR nested in args.\n const cId = payload.connectorId || callArgs?.connectorId || callArgs?.params?.connectorId;\n const tool = payload.tool || callArgs?.tool || callArgs?.params?.tool;\n const toolArgs = payload.args || callArgs?.args || callArgs?.params?.args || {};\n\n if (!cId || !tool) {\n console.error(`[PluginBridge] mcp-call missing params — connectorId: ${cId}, tool: ${tool}`);\n sendToPlugin('mcp-result', { requestId, result: null, error: `Missing connectorId or tool in mcp-call. Got connectorId=${cId}, tool=${tool}` });\n return;\n }\n\n try {\n const data = await connectorCall(cId, tool, toolArgs);\n if (data.ok) {\n sendToPlugin('mcp-result', { requestId, result: data.result, error: null });\n } else {\n sendToPlugin('mcp-result', { requestId, result: null, error: data.error || 'MCP call failed' });\n }\n } catch (err: any) {\n sendToPlugin('mcp-result', { requestId, result: null, error: err.message });\n }\n return;\n }\n\n // -----------------------------------------------------------------\n // 3. Plugin self-close — return to chat\n // -----------------------------------------------------------------\n if (action === 'close') {\n pluginCommandEmitter.emit('plugin-close', { pluginId });\n return;\n }\n\n // -----------------------------------------------------------------\n // 4. Plugin command result — WebSocket (preferred) or HTTP POST\n // -----------------------------------------------------------------\n if (type === 'plugin.command.result' && payload?.correlationId) {\n const ws = wsRef?.current;\n if (ws && ws.readyState === WebSocket.OPEN) {\n try {\n ws.send(JSON.stringify({\n type: 'plugin-command-result',\n correlationId: payload.correlationId,\n result: payload.result,\n error: payload.error,\n }));\n } catch (err: any) {\n console.warn('[PluginBridge] WS send failed, falling back to POST:', err.message);\n await postCommandResult(payload.correlationId, payload.result, payload.error).catch(() => {});\n }\n } else {\n try {\n await postCommandResult(payload.correlationId, payload.result, payload.error);\n } catch (err: any) {\n console.warn('[PluginBridge] Failed to send command result:', err.message);\n }\n }\n return;\n }\n },\n [sendToPlugin],\n );\n\n return {\n webViewRef,\n sendInit,\n handleMessage,\n };\n}\n\n/**\n * Build injected JavaScript that:\n * 1. Seeds localStorage with JWT + tenant (plugins read from localStorage)\n * 2. Intercepts fetch(\"/mcp\") and proxies through the postMessage bridge\n * 3. Bridges iframe postMessage API to React Native WebView\n *\n * This makes existing web plugins work on mobile WITHOUT modification.\n */\nexport function buildPluginBridgeJS(jwt: string, tenant: string): string {\n return `\n(function() {\n function _dbg(msg) {\n console.log('[PluginBridge] ' + msg);\n }\n\n // 1. Seed localStorage. JWT is required by web-shared plugin code\n // (cpFeApi.ts etc. read localStorage.adas.jwt directly). Origin lockdown\n // lives in EmbeddedPluginWebView (originWhitelist +\n // onShouldStartLoadWithRequest) — not here. Never log the token.\n try {\n localStorage.setItem('adas.jwt', ${JSON.stringify(jwt)});\n localStorage.setItem('adas.tenant', ${JSON.stringify(tenant)});\n _dbg('localStorage seeded: jwt=' + (${JSON.stringify(jwt)} ? '[present]' : '[absent]') + ' tenant=' + ${JSON.stringify(tenant)});\n } catch(e) { _dbg('localStorage ERROR: ' + e.message); }\n\n // 2. Intercept ALL fetch calls — proxy /mcp through the RN bridge\n var _origFetch = window.fetch.bind(window);\n var _mcpReqId = 0;\n var _pendingMcp = {};\n\n window.fetch = function(url, opts) {\n var urlStr = (typeof url === 'string') ? url : (url && url.url) || '';\n var method = (opts && opts.method) || 'GET';\n\n _dbg('FETCH ' + method + ' ' + urlStr.substring(0, 80));\n\n // Intercept /mcp calls\n if (urlStr === '/mcp' || urlStr.endsWith('/mcp')) {\n _dbg(' -> INTERCEPTED /mcp, proxying via RN bridge');\n return new Promise(function(resolve, reject) {\n var requestId = 'mcp-f-' + (++_mcpReqId) + '-' + Date.now();\n _pendingMcp[requestId] = { resolve: resolve, reject: reject };\n window.ReactNativeWebView.postMessage(JSON.stringify({\n source: 'adas-plugin',\n action: 'mcp-fetch',\n payload: { requestId: requestId, body: opts && opts.body ? opts.body : null }\n }));\n setTimeout(function() {\n if (_pendingMcp[requestId]) {\n delete _pendingMcp[requestId];\n _dbg('TIMEOUT mcp-fetch ' + requestId);\n reject(new Error('MCP fetch timeout (30s)'));\n }\n }, 30000);\n });\n }\n\n // Inject Authorization header ONLY for same-origin requests. A relative\n // path resolves against window.location.origin; an absolute URL must\n // literally match. This stops a plugin from leaking the JWT to a foreign\n // host via fetch('https://attacker.com/x') or via <base href>.\n var sameOrigin = false;\n try {\n var resolved = new URL(urlStr, window.location.origin);\n sameOrigin = (resolved.origin === window.location.origin);\n } catch (_) { sameOrigin = false; }\n if (sameOrigin) {\n opts = Object.assign({}, opts || {});\n var h = opts.headers;\n if (h instanceof Headers) {\n if (!h.has('Authorization')) { var jwt = localStorage.getItem('adas.jwt'); if (jwt) h.set('Authorization', 'Bearer ' + jwt); }\n } else {\n h = Object.assign({}, h || {});\n if (!h['Authorization'] && !h['authorization']) { var jwt2 = localStorage.getItem('adas.jwt'); if (jwt2) h['Authorization'] = 'Bearer ' + jwt2; }\n opts.headers = h;\n }\n }\n\n return _origFetch(url, opts).then(function(res) {\n _dbg(' <- ' + res.status + ' ' + urlStr.substring(0, 60));\n return res;\n }).catch(function(err) {\n _dbg(' <- FETCH ERR: ' + err.message + ' ' + urlStr.substring(0, 40));\n throw err;\n });\n };\n\n // Handle results from RN host\n function _handleHostMessage(d) {\n if (!d || d.source !== 'adas-host') return;\n var msg = d.message || {};\n\n // mcp-fetch-result: response to intercepted fetch(\"/mcp\")\n if (msg.type === 'mcp-fetch-result' && msg.payload) {\n var p = msg.payload;\n var pending = _pendingMcp[p.requestId];\n if (pending) {\n delete _pendingMcp[p.requestId];\n if (p.error) {\n pending.reject(new Error(p.error));\n } else {\n pending.resolve(new Response(JSON.stringify(p.result), {\n status: 200,\n headers: { 'Content-Type': 'application/json' }\n }));\n }\n }\n }\n }\n\n // 3. Override window.parent.postMessage (plugins use this in iframes)\n window.parent = window.parent || {};\n window.parent.postMessage = function(data, origin) {\n if (data && data.source === 'adas-plugin') {\n window.ReactNativeWebView.postMessage(JSON.stringify(data));\n }\n };\n\n // 4. Also intercept direct window.postMessage\n var origPost = window.postMessage.bind(window);\n window.postMessage = function(data, origin) {\n if (data && data.source === 'adas-plugin') {\n window.ReactNativeWebView.postMessage(JSON.stringify(data));\n }\n origPost(data, origin);\n };\n\n // 5. Forward messages from RN host -> plugin\n // iOS: window 'message' event, Android: document 'message' event\n window.addEventListener('message', function(e) {\n try {\n var d = typeof e.data === 'string' ? JSON.parse(e.data) : e.data;\n if (d && d.source === 'adas-host') {\n _handleHostMessage(d);\n if (typeof e.data === 'string') {\n window.dispatchEvent(new MessageEvent('message', { data: d }));\n }\n }\n } catch(_) {}\n });\n\n document.addEventListener('message', function(e) {\n try {\n var d = typeof e.data === 'string' ? JSON.parse(e.data) : e.data;\n _handleHostMessage(d);\n window.dispatchEvent(new MessageEvent('message', { data: d }));\n } catch(_) {}\n });\n\n _dbg('Bridge JS loaded. Waiting for plugin...');\n true;\n})();\n`;\n}\n","import { View, Text, StyleSheet, Platform } from 'react-native';\nimport { ada, borderRadius, fontSize, spacing } from '@ateam-ai-mobile/core';\n\nconst fontFam = Platform.OS === 'ios' ? 'SF Pro Rounded' : undefined;\n\ninterface Props {\n columns: string[];\n rows: any[][];\n}\n\n/**\n * Renders tabular data as a vertical stack of cards — one card per row.\n * The first column becomes the card title; remaining columns become\n * key:value rows inside the card. Built specifically for narrow phone\n * screens where horizontal markdown tables become unreadable.\n */\nexport default function TableCardBlock({ columns, rows }: Props) {\n if (!columns?.length || !rows?.length) return null;\n\n const [titleCol, ...detailCols] = columns;\n\n return (\n <View style={styles.wrap}>\n {rows.map((row, i) => {\n const cells = Array.isArray(row) ? row : [row];\n const title = cells[0];\n return (\n <View key={i} style={styles.card}>\n <Text style={styles.title}>{String(title ?? '')}</Text>\n {detailCols.length > 0 && (\n <View style={styles.details}>\n {detailCols.map((col, ci) => {\n const value = cells[ci + 1];\n if (value == null || value === '') return null;\n return (\n <View key={ci} style={styles.row}>\n <Text style={styles.label}>{String(col)}</Text>\n <Text style={styles.value}>{String(value)}</Text>\n </View>\n );\n })}\n </View>\n )}\n </View>\n );\n })}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n wrap: {\n marginVertical: 6,\n gap: 8,\n },\n card: {\n backgroundColor: ada.paper,\n borderRadius: borderRadius.md,\n borderWidth: 1,\n borderColor: ada.border,\n padding: spacing.md,\n },\n title: {\n color: ada.ink,\n fontSize: fontSize.md,\n fontWeight: '600',\n fontFamily: fontFam,\n letterSpacing: -0.2,\n marginBottom: 6,\n },\n details: {\n gap: 4,\n },\n row: {\n flexDirection: 'row',\n alignItems: 'flex-start',\n gap: 8,\n },\n label: {\n color: ada.inkMuted,\n fontSize: fontSize.xs,\n fontFamily: fontFam,\n fontWeight: '500',\n width: 84,\n textTransform: 'uppercase',\n letterSpacing: 0.6,\n paddingTop: 2,\n },\n value: {\n flex: 1,\n color: ada.inkSoft,\n fontSize: fontSize.sm,\n fontFamily: fontFam,\n lineHeight: 18,\n },\n});\n","/**\n * Lightbox store — any component can open a fullscreen image viewer\n * by calling `useLightboxStore.getState().show(uri)`. The lightbox is\n * mounted once at the app root.\n */\nimport { create } from 'zustand';\n\ninterface LightboxState {\n uri: string | null;\n show: (uri: string) => void;\n hide: () => void;\n}\n\nexport const useLightboxStore = create<LightboxState>((set) => ({\n uri: null,\n show: (uri) => set({ uri }),\n hide: () => set({ uri: null }),\n}));\n","import { View, StyleSheet } from 'react-native';\nimport { AdaOrb } from '@ateam-ai-mobile/plugin-runtime';\n\nexport default function TypingIndicator() {\n return (\n <View style={styles.row}>\n <AdaOrb size={32} state=\"thinking\" />\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n row: {\n flexDirection: 'row',\n alignItems: 'center',\n marginBottom: 12,\n paddingHorizontal: 16,\n paddingVertical: 4,\n },\n});\n","import { useState, useRef, useCallback, useEffect } from 'react';\nimport {\n View,\n TextInput,\n Pressable,\n StyleSheet,\n Platform,\n} from 'react-native';\nimport Svg, { Path, Line, Polygon } from 'react-native-svg';\nimport { colors, borderRadius } from '@ateam-ai-mobile/core';\nimport { getHaptics } from '@ateam-ai-mobile/plugin-runtime';\n\ninterface Props {\n onSend: (text: string) => void;\n onCallStart?: () => void;\n loading: boolean;\n /** Pre-fill the composer (e.g. from bridge.prepareMessage). The text is\n * placed in the input and focused — not sent. */\n prefill?: string;\n placeholder?: string;\n}\n\nexport default function ChatInput({ onSend, onCallStart, loading, prefill, placeholder }: Props) {\n const [text, setText] = useState('');\n const [height, setHeight] = useState(40);\n const inputRef = useRef<TextInput>(null);\n\n useEffect(() => {\n if (prefill) {\n setText(prefill);\n inputRef.current?.focus();\n }\n }, [prefill]);\n\n // NOTE: no `loading` guard and no editable={!loading} — sending WHILE a\n // chain runs is a feature (backend Chain Additions router decides\n // attach/cancel/new), and the input must never be disabled mid-run.\n const handleSend = useCallback(() => {\n const trimmed = text.trim();\n if (!trimmed) return;\n getHaptics()?.impact('light');\n onSend(trimmed);\n setText('');\n setHeight(40);\n }, [text, loading, onSend]);\n\n const canSend = text.trim().length > 0;\n\n return (\n <View style={styles.dock}>\n <View style={styles.inputRow}>\n {onCallStart && (\n <Pressable style={styles.callBtn} onPress={onCallStart}>\n <Svg width={20} height={20} viewBox=\"0 0 24 24\" fill=\"none\" stroke={colors.light.accent} strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <Path d=\"M22 16.92v3a2 2 0 01-2.18 2 19.79 19.79 0 01-8.63-3.07 19.5 19.5 0 01-6-6 19.79 19.79 0 01-3.07-8.63A2 2 0 014.11 2h3a2 2 0 012 1.72 12.84 12.84 0 00.7 2.81 2 2 0 01-.45 2.11L8.09 9.91a16 16 0 006 6l1.27-1.27a2 2 0 012.11-.45 12.84 12.84 0 002.81.7A2 2 0 0122 16.92z\" />\n </Svg>\n </Pressable>\n )}\n <TextInput\n ref={inputRef}\n style={[styles.input, { height: Math.min(Math.max(40, height), 120) }]}\n value={text}\n onChangeText={setText}\n onContentSizeChange={e => setHeight(e.nativeEvent.contentSize.height)}\n placeholder={placeholder || 'Message A-Team...'}\n placeholderTextColor={colors.light.textMuted}\n multiline\n returnKeyType=\"default\"\n blurOnSubmit={false}\n onSubmitEditing={() => {\n if (Platform.OS === 'web') handleSend();\n }}\n />\n <Pressable\n style={[styles.sendBtn, canSend && styles.sendBtnActive]}\n onPress={handleSend}\n disabled={!canSend}\n >\n <Svg width={18} height={18} viewBox=\"0 0 24 24\" fill=\"none\" stroke={canSend ? '#fff' : colors.light.textMuted} strokeWidth={2}>\n <Line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" />\n <Polygon points=\"22 2 15 22 11 13 2 9 22 2\" />\n </Svg>\n </Pressable>\n </View>\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n dock: {\n paddingHorizontal: 12,\n paddingVertical: 8,\n backgroundColor: colors.light.bgPrimary,\n borderTopWidth: 0.5,\n borderTopColor: colors.light.border,\n },\n inputRow: {\n flexDirection: 'row',\n alignItems: 'flex-end',\n backgroundColor: colors.light.bgInput,\n borderRadius: borderRadius.xl,\n borderWidth: 1,\n borderColor: colors.light.border,\n paddingHorizontal: 4,\n paddingVertical: 4,\n gap: 4,\n },\n callBtn: {\n width: 36,\n height: 36,\n borderRadius: 18,\n justifyContent: 'center',\n alignItems: 'center',\n },\n input: {\n flex: 1,\n fontSize: 16,\n color: colors.light.textPrimary,\n paddingHorizontal: 8,\n paddingVertical: 8,\n maxHeight: 120,\n },\n sendBtn: {\n width: 36,\n height: 36,\n borderRadius: 18,\n justifyContent: 'center',\n alignItems: 'center',\n backgroundColor: colors.light.bgTertiary,\n },\n sendBtnActive: {\n backgroundColor: colors.light.accent,\n },\n});\n","/**\n * Fullscreen image viewer — mounted once inside AdasChatScreen (or at the\n * host root). Any component opens it via useLightboxStore.getState().show(uri).\n */\nimport { Modal, View, Image, Pressable, Text, StyleSheet } from 'react-native';\nimport { getConfig } from '@ateam-ai-mobile/core';\nimport { useLightboxStore } from './stores/lightboxStore';\n\nexport default function Lightbox() {\n const uri = useLightboxStore(s => s.uri);\n const hide = useLightboxStore(s => s.hide);\n\n if (!uri) return null;\n\n return (\n <Modal visible transparent animationType=\"fade\" onRequestClose={hide}>\n <Pressable style={styles.backdrop} onPress={hide}>\n <Image\n source={{\n uri,\n ...(uri.startsWith('http') ? {\n headers: { Authorization: `Bearer ${getConfig().tokenProvider.getToken()}` },\n } : {}),\n }}\n style={styles.image}\n resizeMode=\"contain\"\n />\n <View style={styles.closeHint}>\n <Text style={styles.closeHintText}>Tap to close</Text>\n </View>\n </Pressable>\n </Modal>\n );\n}\n\nconst styles = StyleSheet.create({\n backdrop: {\n flex: 1,\n backgroundColor: 'rgba(0,0,0,0.92)',\n justifyContent: 'center',\n },\n image: {\n width: '100%',\n height: '85%',\n },\n closeHint: {\n position: 'absolute',\n bottom: 40,\n alignSelf: 'center',\n },\n closeHintText: {\n color: 'rgba(255,255,255,0.6)',\n fontSize: 13,\n },\n});\n","// src/components/widgets/WidgetWebView.tsx\n//\n// Fullscreen modal that renders an ACS widget bundle in a WebView.\n//\n// The bundleUrl on each /surface item is a signed URL minted by the backend\n// proxy (apps/backend/routes/acsProxy.js → signItemBundleUrl). The URL\n// self-authenticates — the bundle endpoint verifies sig/exp/tenant/actor on\n// the server side — so the WebView doesn't need to pass auth headers.\n//\n// Relative URLs (e.g. `/api/acs/artifacts/.../bundle/1?sig=…`) are prepended\n// with the current core URL from configStore.\n//\n// Strict CSP is set on the response by the bundle endpoint. We additionally\n// disable JS injection paths we don't need (no onMessage handlers wired,\n// no injectedJavaScriptBeforeContentLoaded).\n\nimport { useMemo, useState } from 'react';\nimport {\n Modal,\n View,\n Text,\n Pressable,\n StyleSheet,\n ActivityIndicator,\n Platform,\n} from 'react-native';\nimport { WebView } from 'react-native-webview';\nimport { ada } from '@ateam-ai-mobile/core';\nimport { getCoreApiUrl } from '@ateam-ai-mobile/core';\n\nconst fontFam = Platform.OS === 'ios' ? 'SF Pro Rounded' : undefined;\n\ninterface Props {\n visible: boolean;\n /** Display title shown in the top bar. */\n title?: string;\n /** Signed bundle URL from a /surface item. Relative or absolute. */\n bundleUrl?: string;\n onClose: () => void;\n}\n\nexport default function WidgetWebView({ visible, title, bundleUrl, onClose }: Props) {\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n // Absolute URL — prepend the resolved core if backend returned a relative path.\n const uri = useMemo(() => {\n if (!bundleUrl) return null;\n if (/^https?:\\/\\//i.test(bundleUrl)) return bundleUrl;\n return `${getCoreApiUrl()}${bundleUrl}`;\n }, [bundleUrl]);\n\n return (\n <Modal\n visible={visible}\n animationType=\"slide\"\n presentationStyle=\"pageSheet\"\n onRequestClose={onClose}\n >\n <View style={styles.root}>\n <View style={styles.bar}>\n <Pressable onPress={onClose} hitSlop={12} style={styles.closeBtn}>\n <Text style={styles.closeIcon}>{'✕'}</Text>\n </Pressable>\n <Text style={styles.title} numberOfLines={1}>{title || 'Widget'}</Text>\n {/* Spacer matches closeBtn width so the title stays centered */}\n <View style={styles.closeBtn} />\n </View>\n {!uri ? (\n <View style={styles.errorWrap}>\n <Text style={styles.errorText}>No bundle available for this widget.</Text>\n </View>\n ) : error ? (\n <View style={styles.errorWrap}>\n <Text style={styles.errorText}>Couldn't load widget</Text>\n <Text style={styles.errorSub}>{error}</Text>\n </View>\n ) : (\n <>\n <WebView\n source={{ uri }}\n style={styles.web}\n onLoadStart={() => { setLoading(true); setError(null); }}\n onLoadEnd={() => setLoading(false)}\n onError={(e) => {\n setLoading(false);\n setError(e.nativeEvent.description || 'Unknown error');\n }}\n onHttpError={(e) => {\n setLoading(false);\n setError(`HTTP ${e.nativeEvent.statusCode}`);\n }}\n // The bundle is the only thing this WebView should render.\n // Block navigation away from it (prevents accidental browse\n // out of the widget sandbox into arbitrary URLs).\n originWhitelist={['https://*']}\n setSupportMultipleWindows={false}\n />\n {loading && (\n <View pointerEvents=\"none\" style={styles.spinner}>\n <ActivityIndicator color={ada.orange} />\n </View>\n )}\n </>\n )}\n </View>\n </Modal>\n );\n}\n\nconst styles = StyleSheet.create({\n root: {\n flex: 1,\n backgroundColor: ada.paper,\n },\n bar: {\n flexDirection: 'row',\n alignItems: 'center',\n paddingHorizontal: 14,\n paddingVertical: 12,\n borderBottomWidth: 1,\n borderBottomColor: ada.border,\n backgroundColor: ada.paperSoft,\n },\n closeBtn: {\n width: 32,\n height: 32,\n alignItems: 'center',\n justifyContent: 'center',\n },\n closeIcon: {\n fontSize: 18,\n color: ada.ink,\n fontWeight: '500',\n },\n title: {\n flex: 1,\n textAlign: 'center',\n fontSize: 16,\n fontWeight: '600',\n color: ada.ink,\n fontFamily: fontFam,\n letterSpacing: -0.2,\n },\n web: {\n flex: 1,\n backgroundColor: ada.paper,\n },\n spinner: {\n position: 'absolute',\n top: 80,\n left: 0,\n right: 0,\n alignItems: 'center',\n },\n errorWrap: {\n flex: 1,\n alignItems: 'center',\n justifyContent: 'center',\n paddingHorizontal: 24,\n },\n errorText: {\n fontSize: 15,\n color: ada.ink,\n fontWeight: '600',\n marginBottom: 6,\n },\n errorSub: {\n fontSize: 13,\n color: ada.inkMuted,\n textAlign: 'center',\n },\n});\n","/**\n * TenantPicker — prebuilt team switcher, fully SDK-driven.\n *\n * Lists the user's REAL memberships via core's listMyTenants() and, on tap,\n * re-scopes the whole session with core's switchTenant() (which mints the new\n * tenant JWT, persists it through config.onSession, and reconnects chat). The\n * host only reacts via onSwitched (e.g. navigate home). Single-tenant hosts\n * simply never render it.\n *\n * For custom flows, pass `onSelect` to intercept the tap instead of switching.\n */\nimport { useEffect, useState } from 'react';\nimport { View, Text, Pressable, ActivityIndicator, StyleSheet, Platform } from 'react-native';\nimport { ada, fontSize, borderRadius, listMyTenants, switchTenant, getTenant } from '@ateam-ai-mobile/core';\nimport type { TenantMembership, AdasSession } from '@ateam-ai-mobile/core';\n\nconst fontFam = Platform.OS === 'ios' ? 'SF Pro Rounded' : undefined;\n\nexport interface TenantPickerProps {\n /** Called after a successful SDK-driven switch (host navigates/refreshes). */\n onSwitched?: (session: AdasSession) => void;\n /** Intercept the tap instead of switching — for fully custom host flows.\n * When provided, the SDK does NOT call switchTenant(). */\n onSelect?: (tenant: TenantMembership) => void;\n /** Highlight the active tenant. Defaults to the SDK config's tenant. */\n currentTenantId?: string;\n}\n\nexport default function TenantPicker({ onSwitched, onSelect, currentTenantId }: TenantPickerProps) {\n const [tenants, setTenants] = useState<TenantMembership[] | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [switching, setSwitching] = useState<string | null>(null);\n const active = currentTenantId ?? getTenant();\n\n useEffect(() => {\n let cancelled = false;\n listMyTenants()\n .then(list => { if (!cancelled) setTenants(list); })\n .catch(e => { if (!cancelled) setError(e?.message || 'Failed to load teams'); });\n return () => { cancelled = true; };\n }, []);\n\n const handlePress = async (t: TenantMembership) => {\n if (t.id === active || switching) return;\n if (onSelect) { onSelect(t); return; }\n setError(null);\n setSwitching(t.id);\n try {\n const session = await switchTenant(t.id);\n onSwitched?.(session);\n } catch (e: any) {\n setError(e?.message || 'Could not switch team');\n } finally {\n setSwitching(null);\n }\n };\n\n if (error) return <Text style={styles.error}>{error}</Text>;\n if (!tenants) {\n return (\n <View style={styles.loading}>\n <ActivityIndicator color={ada.orange} />\n </View>\n );\n }\n if (tenants.length === 0) return <Text style={styles.empty}>No teams found for this account.</Text>;\n\n return (\n <View style={styles.list}>\n {tenants.map(t => {\n const isActive = t.id === active;\n const isSwitching = switching === t.id;\n return (\n <Pressable\n key={t.id}\n accessibilityRole=\"button\"\n accessibilityLabel={`Team ${t.name}${isActive ? ', current' : ''}`}\n disabled={!!switching}\n onPress={() => handlePress(t)}\n style={[styles.row, isActive && styles.rowActive]}\n >\n <View style={styles.dot} />\n <View style={styles.rowText}>\n <Text style={styles.name}>{t.name}</Text>\n <Text style={styles.slug}>{t.id}</Text>\n </View>\n {isSwitching ? <ActivityIndicator color={ada.orange} /> : isActive ? <Text style={styles.check}>✓</Text> : null}\n </Pressable>\n );\n })}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n list: {\n gap: 10,\n },\n row: {\n flexDirection: 'row',\n alignItems: 'center',\n gap: 12,\n backgroundColor: ada.paperSoft,\n borderRadius: borderRadius.lg,\n borderWidth: 1,\n borderColor: 'transparent',\n paddingHorizontal: 16,\n paddingVertical: 14,\n },\n rowActive: {\n backgroundColor: ada.orangeSoft,\n borderColor: ada.orange,\n },\n dot: {\n width: 10,\n height: 10,\n borderRadius: 5,\n backgroundColor: ada.orange,\n },\n rowText: {\n flex: 1,\n },\n name: {\n color: ada.ink,\n fontSize: fontSize.lg,\n fontWeight: '600',\n fontFamily: fontFam,\n },\n slug: {\n color: ada.inkMuted,\n fontSize: fontSize.sm,\n fontFamily: 'monospace',\n },\n check: {\n color: ada.orangeDeep,\n fontSize: fontSize.lg,\n fontWeight: '700',\n },\n loading: {\n paddingVertical: 24,\n alignItems: 'center',\n },\n empty: {\n color: ada.inkMuted,\n fontSize: fontSize.md,\n textAlign: 'center',\n paddingVertical: 16,\n },\n error: {\n color: '#C15545',\n fontSize: fontSize.md,\n textAlign: 'center',\n paddingVertical: 16,\n },\n});\n","/**\n * VoiceCallSheet — the full-screen voice call experience.\n *\n * AdaOrb hero + live transcript (with important-data highlighting) + mute\n * control + an offscreen WebView that runs the actual WebRTC session (see\n * useVoiceCall). Requires `voiceUrl` in the initAdas() config.\n */\nimport { useEffect, useRef, useMemo } from 'react';\nimport {\n View,\n Text,\n StyleSheet,\n Platform,\n Pressable,\n ScrollView,\n} from 'react-native';\nimport Svg, { Path, Line } from 'react-native-svg';\nimport { WebView } from 'react-native-webview';\nimport { ada } from '@ateam-ai-mobile/core';\nimport { AdaOrb, SurfaceFullscreen, type AdaOrbState } from '@ateam-ai-mobile/plugin-runtime';\nimport useVoiceCall from './useVoiceCall';\n\ninterface Props {\n visible: boolean;\n onClose: () => void;\n /** Optional skill to hand the mic to on connect (voice /session → takeMic). */\n skillSlug?: string;\n}\n\nconst fontFam = Platform.OS === 'ios' ? 'SF Pro Rounded' : undefined;\n\n// Detect important data in voice transcripts so the user can verify it visually.\nconst HIGHLIGHT_PATTERNS = [\n /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}/g,\n /(?:\\+?\\d[\\s\\-().]?){7,}\\d/g,\n /\\$\\d[\\d,]*(?:\\.\\d{1,2})?/g,\n /\\b\\d{1,2}:\\d{2}\\s?(?:am|pm|AM|PM)?\\b/g,\n /\\bhttps?:\\/\\/\\S+/g,\n /\\b\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}\\b/g,\n];\n\nfunction highlightSegments(text: string): Array<{ text: string; important: boolean }> {\n const ranges: Array<[number, number]> = [];\n for (const p of HIGHLIGHT_PATTERNS) {\n p.lastIndex = 0;\n let m;\n while ((m = p.exec(text)) !== null) {\n ranges.push([m.index, m.index + m[0].length]);\n }\n }\n if (!ranges.length) return [{ text, important: false }];\n ranges.sort((a, b) => a[0] - b[0]);\n const merged: Array<[number, number]> = [];\n for (const r of ranges) {\n if (merged.length && r[0] <= merged[merged.length - 1][1]) {\n merged[merged.length - 1][1] = Math.max(merged[merged.length - 1][1], r[1]);\n } else {\n merged.push([r[0], r[1]]);\n }\n }\n const segments: Array<{ text: string; important: boolean }> = [];\n let cursor = 0;\n for (const [start, end] of merged) {\n if (start > cursor) segments.push({ text: text.slice(cursor, start), important: false });\n segments.push({ text: text.slice(start, end), important: true });\n cursor = end;\n }\n if (cursor < text.length) segments.push({ text: text.slice(cursor), important: false });\n return segments;\n}\n\nfunction HighlightedText({\n text,\n baseStyle,\n importantStyle,\n}: {\n text: string;\n baseStyle: any;\n importantStyle: any;\n}) {\n const segments = useMemo(() => highlightSegments(text), [text]);\n return (\n <Text style={baseStyle}>\n {segments.map((seg, i) => (\n <Text key={i} style={seg.important ? importantStyle : undefined}>\n {seg.text}\n </Text>\n ))}\n </Text>\n );\n}\n\nexport default function VoiceCallSheet({ visible, onClose, skillSlug }: Props) {\n const {\n callState, aiPartial, userPartial, transcript, error, muted,\n startCall, stopCall, toggleMute, handleWebViewMessage, getWebViewSource, webViewRef,\n injectedTrackHook,\n } = useVoiceCall({ skillSlug });\n\n const scrollRef = useRef<ScrollView>(null);\n\n useEffect(() => {\n if (visible && callState === 'idle') startCall();\n }, [visible]); // eslint-disable-line react-hooks/exhaustive-deps\n\n useEffect(() => {\n scrollRef.current?.scrollToEnd?.({ animated: true });\n }, [transcript.length, aiPartial, userPartial]);\n\n const handleHangUp = () => {\n stopCall();\n onClose();\n };\n\n const orbState: AdaOrbState = useMemo(() => {\n if (callState === 'connecting') return 'thinking';\n if (callState === 'error') return 'idle';\n if (aiPartial) return 'speaking';\n if (userPartial) return 'listening';\n return 'idle';\n }, [callState, aiPartial, userPartial]);\n\n const statusLabel = useMemo(() => {\n if (callState === 'connecting') return 'Connecting…';\n if (callState === 'error') return error || 'Couldn’t connect';\n if (aiPartial) return 'Ada is speaking';\n if (userPartial) return 'Listening';\n if (callState === 'connected') return 'Go ahead, I’m here.';\n return '';\n }, [callState, aiPartial, userPartial, error]);\n\n if (!visible) return null;\n\n const visibleEntries = transcript.filter(e => e.role === 'user' || e.role === 'ai');\n\n return (\n <SurfaceFullscreen\n visible={visible}\n onClose={handleHangUp}\n status={statusLabel}\n hero={<AdaOrb size={180} state={orbState} />}\n closeIcon=\"hangup\"\n closeLabel=\"End\"\n >\n <ScrollView\n ref={scrollRef}\n style={styles.transcript}\n contentContainerStyle={styles.transcriptContent}\n showsVerticalScrollIndicator={false}\n >\n {callState === 'error' && error ? (\n <View style={styles.errorBox}>\n <Text style={styles.errorText}>{error}</Text>\n </View>\n ) : null}\n {visibleEntries.map((entry, i) => (\n <View key={`${entry.ts}-${i}`} style={styles.entry}>\n <Text style={styles.role}>\n {entry.role === 'user' ? 'YOU' : 'ADA'}\n </Text>\n <HighlightedText\n text={entry.text}\n baseStyle={styles.entryText}\n importantStyle={styles.important}\n />\n </View>\n ))}\n {(userPartial || aiPartial) ? (\n <View style={styles.entry}>\n <Text style={styles.role}>\n {userPartial ? 'YOU' : 'ADA'}\n </Text>\n <HighlightedText\n text={userPartial || aiPartial}\n baseStyle={styles.entryTextLive}\n importantStyle={styles.important}\n />\n </View>\n ) : null}\n </ScrollView>\n\n {/* Mute control — floating above transcript, only when call is live */}\n {callState === 'connected' || callState === 'connecting' ? (\n <View style={styles.muteWrap} pointerEvents=\"box-none\">\n <Pressable\n onPress={toggleMute}\n accessibilityRole=\"button\"\n accessibilityLabel={muted ? 'Unmute microphone' : 'Mute microphone'}\n accessibilityState={{ selected: muted }}\n style={[styles.muteBtn, muted && styles.muteBtnActive]}\n hitSlop={12}\n >\n <Svg width={22} height={22} viewBox=\"0 0 24 24\" fill=\"none\" stroke={muted ? ada.paper : ada.ink} strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <Path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z\" />\n <Path d=\"M19 10v2a7 7 0 0 1-14 0v-2\" />\n <Line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\" />\n <Line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\" />\n {muted ? <Line x1=\"3\" y1=\"3\" x2=\"21\" y2=\"21\" stroke={ada.paper} strokeWidth={2.4} /> : null}\n </Svg>\n </Pressable>\n <Text style={styles.muteLabel}>{muted ? 'Muted' : 'Mute'}</Text>\n </View>\n ) : null}\n\n {/* WebView mounted offscreen — runs WebRTC silently */}\n {callState !== 'idle' && (\n <View style={styles.hiddenWebView} pointerEvents=\"none\">\n <WebView\n ref={webViewRef}\n source={getWebViewSource()}\n style={{ flex: 1, backgroundColor: 'transparent' }}\n onMessage={handleWebViewMessage}\n onError={(e: any) => console.log('[VoiceWebView] error:', e.nativeEvent?.description)}\n injectedJavaScriptBeforeContentLoaded={injectedTrackHook}\n mediaPlaybackRequiresUserAction={false}\n allowsInlineMediaPlayback={true}\n mediaCapturePermissionGrantType=\"grant\"\n javaScriptEnabled={true}\n originWhitelist={['*']}\n />\n </View>\n )}\n </SurfaceFullscreen>\n );\n}\n\nconst styles = StyleSheet.create({\n transcript: {\n flex: 1,\n paddingHorizontal: 28,\n },\n transcriptContent: {\n paddingTop: 8,\n paddingBottom: 16,\n gap: 14,\n },\n entry: {\n flexDirection: 'row',\n gap: 10,\n alignItems: 'flex-start',\n },\n role: {\n fontSize: 10,\n fontFamily: fontFam,\n fontWeight: '700',\n color: ada.inkMuted,\n letterSpacing: 1.4,\n minWidth: 32,\n paddingTop: 3,\n opacity: 0.55,\n },\n entryText: {\n flex: 1,\n fontSize: 14,\n fontFamily: fontFam,\n fontWeight: '400',\n color: ada.inkSoft,\n lineHeight: 20,\n letterSpacing: -0.1,\n opacity: 0.42,\n },\n entryTextLive: {\n flex: 1,\n fontSize: 14,\n fontFamily: fontFam,\n fontWeight: '400',\n color: ada.inkSoft,\n lineHeight: 20,\n letterSpacing: -0.1,\n opacity: 0.7,\n },\n important: {\n fontSize: 17,\n fontFamily: fontFam,\n fontWeight: '700',\n color: ada.ink,\n letterSpacing: -0.1,\n opacity: 1,\n },\n errorBox: {\n backgroundColor: 'rgba(239,68,68,0.12)',\n borderColor: 'rgba(239,68,68,0.45)',\n borderWidth: 1,\n borderRadius: 10,\n paddingVertical: 10,\n paddingHorizontal: 14,\n marginBottom: 12,\n },\n errorText: {\n fontSize: 13,\n fontFamily: fontFam,\n fontWeight: '500',\n color: '#fca5a5',\n lineHeight: 18,\n },\n muteWrap: {\n position: 'absolute',\n bottom: Platform.OS === 'ios' ? 56 : 40,\n left: 28,\n alignItems: 'center',\n gap: 6,\n },\n muteBtn: {\n width: 56,\n height: 56,\n borderRadius: 28,\n backgroundColor: ada.paperSoft,\n borderWidth: 1,\n borderColor: ada.border,\n justifyContent: 'center',\n alignItems: 'center',\n },\n muteBtnActive: {\n backgroundColor: '#C15545',\n borderColor: '#C15545',\n },\n muteLabel: {\n fontSize: 12,\n fontFamily: fontFam,\n fontWeight: '500',\n color: ada.inkMuted,\n letterSpacing: 0.3,\n },\n hiddenWebView: {\n position: 'absolute',\n width: 1,\n height: 1,\n top: -100,\n left: -100,\n opacity: 0,\n },\n});\n","/**\n * useVoiceCall — WebView-based voice hook.\n *\n * The WebView runs WebRTC + OpenAI Realtime internally (iOS WebView supports\n * WebRTC); communication is postMessage (transcript/state events → RN).\n * Requires `voiceUrl` in the initAdas() config — getWebViewSource() throws\n * without it. Identity (token/tenant/actor) comes from the host-owned config.\n */\nimport { useState, useRef, useCallback } from 'react';\nimport { getVoiceApiUrl, getToken, getTenant, getUser, refreshToken } from '@ateam-ai-mobile/core';\n\n/**\n * The voice WebView bakes the JWT into its URL once at mount and never\n * refreshes it (unlike the SDK REST client, which self-heals on 401). So a\n * token that has gone stale by the time the user taps the mic is handed to\n * voice-backend and rejected by Core /api/auth/me (\"Invalid or expired\n * token\"). Guard: if the current token is expired or within `SKEW_MS` of\n * expiry, refresh it BEFORE the WebView mounts so it gets a fresh token.\n * Cheap in the common case — we only pay the round-trip when actually near\n * expiry (decoded locally, no network unless needed).\n */\nconst TOKEN_REFRESH_SKEW_MS = 90_000; // refresh if <90s of life left (or expired)\nfunction tokenNeedsRefresh(token: string | null): boolean {\n if (!token) return true;\n try {\n const payloadB64 = token.split('.')[1];\n const padded = payloadB64.replace(/-/g, '+').replace(/_/g, '/');\n // Hermes has atob; Buffer fallback for older runtimes (mirrors\n // apps/mobile authStore.decodeJwtPayload).\n const json = typeof atob === 'function'\n ? atob(padded)\n : Buffer.from(padded, 'base64').toString('utf8');\n const exp = JSON.parse(json)?.exp;\n if (typeof exp !== 'number') return false;\n return Date.now() >= exp * 1000 - TOKEN_REFRESH_SKEW_MS;\n } catch {\n return false; // can't decode → let the server decide, don't block the call\n }\n}\n\nexport interface TranscriptEntry {\n role: 'user' | 'ai' | 'tool';\n text: string;\n ts: number;\n}\n\nexport type CallState = 'idle' | 'connecting' | 'connected' | 'error';\n\n// Installed BEFORE the voice app loads. Captures every audio track that\n// could possibly be sent to the peer connection so the mute button can flip\n// enabled=false on all of them, regardless of how the voice app obtained or\n// added the track.\nconst INJECT_TRACK_HOOK = `\n(function() {\n if (window._adaTrackHookInstalled) return;\n window._adaTrackHookInstalled = true;\n window._allAudioTracks = [];\n window._adaPeerConnections = [];\n\n function track(t) {\n if (t && t.kind === 'audio' && window._allAudioTracks.indexOf(t) === -1) {\n window._allAudioTracks.push(t);\n }\n }\n\n // 1) Hook getUserMedia — captures mic streams at request time.\n try {\n if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {\n const origGUM = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);\n navigator.mediaDevices.getUserMedia = async function(constraints) {\n const stream = await origGUM(constraints);\n if (constraints && constraints.audio) {\n try { stream.getAudioTracks().forEach(track); } catch (e) {}\n }\n return stream;\n };\n }\n } catch (e) {}\n\n // 2) Hook RTCPeerConnection.addTrack — catches whatever the app sends.\n try {\n if (window.RTCPeerConnection) {\n const origPC = window.RTCPeerConnection;\n const origAddTrack = origPC.prototype.addTrack;\n const origAddStream = origPC.prototype.addStream;\n const origAddTransceiver = origPC.prototype.addTransceiver;\n\n origPC.prototype.addTrack = function(t) {\n if (t && t.kind === 'audio') track(t);\n return origAddTrack.apply(this, arguments);\n };\n if (origAddStream) {\n origPC.prototype.addStream = function(stream) {\n try { stream.getAudioTracks().forEach(track); } catch (e) {}\n return origAddStream.apply(this, arguments);\n };\n }\n if (origAddTransceiver) {\n origPC.prototype.addTransceiver = function(arg) {\n if (arg && arg.kind === 'audio') {\n // Transceiver created with kind 'audio' — sender track set later.\n } else if (arg && arg.kind === undefined && arg.track && arg.track.kind === 'audio') {\n track(arg.track);\n }\n const tx = origAddTransceiver.apply(this, arguments);\n try {\n if (tx && tx.sender && tx.sender.track && tx.sender.track.kind === 'audio') track(tx.sender.track);\n } catch (e) {}\n return tx;\n };\n }\n }\n } catch (e) {}\n\n // 3) Helper exposed for direct calls.\n window._adaSetMuted = function(muted) {\n let n = 0;\n if (Array.isArray(window._allAudioTracks)) {\n window._allAudioTracks.forEach(function(t) {\n try { t.enabled = !muted; n++; } catch (e) {}\n });\n }\n return n;\n };\n})(); true;\n`;\n\nconst buildMuteScript = (muted: boolean) => `\n(function(muted) {\n if (typeof window.setMuted === 'function') { window.setMuted(muted); }\n let n = 0;\n if (typeof window._adaSetMuted === 'function') {\n n = window._adaSetMuted(muted);\n }\n // Last-resort scan if hook somehow missed.\n if (n === 0 && Array.isArray(window._allAudioTracks)) {\n window._allAudioTracks.forEach(function(t) {\n try { t.enabled = !muted; n++; } catch (e) {}\n });\n }\n console.log('[ada-mute]', muted ? 'MUTED' : 'UNMUTED', 'tracks=', n);\n})(${muted}); true;\n`;\n\nexport default function useVoiceCall({ skillSlug }: { skillSlug?: string } = {}) {\n const [callState, setCallState] = useState<CallState>('idle');\n const [sessionId, setSessionId] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [transcript, setTranscript] = useState<TranscriptEntry[]>([]);\n const [aiPartial, setAiPartial] = useState('');\n const [userPartial, setUserPartial] = useState('');\n const [muted, setMuted] = useState(false);\n const webViewRef = useRef<any>(null);\n\n /** Handle postMessage events from the WebView */\n const handleWebViewMessage = useCallback((event: any) => {\n try {\n const data = JSON.parse(event.nativeEvent.data);\n console.log('[VoiceWebView] message:', data.type, data.text?.slice?.(0, 50) || data.state || '');\n switch (data.type) {\n case 'callState':\n case 'call-state':\n setCallState(data.state);\n if (data.sessionId) setSessionId(data.sessionId);\n if (data.error) setError(data.error);\n break;\n case 'transcript':\n setTranscript(prev => [...prev, { role: data.role, text: data.text, ts: Date.now() }]);\n break;\n case 'aiPartial':\n setAiPartial(data.text);\n break;\n case 'userPartial':\n setUserPartial(data.text);\n break;\n case 'clearPartials':\n setAiPartial('');\n setUserPartial('');\n break;\n case 'error':\n setError(data.message);\n setCallState('error');\n break;\n }\n } catch {}\n }, []);\n\n const startCall = useCallback(async () => {\n setError(null);\n setTranscript([]);\n setAiPartial('');\n setUserPartial('');\n // Ensure the WebView is handed a FRESH token BEFORE it mounts (it never\n // refreshes once mounted, and the WebView mounts as soon as callState\n // leaves 'idle'). Only pays a round-trip when the token is expired or\n // near-expiry; otherwise instant. Flip to 'connecting' only after, so\n // getWebViewSource() reads the refreshed token.\n try {\n if (tokenNeedsRefresh(getToken())) {\n await refreshToken();\n }\n } catch {\n // Refresh failed — proceed with whatever token we have; voice-backend\n // will surface a clean auth error rather than us blocking the call.\n }\n setCallState('connecting');\n }, []);\n\n const stopCall = useCallback(() => {\n // Tell WebView to hang up\n webViewRef.current?.injectJavaScript?.('window.hangUp && window.hangUp(); true;');\n setCallState('idle');\n setAiPartial('');\n setUserPartial('');\n setMuted(false);\n }, []);\n\n const toggleMute = useCallback(() => {\n setMuted(prev => {\n const next = !prev;\n webViewRef.current?.injectJavaScript?.(buildMuteScript(next));\n return next;\n });\n }, []);\n\n /** Build the WebView source. Identity comes from the SDK config (host-owned\n * auth) — token, tenant, actorId are passed to the voice mini-app. */\n const getWebViewSource = useCallback(() => {\n const token = getToken();\n const tenant = getTenant();\n const actorId = getUser()?.actorId || '';\n // skillSlug (when opened for a specific skill) is read by the voice mini-app\n // and posted to /session, which turns it into takeMic (E1 held-mic entry).\n const skillParam = skillSlug ? `&skillSlug=${encodeURIComponent(skillSlug)}` : '';\n return {\n uri: `${getVoiceApiUrl()}/app?mode=mini&embedded=rn&authToken=${encodeURIComponent(token || '')}&tenant=${encodeURIComponent(tenant)}&actorId=${encodeURIComponent(actorId)}${skillParam}`,\n };\n }, [skillSlug]);\n\n return {\n callState, sessionId, error, transcript, aiPartial, userPartial, muted,\n startCall, stopCall, toggleMute, handleWebViewMessage, getWebViewSource, webViewRef,\n injectedTrackHook: INJECT_TRACK_HOOK,\n };\n}\n"],"mappings":"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","names":["useCallback","useEffect","useMemo","useRef","useState","Platform","StyleSheet","View","ada","pluginCommandEmitter","useState","useCallback","View","Text","Pressable","StyleSheet","Platform","getConfig","ada","borderRadius","fontSize","getHaptics","View","Text","Pressable","StyleSheet","Platform","ada","fontSize","useSurfaceStore","useEffect","pluginCommandEmitter","useEffect","useState","View","ActivityIndicator","ada","useMemo","View","Text","ActivityIndicator","StyleSheet","getTenant","useState","useCallback","View","Text","StyleSheet","getTenant","ada","useEffect","useRef","data","jsx","jsxs","useState","getTenant","useCallback","View","styles","Text","ada","StyleSheet","jsx","jsxs","View","styles","Text","useMemo","getTenant","ActivityIndicator","StyleSheet","jsx","useState","useEffect","View","ActivityIndicator","ada","jsx","useEffect","pluginCommandEmitter","jsx","jsxs","Platform","useSurfaceStore","View","styles","Pressable","Text","StyleSheet","ada","fontSize","View","Text","StyleSheet","Platform","ada","fontSize","jsx","jsxs","fontFam","styles","create","jsx","jsxs","fontFam","Platform","View","Text","StyleSheet","ada","useState","useCallback","getHaptics","styles","Pressable","getConfig","borderRadius","fontSize","View","StyleSheet","AdaOrb","jsx","styles","useState","useRef","useCallback","useEffect","View","Pressable","StyleSheet","Platform","colors","borderRadius","getHaptics","jsx","jsxs","styles","View","Image","Pressable","Text","StyleSheet","getConfig","jsx","jsxs","Pressable","styles","Image","getConfig","View","Text","StyleSheet","jsx","jsxs","isSameDay","useRef","useState","useEffect","pluginCommandEmitter","Platform","useMemo","useCallback","View","styles","ada","StyleSheet","useMemo","useState","Modal","View","Text","Pressable","StyleSheet","ActivityIndicator","Platform","WebView","ada","getCoreApiUrl","Fragment","jsx","jsxs","fontFam","styles","useEffect","useState","View","Text","Pressable","ActivityIndicator","StyleSheet","Platform","ada","fontSize","borderRadius","getTenant","jsx","jsxs","fontFam","styles","useEffect","useRef","useMemo","View","Text","StyleSheet","Platform","Pressable","Svg","Path","Line","WebView","ada","AdaOrb","SurfaceFullscreen","useState","useRef","useCallback","getVoiceApiUrl","getToken","getTenant","getUser","jsx","jsxs","fontFam","Platform","useMemo","Text","useRef","useEffect","SurfaceFullscreen","AdaOrb","styles","View","Pressable","Svg","ada","Path","Line","WebView","StyleSheet"]}