import { agentNoUpdateLabel } from '../../../src/shared/agent-status/presentation/agent-row-decay-state'
import { memo, type ReactNode } from 'react'
import { Pressable, Text, View } from 'react-native'
import type { RuntimeWorktreeAgentRow } from '../../../src/shared/runtime-types'
import { withoutNativeChatVisualDirectiveLines } from '../../../src/shared/native-chat/native-chat-visual-directive'
import { colors, spacing, pressedStyle } from '../theme/mobile-theme'
import { themedStyleSheet } from '../theme/themed-styles'
import { useMobileColorScheme } from '../theme/use-mobile-color-scheme'
import {
agentDisplayLabel,
agentDotState,
agentRowTimeAt,
formatTimeAgo
} from '../worktree/agent-row-display'
import { AgentStateDot } from './AgentStateDot'
import { MobileAgentIcon } from './MobileAgentIcon'
import type { AgentChildRowModel } from '../../../src/shared/agent-status/presentation/agent-child-row-model'
import { mobileAgentChildRowText } from '../worktree/mobile-agent-child-row-text'
export const AGENT_ROW_INDENT_PER_DEPTH = 14
type Props = {
agent: RuntimeWorktreeAgentRow
depth: number
now: number
// Use workspace’s unvisited signal for agent bold/foreground too, matching desktop.
unvisited: boolean
childRow?: AgentChildRowModel
isReadOnly?: boolean
onPress?: (paneKey: string) => void
onLongPress?: () => void
trailing?: ReactNode
}
// Match compact desktop DashboardAgentRow: state→identity→message/prompt→age.
function WorktreeAgentRowComponent({
agent,
depth,
now,
unvisited,
childRow,
isReadOnly,
onPress,
onLongPress,
trailing
}: Props) {
useMobileColorScheme()
const dotState = childRow?.displayState ?? agentDotState(agent, now)
// Visuals render only in transcript; row keeps surrounding prose and treats visual-only reply as empty.
const reply = agent.lastAssistantMessage
const label = agentDisplayLabel(
reply
? { ...agent, lastAssistantMessage: withoutNativeChatVisualDirectiveLines(reply) }
: agent,
now
)
const childText = childRow ? mobileAgentChildRowText(childRow, now) : null
const timeAt = childRow ? childRow.firstObservedAt : agentRowTimeAt(agent)
// Like desktop, a silent row reports how long since its last update, not when its turn began.
const ts =
childRow && timeAt <= 0
? ''
: !childRow && dotState === 'unverifiable'
? agentNoUpdateLabel(agent, now)
: formatTimeAgo(timeAt, now)
const content = (
{/* Use desktop-style agent identity logo instead of two-letter code. */}
{!childRow && agent.agentType ? (
) : null}
{childText ? (
<>
{childText.lead}
{childText.trail ? ` · ${childText.trail}` : ''}
>
) : (
label
)}
{trailing}
{ts}
)
return onPress ? (
pressed && pressedStyle}
disabled={isReadOnly}
accessibilityRole="button"
onPress={(event) => {
event.stopPropagation()
onPress(agent.paneKey)
}}
onLongPress={onLongPress}
delayLongPress={400}
>
{content}
) : (
content
)
}
export const WorktreeAgentRow = memo(WorktreeAgentRowComponent)
const styles = themedStyleSheet(() => ({
row: {
flexDirection: 'row',
alignItems: 'center',
gap: spacing.xs,
marginTop: 3
},
label: {
flex: 1,
fontSize: 11,
color: colors.textMuted
},
labelUnvisited: {
color: colors.textPrimary,
fontWeight: '600'
},
time: {
fontSize: 10,
color: colors.textMuted
}
}))