fix(mobile): synchronize native chat refs after commit

This commit is contained in:
Brennan Benson
2026-08-03 17:59:52 -07:00
parent 13f6d086c6
commit c208bc883c
3 changed files with 17 additions and 12 deletions
@@ -1,5 +1,6 @@
import {
useCallback,
useLayoutEffect,
useRef,
type Dispatch,
type MutableRefObject,
@@ -125,9 +126,12 @@ export function useMobileNativeChatController(args: {
: null
const showNativeChat = activeChatResolution != null
const showNativeChatRef = useRef(showNativeChat)
showNativeChatRef.current = showNativeChat
const activeChatAgentRef = useRef<string | null>(activeChatResolution?.agent ?? null)
activeChatAgentRef.current = activeChatResolution?.agent ?? null
const activeChatAgent = activeChatResolution?.agent ?? null
const activeChatAgentRef = useRef<string | null>(activeChatAgent)
useLayoutEffect(() => {
showNativeChatRef.current = showNativeChat
activeChatAgentRef.current = activeChatAgent
}, [activeChatAgent, showNativeChat])
const activeChatSessionId = activeChatResolution?.sessionId ?? null
const streamIdentity = `${hostId}\0${worktreeId}\0${activeSessionTabId ?? ''}\0${activeChatSessionId ?? ''}\0${activeHandleRef.current ?? ''}`
@@ -286,7 +290,9 @@ export function useMobileNativeChatController(args: {
dispatchCommand: handleNativeChatDispatchCommand,
onAgentPicker: handleAgentPicker
})
recordSessionOptionCommandRef.current = sessionOptions.recordCommand
useLayoutEffect(() => {
recordSessionOptionCommandRef.current = sessionOptions.recordCommand
}, [sessionOptions.recordCommand])
// Card actions retire the route's held failure banner too, not just sends.
const answerAsk = useNativeChatAcceptedAction(handleNativeChatAnswerAsk, onSendResolved)
const cancelAsk = useNativeChatAcceptedAction(handleNativeChatCancelAsk, onSendResolved)
@@ -136,7 +136,7 @@ describe('useMobileNativeChatSessionOptions', () => {
})
it('keeps the latest queued operation pending until it settles', async () => {
const resolvers: Array<(outcome: MobileNativeChatSendOutcome) => void> = []
const resolvers: ((outcome: MobileNativeChatSendOutcome) => void)[] = []
dispatchCommand.mockImplementation(
() =>
new Promise<MobileNativeChatSendOutcome>((resolve) => {
@@ -1,4 +1,4 @@
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'
import { getAgentSessionOptionCatalog } from '../../../src/shared/agent-session-option-catalog'
import type {
SessionOptionDescriptor,
@@ -85,16 +85,15 @@ export function useMobileNativeChatSessionOptions(args: {
const pendingId = identity ? (pendingByIdentity[identity]?.id ?? null) : null
const bump = useCallback(() => setVersion((current) => current + 1), [])
const activeIdentityRef = useRef(identity)
activeIdentityRef.current = identity
const applyQueuesRef = useRef(new Map<string, Promise<void>>())
const operationTokenRef = useRef(0)
useEffect(
() => () => {
useLayoutEffect(() => {
activeIdentityRef.current = identity
return () => {
activeIdentityRef.current = null
},
[]
)
}
}, [identity])
// Seed the current model from live agent status; hook reports are authority
// over locally dispatched guesses (desktop 'reported' source parity).