From 6bb0c14a98530c40afb93eb60cd31ef808ce3ebe Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Tue, 27 Oct 2026 19:48:24 -0700 Subject: [PATCH] refactor: group native chat text presentation (#34647) --- config/scripts/ci-shard-timings.json | 2 +- .../transcript/MobileNativeChatMessage.paced-reveal.test.ts | 4 ++-- .../native-chat/transcript/MobileNativeChatMessageTime.tsx | 2 +- .../native-chat/transcript/MobileNativeChatPacedProse.tsx | 2 +- .../transcript/MobileNativeChatUserMessageFold.tsx | 2 +- .../transcript/mobile-native-chat-reply-reveals.ts | 2 +- .../transcript/use-mobile-native-chat-paced-text.ts | 2 +- .../native-chat/NativeChatMessageList.render-cost.test.tsx | 4 ++-- .../src/components/native-chat/NativeChatMessageTimestamp.tsx | 2 +- .../native-chat/NativeChatPacedMarkdown.file-links.test.tsx | 2 +- .../native-chat/NativeChatPacedMarkdown.mermaid.test.tsx | 2 +- .../src/components/native-chat/NativeChatUserMessageFold.tsx | 2 +- .../src/components/native-chat/native-chat-reply-reveals.ts | 2 +- .../components/native-chat/native-chat-row-height-estimate.ts | 2 +- .../native-chat/use-native-chat-paced-text.remount.test.tsx | 2 +- .../src/components/native-chat/use-native-chat-paced-text.ts | 2 +- .../src/components/sidebar/comment-markdown-word-fade.ts | 2 +- src/shared/native-chat-row-content.ts | 2 +- .../{ => native-chat/transcript}/native-chat-message-time.ts | 0 src/shared/{ => native-chat/transcript}/native-chat-prose.ts | 2 +- .../{ => native-chat/transcript}/native-chat-reply-reveals.ts | 0 .../transcript}/native-chat-text-reveal.test.ts | 0 .../{ => native-chat/transcript}/native-chat-text-reveal.ts | 0 .../transcript}/native-chat-user-message-fold.ts | 0 24 files changed, 21 insertions(+), 21 deletions(-) rename src/shared/{ => native-chat/transcript}/native-chat-message-time.ts (100%) rename src/shared/{ => native-chat/transcript}/native-chat-prose.ts (73%) rename src/shared/{ => native-chat/transcript}/native-chat-reply-reveals.ts (100%) rename src/shared/{ => native-chat/transcript}/native-chat-text-reveal.test.ts (100%) rename src/shared/{ => native-chat/transcript}/native-chat-text-reveal.ts (100%) rename src/shared/{ => native-chat/transcript}/native-chat-user-message-fold.ts (100%) diff --git a/config/scripts/ci-shard-timings.json b/config/scripts/ci-shard-timings.json index fd0510c8c72..e27ef77f5f2 100644 --- a/config/scripts/ci-shard-timings.json +++ b/config/scripts/ci-shard-timings.json @@ -12509,7 +12509,7 @@ "src/shared/native-chat-subagent-summary.test.ts": 45, "src/shared/native-chat/input/native-chat-task-list-history.test.ts": 58, "src/shared/native-chat/input/native-chat-task-list.test.ts": 41, - "src/shared/native-chat-text-reveal.test.ts": 27, + "src/shared/native-chat/transcript/native-chat-text-reveal.test.ts": 27, "src/shared/native-chat-transcript-contracts.test.ts": 591, "src/shared/native-chat-transcript-projection.test.ts": 134, "src/shared/native-chat-transcript-retention.test.ts": 55, diff --git a/mobile/src/session/native-chat/transcript/MobileNativeChatMessage.paced-reveal.test.ts b/mobile/src/session/native-chat/transcript/MobileNativeChatMessage.paced-reveal.test.ts index 94863c774b6..a15fcf61686 100644 --- a/mobile/src/session/native-chat/transcript/MobileNativeChatMessage.paced-reveal.test.ts +++ b/mobile/src/session/native-chat/transcript/MobileNativeChatMessage.paced-reveal.test.ts @@ -5,8 +5,8 @@ import type { NativeChatMessage } from '../../../../../src/shared/native-chat-ty import { createNativeChatReplyRevealTracker, trackNativeChatReplyRows -} from '../../../../../src/shared/native-chat-reply-reveals' -import { NATIVE_CHAT_TEXT_REVEAL_DELAY_MS } from '../../../../../src/shared/native-chat-text-reveal' +} from '../../../../../src/shared/native-chat/transcript/native-chat-reply-reveals' +import { NATIVE_CHAT_TEXT_REVEAL_DELAY_MS } from '../../../../../src/shared/native-chat/transcript/native-chat-text-reveal' import { MobileNativeChatReplyRevealsContext, type MobileNativeChatReplyReveals diff --git a/mobile/src/session/native-chat/transcript/MobileNativeChatMessageTime.tsx b/mobile/src/session/native-chat/transcript/MobileNativeChatMessageTime.tsx index ee56472b941..f94409b53f4 100644 --- a/mobile/src/session/native-chat/transcript/MobileNativeChatMessageTime.tsx +++ b/mobile/src/session/native-chat/transcript/MobileNativeChatMessageTime.tsx @@ -3,7 +3,7 @@ import { Text } from 'react-native' import { NATIVE_CHAT_MESSAGE_FULL_TIME_FORMAT, NATIVE_CHAT_MESSAGE_TIME_FORMAT -} from '../../../../../src/shared/native-chat-message-time' +} from '../../../../../src/shared/native-chat/transcript/native-chat-message-time' import { colors, typography } from '../../../theme/mobile-theme' import { themedStyleSheet } from '../../../theme/themed-styles' import { useMobileColorScheme } from '../../../theme/use-mobile-color-scheme' diff --git a/mobile/src/session/native-chat/transcript/MobileNativeChatPacedProse.tsx b/mobile/src/session/native-chat/transcript/MobileNativeChatPacedProse.tsx index e1f2612b678..284bcbc4b54 100644 --- a/mobile/src/session/native-chat/transcript/MobileNativeChatPacedProse.tsx +++ b/mobile/src/session/native-chat/transcript/MobileNativeChatPacedProse.tsx @@ -1,5 +1,5 @@ import { useMemo, type ReactNode } from 'react' -import { nativeChatProseToMarkdown } from '../../../../../src/shared/native-chat-prose' +import { nativeChatProseToMarkdown } from '../../../../../src/shared/native-chat/transcript/native-chat-prose' import { isTextBlock, type NativeChatBlock } from '../../../../../src/shared/native-chat-types' import { useMobileNativeChatPacedText, diff --git a/mobile/src/session/native-chat/transcript/MobileNativeChatUserMessageFold.tsx b/mobile/src/session/native-chat/transcript/MobileNativeChatUserMessageFold.tsx index 71de3105885..380ef6a9130 100644 --- a/mobile/src/session/native-chat/transcript/MobileNativeChatUserMessageFold.tsx +++ b/mobile/src/session/native-chat/transcript/MobileNativeChatUserMessageFold.tsx @@ -3,7 +3,7 @@ import { Pressable, Text, View } from 'react-native' import { NATIVE_CHAT_USER_MESSAGE_MAX_UNFOLDED_LINES, nativeChatUserMessageFolds -} from '../../../../../src/shared/native-chat-user-message-fold' +} from '../../../../../src/shared/native-chat/transcript/native-chat-user-message-fold' import { styles as markdownStyles } from '../../../components/mobile-markdown-styles' import { colors, spacing, typography } from '../../../theme/mobile-theme' import { themedStyleSheet } from '../../../theme/themed-styles' diff --git a/mobile/src/session/native-chat/transcript/mobile-native-chat-reply-reveals.ts b/mobile/src/session/native-chat/transcript/mobile-native-chat-reply-reveals.ts index 8ff5d3460de..9a40584c888 100644 --- a/mobile/src/session/native-chat/transcript/mobile-native-chat-reply-reveals.ts +++ b/mobile/src/session/native-chat/transcript/mobile-native-chat-reply-reveals.ts @@ -5,7 +5,7 @@ import { createNativeChatReplyRevealTracker, trackNativeChatReplyRows, type NativeChatReplyReveals -} from '../../../../../src/shared/native-chat-reply-reveals' +} from '../../../../../src/shared/native-chat/transcript/native-chat-reply-reveals' import { useReducedMotionEnabled } from '../../../platform/use-reduced-motion' // Retain reveal state above list remounts/view toggles so replies resume instead of replaying. diff --git a/mobile/src/session/native-chat/transcript/use-mobile-native-chat-paced-text.ts b/mobile/src/session/native-chat/transcript/use-mobile-native-chat-paced-text.ts index 7bf5e6f7f69..43833783720 100644 --- a/mobile/src/session/native-chat/transcript/use-mobile-native-chat-paced-text.ts +++ b/mobile/src/session/native-chat/transcript/use-mobile-native-chat-paced-text.ts @@ -11,7 +11,7 @@ import { receiveNativeChatText, startNativeChatTextReveal, type NativeChatTextRevealFrames -} from '../../../../../src/shared/native-chat-text-reveal' +} from '../../../../../src/shared/native-chat/transcript/native-chat-text-reveal' import { MobileNativeChatReplyRevealsContext } from './mobile-native-chat-reply-reveals' import { MobileNativeChatGrowthHoldContext } from '../../mobile-native-chat-growth-hold' diff --git a/src/renderer/src/components/native-chat/NativeChatMessageList.render-cost.test.tsx b/src/renderer/src/components/native-chat/NativeChatMessageList.render-cost.test.tsx index c94acf75a3e..3ce7b5cf16a 100644 --- a/src/renderer/src/components/native-chat/NativeChatMessageList.render-cost.test.tsx +++ b/src/renderer/src/components/native-chat/NativeChatMessageList.render-cost.test.tsx @@ -25,7 +25,7 @@ afterEach(() => { expect(unusedChatLeaves.openSender).not.toHaveBeenCalled() }) import type * as NativeChatWorkRunModule from '../../../../shared/native-chat/native-chat-work-run' -import type * as NativeChatProseModule from '../../../../shared/native-chat-prose' +import type * as NativeChatProseModule from '../../../../shared/native-chat/transcript/native-chat-prose' import type { NativeChatMessage } from '../../../../shared/native-chat-types' import { projectStructuredAgentSessionMessages } from '../../../../shared/structured-agent-session-message-projection' import type { AgentJournalRenderItem } from '../../../../shared/agent-session-journal-types' @@ -35,7 +35,7 @@ import { installNativeChatMessageListTestViewport } from './native-chat-message- // Count markdown derivations: low render counts alone can hide repeated settled-row work. const proseCalls = vi.hoisted(() => ({ count: 0 })) -vi.mock('../../../../shared/native-chat-prose', async (importOriginal) => { +vi.mock('../../../../shared/native-chat/transcript/native-chat-prose', async (importOriginal) => { const actual = await importOriginal() return { ...actual, diff --git a/src/renderer/src/components/native-chat/NativeChatMessageTimestamp.tsx b/src/renderer/src/components/native-chat/NativeChatMessageTimestamp.tsx index 438c5b5c442..22d99d1edd4 100644 --- a/src/renderer/src/components/native-chat/NativeChatMessageTimestamp.tsx +++ b/src/renderer/src/components/native-chat/NativeChatMessageTimestamp.tsx @@ -4,7 +4,7 @@ import { cn } from '@/lib/utils' import { NATIVE_CHAT_MESSAGE_FULL_TIME_FORMAT, NATIVE_CHAT_MESSAGE_TIME_FORMAT -} from '../../../../shared/native-chat-message-time' +} from '../../../../shared/native-chat/transcript/native-chat-message-time' let cached: { locale: string diff --git a/src/renderer/src/components/native-chat/NativeChatPacedMarkdown.file-links.test.tsx b/src/renderer/src/components/native-chat/NativeChatPacedMarkdown.file-links.test.tsx index c320d19ea52..6ef44852e7e 100644 --- a/src/renderer/src/components/native-chat/NativeChatPacedMarkdown.file-links.test.tsx +++ b/src/renderer/src/components/native-chat/NativeChatPacedMarkdown.file-links.test.tsx @@ -11,7 +11,7 @@ import { NativeChatReplyRevealsContext, type NativeChatReplyReveals } from './native-chat-reply-reveals' -import { NATIVE_CHAT_TEXT_REVEAL_DELAY_MS } from '../../../../shared/native-chat-text-reveal' +import { NATIVE_CHAT_TEXT_REVEAL_DELAY_MS } from '../../../../shared/native-chat/transcript/native-chat-text-reveal' vi.mock('@/hooks/usePrefersReducedMotion', () => ({ usePrefersReducedMotion: () => false })) vi.mock('./native-chat-visual-markdown-extension', () => ({ diff --git a/src/renderer/src/components/native-chat/NativeChatPacedMarkdown.mermaid.test.tsx b/src/renderer/src/components/native-chat/NativeChatPacedMarkdown.mermaid.test.tsx index 87ec8efebad..0482599f614 100644 --- a/src/renderer/src/components/native-chat/NativeChatPacedMarkdown.mermaid.test.tsx +++ b/src/renderer/src/components/native-chat/NativeChatPacedMarkdown.mermaid.test.tsx @@ -6,7 +6,7 @@ import { NativeChatReplyRevealsContext, type NativeChatReplyReveals } from './native-chat-reply-reveals' -import { NATIVE_CHAT_TEXT_REVEAL_DELAY_MS } from '../../../../shared/native-chat-text-reveal' +import { NATIVE_CHAT_TEXT_REVEAL_DELAY_MS } from '../../../../shared/native-chat/transcript/native-chat-text-reveal' const reveals: NativeChatReplyReveals = { begun: new Set(['reply']), drawn: new Map() } diff --git a/src/renderer/src/components/native-chat/NativeChatUserMessageFold.tsx b/src/renderer/src/components/native-chat/NativeChatUserMessageFold.tsx index ef2e89ae12f..1eb23f8ceaf 100644 --- a/src/renderer/src/components/native-chat/NativeChatUserMessageFold.tsx +++ b/src/renderer/src/components/native-chat/NativeChatUserMessageFold.tsx @@ -3,7 +3,7 @@ import { Button } from '@/components/ui/button' import { translate } from '@/i18n/i18n' import { cn } from '@/lib/utils' import { useNativeChatDisclosure } from './native-chat-disclosure-store' -import { nativeChatUserMessageFolds } from '../../../../shared/native-chat-user-message-fold' +import { nativeChatUserMessageFolds } from '../../../../shared/native-chat/transcript/native-chat-user-message-fold' export function NativeChatUserMessageFold({ messageId, diff --git a/src/renderer/src/components/native-chat/native-chat-reply-reveals.ts b/src/renderer/src/components/native-chat/native-chat-reply-reveals.ts index 894b26a2d41..dbb675380e6 100644 --- a/src/renderer/src/components/native-chat/native-chat-reply-reveals.ts +++ b/src/renderer/src/components/native-chat/native-chat-reply-reveals.ts @@ -3,7 +3,7 @@ import { createNativeChatReplyRevealTracker, trackNativeChatReplyRows, type NativeChatReplyReveals -} from '../../../../shared/native-chat-reply-reveals' +} from '../../../../shared/native-chat/transcript/native-chat-reply-reveals' export type { NativeChatReplyReveals } diff --git a/src/renderer/src/components/native-chat/native-chat-row-height-estimate.ts b/src/renderer/src/components/native-chat/native-chat-row-height-estimate.ts index f6f873ce1dd..6a56ed3b174 100644 --- a/src/renderer/src/components/native-chat/native-chat-row-height-estimate.ts +++ b/src/renderer/src/components/native-chat/native-chat-row-height-estimate.ts @@ -5,7 +5,7 @@ import { deriveNativeChatRowContent } from '../../../../shared/native-chat-row-c import { NATIVE_CHAT_USER_MESSAGE_FOLDED_PX, nativeChatUserMessageFolds -} from '../../../../shared/native-chat-user-message-fold' +} from '../../../../shared/native-chat/transcript/native-chat-user-message-fold' export type NativeChatRowContentMetrics = { role: NativeChatMessage['role'] diff --git a/src/renderer/src/components/native-chat/use-native-chat-paced-text.remount.test.tsx b/src/renderer/src/components/native-chat/use-native-chat-paced-text.remount.test.tsx index 88b239e09b4..89d3cfa6609 100644 --- a/src/renderer/src/components/native-chat/use-native-chat-paced-text.remount.test.tsx +++ b/src/renderer/src/components/native-chat/use-native-chat-paced-text.remount.test.tsx @@ -6,7 +6,7 @@ import { NativeChatReplyRevealsContext, type NativeChatReplyReveals } from './native-chat-reply-reveals' -import { NATIVE_CHAT_TEXT_REVEAL_DELAY_MS as D } from '../../../../shared/native-chat-text-reveal' +import { NATIVE_CHAT_TEXT_REVEAL_DELAY_MS as D } from '../../../../shared/native-chat/transcript/native-chat-text-reveal' import { useNativeChatPacedText } from './use-native-chat-paced-text' const motion = vi.hoisted(() => ({ reduced: false })) diff --git a/src/renderer/src/components/native-chat/use-native-chat-paced-text.ts b/src/renderer/src/components/native-chat/use-native-chat-paced-text.ts index ca2925c996b..a6937de36df 100644 --- a/src/renderer/src/components/native-chat/use-native-chat-paced-text.ts +++ b/src/renderer/src/components/native-chat/use-native-chat-paced-text.ts @@ -8,7 +8,7 @@ import { startNativeChatTextReveal, type NativeChatTextReveal, type NativeChatTextRevealFrames -} from '../../../../shared/native-chat-text-reveal' +} from '../../../../shared/native-chat/transcript/native-chat-text-reveal' const WORD_FADE_MS = 300 diff --git a/src/renderer/src/components/sidebar/comment-markdown-word-fade.ts b/src/renderer/src/components/sidebar/comment-markdown-word-fade.ts index bf15a92437d..2b2461c689f 100644 --- a/src/renderer/src/components/sidebar/comment-markdown-word-fade.ts +++ b/src/renderer/src/components/sidebar/comment-markdown-word-fade.ts @@ -1,7 +1,7 @@ // Keep existing word elements stable while streams append so only newly mounted words fade. import type { Element, Root } from 'hast' -import { SPACELESS_SCRIPT_RANGES } from '../../../../shared/native-chat-text-reveal' +import { SPACELESS_SCRIPT_RANGES } from '../../../../shared/native-chat/transcript/native-chat-text-reveal' /** Elements whose renderers read their text, or that are faded in as a whole. */ const UNSPLIT_TAGS = new Set(['a', 'code', 'pre', 'kbd', 'svg', 'math']) diff --git a/src/shared/native-chat-row-content.ts b/src/shared/native-chat-row-content.ts index ebe4bb475c9..17680653b7c 100644 --- a/src/shared/native-chat-row-content.ts +++ b/src/shared/native-chat-row-content.ts @@ -13,7 +13,7 @@ import { type NativeChatBlock } from './native-chat-types' import { splitNativeChatBlocks } from './native-chat/tools/native-chat-tool-fold' -import { nativeChatProseToMarkdown } from './native-chat-prose' +import { nativeChatProseToMarkdown } from './native-chat/transcript/native-chat-prose' /** Inferred from `derive` so the shape cannot drift from what it returns. */ export type NativeChatRowContent = ReturnType diff --git a/src/shared/native-chat-message-time.ts b/src/shared/native-chat/transcript/native-chat-message-time.ts similarity index 100% rename from src/shared/native-chat-message-time.ts rename to src/shared/native-chat/transcript/native-chat-message-time.ts diff --git a/src/shared/native-chat-prose.ts b/src/shared/native-chat/transcript/native-chat-prose.ts similarity index 73% rename from src/shared/native-chat-prose.ts rename to src/shared/native-chat/transcript/native-chat-prose.ts index c22ad2e3bc5..b57a670b536 100644 --- a/src/shared/native-chat-prose.ts +++ b/src/shared/native-chat/transcript/native-chat-prose.ts @@ -1,4 +1,4 @@ -import { isTextBlock, type NativeChatBlock } from './native-chat-types' +import { isTextBlock, type NativeChatBlock } from '../../native-chat-types' export function nativeChatProseToMarkdown(blocks: NativeChatBlock[]): string { return blocks diff --git a/src/shared/native-chat-reply-reveals.ts b/src/shared/native-chat/transcript/native-chat-reply-reveals.ts similarity index 100% rename from src/shared/native-chat-reply-reveals.ts rename to src/shared/native-chat/transcript/native-chat-reply-reveals.ts diff --git a/src/shared/native-chat-text-reveal.test.ts b/src/shared/native-chat/transcript/native-chat-text-reveal.test.ts similarity index 100% rename from src/shared/native-chat-text-reveal.test.ts rename to src/shared/native-chat/transcript/native-chat-text-reveal.test.ts diff --git a/src/shared/native-chat-text-reveal.ts b/src/shared/native-chat/transcript/native-chat-text-reveal.ts similarity index 100% rename from src/shared/native-chat-text-reveal.ts rename to src/shared/native-chat/transcript/native-chat-text-reveal.ts diff --git a/src/shared/native-chat-user-message-fold.ts b/src/shared/native-chat/transcript/native-chat-user-message-fold.ts similarity index 100% rename from src/shared/native-chat-user-message-fold.ts rename to src/shared/native-chat/transcript/native-chat-user-message-fold.ts