diff --git a/packages/app/e2e/find-in-pane.spec.ts b/packages/app/e2e/find-in-pane.spec.ts index 3bc178114e..0576fccf88 100644 --- a/packages/app/e2e/find-in-pane.spec.ts +++ b/packages/app/e2e/find-in-pane.spec.ts @@ -1,10 +1,7 @@ import { expect, test, type Page } from "./fixtures"; import { waitForTabBar } from "./helpers/launcher"; -import { - connectTerminalClient, - setupDeterministicPrompt, - waitForTerminalContent, -} from "./helpers/terminal-perf"; +import { setupDeterministicPrompt, waitForTerminalContent } from "./helpers/terminal-perf"; +import { connectSeedClient } from "./helpers/seed-client"; import { createTempGitRepo } from "./helpers/workspace"; import { openFileExplorer, openFileFromExplorer } from "./helpers/file-explorer"; import { @@ -51,7 +48,7 @@ test.describe("in-pane find", () => { test.setTimeout(120_000); const client = await connectWorkspaceSetupClient(); - const agentClient = await connectTerminalClient(); + const agentClient = await connectSeedClient(); const repo = await createTempGitRepo("find-pane-qa-", { files: [ { diff --git a/packages/app/src/agent-stream/view.tsx b/packages/app/src/agent-stream/view.tsx index 9686ba7b15..9f453bd895 100644 --- a/packages/app/src/agent-stream/view.tsx +++ b/packages/app/src/agent-stream/view.tsx @@ -63,7 +63,7 @@ import { buildAgentStreamSearchModel, findAgentStreamSearchMatches, type AgentStreamSearchMatch, -} from "./agent-stream-search-model"; +} from "@/components/agent-stream-search-model"; import { type BottomAnchorLocalRequest, type BottomAnchorRouteRequest, @@ -87,11 +87,6 @@ import { type UsePaneFindResult, usePaneFind, } from "@/panels/pane-find"; -import { - getWorkingIndicatorDotStrength, - WORKING_INDICATOR_CYCLE_MS, - WORKING_INDICATOR_OFFSETS, -} from "@/utils/working-indicator"; import { isWeb } from "@/constants/platform"; import type { Theme } from "@/styles/theme"; @@ -601,25 +596,6 @@ const AgentStreamViewComponent = forwardRef { - if (agent.status !== "running") { - return null; - } - const footerItem = baseRenderModel.segments.liveHead.find((item, index, items) => { - if (item.kind !== "assistant_message") { - return false; - } - return ( - getStreamNeighborItem({ - strategy: streamRenderStrategy, - items, - index, - relation: "below", - }) === undefined - ); - }); - return footerItem?.id ?? null; - }, [agent.status, baseRenderModel.segments.liveHead, streamRenderStrategy]); useImperativeHandle( ref, () => ({ @@ -699,7 +675,14 @@ const AgentStreamViewComponent = forwardRef ); }, - [client, findHighlightsByItemId, handleInlinePathPress, resolvedServerId, toast, workspaceRoot], + [ + client, + findHighlightsByItemId, + handleInlinePathPress, + resolvedServerId, + toast, + workspaceRoot, + ], ); const renderThoughtItem = useCallback( @@ -998,110 +981,10 @@ const AgentStreamViewComponent = forwardRef { - progress.value = 0; - progress.value = withRepeat( - withTiming(1, { - duration: WORKING_INDICATOR_CYCLE_MS, - easing: Easing.linear, - }), - -1, - false, - ); - - return () => { - cancelAnimation(progress); - progress.value = 0; - }; - }, [progress]); - - const translateDistance = -2; - const dotOneStyle = useAnimatedStyle(() => { - const strength = getWorkingIndicatorDotStrength(progress.value, WORKING_INDICATOR_OFFSETS[0]); - return { - opacity: 0.3 + strength * 0.7, - transform: [{ translateY: strength * translateDistance }], - }; - }); - - const dotTwoStyle = useAnimatedStyle(() => { - const strength = getWorkingIndicatorDotStrength(progress.value, WORKING_INDICATOR_OFFSETS[1]); - return { - opacity: 0.3 + strength * 0.7, - transform: [{ translateY: strength * translateDistance }], - }; - }); - - const dotThreeStyle = useAnimatedStyle(() => { - const strength = getWorkingIndicatorDotStrength(progress.value, WORKING_INDICATOR_OFFSETS[2]); - return { - opacity: 0.3 + strength * 0.7, - transform: [{ translateY: strength * translateDistance }], - }; - }); - - const dotOneCombinedStyle = useMemo(() => [stylesheet.workingDot, dotOneStyle], [dotOneStyle]); - const dotTwoCombinedStyle = useMemo(() => [stylesheet.workingDot, dotTwoStyle], [dotTwoStyle]); - const dotThreeCombinedStyle = useMemo( - () => [stylesheet.workingDot, dotThreeStyle], - [dotThreeStyle], - ); - - const containerStyle = - variant === "inline" - ? stylesheet.inlineWorkingIndicatorFrame - : stylesheet.workingIndicatorBubble; - - return ( - - - - - - - - ); -} - -function InlineWorkingIndicatorSlot() { - return ( - - - - ); -} - function AgentStreamFindBarSlot({ paneFind }: { paneFind: UsePaneFindResult }) { return paneFind.isOpen ? : null; } -// Permission Request Card Component -type TurnContentStrategy = Parameters< - typeof collectAssistantTurnContentForStreamRenderStrategy ->[0]["strategy"]; - -interface TurnCopyButtonSlotProps { - strategy: TurnContentStrategy; - items: StreamItem[]; - startIndex: number; -} - -function TurnCopyButtonSlot({ strategy, items, startIndex }: TurnCopyButtonSlotProps) { - const getContent = useCallback( - () => - collectAssistantTurnContentForStreamRenderStrategy({ - strategy, - items, - startIndex, - }), - [strategy, items, startIndex], - ); - return ; -} - interface ToolCallSlotProps extends Omit< ComponentProps, "onInlineDetailsExpandedChange" diff --git a/packages/app/src/components/agent-stream-search-model.ts b/packages/app/src/components/agent-stream-search-model.ts index 9585bcec35..107f62ae46 100644 --- a/packages/app/src/components/agent-stream-search-model.ts +++ b/packages/app/src/components/agent-stream-search-model.ts @@ -3,7 +3,7 @@ import { findMountedWindowStart, getWebMountedRecentStreamItems, getWebPartialVirtualizationThreshold, -} from "./agent-stream-web-virtualization"; +} from "@/agent-stream/web-virtualization"; type AgentStreamSearchSource = "historyVirtualized" | "historyMounted" | "liveHead"; diff --git a/packages/app/src/components/browser-pane.electron.test.tsx b/packages/app/src/components/browser-pane.electron.test.tsx index 114f6673a9..0277794f70 100644 --- a/packages/app/src/components/browser-pane.electron.test.tsx +++ b/packages/app/src/components/browser-pane.electron.test.tsx @@ -236,6 +236,7 @@ const paneContextValue: PaneContextValue = { closeCurrentTab: vi.fn(), retargetCurrentTab: vi.fn(), openFileInWorkspace: vi.fn(), + openImportSheet: vi.fn(), }; function installWebviewElementFactory(): void { diff --git a/packages/app/src/components/file-pane.test.tsx b/packages/app/src/components/file-pane.test.tsx index 7160225046..9f4cb523ba 100644 --- a/packages/app/src/components/file-pane.test.tsx +++ b/packages/app/src/components/file-pane.test.tsx @@ -216,6 +216,7 @@ const paneContext: PaneContextValue = { closeCurrentTab: () => {}, retargetCurrentTab: () => {}, openFileInWorkspace: () => {}, + openImportSheet: () => {}, }; const paneFocus = createPaneFocusContextValue({ isPaneFocused: true, @@ -248,12 +249,12 @@ afterEach(() => { vi.unstubAllGlobals(); }); -function renderFilePane(filePath = "src/example.ts") { +function renderFilePane(location: { path: string } = { path: "src/example.ts" }) { act(() => { root?.render( - + , ); @@ -325,7 +326,7 @@ describe("FilePane preview rendering", () => { isFetching: false, }; - renderFilePane("README.md"); + renderFilePane({ path: "README.md" }); expect(container?.querySelector('[data-testid="markdown-preview"]')?.textContent).toBe( "# Guide", @@ -342,7 +343,7 @@ describe("FilePane preview rendering", () => { isFetching: false, }; - renderFilePane("logo.png"); + renderFilePane({ path: "logo.png" }); expect(container?.querySelector("img")?.getAttribute("src")).toBe("blob:preview"); }); @@ -362,7 +363,7 @@ describe("FilePane preview rendering", () => { isFetching: false, }; - renderFilePane("tool"); + renderFilePane({ path: "tool" }); expect(container?.textContent).toContain("Binary preview unavailable"); expect(container?.textContent).toContain("2.0 KB"); diff --git a/packages/app/src/components/file-pane.tsx b/packages/app/src/components/file-pane.tsx index 5390bd5262..7f71d5b7c1 100644 --- a/packages/app/src/components/file-pane.tsx +++ b/packages/app/src/components/file-pane.tsx @@ -238,7 +238,10 @@ interface CodeLineTokenProps { function CodeLineToken({ backgroundColor, style, text }: CodeLineTokenProps) { const tokenStyle = useMemo( - () => [style ? syntaxTokenStyleFor(style) : undefined, backgroundColor ? { backgroundColor } : null], + () => [ + style ? syntaxTokenStyleFor(style) : undefined, + backgroundColor ? { backgroundColor } : null, + ], [backgroundColor, style], ); return {text}; @@ -748,12 +751,11 @@ function FilePreviewBody({ } else if (preview.kind === "text" && textRenderData) { content = ( { it("approximates the offset for an unmeasured native FlatList row", () => { diff --git a/packages/app/src/components/terminal-emulator.tsx b/packages/app/src/components/terminal-emulator.tsx index acd75f212e..6591a39dbe 100644 --- a/packages/app/src/components/terminal-emulator.tsx +++ b/packages/app/src/components/terminal-emulator.tsx @@ -312,18 +312,6 @@ export default function TerminalEmulator({ blur: () => { runtimeRef.current?.blur(); }, - findNext: (input: { query: string }) => { - return runtimeRef.current?.findNext(input) ?? false; - }, - findPrevious: (input: { query: string }) => { - return runtimeRef.current?.findPrevious(input) ?? false; - }, - clearFindDecorations: () => { - runtimeRef.current?.clearFindDecorations(); - }, - onFindResultsChanged: (listener: (event: TerminalFindResultChangeEvent) => void) => { - return runtimeRef.current?.onFindResultsChanged(listener) ?? (() => {}); - }, }), [], ); diff --git a/packages/app/src/components/terminal-pane.test.tsx b/packages/app/src/components/terminal-pane.test.tsx index 1b2845aafc..2a49393e0c 100644 --- a/packages/app/src/components/terminal-pane.test.tsx +++ b/packages/app/src/components/terminal-pane.test.tsx @@ -28,8 +28,10 @@ const { client, findListeners, terminalProps, theme, terminalHandle, resetTermin const listeners: Array<(event: FindResultChange) => void> = []; const handle = { writeOutput: vi.fn(), + restoreOutput: vi.fn(), renderSnapshot: vi.fn(), clear: vi.fn(), + blur: vi.fn(), findNext: vi.fn(() => true), findPrevious: vi.fn(() => true), clearFindDecorations: vi.fn(), @@ -278,6 +280,7 @@ const paneContext: PaneContextValue = { closeCurrentTab: () => {}, retargetCurrentTab: () => {}, openFileInWorkspace: () => {}, + openImportSheet: () => {}, }; const paneFocus = createPaneFocusContextValue({ isPaneFocused: true, @@ -323,6 +326,7 @@ function renderTerminalPane(): void { isWorkspaceFocused isPaneFocused onOpenFileExplorer={vi.fn()} + onOpenWorkspaceFile={vi.fn()} /> , diff --git a/packages/app/src/panels/pane-find.test.tsx b/packages/app/src/panels/pane-find.test.tsx index a60ddf11a5..436f245543 100644 --- a/packages/app/src/panels/pane-find.test.tsx +++ b/packages/app/src/panels/pane-find.test.tsx @@ -222,6 +222,7 @@ const harnessPaneContext: PaneContextValue = { closeCurrentTab: () => {}, retargetCurrentTab: () => {}, openFileInWorkspace: () => {}, + openImportSheet: () => {}, }; const harnessPaneFocus = createPaneFocusContextValue({ isPaneFocused: true, @@ -451,6 +452,7 @@ describe("FindBar", () => { onCloseCurrentTab: vi.fn(), onRetargetCurrentTab: vi.fn(), onOpenWorkspaceFile: vi.fn(), + onOpenImportSheet: vi.fn(), }); const rightContent = buildWorkspacePaneContentModel({ @@ -462,6 +464,7 @@ describe("FindBar", () => { onCloseCurrentTab: vi.fn(), onRetargetCurrentTab: vi.fn(), onOpenWorkspaceFile: vi.fn(), + onOpenImportSheet: vi.fn(), }); const focusLeft = vi.fn(); const focusRight = vi.fn();