Fix workspace composer focus routing

This commit is contained in:
Mohamed Boudra
2026-04-20 17:41:00 +07:00
parent 33ac657fed
commit 95c1d1fe0f
2 changed files with 32 additions and 8 deletions
+30 -6
View File
@@ -7,7 +7,7 @@ import { createRoot, type Root } from "react-dom/client";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { afterEach, describe, expect, it, vi } from "vitest";
import { DaemonClient } from "@server/client/daemon-client";
import { PaneFocusProvider, PaneProvider } from "@/panels/pane-context";
import { PaneFocusProvider, PaneProvider, type PaneFocusContextValue } from "@/panels/pane-context";
import { agentPanelRegistration } from "@/panels/agent-panel";
import { useDraftStore } from "@/stores/draft-store";
import { useSessionStore, type Agent } from "@/stores/session-store";
@@ -39,6 +39,7 @@ const {
composerRenderCount,
composerUnmountCount,
latestComposerCwd,
latestComposerIsPaneFocused,
streamRenderCount,
latestStreamPermissionKeys,
latestStreamText,
@@ -66,6 +67,7 @@ const {
composerRenderCount: vi.fn(),
composerUnmountCount: vi.fn(),
latestComposerCwd: { current: null as string | null },
latestComposerIsPaneFocused: { current: null as boolean | null },
streamRenderCount: vi.fn(),
latestStreamPermissionKeys: { current: [] as string[] },
latestStreamText: { current: null as string | null },
@@ -166,7 +168,7 @@ vi.mock("@/hooks/use-archive-agent", () => ({
}));
vi.mock("@/components/composer", () => ({
Composer: ({ cwd }: { cwd: string }) => {
Composer: ({ cwd, isPaneFocused }: { cwd: string; isPaneFocused: boolean }) => {
React.useEffect(
() => () => {
composerUnmountCount();
@@ -175,6 +177,7 @@ vi.mock("@/components/composer", () => ({
);
composerRenderCount();
latestComposerCwd.current = cwd;
latestComposerIsPaneFocused.current = isPaneFocused;
return <div data-testid="composer">{cwd}</div>;
},
}));
@@ -244,7 +247,14 @@ function seedReadyAgent(agent: Agent = makeAgent()) {
store.setAgentAuthoritativeHistoryApplied("server", "agent", true);
}
async function renderAgentPanel(root: Root) {
async function renderAgentPanel(
root: Root,
focus: PaneFocusContextValue = {
isWorkspaceFocused: true,
isPaneFocused: false,
isInteractive: false,
},
) {
const AgentPanel = agentPanelRegistration.component;
const queryClient = new QueryClient({
defaultOptions: {
@@ -267,9 +277,7 @@ async function renderAgentPanel(root: Root) {
openFileInWorkspace: vi.fn(),
}}
>
<PaneFocusProvider
value={{ isWorkspaceFocused: true, isPaneFocused: false, isInteractive: false }}
>
<PaneFocusProvider value={focus}>
<AgentPanel />
</PaneFocusProvider>
</PaneProvider>
@@ -355,6 +363,7 @@ describe("AgentPanel render isolation", () => {
composerRenderCount.mockClear();
composerUnmountCount.mockClear();
latestComposerCwd.current = null;
latestComposerIsPaneFocused.current = null;
streamRenderCount.mockClear();
latestStreamPermissionKeys.current = [];
latestStreamText.current = null;
@@ -379,6 +388,21 @@ describe("AgentPanel render isolation", () => {
expect(composerRenderCount).toHaveBeenCalledTimes(composerBaseline);
});
it("does not advertise the composer as focused when its workspace is hidden", async () => {
seedReadyAgent();
container = document.createElement("div");
document.body.appendChild(container);
root = createRoot(container);
await renderAgentPanel(root, {
isWorkspaceFocused: false,
isPaneFocused: true,
isInteractive: false,
});
expect(latestComposerIsPaneFocused.current).toBe(false);
});
it("still invokes Composer for current-agent cwd changes and unmounts it for archives", async () => {
seedReadyAgent();
container = document.createElement("div");
+2 -2
View File
@@ -113,7 +113,7 @@ function useAgentPanelDescriptor(
function AgentPanel() {
const { serverId, target, openFileInWorkspace } = usePaneContext();
const { isPaneFocused } = usePaneFocus();
const { isInteractive } = usePaneFocus();
invariant(target.kind === "agent", "AgentPanel requires agent target");
function openWorkspaceFile(input: { filePath: string }) {
@@ -126,7 +126,7 @@ function AgentPanel() {
<AgentPanelContent
serverId={serverId}
agentId={target.agentId}
isPaneFocused={isPaneFocused}
isPaneFocused={isInteractive}
onOpenWorkspaceFile={handleOpenWorkspaceFile}
/>
);