@adminide-stack/yantra-mobile 12.0.133 → 12.0.135

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/lib/features/apps/nativeAppHandoff.js +26 -2
  2. package/lib/features/apps/nativeAppHandoff.js.map +1 -1
  3. package/lib/features/chat/askUser.js +8 -1
  4. package/lib/features/chat/askUser.js.map +1 -1
  5. package/lib/features/chat/toolActivity.js +4 -2
  6. package/lib/features/chat/toolActivity.js.map +1 -1
  7. package/lib/features/webbuilder/components/ProjectChat.js +4 -1
  8. package/lib/features/webbuilder/components/ProjectChat.js.map +1 -1
  9. package/lib/hooks/useCdecliChannel.js +1 -1
  10. package/lib/hooks/useCdecliChannel.js.map +1 -1
  11. package/lib/hooks/useChatStream.js +15 -1
  12. package/lib/hooks/useChatStream.js.map +1 -1
  13. package/lib/screens/Chat/index.js +23 -2
  14. package/lib/screens/Chat/index.js.map +1 -1
  15. package/lib/screens/ChatHistory/index.js +18 -5
  16. package/lib/screens/ChatHistory/index.js.map +1 -1
  17. package/lib/screens/Home/components/ChatHistoryLanding.js +4 -2
  18. package/lib/screens/Home/components/ChatHistoryLanding.js.map +1 -1
  19. package/lib/screens/WebBuilderNative/runningBuilds.js +4 -1
  20. package/lib/screens/WebBuilderNative/runningBuilds.js.map +1 -1
  21. package/lib/screens/WebBuilderNative/siteLane.js +5 -0
  22. package/lib/screens/WebBuilderNative/siteLane.js.map +1 -0
  23. package/lib/screens/WebBuilderNative/useWebBuilderGallery.js +42 -2
  24. package/lib/screens/WebBuilderNative/useWebBuilderGallery.js.map +1 -1
  25. package/lib/screens/WebBuilderNative/useWebBuilderHost.js +54 -15
  26. package/lib/screens/WebBuilderNative/useWebBuilderHost.js.map +1 -1
  27. package/lib/screens/WebBuilderNative/useWebBuilderJobs.js +1 -0
  28. package/lib/screens/WebBuilderNative/useWebBuilderJobs.js.map +1 -1
  29. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/screens/Chat/index.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport { Keyboard, Pressable, StyleSheet, TextInput, View, useWindowDimensions } from 'react-native';\nimport { Box, InputToolBar, Text, getDefaultLeftItems } from '@admin-layout/gluestack-ui-mobile';\nimport { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';\nimport {\n useNavigation,\n useRoute,\n CommonActions,\n type NavigationProp,\n type ParamListBase,\n type RouteProp,\n} from '@react-navigation/native';\nimport { MessageActionBar } from '../../features/chat/MessageActionBar';\nimport { ChatTranscript } from '../../features/chat/ChatTranscript';\nimport { ChatLinkOpenerProvider } from '../../features/links/ChatLinkOpenerProvider';\nimport { AskUserCard } from '../../features/chat/AskUserCard';\nimport { pendingAskUser } from '../../features/chat/askUser';\nimport { PendingConnectorConnectCard } from '../../features/chat/ConnectorConnectPrompt';\nimport { QueuedFollowUps } from '../../features/chat/QueuedFollowUps';\nimport { displayConnectorConnectMessages, displayConnectorConnectText } from '../../features/chat/connectorConnect';\nimport { splitPreResponse } from '../../features/chat/preResponse';\nimport { useCdecliConnection } from '../../contexts/CdecliConnectionContext';\nimport { useChatLiveStream } from '../../contexts/ChatLiveStreamContext';\nimport type { MessageAttachment } from '../../hooks/useChatStream';\nimport { KeyboardAwareScreen, KeyboardComposerDock } from '../../components/KeyboardComposerDock';\nimport { YantraBrandLoader, YANTRA_LOADER_SIZE_COMPACT } from '../../components/YantraBrandLoader';\nimport ThinkingIndicator from '../../components/ThinkingIndicator';\nimport { mobileTokens } from '../../theme/mobileTokens';\nimport { useAppTheme } from '../../theme/AppThemeProvider';\nimport DeepSearchModal from '../Home/components/DeepSearchModal';\nimport { extractDeepSearchSources, normalizeSummaryText, type DeepSearchSourceItem } from '../Home/deepSearchUtils';\nimport type { ModeSubmission, RoutingMode } from '../Home/types';\nimport { AudioRecorderPanel } from '../../features/audio-input/AudioRecorderPanel';\nimport { NativeDictationBar } from '../../features/audio-input/NativeDictationBar';\nimport { isNativeDictationAvailable } from '../../features/audio-input/nativeDictation';\nimport { useImageAttachments } from '../../features/attachments/useImageAttachments';\nimport { ComposerAttachmentBar } from '../../features/attachments/ComposerAttachmentBar';\nimport { useComposerAttachMenu } from '../../features/attachments/ComposerAttachMenu';\nimport {\n hasComposerAttachments,\n peekComposerAttachments,\n takeComposerAttachments,\n} from '../../features/attachments/composerAttachmentHandoff';\nimport { MicErrorBoundary } from '../../features/audio-input/MicErrorBoundary';\nimport { requestMicPermission } from '../../features/audio-input/useAudioPermission';\nimport { shouldRedirectToShop } from '../../features/shopping/chat/homeShoppingIntent';\nimport { pushShopNative, replaceWithShopNative, shopHandoffParams } from '../../features/shopping/chat/openShopNative';\nimport { resolveNativeHandoff } from '../../features/apps/nativeAppHandoff';\nimport { nativeHandoffParams, pushNativeApp, replaceWithNativeApp } from '../../features/apps/nativeAppNavigation';\n\n/** Route params passed by Home (or by deep-link) when entering the Chat surface. */\nexport interface ChatScreenRouteParams {\n /** Channel id is required — the screen is keyed on the conversation. */\n channelId: string;\n /** Org slug used by gateway/account context. */\n orgName?: string | null;\n /**\n * First user message to auto-fire when the screen mounts. Home generates\n * this when the user submits from the empty composer so the assistant\n * starts streaming on Chat without an extra round trip.\n */\n initialQuery?: string | null;\n /**\n * Seed for the composer's mode (`'chat'` | `'deep-search'` | `'build'`).\n *\n * Set by `HomeScreen` to carry the user's last selection across the\n * navigation hop (\"research from home → research-shaped composer on chat\").\n * `ChatHistoryScreen` does NOT forward this — revisits always land on the\n * default `'chat'` mode, matching Home's defaults, and the user is free to\n * switch from there. Build-mode send hands off to Web Builder.\n *\n * After mount, this param is purely a seed: the screen keeps its own\n * `activeMode` so the user can toggle freely while inside the thread.\n */\n initialMode?: RoutingMode;\n /** Optional attachments forwarded with the initial message. */\n initialAttachments?: ModeSubmission['attachments'];\n /**\n * Home already decided this first turn belongs in Chat, not Shop. The\n * auto-fire honours that instead of classifying the same text a second time.\n */\n shopRouteChecked?: boolean;\n}\n\n/** The mode a route param asks for; anything else is plain chat. */\nfunction routingModeOf(value: unknown): RoutingMode {\n if (value === 'deep-search' || value === 'build') return value;\n return 'chat';\n}\n\nfunction modeOf(isDeepSearchMode: boolean, isBuildMode: boolean): RoutingMode {\n if (isDeepSearchMode) return 'deep-search';\n if (isBuildMode) return 'build';\n return 'chat';\n}\n\n/** A sent turn on screen while the brain routes it (see `routingTurns`). */\ninterface RoutingTurn {\n id: string;\n text: string;\n attachments?: MessageAttachment[];\n /** In the thread, or above the composer when it was sent while the agent was busy. */\n placement: 'thread' | 'queue';\n}\n\nconst FIRST_TURN = 'first';\n\n/**\n * Route params carry the looser `ModeAttachment` (everything optional); the send\n * lane wants a `MessageAttachment`. Normalise once - `shopHandoffParams` takes the\n * narrower shape just as happily.\n */\nfunction normalizeRouteAttachments(\n attachments: ChatScreenRouteParams['initialAttachments'] | undefined,\n): MessageAttachment[] | undefined {\n return attachments?.map((a, index) => ({\n id: a.id ?? `att-${index}`,\n name: a.name ?? `attachment-${index + 1}`,\n type: a.type === 'screenshot' ? ('screenshot' as const) : ('file' as const),\n ...(a.mimeType ? { mimeType: a.mimeType } : {}),\n ...(a.size ? { size: a.size } : {}),\n ...((a.url ?? a.uri) ? { url: a.url ?? a.uri } : {}),\n ...(a.dataUrl ? { dataUrl: a.dataUrl } : {}),\n }));\n}\n\nconst PLACEHOLDER: Record<RoutingMode, string> = {\n 'deep-search': 'Research anything...',\n build: 'Describe an app to build...',\n chat: 'Ask anything...',\n};\n\nexport default function ChatScreen() {\n const navigation = useNavigation<NavigationProp<ParamListBase>>();\n const route = useRoute<RouteProp<Record<string, Partial<ChatScreenRouteParams> | undefined>, string>>();\n\n const params = (route?.params ?? {}) as Partial<ChatScreenRouteParams>;\n const channelId = useMemo(() => {\n const raw = typeof params.channelId === 'string' ? params.channelId.trim() : '';\n return raw.length > 0 ? raw : null;\n }, [params.channelId]);\n const initialQuery = useMemo(() => {\n const raw = typeof params.initialQuery === 'string' ? params.initialQuery.trim() : '';\n return raw.length > 0 ? raw : null;\n }, [params.initialQuery]);\n const { initialAttachments } = params;\n const shopRouteChecked = params.shopRouteChecked === true;\n\n const { isDark } = useAppTheme();\n const { width: screenWidth } = useWindowDimensions();\n const contentMaxWidth = Math.min(720, Math.max(360, screenWidth - 24));\n\n const surfaceColor = isDark ? '#0f172a' : mobileTokens.color.surface;\n const secondaryTextColor = isDark ? '#94a3b8' : mobileTokens.color.textMuted;\n\n const insets = useSafeAreaInsets();\n\n /**\n * Gateway + chat stream routing.\n *\n * The CDeCLI lifecycle is owned app-wide by `CdecliConnectionProvider`,\n * so we just register this screen's channelId and read the shared status.\n * This avoids racing `gatewayConnect` mutations with the header's\n * `GatewayConnector` (which previously ran its own `useCdecliAutoConnect`\n * and could clobber the chat session binding).\n */\n const cdecli = useCdecliConnection();\n const { setActiveChannelId } = cdecli;\n\n useLayoutEffect(() => {\n if (!channelId) return;\n setActiveChannelId(channelId);\n }, [channelId, setActiveChannelId]);\n\n const chat = useChatLiveStream();\n\n /**\n * Turns the user sent that are still being routed - the brain decides whether\n * each stays in this chat or moves to Shop or another app's screen. They show\n * from the tap, not from the routing decision or the gateway's answer: the\n * send lane takes each one over (or the hand-off does) in the same update that\n * drops it here. A turn sent while the agent is busy waits above the composer,\n * where the gateway's queued messages show; any other in the thread.\n */\n const [routingTurns, setRoutingTurns] = useState<RoutingTurn[]>(() =>\n initialQuery || initialAttachments?.length || peekComposerAttachments(channelId)?.length\n ? [\n {\n id: FIRST_TURN,\n text: initialQuery ?? '',\n attachments: peekComposerAttachments(channelId) ?? normalizeRouteAttachments(initialAttachments),\n placement: 'thread',\n },\n ]\n : [],\n );\n const releaseRoutingTurn = useCallback((id: string) => {\n setRoutingTurns((prev) => prev.filter((turn) => turn.id !== id));\n }, []);\n const routingSeqRef = useRef(0);\n\n /**\n * Gifted-shaped transcript rows, memoised on `messages` alone.\n *\n * This screen re-renders on every streamed token — `useChatStream` does\n * `setResponse((r) => r + text)` per delta. Building this array inline in\n * the JSX therefore handed `PlanModeView` a fresh `messages` identity on\n * every token, which invalidated its own `useMemo([messages, …])`, re-mapped\n * every row, and re-rendered every bubble. Assistant bubbles render through\n * `react-native-markdown-display`, so that meant re-parsing the markdown of\n * the whole thread once per token — O(messages) parses per delta, on the JS\n * thread, which is exactly when the UI has to stay responsive.\n *\n * `messages` is already stable upstream (`useChatApi` memoises it on the\n * Apollo result), so this only rebuilds when a message is actually added or\n * changed.\n */\n const transcriptRows = useMemo(() => {\n // A message the gateway queued is persisted as it is sent, so the next\n // backend hydration brings it into `messages` too. While it waits it\n // belongs above the composer, not in the thread: hide the newest user\n // rows that match what is still queued.\n const waiting = chat.queuedFollowUps.map((queued) => queued.text.trim());\n const hidden = new Set<number>();\n for (let i = chat.messages.length - 1; i >= 0 && waiting.length > 0; i -= 1) {\n const msg = chat.messages[i];\n const match = msg.role === 'user' ? waiting.indexOf((msg.content ?? '').trim()) : -1;\n if (match >= 0) {\n hidden.add(i);\n waiting.splice(match, 1);\n }\n }\n return [\n ...chat.messages.flatMap((msg, index) =>\n hidden.has(index)\n ? []\n : [\n {\n id: `msg-${index}-${msg.role}`,\n role: msg.role,\n content: msg.content,\n attachments: msg.attachments,\n metadata: (msg as { metadata?: unknown }).metadata,\n },\n ],\n ),\n // Turns typed while the gateway was down. They live in the outbox, not in\n // the thread, so they survive a backend hydration and an app restart - and\n // they are always the newest rows, so they belong at the end.\n ...chat.queuedMessages.map((queued) => ({\n id: `queued-${queued.id}`,\n role: 'user' as const,\n content: queued.text,\n attachments: queued.attachments,\n queued: true,\n // The gateway is there; this turn's own send failed.\n ...(cdecli.channelConnected\n ? { queuedNote: chat.outboxRetrying ? 'Not sent yet · trying again' : 'Not sent · tap Send now' }\n : {}),\n })),\n ...routingTurns\n .filter((turn) => turn.placement === 'thread')\n .map((turn) => ({\n id: `routing-${turn.id}`,\n role: 'user' as const,\n content: turn.text,\n attachments: turn.attachments,\n })),\n ];\n }, [\n chat.messages,\n chat.queuedMessages,\n chat.queuedFollowUps,\n chat.outboxRetrying,\n cdecli.channelConnected,\n routingTurns,\n ]);\n const {\n messages,\n response,\n quickReply,\n error: chatError,\n isLoading,\n isStreaming,\n messagesLoading,\n queuedMessages,\n outboxRetrying,\n flushQueuedMessages,\n discardQueuedMessages,\n queuedFollowUps,\n cancelQueuedFollowUp,\n sendQueuedNow,\n sendMessage,\n cancel,\n } = chat;\n\n /**\n * \"Try again\" on an assistant message: resend the nearest preceding user\n * prompt on the same channel. Row ids are `msg-<index>-<role>` (see\n * transcriptRows), so the transcript index comes straight out of the id.\n */\n const regenerateFrom = useCallback(\n (messageId: string) => {\n const match = /^msg-(\\d+)-assistant$/.exec(messageId);\n if (!match || !channelId) return;\n for (let i = Number(match[1]) - 1; i >= 0; i -= 1) {\n const prior = chat.messages[i];\n if (prior?.role === 'user' && (prior.content?.trim() || prior.attachments?.length)) {\n void chat.sendMessage(prior.content, prior.attachments, channelId);\n return;\n }\n }\n },\n [chat, channelId],\n );\n\n const chatBusy = isLoading || isStreaming;\n const renderMessageActions = useCallback(\n (message: { id: string; role: string; content: string }) =>\n message.role === 'assistant' ? (\n <MessageActionBar\n text={message.content}\n onRegenerate={chatBusy ? undefined : () => regenerateFrom(message.id)}\n />\n ) : null,\n [chatBusy, regenerateFrom],\n );\n\n const imageAttachments = useImageAttachments();\n const { rightItems, menu: attachMenu } = useComposerAttachMenu(imageAttachments, isDark);\n\n /*\n * Composer state — kept local so it doesn't leak across navigations.\n *\n * `valueRef` mirrors the controlled `value` so `handleSend` can read the\n * latest text without taking a dependency on it. Without this, `handleSend`\n * (and therefore `micSendButton.onSend`) would be recreated on every\n * keystroke, which is unnecessary churn for `InputToolBar`.\n *\n * `inputRef` is forwarded to InputToolBar's TextInput so we can call\n * `.clear()` imperatively after sending. On iOS, the native text buffer\n * can stay desynced from the controlled `value` for a frame when a state\n * update is followed by an async dispatch in the same gesture — the\n * \"send-and-clear\" race. The imperative clear closes that gap deterministically.\n */\n const [value, setValue] = useState('');\n const valueRef = useRef(value);\n valueRef.current = value;\n const inputRef = useRef<TextInput>(null);\n const trimmed = value.trim();\n const hasQuery = trimmed.length > 0;\n const hasAttachments = imageAttachments.pending.length > 0;\n const canSubmit = (hasQuery || hasAttachments) && Boolean(channelId);\n\n /**\n * Composer mode is FREELY user-controlled, mirroring `HomeScreen`.\n *\n * Seed:\n * • From Home (which forwards `initialMode` alongside `initialQuery`):\n * start in whatever mode the user picked there so the \"research from\n * home → research-shaped chat\" hand-off feels continuous.\n * • From ChatHistory (which intentionally does NOT pass `initialMode`):\n * default to `'chat'`, same as Home's empty composer.\n *\n * Post-mount this is a normal local state — the search/zap pills toggle\n * it on tap, and every place that previously branched on\n * `params.initialMode` now branches on `activeMode` instead.\n */\n const [activeMode, setActiveMode] = useState<RoutingMode>(() => routingModeOf(params.initialMode));\n const handleModeSwitch = useCallback((mode: RoutingMode) => {\n setActiveMode(mode);\n }, []);\n const isDeepSearchMode = activeMode === 'deep-search';\n const isBuildMode = activeMode === 'build';\n\n /**\n * Inline voice recorder state — parity with HomeScreen and the web\n * `YantraSearchComposer.showAudioRecorder` flow. When active, the panel\n * fully replaces the InputToolBar so the toolbar's mic→send button\n * doesn't compete with the panel's own send/cancel affordances.\n */\n const [showAudioRecorder, setShowAudioRecorder] = useState(false);\n // Apple on-device dictation (the iOS-built-in mic) is preferred when the\n // binary has it; the Whisper recorder above is the fallback.\n const [showNativeDictation, setShowNativeDictation] = useState(false);\n const [voiceError, setVoiceError] = useState<string | null>(null);\n\n /**\n * The first turn of a chat opened with a prompt (Home, a template, a hand-off).\n *\n * Its bubble is already on screen (the routing turn above). Routing starts at\n * once - it needs the brain, not the gateway - and either hands the ask to Shop\n * or another app's screen, or marks it for this chat. The send then waits for\n * CDeCLI to connect (or fail: the send lane parks a turn it cannot deliver),\n * because chat is cdecli-only.\n */\n const autoFiredRef = useRef(false);\n const firstTurnRef = useRef<{ text: string; attachments?: MessageAttachment[] } | null>(null);\n const [firstTurnRouted, setFirstTurnRouted] = useState(false);\n useEffect(() => {\n if (autoFiredRef.current) return;\n if (!channelId) return;\n const stashed = hasComposerAttachments(channelId) ? takeComposerAttachments(channelId) : undefined;\n const attachments = stashed?.length ? stashed : normalizeRouteAttachments(initialAttachments);\n if (!initialQuery && !attachments?.length) return;\n\n autoFiredRef.current = true;\n firstTurnRef.current = { text: initialQuery ?? '', attachments };\n if (isDeepSearchMode) {\n setIsDeepSearchModalOpen(true);\n }\n void (async () => {\n const mode = modeOf(isDeepSearchMode, isBuildMode);\n // Both checks at once: they share one brain classify, so a brain that is\n // down costs this turn one timeout, not one per check.\n const [openShop, nativeRoute] = shopRouteChecked\n ? [false, null]\n : await Promise.all([\n shouldRedirectToShop(initialQuery ?? '', attachments?.length ?? 0, mode).catch(() => false),\n resolveNativeHandoff(initialQuery ?? '', { mode }),\n ]);\n if (openShop) {\n firstTurnRef.current = null;\n releaseRoutingTurn(FIRST_TURN);\n replaceWithShopNative(\n navigation,\n shopHandoffParams({\n orgName: params.orgName,\n query: initialQuery ?? '',\n files: attachments,\n // Nothing was sent here yet: Shop carries on in this chat.\n channelId,\n }),\n );\n return;\n }\n if (nativeRoute) {\n firstTurnRef.current = null;\n releaseRoutingTurn(FIRST_TURN);\n replaceWithNativeApp(\n navigation,\n nativeRoute,\n nativeHandoffParams({\n orgName: params.orgName,\n query: initialQuery ?? '',\n files: attachments,\n channelId,\n }),\n );\n return;\n }\n setFirstTurnRouted(true);\n })();\n try {\n navigation.setParams({ initialQuery: null, initialAttachments: null });\n } catch {\n /* setParams may be unavailable in tests; clearing is best-effort. */\n }\n }, [\n channelId,\n initialQuery,\n initialAttachments,\n navigation,\n isDeepSearchMode,\n isBuildMode,\n params.orgName,\n shopRouteChecked,\n releaseRoutingTurn,\n ]);\n\n useEffect(() => {\n const turn = firstTurnRef.current;\n if (!firstTurnRouted || !turn || !channelId) return;\n if (cdecli.status !== 'connected' && cdecli.status !== 'error') return;\n firstTurnRef.current = null;\n // One update: the send lane's bubble replaces the routing one, no gap between.\n releaseRoutingTurn(FIRST_TURN);\n void sendMessage(turn.text, turn.attachments, channelId);\n }, [firstTurnRouted, cdecli.status, channelId, sendMessage, releaseRoutingTurn]);\n\n /**\n * Answer a parked `[ASK_USER]` question. The formatted `**Title:** answer`\n * block goes out as an ordinary user message — cdecli absorbs it into the\n * turn it parked, which is what releases the run. Deliberately NOT routed\n * through handleSend: no deep-search/build-mode rewriting, no attachments,\n * and it must send even while the turn is still streaming.\n */\n const handleAskUserAnswer = useCallback(\n (formatted: string) => {\n const text = formatted.trim();\n if (!text) return;\n void sendMessage(text, undefined, channelId);\n },\n [sendMessage, channelId],\n );\n\n const [resolvedAskIds, setResolvedAskIds] = useState<Record<string, boolean>>({});\n const pendingAsk = useMemo(\n () =>\n pendingAskUser([\n ...transcriptRows,\n ...(response?.trim() ? [{ role: 'assistant', content: response }] : []),\n ]),\n [transcriptRows, response],\n );\n const showAskCard = Boolean(pendingAsk && !resolvedAskIds[pendingAsk.requestId]);\n\n /**\n * Answer a `[CONNECTOR_CONNECT]` card (a login to save, a connector to connect).\n * Like the ASK_USER answer it skips handleSend's mode rewriting: the\n * `[CONNECTOR_CONNECTED:<requestId>:<credentialId>]` reply goes out as is, names\n * the saved credential so the agent can sign in with it at once, and the\n * transcript hides it (it is protocol, not something the user said).\n */\n const sendConnectorReply = useCallback(\n async (text: string): Promise<boolean> => {\n if (!channelId) return false;\n return (await sendMessage(text, undefined, channelId)) !== 'failed';\n },\n [sendMessage, channelId],\n );\n // The transcript shows the thread without the protocol: the card stands in for\n // the marker, and its reply is not something the user said. Ids are kept, so\n // regenerate-from-row still indexes chat.messages.\n const transcriptDisplayRows = useMemo(() => displayConnectorConnectMessages(transcriptRows), [transcriptRows]);\n const transcriptStreaming = useMemo(\n () => (response ? displayConnectorConnectText(response, true) : response),\n [response],\n );\n\n // A turn after an answer is a follow-up: the brain must be near-certain to move it to an app.\n const hasAssistantReply = useMemo(() => messages.some((m) => m.role === 'assistant'), [messages]);\n\n const handleSend = useCallback(\n (text?: string) => {\n const pending = imageAttachments.forSend();\n const t = (text ?? valueRef.current).trim();\n if ((!t && !pending?.length) || !channelId) return;\n // Clear both ways: the controlled state (so React's model stays\n // consistent on next render) AND the native buffer via the ref\n // (so the visible text disappears on the same frame the user\n // pressed send, even before React flushes).\n setValue('');\n inputRef.current?.clear();\n\n // Build mode: hand the ask to the native Web Builder's agent (web `/c/:id/webbuilder`).\n if (isBuildMode) {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.WebBuilderNative',\n params: nativeHandoffParams({ orgName: params.orgName, query: t, files: pending }),\n }),\n );\n return;\n }\n\n // Deep-search mode: every new query pops the structured research\n // modal back open (parity with the previous Home flow, where every\n // submit re-opened the DeepSearchModal). Without this, a user who\n // closed the modal once would see plain assistant turns for every\n // subsequent send. Reads the LOCAL `isDeepSearchMode` so the user\n // can toggle modes mid-thread and have sends behave accordingly.\n if (isDeepSearchMode) {\n setIsDeepSearchModalOpen(true);\n }\n const turnId = `turn-${(routingSeqRef.current += 1)}`;\n setRoutingTurns((prev) => [\n ...prev,\n { id: turnId, text: t, attachments: pending, placement: chatBusy ? 'queue' : 'thread' },\n ]);\n void (async () => {\n const mode = isDeepSearchMode ? 'deep-search' : 'chat';\n // Both checks at once (one shared brain classify). Mid-conversation the\n // brain must be near-certain before the ask leaves the thread.\n const [openShop, nativeRoute] = await Promise.all([\n // `forSend()` is undefined with nothing attached; `.length` on it threw,\n // so a typed shopping ask never reached Shop.\n shouldRedirectToShop(t, pending?.length ?? 0, mode).catch(() => false),\n resolveNativeHandoff(t, { mode, followUp: hasAssistantReply }),\n ]);\n if (openShop) {\n releaseRoutingTurn(turnId);\n if (messages.length === 0) {\n // An empty thread is replaced, so Shop carries on in it.\n replaceWithShopNative(\n navigation,\n shopHandoffParams({ orgName: params.orgName, query: t, files: pending, channelId }),\n );\n } else {\n pushShopNative(\n navigation,\n shopHandoffParams({ orgName: params.orgName, query: t, files: pending }),\n );\n }\n return;\n }\n if (nativeRoute) {\n releaseRoutingTurn(turnId);\n if (messages.length === 0) {\n replaceWithNativeApp(\n navigation,\n nativeRoute,\n nativeHandoffParams({ orgName: params.orgName, query: t, files: pending, channelId }),\n );\n } else {\n pushNativeApp(\n navigation,\n nativeRoute,\n nativeHandoffParams({ orgName: params.orgName, query: t, files: pending }),\n );\n }\n return;\n }\n releaseRoutingTurn(turnId);\n void sendMessage(t, pending, channelId);\n })();\n imageAttachments.clear();\n },\n [\n channelId,\n sendMessage,\n isDeepSearchMode,\n isBuildMode,\n navigation,\n params.orgName,\n imageAttachments,\n messages.length,\n hasAssistantReply,\n chatBusy,\n releaseRoutingTurn,\n ],\n );\n\n const handleValueChange = useCallback((e: { nativeEvent?: { text?: string } } | undefined) => {\n setValue(e?.nativeEvent?.text ?? '');\n }, []);\n\n /**\n * Mic affordance — web parity (`handleMicClick` in `YantraSearchComposer.tsx`).\n * The shared `MicSendButton` in `InputToolBar.tsx` only routes to `onMic`\n * when the input has no content, so we only need to handle the empty-input\n * case here.\n *\n * Permission is requested HERE, before the panel mounts. The previous flow\n * flipped `showAudioRecorder=true` immediately, which mounted\n * `AudioRecorderPanel` and constructed the native `AVAudioRecorder` via\n * `useAudioRecorder()` during the panel's render phase — before iOS had\n * granted mic access. On SDK 53 + `newArchEnabled: true` + Hermes that\n * ordering hard-crashes TestFlight builds even though it works in Expo Go\n * (Expo Go pre-caches permission). Asking up front means iOS shows the\n * system alert first and the panel only mounts (and therefore the native\n * recorder is only allocated) once permission is granted.\n *\n * `expo-audio` is lazy-imported so a missing/broken native module surfaces\n * as a user-visible banner instead of a synchronous TurboModule crash.\n */\n /** Open the record -> Whisper recorder (the fallback mic lane). */\n const openWhisperRecorder = useCallback(() => {\n setVoiceError(null);\n void (async () => {\n const { granted, error } = await requestMicPermission();\n if (!granted) {\n setVoiceError(error || 'Microphone is not available.');\n return;\n }\n setShowAudioRecorder(true);\n })();\n }, []);\n\n const handleMicPress = useCallback(() => {\n if (hasQuery) return;\n setVoiceError(null);\n Keyboard.dismiss();\n // Prefer Apple's on-device dictation (the iOS-built-in mic): it streams\n // text live and needs no upload. The bar requests its own permission\n // and calls back to the Whisper recorder if the native path is\n // unusable. Only reachable on a build that linked the native module.\n if (isNativeDictationAvailable()) {\n setShowNativeDictation(true);\n return;\n }\n openWhisperRecorder();\n }, [hasQuery, openWhisperRecorder]);\n\n /**\n * On a successful Whisper round-trip, paste the transcript into the input\n * field, close the recorder, and let the user review/send manually. Matches\n * web's `handleTranscriptionComplete`: we deliberately do NOT auto-fire\n * `sendMessage` because the user often wants to edit the dictation first.\n */\n /** Append a finished transcript to the composer and re-focus it. Shared by\n * the Whisper recorder and native dictation. */\n const pasteTranscript = useCallback((text: string) => {\n const cleaned = (text ?? '').trim();\n if (!cleaned) return;\n setValue((prev) => {\n const next = prev.trim().length > 0 ? `${prev.trim()} ${cleaned}` : cleaned;\n /*\n * Keep `inputRef`'s native text in sync with our controlled value\n * for the same reason `handleSend` does (the iOS native buffer\n * can lag the React state across a single gesture). `setNativeProps`\n * is the safe way to do this without re-rendering.\n */\n requestAnimationFrame(() => {\n inputRef.current?.setNativeProps?.({ text: next });\n inputRef.current?.focus?.();\n });\n return next;\n });\n }, []);\n\n const handleTranscriptionComplete = useCallback(\n (text: string) => {\n setShowAudioRecorder(false);\n pasteTranscript(text);\n },\n [pasteTranscript],\n );\n\n const handleRecorderCancel = useCallback(() => {\n setShowAudioRecorder(false);\n }, []);\n\n const handleDictationComplete = useCallback(\n (text: string) => {\n setShowNativeDictation(false);\n pasteTranscript(text);\n },\n [pasteTranscript],\n );\n\n const handleDictationCancel = useCallback(() => setShowNativeDictation(false), []);\n\n /** Native dictation could not run - drop to the Whisper recorder, which\n * requests its own permission and surfaces its own errors. */\n const handleDictationFallback = useCallback(() => {\n setShowNativeDictation(false);\n openWhisperRecorder();\n }, [openWhisperRecorder]);\n\n const handleRecorderError = useCallback((error: string) => {\n setVoiceError(error);\n }, []);\n\n const waitingForAssistant = useMemo(() => {\n if ((!isLoading && !isStreaming) || messages.length === 0) return false;\n if ((response ?? '').trim()) return false;\n return messages[messages.length - 1]?.role === 'user';\n }, [isLoading, isStreaming, messages, response]);\n\n /*\n * NOTE: the previous read-only `isDeepSearchChannel` derivation has been\n * removed. Mode is now a freely-toggleable local state (`activeMode`)\n * driven by tapping the search/zap pills, mirroring HomeScreen. All\n * downstream branches use `isDeepSearchMode` declared with the rest of\n * the composer state above.\n */\n\n /**\n * Deep-search overlay state.\n *\n * Restored from the previous Home-screen flow (commit history): a deep-search\n * channel renders the structured `DeepSearchModal` (query / live summary /\n * sources / research process) on top of the regular Chat conversation. Closing\n * the modal reveals the same channel's transcript underneath so the\n * user can still see the raw turns.\n *\n * Trigger semantics — IMPORTANT:\n * • Opens ONLY when a request is actually fired in this session:\n * - Home → Chat auto-fire of `initialQuery`\n * - User sends a new message in a deep-search channel from the composer\n * - Explicit retry from inside the modal\n * • Does NOT open on plain entry from ChatHistoryScreen. That's a revisit\n * of an already-completed thread — no new API call, nothing live to\n * stream, so popping the modal would just be a confusing flash. The\n * user still sees the deep-search rendering in the chat conversation\n * underneath, and any new send re-opens the live view.\n *\n * Local UI state (accordions, open flag) lives here; data state (query /\n * summary / sources) is DERIVED from the chat stream, not stored separately,\n * so there's no drift between the modal and the underlying conversation.\n */\n const [isDeepSearchModalOpen, setIsDeepSearchModalOpen] = useState(false);\n const [researchProcessOpen, setResearchProcessOpen] = useState(true);\n const [sourcesAccordionOpen, setSourcesAccordionOpen] = useState(true);\n\n /**\n * Modal data is always scoped to the CURRENT run, not the whole channel.\n * In a multi-turn deep-search channel each send is its own \"run\": one user\n * query → one assistant summary. If we sourced from \"first user message\" /\n * \"any assistant message\", a follow-up send would keep showing the previous\n * run's query and stale sources during the transient window between the new\n * user message being appended and the first stream token arriving.\n *\n * Cursor: the LAST user message in the thread. The assistant content for\n * the current run is either:\n * • `response` while the stream is filling (token-by-token), OR\n * • the assistant message that comes AFTER the last user (run complete), OR\n * • empty — covers the brief \"user message appended, no response yet\"\n * window so the modal flips to \"Running...\" with no stale body.\n */\n const lastUserIndex = useMemo(() => {\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n if (messages[i]?.role === 'user') return i;\n }\n return -1;\n }, [messages]);\n\n const deepSearchQuery = useMemo(() => {\n if (lastUserIndex >= 0) {\n const txt = messages[lastUserIndex]?.content?.trim();\n if (txt) return txt;\n }\n return initialQuery ?? null;\n }, [messages, lastUserIndex, initialQuery]);\n\n const latestAssistantContent = useMemo(() => {\n if (response && response.trim()) return response;\n if (lastUserIndex < 0) return '';\n // Look for an assistant turn strictly AFTER the last user message.\n // Anything before it belongs to a prior run and must not leak into\n // the modal for the current one.\n for (let i = lastUserIndex + 1; i < messages.length; i += 1) {\n if (messages[i]?.role === 'assistant') {\n // The summary is the agent's answer, not the quick answer framed in front of it.\n return splitPreResponse(messages[i]?.content).text;\n }\n }\n return '';\n }, [response, messages, lastUserIndex]);\n\n const deepSearchSummary = useMemo(() => normalizeSummaryText(latestAssistantContent), [latestAssistantContent]);\n const deepSearchSources: DeepSearchSourceItem[] = useMemo(\n () => extractDeepSearchSources(latestAssistantContent),\n [latestAssistantContent],\n );\n\n const handleDeepSearchClose = useCallback(() => {\n if (isStreaming) cancel();\n setIsDeepSearchModalOpen(false);\n }, [isStreaming, cancel]);\n\n const handleDeepSearchRetry = useCallback(() => {\n if (!deepSearchQuery || isStreaming || !channelId) return;\n void sendMessage(deepSearchQuery, undefined, channelId);\n }, [deepSearchQuery, isStreaming, channelId, sendMessage]);\n const leftItems = useMemo(\n () =>\n getDefaultLeftItems({\n search: { active: activeMode === 'chat', onClick: () => handleModeSwitch('chat') },\n zap: { active: activeMode === 'deep-search', onClick: () => handleModeSwitch('deep-search') },\n lightbulb: {\n active: activeMode === 'build',\n onClick: () => handleModeSwitch('build'),\n },\n }),\n [activeMode, handleModeSwitch],\n );\n const inputPlaceholder = PLACEHOLDER[modeOf(isDeepSearchMode, isBuildMode)];\n\n const inputConfig = useMemo(\n () => ({\n value,\n onChange: handleValueChange,\n placeholder: inputPlaceholder,\n disabled: !channelId,\n inputRef,\n returnKeyType: 'send',\n blurOnSubmit: false,\n onSubmitEditing: () => handleSend(),\n }),\n [value, handleValueChange, inputPlaceholder, channelId, handleSend],\n );\n const micSendButton = useMemo(\n () => ({\n hasContent: hasQuery || hasAttachments,\n onSend: () => handleSend(),\n onMic: handleMicPress,\n disabled: !channelId,\n // Empty + streaming → Stop. Typed follow-up → Send (queued for the agent). Never lock the composer.\n isLoading: canSubmit ? false : isLoading,\n onStop: isStreaming && !canSubmit ? cancel : undefined,\n steerable: isLoading || isStreaming,\n }),\n [canSubmit, handleSend, handleMicPress, isLoading, channelId, isStreaming, cancel, hasQuery, hasAttachments],\n );\n\n // With messages parked, the outbox notice above already says the gateway is not\n // there and that they go out once it is; its connect error said \"please send\n // again\" beside it - the opposite of what happens.\n const bannerError = chatError || (queuedMessages.length > 0 ? null : cdecli.error);\n\n // A turn sent mid-reply waits above the composer from the tap, while it is routed.\n const followUpsAboveComposer = useMemo(\n () => [\n ...queuedFollowUps,\n ...routingTurns\n .filter((turn) => turn.placement === 'queue')\n .map((turn) => ({ id: `routing-${turn.id}`, text: turn.text, attachments: turn.attachments })),\n ],\n [queuedFollowUps, routingTurns],\n );\n const cancelFollowUpAboveComposer = useCallback(\n (id: string) => {\n // Still being routed: nothing reached the gateway to cancel.\n if (id.startsWith('routing-')) return;\n void cancelQueuedFollowUp(id);\n },\n [cancelQueuedFollowUp],\n );\n\n // Queue affordances: the gateway is live, so a queue that is still sitting there\n // failed its release and the user gets a manual retry beside the discard.\n const gatewayLive = cdecli.channelConnected;\n // The gateway is down (they wait for it), or it is up and their own send failed.\n const queuedCount = queuedMessages.length === 1 ? '1 message' : `${queuedMessages.length} messages`;\n let queuedNotice = `${queuedCount} waiting for the gateway. They send as soon as it connects.`;\n if (gatewayLive) queuedNotice = `${queuedCount} not sent yet${outboxRetrying ? ' - trying again' : ''}.`;\n const queuedActionColor = isDark ? '#fbbf24' : '#b45309';\n const handleSendQueuedNow = useCallback(() => {\n void flushQueuedMessages();\n }, [flushQueuedMessages]);\n\n /**\n * Loader visibility. A turn the user just sent is never hidden behind one: while\n * it is routed, and while CDeCLI connects for it, it shows in the thread with the\n * thinking indicator under it.\n * - `isHydrating`: Apollo channel history is being fetched and we have nothing to show yet.\n */\n const routingInThread = routingTurns.some((turn) => turn.placement === 'thread');\n const isHydrating =\n messagesLoading && messages.length === 0 && !response && !quickReply && !isStreaming && !routingInThread;\n const showSendingLoader = waitingForAssistant || routingInThread;\n const pinSendingLoaderNearComposer = messages.length > 0 || Boolean((response ?? '').trim()) || routingInThread;\n\n // One of three states fills the transcript area, in this order of precedence.\n let transcriptArea: React.ReactNode;\n if (!channelId) {\n transcriptArea = (\n <Box flex={1} alignItems=\"center\" justifyContent=\"center\">\n <YantraBrandLoader size={YANTRA_LOADER_SIZE_COMPACT} />\n <Text style={[styles.statusText, { color: secondaryTextColor }]}>No channel selected</Text>\n </Box>\n );\n } else if (isHydrating) {\n transcriptArea = (\n <Box flex={1} px=\"$4\" pt=\"$8\">\n <ThinkingIndicator\n variant=\"awaiting\"\n color={secondaryTextColor}\n isDark={isDark}\n label=\"Opening conversation…\"\n />\n </Box>\n );\n } else {\n transcriptArea = (\n // Links in the transcript open in the app on their surface, or in a browser sheet.\n <ChatLinkOpenerProvider>\n <View style={styles.transcriptPane}>\n <ChatTranscript\n messages={transcriptDisplayRows}\n streamingContent={transcriptStreaming}\n quickReply={quickReply}\n listFooter={\n showSendingLoader && pinSendingLoaderNearComposer ? (\n <View style={styles.thinkingInThread}>\n <ThinkingIndicator variant=\"awaiting\" color={secondaryTextColor} isDark={isDark} />\n </View>\n ) : null\n }\n renderMessageActions={renderMessageActions}\n isDark={isDark}\n listContentStyle={{\n paddingTop: 12,\n paddingBottom: 8,\n margin: 0,\n width: contentMaxWidth,\n alignSelf: 'center',\n }}\n />\n </View>\n </ChatLinkOpenerProvider>\n );\n }\n\n // The composer row is the dictation bar, the recorder, or the input - never two at once.\n let composerBody: React.ReactNode;\n if (showNativeDictation) {\n composerBody = (\n // A throw inside the native recognizer degrades to\n // the Whisper recorder rather than killing the JS\n // thread (same guard rationale as the recorder).\n <MicErrorBoundary onCancel={handleDictationFallback} onError={handleDictationFallback}>\n <NativeDictationBar\n isDark={isDark}\n onInterim={() => undefined}\n onTranscriptionComplete={handleDictationComplete}\n onCancel={handleDictationCancel}\n onFallback={handleDictationFallback}\n />\n </MicErrorBoundary>\n );\n } else if (showAudioRecorder) {\n composerBody = (\n /*\n * Render-time JS errors thrown by `useAudioRecorder`\n * (e.g. expo-audio native module missing, recorder\n * constructor throws in a release build) are caught\n * by the boundary and converted into a soft cancel\n * via the same handlers the panel itself uses on\n * runtime errors. Without this, a throw during the\n * panel's render phase kills the JS thread in\n * release / TestFlight.\n */\n <MicErrorBoundary onCancel={handleRecorderCancel} onError={handleRecorderError}>\n <AudioRecorderPanel\n isDark={isDark}\n onTranscriptionComplete={handleTranscriptionComplete}\n onCancel={handleRecorderCancel}\n onError={handleRecorderError}\n />\n </MicErrorBoundary>\n );\n } else {\n composerBody = (\n <>\n <ComposerAttachmentBar\n attachments={imageAttachments.pending}\n onRemove={imageAttachments.remove}\n isDark={isDark}\n />\n <InputToolBar\n inputConfig={inputConfig}\n leftItems={leftItems}\n rightItems={rightItems}\n templateButton={null}\n templateModalConfig={null}\n micSendButton={micSendButton}\n />\n </>\n );\n }\n\n return (\n <SafeAreaView edges={['left', 'right']} style={{ flex: 1, backgroundColor: surfaceColor }}>\n <KeyboardAwareScreen>\n <View style={styles.chatColumn}>\n {queuedMessages.length > 0 && (\n <Box\n mb=\"$2\"\n mx=\"$4\"\n p=\"$3\"\n borderRadius=\"$md\"\n style={{\n backgroundColor: isDark ? '#2a2113' : '#fffbeb',\n borderWidth: 1,\n borderColor: isDark ? '#78350f' : '#fde68a',\n flexDirection: 'row',\n alignItems: 'center',\n }}\n >\n <Text fontSize=\"$sm\" style={{ color: isDark ? '#fde68a' : '#92400e', flex: 1 }}>\n {queuedNotice}\n </Text>\n {gatewayLive ? (\n <Pressable onPress={handleSendQueuedNow} hitSlop={8} style={styles.queuedAction}>\n <Text\n fontSize=\"$xs\"\n style={[styles.queuedActionText, { color: queuedActionColor }]}\n >\n Send now\n </Text>\n </Pressable>\n ) : null}\n <Pressable onPress={discardQueuedMessages} hitSlop={8} style={styles.queuedAction}>\n <Text fontSize=\"$xs\" style={[styles.queuedActionText, { color: queuedActionColor }]}>\n Discard\n </Text>\n </Pressable>\n </Box>\n )}\n {bannerError && (\n <Box\n mb=\"$2\"\n mx=\"$4\"\n p=\"$3\"\n borderRadius=\"$md\"\n style={{\n backgroundColor: isDark ? '#2b1a1d' : '#fef2f2',\n borderWidth: 1,\n borderColor: isDark ? '#7f1d1d' : '#fecaca',\n }}\n >\n <Text fontSize=\"$sm\" style={{ color: isDark ? '#fecaca' : '#991b1b' }}>\n {bannerError}\n </Text>\n </Box>\n )}\n {transcriptArea}\n {showSendingLoader && !pinSendingLoaderNearComposer ? (\n <View pointerEvents=\"none\" style={styles.sendingLoaderEmptyState}>\n <ThinkingIndicator variant=\"awaiting\" color={secondaryTextColor} isDark={isDark} />\n </View>\n ) : null}\n <KeyboardComposerDock closedInset={insets.bottom} onSwipeUp={() => inputRef.current?.focus()}>\n {showAskCard && pendingAsk ? (\n <View style={{ width: contentMaxWidth, paddingHorizontal: 8 }}>\n <AskUserCard\n payload={pendingAsk}\n isDark={isDark}\n onAnswer={(formatted) => {\n setResolvedAskIds((prev) => ({ ...prev, [pendingAsk.requestId]: true }));\n handleAskUserAnswer(formatted);\n }}\n onDismiss={() =>\n setResolvedAskIds((prev) => ({ ...prev, [pendingAsk.requestId]: true }))\n }\n />\n </View>\n ) : null}\n {showAskCard ? null : (\n <PendingConnectorConnectCard\n messages={transcriptRows}\n send={sendConnectorReply}\n isDark={isDark}\n style={{ width: contentMaxWidth, paddingHorizontal: 8 }}\n />\n )}\n <View style={{ width: contentMaxWidth }}>\n <QueuedFollowUps\n items={followUpsAboveComposer}\n onCancel={cancelFollowUpAboveComposer}\n onSendNow={sendQueuedNow}\n isDark={isDark}\n />\n </View>\n <View style={[styles.bottomComposerInner, { width: contentMaxWidth }]}>\n {voiceError || imageAttachments.error ? (\n <View\n style={[\n styles.voiceErrorBanner,\n {\n backgroundColor: isDark ? '#2b1a1d' : '#fef2f2',\n borderColor: isDark ? '#7f1d1d' : '#fecaca',\n },\n ]}\n >\n <Text style={[styles.voiceErrorText, { color: isDark ? '#fecaca' : '#991b1b' }]}>\n {voiceError || imageAttachments.error}\n </Text>\n </View>\n ) : null}\n {composerBody}\n </View>\n </KeyboardComposerDock>\n </View>\n </KeyboardAwareScreen>\n {isDeepSearchMode ? (\n <DeepSearchModal\n visible={isDeepSearchModalOpen}\n query={deepSearchQuery}\n summaryText={deepSearchSummary}\n sources={deepSearchSources}\n isStreaming={isStreaming}\n researchProcessOpen={researchProcessOpen}\n sourcesAccordionOpen={sourcesAccordionOpen}\n onToggleResearchProcess={() => setResearchProcessOpen((prev) => !prev)}\n onToggleSourcesAccordion={() => setSourcesAccordionOpen((prev) => !prev)}\n onRetry={handleDeepSearchRetry}\n onStop={cancel}\n onClose={handleDeepSearchClose}\n />\n ) : null}\n {attachMenu}\n </SafeAreaView>\n );\n}\n\nconst styles = StyleSheet.create({\n chatColumn: {\n flex: 1,\n width: '100%',\n },\n transcriptPane: {\n flex: 1,\n minHeight: 0,\n width: '100%',\n },\n statusText: {\n marginTop: 14,\n fontSize: 13,\n fontWeight: '500',\n },\n bottomComposerInner: {\n paddingHorizontal: 14,\n paddingTop: 10,\n paddingBottom: 0,\n },\n voiceErrorBanner: {\n marginBottom: 8,\n paddingHorizontal: 12,\n paddingVertical: 8,\n borderRadius: 10,\n borderWidth: 1,\n },\n voiceErrorText: {\n fontSize: 12,\n fontWeight: '500',\n },\n sendingLoaderEmptyState: {\n position: 'absolute',\n left: 0,\n right: 0,\n top: 24,\n paddingHorizontal: 20,\n zIndex: 40,\n },\n queuedAction: {\n paddingHorizontal: 8,\n paddingVertical: 2,\n },\n queuedActionText: {\n fontWeight: '600',\n },\n thinkingInThread: {\n paddingHorizontal: 12,\n paddingTop: 10,\n paddingBottom: 4,\n },\n});\n"],"names":["_a"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/screens/Chat/index.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport { Keyboard, Pressable, StyleSheet, TextInput, View, useWindowDimensions } from 'react-native';\nimport { Box, InputToolBar, Text, getDefaultLeftItems } from '@admin-layout/gluestack-ui-mobile';\nimport { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';\nimport {\n useNavigation,\n useRoute,\n CommonActions,\n type NavigationProp,\n type ParamListBase,\n type RouteProp,\n} from '@react-navigation/native';\nimport { MessageActionBar } from '../../features/chat/MessageActionBar';\nimport { ChatTranscript } from '../../features/chat/ChatTranscript';\nimport { ChatLinkOpenerProvider } from '../../features/links/ChatLinkOpenerProvider';\nimport { AskUserCard } from '../../features/chat/AskUserCard';\nimport { pendingAskUser } from '../../features/chat/askUser';\nimport { PendingConnectorConnectCard } from '../../features/chat/ConnectorConnectPrompt';\nimport { QueuedFollowUps } from '../../features/chat/QueuedFollowUps';\nimport { displayConnectorConnectMessages, displayConnectorConnectText } from '../../features/chat/connectorConnect';\nimport { splitPreResponse } from '../../features/chat/preResponse';\nimport { useCdecliConnection } from '../../contexts/CdecliConnectionContext';\nimport { useChatLiveStream } from '../../contexts/ChatLiveStreamContext';\nimport type { MessageAttachment } from '../../hooks/useChatStream';\nimport { KeyboardAwareScreen, KeyboardComposerDock } from '../../components/KeyboardComposerDock';\nimport { YantraBrandLoader, YANTRA_LOADER_SIZE_COMPACT } from '../../components/YantraBrandLoader';\nimport ThinkingIndicator from '../../components/ThinkingIndicator';\nimport { mobileTokens } from '../../theme/mobileTokens';\nimport { useAppTheme } from '../../theme/AppThemeProvider';\nimport DeepSearchModal from '../Home/components/DeepSearchModal';\nimport { extractDeepSearchSources, normalizeSummaryText, type DeepSearchSourceItem } from '../Home/deepSearchUtils';\nimport type { ModeSubmission, RoutingMode } from '../Home/types';\nimport { AudioRecorderPanel } from '../../features/audio-input/AudioRecorderPanel';\nimport { NativeDictationBar } from '../../features/audio-input/NativeDictationBar';\nimport { isNativeDictationAvailable } from '../../features/audio-input/nativeDictation';\nimport { useImageAttachments } from '../../features/attachments/useImageAttachments';\nimport { ComposerAttachmentBar } from '../../features/attachments/ComposerAttachmentBar';\nimport { useComposerAttachMenu } from '../../features/attachments/ComposerAttachMenu';\nimport {\n hasComposerAttachments,\n peekComposerAttachments,\n takeComposerAttachments,\n} from '../../features/attachments/composerAttachmentHandoff';\nimport { MicErrorBoundary } from '../../features/audio-input/MicErrorBoundary';\nimport { requestMicPermission } from '../../features/audio-input/useAudioPermission';\nimport { shouldRedirectToShop } from '../../features/shopping/chat/homeShoppingIntent';\nimport { pushShopNative, replaceWithShopNative, shopHandoffParams } from '../../features/shopping/chat/openShopNative';\nimport { nativeRouteForConnectors, resolveNativeHandoff } from '../../features/apps/nativeAppHandoff';\nimport { parseToolActivity } from '../../features/chat/toolActivity';\nimport { nativeHandoffParams, pushNativeApp, replaceWithNativeApp } from '../../features/apps/nativeAppNavigation';\n\n/** Route params passed by Home (or by deep-link) when entering the Chat surface. */\nexport interface ChatScreenRouteParams {\n /** Channel id is required — the screen is keyed on the conversation. */\n channelId: string;\n /** Org slug used by gateway/account context. */\n orgName?: string | null;\n /**\n * First user message to auto-fire when the screen mounts. Home generates\n * this when the user submits from the empty composer so the assistant\n * starts streaming on Chat without an extra round trip.\n */\n initialQuery?: string | null;\n /**\n * Seed for the composer's mode (`'chat'` | `'deep-search'` | `'build'`).\n *\n * Set by `HomeScreen` to carry the user's last selection across the\n * navigation hop (\"research from home → research-shaped composer on chat\").\n * `ChatHistoryScreen` does NOT forward this — revisits always land on the\n * default `'chat'` mode, matching Home's defaults, and the user is free to\n * switch from there. Build-mode send hands off to Web Builder.\n *\n * After mount, this param is purely a seed: the screen keeps its own\n * `activeMode` so the user can toggle freely while inside the thread.\n */\n initialMode?: RoutingMode;\n /** Optional attachments forwarded with the initial message. */\n initialAttachments?: ModeSubmission['attachments'];\n /**\n * Home already decided this first turn belongs in Chat, not Shop. The\n * auto-fire honours that instead of classifying the same text a second time.\n */\n shopRouteChecked?: boolean;\n}\n\n/** The mode a route param asks for; anything else is plain chat. */\nfunction routingModeOf(value: unknown): RoutingMode {\n if (value === 'deep-search' || value === 'build') return value;\n return 'chat';\n}\n\nfunction modeOf(isDeepSearchMode: boolean, isBuildMode: boolean): RoutingMode {\n if (isDeepSearchMode) return 'deep-search';\n if (isBuildMode) return 'build';\n return 'chat';\n}\n\n/** A sent turn on screen while the brain routes it (see `routingTurns`). */\ninterface RoutingTurn {\n id: string;\n text: string;\n attachments?: MessageAttachment[];\n /** In the thread, or above the composer when it was sent while the agent was busy. */\n placement: 'thread' | 'queue';\n}\n\nconst FIRST_TURN = 'first';\n\n/**\n * Route params carry the looser `ModeAttachment` (everything optional); the send\n * lane wants a `MessageAttachment`. Normalise once - `shopHandoffParams` takes the\n * narrower shape just as happily.\n */\nfunction normalizeRouteAttachments(\n attachments: ChatScreenRouteParams['initialAttachments'] | undefined,\n): MessageAttachment[] | undefined {\n return attachments?.map((a, index) => ({\n id: a.id ?? `att-${index}`,\n name: a.name ?? `attachment-${index + 1}`,\n type: a.type === 'screenshot' ? ('screenshot' as const) : ('file' as const),\n ...(a.mimeType ? { mimeType: a.mimeType } : {}),\n ...(a.size ? { size: a.size } : {}),\n ...((a.url ?? a.uri) ? { url: a.url ?? a.uri } : {}),\n ...(a.dataUrl ? { dataUrl: a.dataUrl } : {}),\n }));\n}\n\nconst PLACEHOLDER: Record<RoutingMode, string> = {\n 'deep-search': 'Research anything...',\n build: 'Describe an app to build...',\n chat: 'Ask anything...',\n};\n\nexport default function ChatScreen() {\n const navigation = useNavigation<NavigationProp<ParamListBase>>();\n const route = useRoute<RouteProp<Record<string, Partial<ChatScreenRouteParams> | undefined>, string>>();\n\n const params = (route?.params ?? {}) as Partial<ChatScreenRouteParams>;\n const channelId = useMemo(() => {\n const raw = typeof params.channelId === 'string' ? params.channelId.trim() : '';\n return raw.length > 0 ? raw : null;\n }, [params.channelId]);\n const initialQuery = useMemo(() => {\n const raw = typeof params.initialQuery === 'string' ? params.initialQuery.trim() : '';\n return raw.length > 0 ? raw : null;\n }, [params.initialQuery]);\n const { initialAttachments } = params;\n const shopRouteChecked = params.shopRouteChecked === true;\n\n const { isDark } = useAppTheme();\n const { width: screenWidth } = useWindowDimensions();\n const contentMaxWidth = Math.min(720, Math.max(360, screenWidth - 24));\n\n const surfaceColor = isDark ? '#0f172a' : mobileTokens.color.surface;\n const secondaryTextColor = isDark ? '#94a3b8' : mobileTokens.color.textMuted;\n\n const insets = useSafeAreaInsets();\n\n /**\n * Gateway + chat stream routing.\n *\n * The CDeCLI lifecycle is owned app-wide by `CdecliConnectionProvider`,\n * so we just register this screen's channelId and read the shared status.\n * This avoids racing `gatewayConnect` mutations with the header's\n * `GatewayConnector` (which previously ran its own `useCdecliAutoConnect`\n * and could clobber the chat session binding).\n */\n const cdecli = useCdecliConnection();\n const { setActiveChannelId } = cdecli;\n\n useLayoutEffect(() => {\n if (!channelId) return;\n setActiveChannelId(channelId);\n }, [channelId, setActiveChannelId]);\n\n const chat = useChatLiveStream();\n\n /**\n * Turns the user sent that are still being routed - the brain decides whether\n * each stays in this chat or moves to Shop or another app's screen. They show\n * from the tap, not from the routing decision or the gateway's answer: the\n * send lane takes each one over (or the hand-off does) in the same update that\n * drops it here. A turn sent while the agent is busy waits above the composer,\n * where the gateway's queued messages show; any other in the thread.\n */\n const [routingTurns, setRoutingTurns] = useState<RoutingTurn[]>(() =>\n initialQuery || initialAttachments?.length || peekComposerAttachments(channelId)?.length\n ? [\n {\n id: FIRST_TURN,\n text: initialQuery ?? '',\n attachments: peekComposerAttachments(channelId) ?? normalizeRouteAttachments(initialAttachments),\n placement: 'thread',\n },\n ]\n : [],\n );\n const releaseRoutingTurn = useCallback((id: string) => {\n setRoutingTurns((prev) => prev.filter((turn) => turn.id !== id));\n }, []);\n const routingSeqRef = useRef(0);\n\n /**\n * Gifted-shaped transcript rows, memoised on `messages` alone.\n *\n * This screen re-renders on every streamed token — `useChatStream` does\n * `setResponse((r) => r + text)` per delta. Building this array inline in\n * the JSX therefore handed `PlanModeView` a fresh `messages` identity on\n * every token, which invalidated its own `useMemo([messages, …])`, re-mapped\n * every row, and re-rendered every bubble. Assistant bubbles render through\n * `react-native-markdown-display`, so that meant re-parsing the markdown of\n * the whole thread once per token — O(messages) parses per delta, on the JS\n * thread, which is exactly when the UI has to stay responsive.\n *\n * `messages` is already stable upstream (`useChatApi` memoises it on the\n * Apollo result), so this only rebuilds when a message is actually added or\n * changed.\n */\n const transcriptRows = useMemo(() => {\n // A message the gateway queued is persisted as it is sent, so the next\n // backend hydration brings it into `messages` too. While it waits it\n // belongs above the composer, not in the thread: hide the newest user\n // rows that match what is still queued.\n const waiting = chat.queuedFollowUps.map((queued) => queued.text.trim());\n const hidden = new Set<number>();\n for (let i = chat.messages.length - 1; i >= 0 && waiting.length > 0; i -= 1) {\n const msg = chat.messages[i];\n const match = msg.role === 'user' ? waiting.indexOf((msg.content ?? '').trim()) : -1;\n if (match >= 0) {\n hidden.add(i);\n waiting.splice(match, 1);\n }\n }\n return [\n ...chat.messages.flatMap((msg, index) =>\n hidden.has(index)\n ? []\n : [\n {\n id: `msg-${index}-${msg.role}`,\n role: msg.role,\n content: msg.content,\n attachments: msg.attachments,\n metadata: (msg as { metadata?: unknown }).metadata,\n },\n ],\n ),\n // Turns typed while the gateway was down. They live in the outbox, not in\n // the thread, so they survive a backend hydration and an app restart - and\n // they are always the newest rows, so they belong at the end.\n ...chat.queuedMessages.map((queued) => ({\n id: `queued-${queued.id}`,\n role: 'user' as const,\n content: queued.text,\n attachments: queued.attachments,\n queued: true,\n // The gateway is there; this turn's own send failed.\n ...(cdecli.channelConnected\n ? { queuedNote: chat.outboxRetrying ? 'Not sent yet · trying again' : 'Not sent · tap Send now' }\n : {}),\n })),\n ...routingTurns\n .filter((turn) => turn.placement === 'thread')\n .map((turn) => ({\n id: `routing-${turn.id}`,\n role: 'user' as const,\n content: turn.text,\n attachments: turn.attachments,\n })),\n ];\n }, [\n chat.messages,\n chat.queuedMessages,\n chat.queuedFollowUps,\n chat.outboxRetrying,\n cdecli.channelConnected,\n routingTurns,\n ]);\n const {\n messages,\n response,\n quickReply,\n error: chatError,\n isLoading,\n isStreaming,\n messagesLoading,\n queuedMessages,\n outboxRetrying,\n flushQueuedMessages,\n discardQueuedMessages,\n queuedFollowUps,\n cancelQueuedFollowUp,\n sendQueuedNow,\n sendMessage,\n cancel,\n } = chat;\n\n /**\n * \"Try again\" on an assistant message: resend the nearest preceding user\n * prompt on the same channel. Row ids are `msg-<index>-<role>` (see\n * transcriptRows), so the transcript index comes straight out of the id.\n */\n const regenerateFrom = useCallback(\n (messageId: string) => {\n const match = /^msg-(\\d+)-assistant$/.exec(messageId);\n if (!match || !channelId) return;\n for (let i = Number(match[1]) - 1; i >= 0; i -= 1) {\n const prior = chat.messages[i];\n if (prior?.role === 'user' && (prior.content?.trim() || prior.attachments?.length)) {\n void chat.sendMessage(prior.content, prior.attachments, channelId);\n return;\n }\n }\n },\n [chat, channelId],\n );\n\n const chatBusy = isLoading || isStreaming;\n const renderMessageActions = useCallback(\n (message: { id: string; role: string; content: string }) =>\n message.role === 'assistant' ? (\n <MessageActionBar\n text={message.content}\n onRegenerate={chatBusy ? undefined : () => regenerateFrom(message.id)}\n />\n ) : null,\n [chatBusy, regenerateFrom],\n );\n\n const imageAttachments = useImageAttachments();\n const { rightItems, menu: attachMenu } = useComposerAttachMenu(imageAttachments, isDark);\n\n /*\n * Composer state — kept local so it doesn't leak across navigations.\n *\n * `valueRef` mirrors the controlled `value` so `handleSend` can read the\n * latest text without taking a dependency on it. Without this, `handleSend`\n * (and therefore `micSendButton.onSend`) would be recreated on every\n * keystroke, which is unnecessary churn for `InputToolBar`.\n *\n * `inputRef` is forwarded to InputToolBar's TextInput so we can call\n * `.clear()` imperatively after sending. On iOS, the native text buffer\n * can stay desynced from the controlled `value` for a frame when a state\n * update is followed by an async dispatch in the same gesture — the\n * \"send-and-clear\" race. The imperative clear closes that gap deterministically.\n */\n const [value, setValue] = useState('');\n const valueRef = useRef(value);\n valueRef.current = value;\n const inputRef = useRef<TextInput>(null);\n const trimmed = value.trim();\n const hasQuery = trimmed.length > 0;\n const hasAttachments = imageAttachments.pending.length > 0;\n const canSubmit = (hasQuery || hasAttachments) && Boolean(channelId);\n\n /**\n * Composer mode is FREELY user-controlled, mirroring `HomeScreen`.\n *\n * Seed:\n * • From Home (which forwards `initialMode` alongside `initialQuery`):\n * start in whatever mode the user picked there so the \"research from\n * home → research-shaped chat\" hand-off feels continuous.\n * • From ChatHistory (which intentionally does NOT pass `initialMode`):\n * default to `'chat'`, same as Home's empty composer.\n *\n * Post-mount this is a normal local state — the search/zap pills toggle\n * it on tap, and every place that previously branched on\n * `params.initialMode` now branches on `activeMode` instead.\n */\n const [activeMode, setActiveMode] = useState<RoutingMode>(() => routingModeOf(params.initialMode));\n const handleModeSwitch = useCallback((mode: RoutingMode) => {\n setActiveMode(mode);\n }, []);\n const isDeepSearchMode = activeMode === 'deep-search';\n const isBuildMode = activeMode === 'build';\n\n /**\n * Inline voice recorder state — parity with HomeScreen and the web\n * `YantraSearchComposer.showAudioRecorder` flow. When active, the panel\n * fully replaces the InputToolBar so the toolbar's mic→send button\n * doesn't compete with the panel's own send/cancel affordances.\n */\n const [showAudioRecorder, setShowAudioRecorder] = useState(false);\n // Apple on-device dictation (the iOS-built-in mic) is preferred when the\n // binary has it; the Whisper recorder above is the fallback.\n const [showNativeDictation, setShowNativeDictation] = useState(false);\n const [voiceError, setVoiceError] = useState<string | null>(null);\n\n /**\n * The first turn of a chat opened with a prompt (Home, a template, a hand-off).\n *\n * Its bubble is already on screen (the routing turn above). Routing starts at\n * once - it needs the brain, not the gateway - and either hands the ask to Shop\n * or another app's screen, or marks it for this chat. The send then waits for\n * CDeCLI to connect (or fail: the send lane parks a turn it cannot deliver),\n * because chat is cdecli-only.\n */\n const autoFiredRef = useRef(false);\n const firstTurnRef = useRef<{ text: string; attachments?: MessageAttachment[] } | null>(null);\n const [firstTurnRouted, setFirstTurnRouted] = useState(false);\n useEffect(() => {\n if (autoFiredRef.current) return;\n if (!channelId) return;\n const stashed = hasComposerAttachments(channelId) ? takeComposerAttachments(channelId) : undefined;\n const attachments = stashed?.length ? stashed : normalizeRouteAttachments(initialAttachments);\n if (!initialQuery && !attachments?.length) return;\n\n autoFiredRef.current = true;\n firstTurnRef.current = { text: initialQuery ?? '', attachments };\n if (isDeepSearchMode) {\n setIsDeepSearchModalOpen(true);\n }\n void (async () => {\n const mode = modeOf(isDeepSearchMode, isBuildMode);\n // Both checks at once: they share one brain classify, so a brain that is\n // down costs this turn one timeout, not one per check.\n const [openShop, nativeRoute] = shopRouteChecked\n ? [false, null]\n : await Promise.all([\n shouldRedirectToShop(initialQuery ?? '', attachments?.length ?? 0, mode).catch(() => false),\n resolveNativeHandoff(initialQuery ?? '', { mode }),\n ]);\n if (openShop) {\n firstTurnRef.current = null;\n releaseRoutingTurn(FIRST_TURN);\n replaceWithShopNative(\n navigation,\n shopHandoffParams({\n orgName: params.orgName,\n query: initialQuery ?? '',\n files: attachments,\n // Nothing was sent here yet: Shop carries on in this chat.\n channelId,\n }),\n );\n return;\n }\n if (nativeRoute) {\n firstTurnRef.current = null;\n releaseRoutingTurn(FIRST_TURN);\n replaceWithNativeApp(\n navigation,\n nativeRoute,\n nativeHandoffParams({\n orgName: params.orgName,\n query: initialQuery ?? '',\n files: attachments,\n channelId,\n }),\n );\n return;\n }\n setFirstTurnRouted(true);\n })();\n try {\n navigation.setParams({ initialQuery: null, initialAttachments: null });\n } catch {\n /* setParams may be unavailable in tests; clearing is best-effort. */\n }\n }, [\n channelId,\n initialQuery,\n initialAttachments,\n navigation,\n isDeepSearchMode,\n isBuildMode,\n params.orgName,\n shopRouteChecked,\n releaseRoutingTurn,\n ]);\n\n useEffect(() => {\n const turn = firstTurnRef.current;\n if (!firstTurnRouted || !turn || !channelId) return;\n if (cdecli.status !== 'connected' && cdecli.status !== 'error') return;\n firstTurnRef.current = null;\n // One update: the send lane's bubble replaces the routing one, no gap between.\n releaseRoutingTurn(FIRST_TURN);\n void sendMessage(turn.text, turn.attachments, channelId);\n }, [firstTurnRouted, cdecli.status, channelId, sendMessage, releaseRoutingTurn]);\n\n /**\n * Answer a parked `[ASK_USER]` question. The formatted `**Title:** answer`\n * block goes out as an ordinary user message — cdecli absorbs it into the\n * turn it parked, which is what releases the run. Deliberately NOT routed\n * through handleSend: no deep-search/build-mode rewriting, no attachments,\n * and it must send even while the turn is still streaming.\n */\n const handleAskUserAnswer = useCallback(\n (formatted: string) => {\n const text = formatted.trim();\n if (!text) return;\n // The agent is parked on this answer: it goes now, never behind the open turn.\n void sendMessage(text, undefined, channelId, false, undefined, { answersAsk: true });\n },\n [sendMessage, channelId],\n );\n\n const [resolvedAskIds, setResolvedAskIds] = useState<Record<string, boolean>>({});\n const pendingAsk = useMemo(\n () =>\n pendingAskUser([\n ...transcriptRows,\n ...(response?.trim() ? [{ role: 'assistant', content: response }] : []),\n ]),\n [transcriptRows, response],\n );\n const showAskCard = Boolean(pendingAsk && !resolvedAskIds[pendingAsk.requestId]);\n\n /**\n * Answer a `[CONNECTOR_CONNECT]` card (a login to save, a connector to connect).\n * Like the ASK_USER answer it skips handleSend's mode rewriting: the\n * `[CONNECTOR_CONNECTED:<requestId>:<credentialId>]` reply goes out as is, names\n * the saved credential so the agent can sign in with it at once, and the\n * transcript hides it (it is protocol, not something the user said).\n */\n const sendConnectorReply = useCallback(\n async (text: string): Promise<boolean> => {\n if (!channelId) return false;\n return (await sendMessage(text, undefined, channelId)) !== 'failed';\n },\n [sendMessage, channelId],\n );\n // The transcript shows the thread without the protocol: the card stands in for\n // the marker, and its reply is not something the user said. Ids are kept, so\n // regenerate-from-row still indexes chat.messages.\n const transcriptDisplayRows = useMemo(() => displayConnectorConnectMessages(transcriptRows), [transcriptRows]);\n const transcriptStreaming = useMemo(\n () => (response ? displayConnectorConnectText(response, true) : response),\n [response],\n );\n\n // A turn after an answer is a follow-up: the brain must be near-certain to move it to an app.\n const hasAssistantReply = useMemo(() => messages.some((m) => m.role === 'assistant'), [messages]);\n\n const handleSend = useCallback(\n (text?: string) => {\n const pending = imageAttachments.forSend();\n const t = (text ?? valueRef.current).trim();\n if ((!t && !pending?.length) || !channelId) return;\n // Clear both ways: the controlled state (so React's model stays\n // consistent on next render) AND the native buffer via the ref\n // (so the visible text disappears on the same frame the user\n // pressed send, even before React flushes).\n setValue('');\n inputRef.current?.clear();\n\n // Build mode: hand the ask to the native Web Builder's agent (web `/c/:id/webbuilder`).\n if (isBuildMode) {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.WebBuilderNative',\n params: nativeHandoffParams({ orgName: params.orgName, query: t, files: pending }),\n }),\n );\n return;\n }\n\n // Deep-search mode: every new query pops the structured research\n // modal back open (parity with the previous Home flow, where every\n // submit re-opened the DeepSearchModal). Without this, a user who\n // closed the modal once would see plain assistant turns for every\n // subsequent send. Reads the LOCAL `isDeepSearchMode` so the user\n // can toggle modes mid-thread and have sends behave accordingly.\n if (isDeepSearchMode) {\n setIsDeepSearchModalOpen(true);\n }\n const turnId = `turn-${(routingSeqRef.current += 1)}`;\n setRoutingTurns((prev) => [\n ...prev,\n { id: turnId, text: t, attachments: pending, placement: chatBusy ? 'queue' : 'thread' },\n ]);\n void (async () => {\n const mode = isDeepSearchMode ? 'deep-search' : 'chat';\n // Both checks at once (one shared brain classify). Mid-conversation the\n // brain must be near-certain before the ask leaves the thread.\n const [openShop, nativeRoute] = await Promise.all([\n // `forSend()` is undefined with nothing attached; `.length` on it threw,\n // so a typed shopping ask never reached Shop.\n shouldRedirectToShop(t, pending?.length ?? 0, mode).catch(() => false),\n resolveNativeHandoff(t, { mode, followUp: hasAssistantReply }),\n ]);\n if (openShop) {\n releaseRoutingTurn(turnId);\n if (messages.length === 0) {\n // An empty thread is replaced, so Shop carries on in it.\n replaceWithShopNative(\n navigation,\n shopHandoffParams({ orgName: params.orgName, query: t, files: pending, channelId }),\n );\n } else {\n pushShopNative(\n navigation,\n shopHandoffParams({ orgName: params.orgName, query: t, files: pending }),\n );\n }\n return;\n }\n if (nativeRoute) {\n releaseRoutingTurn(turnId);\n if (messages.length === 0) {\n replaceWithNativeApp(\n navigation,\n nativeRoute,\n nativeHandoffParams({ orgName: params.orgName, query: t, files: pending, channelId }),\n );\n } else {\n pushNativeApp(\n navigation,\n nativeRoute,\n nativeHandoffParams({ orgName: params.orgName, query: t, files: pending }),\n );\n }\n return;\n }\n releaseRoutingTurn(turnId);\n void sendMessage(t, pending, channelId);\n })();\n imageAttachments.clear();\n },\n [\n channelId,\n sendMessage,\n isDeepSearchMode,\n isBuildMode,\n navigation,\n params.orgName,\n imageAttachments,\n messages.length,\n hasAssistantReply,\n chatBusy,\n releaseRoutingTurn,\n ],\n );\n\n const handleValueChange = useCallback((e: { nativeEvent?: { text?: string } } | undefined) => {\n setValue(e?.nativeEvent?.text ?? '');\n }, []);\n\n /**\n * Mic affordance — web parity (`handleMicClick` in `YantraSearchComposer.tsx`).\n * The shared `MicSendButton` in `InputToolBar.tsx` only routes to `onMic`\n * when the input has no content, so we only need to handle the empty-input\n * case here.\n *\n * Permission is requested HERE, before the panel mounts. The previous flow\n * flipped `showAudioRecorder=true` immediately, which mounted\n * `AudioRecorderPanel` and constructed the native `AVAudioRecorder` via\n * `useAudioRecorder()` during the panel's render phase — before iOS had\n * granted mic access. On SDK 53 + `newArchEnabled: true` + Hermes that\n * ordering hard-crashes TestFlight builds even though it works in Expo Go\n * (Expo Go pre-caches permission). Asking up front means iOS shows the\n * system alert first and the panel only mounts (and therefore the native\n * recorder is only allocated) once permission is granted.\n *\n * `expo-audio` is lazy-imported so a missing/broken native module surfaces\n * as a user-visible banner instead of a synchronous TurboModule crash.\n */\n /** Open the record -> Whisper recorder (the fallback mic lane). */\n const openWhisperRecorder = useCallback(() => {\n setVoiceError(null);\n void (async () => {\n const { granted, error } = await requestMicPermission();\n if (!granted) {\n setVoiceError(error || 'Microphone is not available.');\n return;\n }\n setShowAudioRecorder(true);\n })();\n }, []);\n\n const handleMicPress = useCallback(() => {\n if (hasQuery) return;\n setVoiceError(null);\n Keyboard.dismiss();\n // Prefer Apple's on-device dictation (the iOS-built-in mic): it streams\n // text live and needs no upload. The bar requests its own permission\n // and calls back to the Whisper recorder if the native path is\n // unusable. Only reachable on a build that linked the native module.\n if (isNativeDictationAvailable()) {\n setShowNativeDictation(true);\n return;\n }\n openWhisperRecorder();\n }, [hasQuery, openWhisperRecorder]);\n\n /**\n * On a successful Whisper round-trip, paste the transcript into the input\n * field, close the recorder, and let the user review/send manually. Matches\n * web's `handleTranscriptionComplete`: we deliberately do NOT auto-fire\n * `sendMessage` because the user often wants to edit the dictation first.\n */\n /** Append a finished transcript to the composer and re-focus it. Shared by\n * the Whisper recorder and native dictation. */\n const pasteTranscript = useCallback((text: string) => {\n const cleaned = (text ?? '').trim();\n if (!cleaned) return;\n setValue((prev) => {\n const next = prev.trim().length > 0 ? `${prev.trim()} ${cleaned}` : cleaned;\n /*\n * Keep `inputRef`'s native text in sync with our controlled value\n * for the same reason `handleSend` does (the iOS native buffer\n * can lag the React state across a single gesture). `setNativeProps`\n * is the safe way to do this without re-rendering.\n */\n requestAnimationFrame(() => {\n inputRef.current?.setNativeProps?.({ text: next });\n inputRef.current?.focus?.();\n });\n return next;\n });\n }, []);\n\n const handleTranscriptionComplete = useCallback(\n (text: string) => {\n setShowAudioRecorder(false);\n pasteTranscript(text);\n },\n [pasteTranscript],\n );\n\n const handleRecorderCancel = useCallback(() => {\n setShowAudioRecorder(false);\n }, []);\n\n const handleDictationComplete = useCallback(\n (text: string) => {\n setShowNativeDictation(false);\n pasteTranscript(text);\n },\n [pasteTranscript],\n );\n\n const handleDictationCancel = useCallback(() => setShowNativeDictation(false), []);\n\n /** Native dictation could not run - drop to the Whisper recorder, which\n * requests its own permission and surfaces its own errors. */\n const handleDictationFallback = useCallback(() => {\n setShowNativeDictation(false);\n openWhisperRecorder();\n }, [openWhisperRecorder]);\n\n const handleRecorderError = useCallback((error: string) => {\n setVoiceError(error);\n }, []);\n\n const waitingForAssistant = useMemo(() => {\n if ((!isLoading && !isStreaming) || messages.length === 0) return false;\n if ((response ?? '').trim()) return false;\n return messages[messages.length - 1]?.role === 'user';\n }, [isLoading, isStreaming, messages, response]);\n\n /*\n * NOTE: the previous read-only `isDeepSearchChannel` derivation has been\n * removed. Mode is now a freely-toggleable local state (`activeMode`)\n * driven by tapping the search/zap pills, mirroring HomeScreen. All\n * downstream branches use `isDeepSearchMode` declared with the rest of\n * the composer state above.\n */\n\n /**\n * Deep-search overlay state.\n *\n * Restored from the previous Home-screen flow (commit history): a deep-search\n * channel renders the structured `DeepSearchModal` (query / live summary /\n * sources / research process) on top of the regular Chat conversation. Closing\n * the modal reveals the same channel's transcript underneath so the\n * user can still see the raw turns.\n *\n * Trigger semantics — IMPORTANT:\n * • Opens ONLY when a request is actually fired in this session:\n * - Home → Chat auto-fire of `initialQuery`\n * - User sends a new message in a deep-search channel from the composer\n * - Explicit retry from inside the modal\n * • Does NOT open on plain entry from ChatHistoryScreen. That's a revisit\n * of an already-completed thread — no new API call, nothing live to\n * stream, so popping the modal would just be a confusing flash. The\n * user still sees the deep-search rendering in the chat conversation\n * underneath, and any new send re-opens the live view.\n *\n * Local UI state (accordions, open flag) lives here; data state (query /\n * summary / sources) is DERIVED from the chat stream, not stored separately,\n * so there's no drift between the modal and the underlying conversation.\n */\n const [isDeepSearchModalOpen, setIsDeepSearchModalOpen] = useState(false);\n const [researchProcessOpen, setResearchProcessOpen] = useState(true);\n const [sourcesAccordionOpen, setSourcesAccordionOpen] = useState(true);\n\n /**\n * Modal data is always scoped to the CURRENT run, not the whole channel.\n * In a multi-turn deep-search channel each send is its own \"run\": one user\n * query → one assistant summary. If we sourced from \"first user message\" /\n * \"any assistant message\", a follow-up send would keep showing the previous\n * run's query and stale sources during the transient window between the new\n * user message being appended and the first stream token arriving.\n *\n * Cursor: the LAST user message in the thread. The assistant content for\n * the current run is either:\n * • `response` while the stream is filling (token-by-token), OR\n * • the assistant message that comes AFTER the last user (run complete), OR\n * • empty — covers the brief \"user message appended, no response yet\"\n * window so the modal flips to \"Running...\" with no stale body.\n */\n const lastUserIndex = useMemo(() => {\n for (let i = messages.length - 1; i >= 0; i -= 1) {\n if (messages[i]?.role === 'user') return i;\n }\n return -1;\n }, [messages]);\n\n /**\n * The brain kept an ask in chat, but the chat's agent went to an app's tools\n * (a site build, a flight search, a job search): that turn belongs in the app.\n * Stop it here and hand the ask to the app's native screen, so it runs there\n * and only there - never half in the main chat, half in the app.\n */\n const handedOffTurnRef = useRef(-1);\n useEffect(() => {\n if (!isStreaming || !response || isDeepSearchMode || lastUserIndex < 0) return;\n if (handedOffTurnRef.current === lastUserIndex) return;\n const route = nativeRouteForConnectors(parseToolActivity(response, true).steps.map((step) => step.connector));\n if (!route) return;\n handedOffTurnRef.current = lastUserIndex;\n cancel();\n const ask = messages[lastUserIndex]?.content?.trim() ?? '';\n // A first ask moves the whole chat into the app; a later one opens the app over the thread.\n const firstAsk = !messages.slice(0, lastUserIndex).some((m) => m.role === 'assistant');\n const handoff = nativeHandoffParams({\n orgName: params.orgName,\n query: ask,\n channelId: firstAsk ? channelId : null,\n });\n if (firstAsk) replaceWithNativeApp(navigation, route, handoff);\n else pushNativeApp(navigation, route, handoff);\n }, [\n cancel,\n channelId,\n isDeepSearchMode,\n isStreaming,\n lastUserIndex,\n messages,\n navigation,\n params.orgName,\n response,\n ]);\n\n const deepSearchQuery = useMemo(() => {\n if (lastUserIndex >= 0) {\n const txt = messages[lastUserIndex]?.content?.trim();\n if (txt) return txt;\n }\n return initialQuery ?? null;\n }, [messages, lastUserIndex, initialQuery]);\n\n const latestAssistantContent = useMemo(() => {\n if (response && response.trim()) return response;\n if (lastUserIndex < 0) return '';\n // Look for an assistant turn strictly AFTER the last user message.\n // Anything before it belongs to a prior run and must not leak into\n // the modal for the current one.\n for (let i = lastUserIndex + 1; i < messages.length; i += 1) {\n if (messages[i]?.role === 'assistant') {\n // The summary is the agent's answer, not the quick answer framed in front of it.\n return splitPreResponse(messages[i]?.content).text;\n }\n }\n return '';\n }, [response, messages, lastUserIndex]);\n\n const deepSearchSummary = useMemo(() => normalizeSummaryText(latestAssistantContent), [latestAssistantContent]);\n const deepSearchSources: DeepSearchSourceItem[] = useMemo(\n () => extractDeepSearchSources(latestAssistantContent),\n [latestAssistantContent],\n );\n\n const handleDeepSearchClose = useCallback(() => {\n if (isStreaming) cancel();\n setIsDeepSearchModalOpen(false);\n }, [isStreaming, cancel]);\n\n const handleDeepSearchRetry = useCallback(() => {\n if (!deepSearchQuery || isStreaming || !channelId) return;\n void sendMessage(deepSearchQuery, undefined, channelId);\n }, [deepSearchQuery, isStreaming, channelId, sendMessage]);\n const leftItems = useMemo(\n () =>\n getDefaultLeftItems({\n search: { active: activeMode === 'chat', onClick: () => handleModeSwitch('chat') },\n zap: { active: activeMode === 'deep-search', onClick: () => handleModeSwitch('deep-search') },\n lightbulb: {\n active: activeMode === 'build',\n onClick: () => handleModeSwitch('build'),\n },\n }),\n [activeMode, handleModeSwitch],\n );\n const inputPlaceholder = PLACEHOLDER[modeOf(isDeepSearchMode, isBuildMode)];\n\n const inputConfig = useMemo(\n () => ({\n value,\n onChange: handleValueChange,\n placeholder: inputPlaceholder,\n disabled: !channelId,\n inputRef,\n returnKeyType: 'send',\n blurOnSubmit: false,\n onSubmitEditing: () => handleSend(),\n }),\n [value, handleValueChange, inputPlaceholder, channelId, handleSend],\n );\n const micSendButton = useMemo(\n () => ({\n hasContent: hasQuery || hasAttachments,\n onSend: () => handleSend(),\n onMic: handleMicPress,\n disabled: !channelId,\n // Empty + streaming → Stop. Typed follow-up → Send (queued for the agent). Never lock the composer.\n isLoading: canSubmit ? false : isLoading,\n onStop: isStreaming && !canSubmit ? cancel : undefined,\n steerable: isLoading || isStreaming,\n }),\n [canSubmit, handleSend, handleMicPress, isLoading, channelId, isStreaming, cancel, hasQuery, hasAttachments],\n );\n\n // With messages parked, the outbox notice above already says the gateway is not\n // there and that they go out once it is; its connect error said \"please send\n // again\" beside it - the opposite of what happens.\n const bannerError = chatError || (queuedMessages.length > 0 ? null : cdecli.error);\n\n // A turn sent mid-reply waits above the composer from the tap, while it is routed.\n const followUpsAboveComposer = useMemo(\n () => [\n ...queuedFollowUps,\n ...routingTurns\n .filter((turn) => turn.placement === 'queue')\n .map((turn) => ({ id: `routing-${turn.id}`, text: turn.text, attachments: turn.attachments })),\n ],\n [queuedFollowUps, routingTurns],\n );\n const cancelFollowUpAboveComposer = useCallback(\n (id: string) => {\n // Still being routed: nothing reached the gateway to cancel.\n if (id.startsWith('routing-')) return;\n void cancelQueuedFollowUp(id);\n },\n [cancelQueuedFollowUp],\n );\n\n // Queue affordances: the gateway is live, so a queue that is still sitting there\n // failed its release and the user gets a manual retry beside the discard.\n const gatewayLive = cdecli.channelConnected;\n // The gateway is down (they wait for it), or it is up and their own send failed.\n const queuedCount = queuedMessages.length === 1 ? '1 message' : `${queuedMessages.length} messages`;\n let queuedNotice = `${queuedCount} waiting for the gateway. They send as soon as it connects.`;\n if (gatewayLive) queuedNotice = `${queuedCount} not sent yet${outboxRetrying ? ' - trying again' : ''}.`;\n const queuedActionColor = isDark ? '#fbbf24' : '#b45309';\n const handleSendQueuedNow = useCallback(() => {\n void flushQueuedMessages();\n }, [flushQueuedMessages]);\n\n /**\n * Loader visibility. A turn the user just sent is never hidden behind one: while\n * it is routed, and while CDeCLI connects for it, it shows in the thread with the\n * thinking indicator under it.\n * - `isHydrating`: Apollo channel history is being fetched and we have nothing to show yet.\n */\n const routingInThread = routingTurns.some((turn) => turn.placement === 'thread');\n const isHydrating =\n messagesLoading && messages.length === 0 && !response && !quickReply && !isStreaming && !routingInThread;\n const showSendingLoader = waitingForAssistant || routingInThread;\n const pinSendingLoaderNearComposer = messages.length > 0 || Boolean((response ?? '').trim()) || routingInThread;\n\n // One of three states fills the transcript area, in this order of precedence.\n let transcriptArea: React.ReactNode;\n if (!channelId) {\n transcriptArea = (\n <Box flex={1} alignItems=\"center\" justifyContent=\"center\">\n <YantraBrandLoader size={YANTRA_LOADER_SIZE_COMPACT} />\n <Text style={[styles.statusText, { color: secondaryTextColor }]}>No channel selected</Text>\n </Box>\n );\n } else if (isHydrating) {\n transcriptArea = (\n <Box flex={1} px=\"$4\" pt=\"$8\">\n <ThinkingIndicator\n variant=\"awaiting\"\n color={secondaryTextColor}\n isDark={isDark}\n label=\"Opening conversation…\"\n />\n </Box>\n );\n } else {\n transcriptArea = (\n // Links in the transcript open in the app on their surface, or in a browser sheet.\n <ChatLinkOpenerProvider>\n <View style={styles.transcriptPane}>\n <ChatTranscript\n messages={transcriptDisplayRows}\n streamingContent={transcriptStreaming}\n quickReply={quickReply}\n listFooter={\n showSendingLoader && pinSendingLoaderNearComposer ? (\n <View style={styles.thinkingInThread}>\n <ThinkingIndicator variant=\"awaiting\" color={secondaryTextColor} isDark={isDark} />\n </View>\n ) : null\n }\n renderMessageActions={renderMessageActions}\n isDark={isDark}\n listContentStyle={{\n paddingTop: 12,\n paddingBottom: 8,\n margin: 0,\n width: contentMaxWidth,\n alignSelf: 'center',\n }}\n />\n </View>\n </ChatLinkOpenerProvider>\n );\n }\n\n // The composer row is the dictation bar, the recorder, or the input - never two at once.\n let composerBody: React.ReactNode;\n if (showNativeDictation) {\n composerBody = (\n // A throw inside the native recognizer degrades to\n // the Whisper recorder rather than killing the JS\n // thread (same guard rationale as the recorder).\n <MicErrorBoundary onCancel={handleDictationFallback} onError={handleDictationFallback}>\n <NativeDictationBar\n isDark={isDark}\n onInterim={() => undefined}\n onTranscriptionComplete={handleDictationComplete}\n onCancel={handleDictationCancel}\n onFallback={handleDictationFallback}\n />\n </MicErrorBoundary>\n );\n } else if (showAudioRecorder) {\n composerBody = (\n /*\n * Render-time JS errors thrown by `useAudioRecorder`\n * (e.g. expo-audio native module missing, recorder\n * constructor throws in a release build) are caught\n * by the boundary and converted into a soft cancel\n * via the same handlers the panel itself uses on\n * runtime errors. Without this, a throw during the\n * panel's render phase kills the JS thread in\n * release / TestFlight.\n */\n <MicErrorBoundary onCancel={handleRecorderCancel} onError={handleRecorderError}>\n <AudioRecorderPanel\n isDark={isDark}\n onTranscriptionComplete={handleTranscriptionComplete}\n onCancel={handleRecorderCancel}\n onError={handleRecorderError}\n />\n </MicErrorBoundary>\n );\n } else {\n composerBody = (\n <>\n <ComposerAttachmentBar\n attachments={imageAttachments.pending}\n onRemove={imageAttachments.remove}\n isDark={isDark}\n />\n <InputToolBar\n inputConfig={inputConfig}\n leftItems={leftItems}\n rightItems={rightItems}\n templateButton={null}\n templateModalConfig={null}\n micSendButton={micSendButton}\n />\n </>\n );\n }\n\n return (\n <SafeAreaView edges={['left', 'right']} style={{ flex: 1, backgroundColor: surfaceColor }}>\n <KeyboardAwareScreen>\n <View style={styles.chatColumn}>\n {queuedMessages.length > 0 && (\n <Box\n mb=\"$2\"\n mx=\"$4\"\n p=\"$3\"\n borderRadius=\"$md\"\n style={{\n backgroundColor: isDark ? '#2a2113' : '#fffbeb',\n borderWidth: 1,\n borderColor: isDark ? '#78350f' : '#fde68a',\n flexDirection: 'row',\n alignItems: 'center',\n }}\n >\n <Text fontSize=\"$sm\" style={{ color: isDark ? '#fde68a' : '#92400e', flex: 1 }}>\n {queuedNotice}\n </Text>\n {gatewayLive ? (\n <Pressable onPress={handleSendQueuedNow} hitSlop={8} style={styles.queuedAction}>\n <Text\n fontSize=\"$xs\"\n style={[styles.queuedActionText, { color: queuedActionColor }]}\n >\n Send now\n </Text>\n </Pressable>\n ) : null}\n <Pressable onPress={discardQueuedMessages} hitSlop={8} style={styles.queuedAction}>\n <Text fontSize=\"$xs\" style={[styles.queuedActionText, { color: queuedActionColor }]}>\n Discard\n </Text>\n </Pressable>\n </Box>\n )}\n {bannerError && (\n <Box\n mb=\"$2\"\n mx=\"$4\"\n p=\"$3\"\n borderRadius=\"$md\"\n style={{\n backgroundColor: isDark ? '#2b1a1d' : '#fef2f2',\n borderWidth: 1,\n borderColor: isDark ? '#7f1d1d' : '#fecaca',\n }}\n >\n <Text fontSize=\"$sm\" style={{ color: isDark ? '#fecaca' : '#991b1b' }}>\n {bannerError}\n </Text>\n </Box>\n )}\n {transcriptArea}\n {showSendingLoader && !pinSendingLoaderNearComposer ? (\n <View pointerEvents=\"none\" style={styles.sendingLoaderEmptyState}>\n <ThinkingIndicator variant=\"awaiting\" color={secondaryTextColor} isDark={isDark} />\n </View>\n ) : null}\n <KeyboardComposerDock closedInset={insets.bottom} onSwipeUp={() => inputRef.current?.focus()}>\n {showAskCard && pendingAsk ? (\n <View style={{ width: contentMaxWidth, paddingHorizontal: 8 }}>\n <AskUserCard\n payload={pendingAsk}\n isDark={isDark}\n onAnswer={(formatted) => {\n setResolvedAskIds((prev) => ({ ...prev, [pendingAsk.requestId]: true }));\n handleAskUserAnswer(formatted);\n }}\n onDismiss={() =>\n setResolvedAskIds((prev) => ({ ...prev, [pendingAsk.requestId]: true }))\n }\n />\n </View>\n ) : null}\n {showAskCard ? null : (\n <PendingConnectorConnectCard\n messages={transcriptRows}\n send={sendConnectorReply}\n isDark={isDark}\n style={{ width: contentMaxWidth, paddingHorizontal: 8 }}\n />\n )}\n <View style={{ width: contentMaxWidth }}>\n <QueuedFollowUps\n items={followUpsAboveComposer}\n onCancel={cancelFollowUpAboveComposer}\n onSendNow={sendQueuedNow}\n isDark={isDark}\n />\n </View>\n <View style={[styles.bottomComposerInner, { width: contentMaxWidth }]}>\n {voiceError || imageAttachments.error ? (\n <View\n style={[\n styles.voiceErrorBanner,\n {\n backgroundColor: isDark ? '#2b1a1d' : '#fef2f2',\n borderColor: isDark ? '#7f1d1d' : '#fecaca',\n },\n ]}\n >\n <Text style={[styles.voiceErrorText, { color: isDark ? '#fecaca' : '#991b1b' }]}>\n {voiceError || imageAttachments.error}\n </Text>\n </View>\n ) : null}\n {composerBody}\n </View>\n </KeyboardComposerDock>\n </View>\n </KeyboardAwareScreen>\n {isDeepSearchMode ? (\n <DeepSearchModal\n visible={isDeepSearchModalOpen}\n query={deepSearchQuery}\n summaryText={deepSearchSummary}\n sources={deepSearchSources}\n isStreaming={isStreaming}\n researchProcessOpen={researchProcessOpen}\n sourcesAccordionOpen={sourcesAccordionOpen}\n onToggleResearchProcess={() => setResearchProcessOpen((prev) => !prev)}\n onToggleSourcesAccordion={() => setSourcesAccordionOpen((prev) => !prev)}\n onRetry={handleDeepSearchRetry}\n onStop={cancel}\n onClose={handleDeepSearchClose}\n />\n ) : null}\n {attachMenu}\n </SafeAreaView>\n );\n}\n\nconst styles = StyleSheet.create({\n chatColumn: {\n flex: 1,\n width: '100%',\n },\n transcriptPane: {\n flex: 1,\n minHeight: 0,\n width: '100%',\n },\n statusText: {\n marginTop: 14,\n fontSize: 13,\n fontWeight: '500',\n },\n bottomComposerInner: {\n paddingHorizontal: 14,\n paddingTop: 10,\n paddingBottom: 0,\n },\n voiceErrorBanner: {\n marginBottom: 8,\n paddingHorizontal: 12,\n paddingVertical: 8,\n borderRadius: 10,\n borderWidth: 1,\n },\n voiceErrorText: {\n fontSize: 12,\n fontWeight: '500',\n },\n sendingLoaderEmptyState: {\n position: 'absolute',\n left: 0,\n right: 0,\n top: 24,\n paddingHorizontal: 20,\n zIndex: 40,\n },\n queuedAction: {\n paddingHorizontal: 8,\n paddingVertical: 2,\n },\n queuedActionText: {\n fontWeight: '600',\n },\n thinkingInThread: {\n paddingHorizontal: 12,\n paddingTop: 10,\n paddingBottom: 4,\n },\n});\n"],"names":["_a","route"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import {jsx}from'react/jsx-runtime';import {useMemo,useCallback}from'react';import {useColorScheme,StyleSheet}from'react-native';import {SafeAreaView}from'react-native-safe-area-context';import {useNavigation,useRoute,CommonActions}from'@react-navigation/native';import {mobileTokens}from'../../theme/mobileTokens.js';import ChatHistoryLanding from'../Home/components/ChatHistoryLanding.js';import {navigateToNewChatHome}from'../../utils/navigateToNewChatHome.js';var __defProp = Object.defineProperty;
1
+ import {jsx}from'react/jsx-runtime';import {useMemo,useState,useEffect,useCallback}from'react';import {useColorScheme,StyleSheet}from'react-native';import {SafeAreaView}from'react-native-safe-area-context';import {useApolloClient}from'@apollo/client/index.js';import {useNavigation,useRoute,CommonActions}from'@react-navigation/native';import {mobileTokens}from'../../theme/mobileTokens.js';import ChatHistoryLanding from'../Home/components/ChatHistoryLanding.js';import {navigateToNewChatHome}from'../../utils/navigateToNewChatHome.js';import {knownWebBuilderProjectIds,channelHoldsBuild}from'../WebBuilderNative/useWebBuilderGallery.js';var __defProp = Object.defineProperty;
2
2
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
3
  var __hasOwnProp = Object.prototype.hasOwnProperty;
4
4
  var __propIsEnum = Object.prototype.propertyIsEnumerable;
@@ -26,8 +26,20 @@ function ChatHistoryScreen() {
26
26
  return typeof raw === "string" && raw.trim() ? raw.trim() : null;
27
27
  }, [(_a = route == null ? void 0 : route.params) == null ? void 0 : _a.orgName]);
28
28
  const surfaceColor = isDark ? "#0f172a" : mobileTokens.color.surface;
29
- const handleSelectSession = useCallback((channelId, mode) => {
30
- if (mode === "build") {
29
+ const client = useApolloClient();
30
+ const [buildChannelIds, setBuildChannelIds] = useState(() => /* @__PURE__ */ new Set());
31
+ useEffect(() => {
32
+ let live = true;
33
+ void knownWebBuilderProjectIds().then((ids) => {
34
+ if (live) setBuildChannelIds(ids);
35
+ });
36
+ return () => {
37
+ live = false;
38
+ };
39
+ }, []);
40
+ const handleSelectSession = useCallback(async (channelId, mode) => {
41
+ const isSite = mode === "build" || buildChannelIds.has(channelId) || await channelHoldsBuild(client, channelId);
42
+ if (isSite) {
31
43
  navigation.dispatch(CommonActions.navigate({
32
44
  name: "MainStack.WebBuilderNative",
33
45
  params: __spreadValues({
@@ -47,13 +59,14 @@ function ChatHistoryScreen() {
47
59
  orgName
48
60
  } : {})
49
61
  }));
50
- }, [navigation, orgName]);
62
+ }, [buildChannelIds, client, navigation, orgName]);
63
+ const onSelectSession = useCallback((channelId, mode) => void handleSelectSession(channelId, mode), [handleSelectSession]);
51
64
  const handleCompose = useCallback(() => {
52
65
  navigateToNewChatHome(navigation, orgName);
53
66
  }, [navigation, orgName]);
54
67
  return /* @__PURE__ */ jsx(SafeAreaView, { edges: ["left", "right", "bottom"], style: [styles.container, {
55
68
  backgroundColor: surfaceColor
56
- }], children: /* @__PURE__ */ jsx(ChatHistoryLanding, { onSelectSession: handleSelectSession, onCompose: handleCompose, orgName }) });
69
+ }], children: /* @__PURE__ */ jsx(ChatHistoryLanding, { onSelectSession, onCompose: handleCompose, orgName, buildChannelIds }) });
57
70
  }
58
71
  const styles = StyleSheet.create({
59
72
  container: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/screens/ChatHistory/index.tsx"],"sourcesContent":["/**\n * Standalone Chat History screen.\n *\n * Header chrome (back, title, gateway pill, new-chat shortcut) is owned entirely\n * by `NavigationHeader` via `customHeader.props` in `compute.ts` — this screen\n * contains no header logic.\n */\nimport React, { useCallback, useMemo } from 'react';\nimport { StyleSheet, useColorScheme } from 'react-native';\nimport { SafeAreaView } from 'react-native-safe-area-context';\nimport { CommonActions, useNavigation, useRoute } from '@react-navigation/native';\nimport { mobileTokens } from '../../theme/mobileTokens';\nimport ChatHistoryLanding from '../Home/components/ChatHistoryLanding';\nimport type { ChatHistoryMode } from '../../hooks/useChatApi';\nimport { navigateToNewChatHome } from '../../utils/navigateToNewChatHome';\n\nexport interface ChatHistoryRouteParams {\n orgName?: string | null;\n}\n\nexport default function ChatHistoryScreen() {\n const navigation = useNavigation<any>();\n const route = useRoute<any>();\n const colorScheme = useColorScheme();\n const isDark = colorScheme === 'dark';\n\n const orgName = useMemo(() => {\n const raw = (route?.params?.orgName as string | undefined) ?? '';\n return typeof raw === 'string' && raw.trim() ? raw.trim() : null;\n }, [route?.params?.orgName]);\n\n const surfaceColor = isDark ? '#0f172a' : mobileTokens.color.surface;\n\n /**\n * Reopen the original surface: build sessions go back to the native Web\n * Builder on that site (`openChannelId`, as the Tasks sheet opens one),\n * matching browser history's `/c/:channelId/webbuilder`. Chat / deep-search\n * stay on Chat.\n */\n const handleSelectSession = useCallback(\n (channelId: string, mode: ChatHistoryMode) => {\n if (mode === 'build') {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.WebBuilderNative',\n params: {\n openChannelId: channelId,\n appTitle: 'Web Builder',\n ...(orgName ? { orgName } : {}),\n },\n }),\n );\n return;\n }\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.Chat',\n params: {\n channelId,\n ...(orgName ? { orgName } : {}),\n },\n }),\n );\n },\n [navigation, orgName],\n );\n\n const handleCompose = useCallback(() => {\n navigateToNewChatHome(navigation, orgName);\n }, [navigation, orgName]);\n\n return (\n <SafeAreaView edges={['left', 'right', 'bottom']} style={[styles.container, { backgroundColor: surfaceColor }]}>\n <ChatHistoryLanding onSelectSession={handleSelectSession} onCompose={handleCompose} orgName={orgName} />\n </SafeAreaView>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n },\n});\n"],"names":["_a"],"mappings":";;;;;;;;;;;;;;;;AAkBA,SAAwB,iBAAoB,GAAA;AAlB5C,EAAA,IAAA,EAAA;AAmBE,EAAA,MAAM,aAAa,aAAmB,EAAA;AACtC,EAAA,MAAM,QAAQ,QAAc,EAAA;AAC5B,EAAA,MAAM,cAAc,cAAe,EAAA;AACnC,EAAA,MAAM,SAAS,WAAgB,KAAA,MAAA;AAC/B,EAAM,MAAA,OAAA,GAAU,QAAQ,MAAM;AAvBhC,IAAA,IAAAA,GAAA,EAAA,EAAA;AAwBI,IAAM,MAAA,GAAA,GAAA,CAAM,MAAAA,GAAA,GAAA,KAAA,IAAA,IAAA,GAAA,MAAA,GAAA,KAAA,CAAO,WAAP,IAAAA,GAAAA,MAAAA,GAAAA,GAAAA,CAAe,YAAf,IAAgD,GAAA,EAAA,GAAA,EAAA;AAC5D,IAAO,OAAA,OAAO,QAAQ,QAAY,IAAA,GAAA,CAAI,MAAS,GAAA,GAAA,CAAI,MAAS,GAAA,IAAA;AAAA,KAC3D,CAAC,CAAA,EAAA,GAAA,KAAA,IAAA,IAAA,GAAA,MAAA,GAAA,KAAA,CAAO,MAAP,KAAA,IAAA,GAAA,MAAA,GAAA,EAAA,CAAe,OAAO,CAAC,CAAA;AAC3B,EAAA,MAAM,YAAe,GAAA,MAAA,GAAS,SAAY,GAAA,YAAA,CAAa,KAAM,CAAA,OAAA;AAQ7D,EAAA,MAAM,mBAAsB,GAAA,WAAA,CAAY,CAAC,SAAA,EAAmB,IAA0B,KAAA;AACpF,IAAA,IAAI,SAAS,OAAS,EAAA;AACpB,MAAW,UAAA,CAAA,QAAA,CAAS,cAAc,QAAS,CAAA;AAAA,QACzC,IAAM,EAAA,4BAAA;AAAA,QACN,MAAQ,EAAA,cAAA,CAAA;AAAA,UACN,aAAe,EAAA,SAAA;AAAA,UACf,QAAU,EAAA;AAAA,SAAA,EACN,OAAU,GAAA;AAAA,UACZ;AAAA,YACE,EAAC;AAAA,OAER,CAAC,CAAA;AACF,MAAA;AAAA;AAEF,IAAW,UAAA,CAAA,QAAA,CAAS,cAAc,QAAS,CAAA;AAAA,MACzC,IAAM,EAAA,gBAAA;AAAA,MACN,MAAQ,EAAA,cAAA,CAAA;AAAA,QACN;AAAA,OAAA,EACI,OAAU,GAAA;AAAA,QACZ;AAAA,UACE,EAAC;AAAA,KAER,CAAC,CAAA;AAAA,GACD,EAAA,CAAC,UAAY,EAAA,OAAO,CAAC,CAAA;AACxB,EAAM,MAAA,aAAA,GAAgB,YAAY,MAAM;AACtC,IAAA,qBAAA,CAAsB,YAAY,OAAO,CAAA;AAAA,GACxC,EAAA,CAAC,UAAY,EAAA,OAAO,CAAC,CAAA;AACxB,EAAO,uBAAA,GAAA,CAAC,YAAa,EAAA,EAAA,KAAA,EAAO,CAAC,MAAA,EAAQ,OAAS,EAAA,QAAQ,CAAG,EAAA,KAAA,EAAO,CAAC,MAAA,CAAO,SAAW,EAAA;AAAA,IACjF,eAAiB,EAAA;AAAA,GAClB,GACS,QAAC,kBAAA,GAAA,CAAA,kBAAA,EAAA,EAAmB,iBAAiB,mBAAqB,EAAA,SAAA,EAAW,aAAe,EAAA,OAAA,EAAkB,CAC1G,EAAA,CAAA;AACR;AACA,MAAM,MAAA,GAAS,WAAW,MAAO,CAAA;AAAA,EAC/B,SAAW,EAAA;AAAA,IACT,IAAM,EAAA;AAAA;AAEV,CAAC,CAAA"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/screens/ChatHistory/index.tsx"],"sourcesContent":["/**\n * Standalone Chat History screen.\n *\n * Header chrome (back, title, gateway pill, new-chat shortcut) is owned entirely\n * by `NavigationHeader` via `customHeader.props` in `compute.ts` — this screen\n * contains no header logic.\n */\nimport React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport { StyleSheet, useColorScheme } from 'react-native';\nimport { SafeAreaView } from 'react-native-safe-area-context';\nimport { useApolloClient } from '@apollo/client';\nimport { CommonActions, useNavigation, useRoute } from '@react-navigation/native';\nimport { mobileTokens } from '../../theme/mobileTokens';\nimport ChatHistoryLanding from '../Home/components/ChatHistoryLanding';\nimport type { ChatHistoryMode } from '../../hooks/useChatApi';\nimport { navigateToNewChatHome } from '../../utils/navigateToNewChatHome';\nimport { channelHoldsBuild, knownWebBuilderProjectIds } from '../WebBuilderNative/useWebBuilderGallery';\n\nexport interface ChatHistoryRouteParams {\n orgName?: string | null;\n}\n\nexport default function ChatHistoryScreen() {\n const navigation = useNavigation<any>();\n const route = useRoute<any>();\n const colorScheme = useColorScheme();\n const isDark = colorScheme === 'dark';\n\n const orgName = useMemo(() => {\n const raw = (route?.params?.orgName as string | undefined) ?? '';\n return typeof raw === 'string' && raw.trim() ? raw.trim() : null;\n }, [route?.params?.orgName]);\n\n const surfaceColor = isDark ? '#0f172a' : mobileTokens.color.surface;\n\n // Sites Web Builder already lists: their rows read as builds before they are tapped.\n const client = useApolloClient();\n const [buildChannelIds, setBuildChannelIds] = useState<ReadonlySet<string>>(() => new Set());\n useEffect(() => {\n let live = true;\n void knownWebBuilderProjectIds().then((ids) => {\n if (live) setBuildChannelIds(ids);\n });\n return () => {\n live = false;\n };\n }, []);\n\n /**\n * Reopen the original surface. A site - a build session, a chat Web Builder\n * lists, or a chat whose posts hold a build - opens in the native Web Builder\n * on that site (`openChannelId`, as the Tasks sheet opens one), the same place\n * its Projects tile opens. Chat / deep-search stay on Chat.\n */\n const handleSelectSession = useCallback(\n async (channelId: string, mode: ChatHistoryMode) => {\n const isSite =\n mode === 'build' || buildChannelIds.has(channelId) || (await channelHoldsBuild(client, channelId));\n if (isSite) {\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.WebBuilderNative',\n params: {\n openChannelId: channelId,\n appTitle: 'Web Builder',\n ...(orgName ? { orgName } : {}),\n },\n }),\n );\n return;\n }\n navigation.dispatch(\n CommonActions.navigate({\n name: 'MainStack.Chat',\n params: {\n channelId,\n ...(orgName ? { orgName } : {}),\n },\n }),\n );\n },\n [buildChannelIds, client, navigation, orgName],\n );\n\n const onSelectSession = useCallback(\n (channelId: string, mode: ChatHistoryMode) => void handleSelectSession(channelId, mode),\n [handleSelectSession],\n );\n\n const handleCompose = useCallback(() => {\n navigateToNewChatHome(navigation, orgName);\n }, [navigation, orgName]);\n\n return (\n <SafeAreaView edges={['left', 'right', 'bottom']} style={[styles.container, { backgroundColor: surfaceColor }]}>\n <ChatHistoryLanding\n onSelectSession={onSelectSession}\n onCompose={handleCompose}\n orgName={orgName}\n buildChannelIds={buildChannelIds}\n />\n </SafeAreaView>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n },\n});\n"],"names":["_a"],"mappings":"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"}
@@ -262,7 +262,8 @@ let lastKnownHistoryOrgName = null;
262
262
  const AUTO_FILL_PAGES = 3;
263
263
  function ChatHistoryLanding({
264
264
  onSelectSession,
265
- orgName: orgNameProp
265
+ orgName: orgNameProp,
266
+ buildChannelIds
266
267
  }) {
267
268
  var _a, _b;
268
269
  const {
@@ -446,12 +447,13 @@ function ChatHistoryLanding({
446
447
  for (const row of channelSessions) byId.set(row.channelId, row);
447
448
  const merged = enrichHistorySessionsWithUserPrompts(Array.from(byId.values()), [...channelMessageOverlays, ...olderPromptSessions, ...overlaySessions]);
448
449
  return merged.filter((s) => !(emptyChannelIds.has(s.channelId) && (s.isPlaceholder || /^new chat$/i.test(s.title)))).sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime()).map((s) => __spreadProps(__spreadValues({}, s), {
450
+ mode: (buildChannelIds == null ? void 0 : buildChannelIds.has(s.channelId)) ? "build" : s.mode,
449
451
  id: s.channelId,
450
452
  titleForRender: truncate(s.title, 64),
451
453
  previewForRender: s.preview ? truncate(s.preview, 96) : "",
452
454
  sortAt: s.updatedAt.getTime()
453
455
  }));
454
- }, [channelMessageOverlays, emptyChannelIds, liveSessions, olderPromptSessions, olderSessions, overlaySessions, rememberedTick, sessionsLoaded, snapshotRows]);
456
+ }, [buildChannelIds, channelMessageOverlays, emptyChannelIds, liveSessions, olderPromptSessions, olderSessions, overlaySessions, rememberedTick, sessionsLoaded, snapshotRows]);
455
457
  const autoFilledPagesRef = React__default.useRef(0);
456
458
  React__default.useEffect(() => {
457
459
  if (!sessionsLoaded || !hasMore || loadingMore || emptyChannelIds.size === 0) return;