From 1b3d788f684b08ce7d5c4f3758bdd88a9be66392 Mon Sep 17 00:00:00 2001 From: arman Date: Thu, 12 Nov 2026 10:55:37 +0000 Subject: [PATCH] fix(web): Cmd+F in the right panel reaches Files search on a new thread Co-Authored-By: Claude Opus 5.5 --- .../src/shortcuts/chatRouteCommands.test.ts | 30 +++++++++++++++++++ apps/web/src/shortcuts/chatRouteCommands.ts | 10 +++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/apps/web/src/shortcuts/chatRouteCommands.test.ts b/apps/web/src/shortcuts/chatRouteCommands.test.ts index a4c6b53279c84..4974afbff71ab 100644 --- a/apps/web/src/shortcuts/chatRouteCommands.test.ts +++ b/apps/web/src/shortcuts/chatRouteCommands.test.ts @@ -3,11 +3,14 @@ import type { AnyRouter } from "@tanstack/react-router"; import { describe, expect, it, vi } from "vite-plus/test"; import * as commandPalette from "../commandPaletteBus"; +import { useComposerDraftStore } from "../composerDraftStore"; +import * as previewActions from "../components/preview/previewActionBus"; import * as settings from "../hooks/useSettings"; import * as storage from "../hooks/useLocalStorage"; import * as threadActions from "../lib/chatThreadActions"; import * as entities from "../state/entities"; import * as projectsState from "../state/projects"; +import * as session from "../state/session"; import { Atom } from "effect/reactivity"; import type { Project } from "../types"; import { installChatRouteCommands } from "./chatRouteCommands"; @@ -73,3 +76,30 @@ describe("new thread commands", () => { } }); }); + +describe("preview commands", () => { + it.each([ + { route: "saved thread", params: { environmentId: "local", threadId: "thread-1" } }, + { route: "draft thread", params: { draftId: "draft-1" } }, + ])("find reaches the panel on a $route", ({ params }) => { + using _scope = vi.spyOn(session, "readEnvironmentScope").mockReturnValue(true); + using _draft = vi + .spyOn(useComposerDraftStore.getState(), "getDraftSession") + .mockReturnValue({ environmentId: EnvironmentId.make("local") } as never); + using dispatchAction = vi + .spyOn(previewActions, "dispatchPreviewAction") + .mockImplementation(() => {}); + using register = vi.spyOn(dispatcher, "registerCommands").mockReturnValue(() => {}); + const router = { state: { matches: [{ params }] } } as unknown as AnyRouter; + using stack = new DisposableStack(); + stack.defer(installChatRouteCommands(router)); + const commands = register.mock.calls[0]![0]; + + commands["preview.find"]!({ + preventDefault: vi.fn(), + stopPropagation: vi.fn(), + } as unknown as KeyboardEvent); + + expect(dispatchAction).toHaveBeenCalledWith("find"); + }); +}); diff --git a/apps/web/src/shortcuts/chatRouteCommands.ts b/apps/web/src/shortcuts/chatRouteCommands.ts index a08e2fa5a46f4..47ccfed989e24 100644 --- a/apps/web/src/shortcuts/chatRouteCommands.ts +++ b/apps/web/src/shortcuts/chatRouteCommands.ts @@ -114,8 +114,14 @@ export function installChatRouteCommands(router: AnyRouter): () => void { (action: PreviewAction): CommandHandler => (event) => { claim(event); - const threadRef = readRouteThreadRef(); - if (threadRef && canOperatePreview(threadRef.environmentId)) dispatchPreviewAction(action); + const target = readRouteTarget(); + const environmentId = + target?.kind === "server" + ? target.threadRef.environmentId + : target + ? useComposerDraftStore.getState().getDraftSession(target.draftId)?.environmentId + : undefined; + if (environmentId && canOperatePreview(environmentId)) dispatchPreviewAction(action); }; return registerCommands(