diff --git a/apps/app/src/components/secondary-panel/ThreadMetadataContent.tsx b/apps/app/src/components/secondary-panel/ThreadMetadataContent.tsx index 493b5a603c..d9cdccf6d1 100644 --- a/apps/app/src/components/secondary-panel/ThreadMetadataContent.tsx +++ b/apps/app/src/components/secondary-panel/ThreadMetadataContent.tsx @@ -241,6 +241,7 @@ export function EnvironmentRow({ const createThreadInEnvironment = useCreateThreadInEnvironment({ projectId: thread.projectId, environmentId: environment?.id ?? "", + sectionId: thread.sectionId, }); const { providers } = useSystemEnvironmentProviders(); const { providers: machineProviders } = useSystemMachineProviders(); diff --git a/apps/app/src/components/sidebar/ProjectRow.tsx b/apps/app/src/components/sidebar/ProjectRow.tsx index f240914897..cfacb87dce 100644 --- a/apps/app/src/components/sidebar/ProjectRow.tsx +++ b/apps/app/src/components/sidebar/ProjectRow.tsx @@ -1064,6 +1064,7 @@ const EnvironmentThreadGroupRow = memo(function EnvironmentThreadGroupRow({ const createThreadInEnvironment = useCreateThreadInEnvironment({ projectId, environmentId, + sectionId: representativeThread.sectionId, }); const threads = useMemo(() => nodes.map((node) => node.thread), [nodes]); const { archiveThreadsPending, onArchiveThreads } = diff --git a/apps/app/src/hooks/useCreateThreadInEnvironment.test.ts b/apps/app/src/hooks/useCreateThreadInEnvironment.test.ts index 14c80c0ff2..bca5cfba37 100644 --- a/apps/app/src/hooks/useCreateThreadInEnvironment.test.ts +++ b/apps/app/src/hooks/useCreateThreadInEnvironment.test.ts @@ -4,6 +4,7 @@ import { renderHook } from "@testing-library/react"; import { describe, expect, it, vi } from "vitest"; import { hasSingleUseRootComposeTargetState, + readRootComposeSectionTargetFromLocationState, shouldStartComposingFromLocationState, } from "@/views/RootComposeView"; import { useCreateThreadInEnvironment } from "./useCreateThreadInEnvironment"; @@ -19,19 +20,27 @@ vi.mock("@/lib/root-compose-selection", () => ({ })); describe("useCreateThreadInEnvironment", () => { - it("navigates with state that opens the composer and seeds the environment", () => { - navigate.mockClear(); - const { result } = renderHook(() => - useCreateThreadInEnvironment({ - projectId: "proj_personal", - environmentId: "env_1", - }), - ); + it.each(["sec_a", null])( + "opens the composer in the source environment and section %s", + (sectionId) => { + navigate.mockClear(); + const { result } = renderHook(() => + useCreateThreadInEnvironment({ + projectId: "proj_personal", + environmentId: "env_1", + sectionId, + }), + ); - result.current(); + result.current(); - const state = navigate.mock.calls[0][1].state; - expect(shouldStartComposingFromLocationState(state)).toBe(true); - expect(hasSingleUseRootComposeTargetState(state)).toBe(true); - }); + const state = navigate.mock.calls[0][1].state; + expect(state.reuseEnvironmentId).toBe("env_1"); + expect(readRootComposeSectionTargetFromLocationState(state)).toEqual( + sectionId ? { kind: "set", sectionId } : { kind: "clear" }, + ); + expect(shouldStartComposingFromLocationState(state)).toBe(true); + expect(hasSingleUseRootComposeTargetState(state)).toBe(true); + }, + ); }); diff --git a/apps/app/src/hooks/useCreateThreadInEnvironment.ts b/apps/app/src/hooks/useCreateThreadInEnvironment.ts index 7588c0a3b4..bd8e8c278d 100644 --- a/apps/app/src/hooks/useCreateThreadInEnvironment.ts +++ b/apps/app/src/hooks/useCreateThreadInEnvironment.ts @@ -6,18 +6,24 @@ import { useSetRootComposeProjectId } from "@/lib/root-compose-selection"; interface UseCreateThreadInEnvironmentArgs { projectId: string; environmentId: string; + sectionId: string | null; } export function useCreateThreadInEnvironment({ projectId, environmentId, + sectionId, }: UseCreateThreadInEnvironmentArgs): () => void { const navigate = useRouteNavigate(); const setRootComposeProjectId = useSetRootComposeProjectId(); return useCallback(() => { setRootComposeProjectId(projectId); navigate(getRootComposeRoutePath(), { - state: { focusPrompt: true, reuseEnvironmentId: environmentId }, + state: { + focusPrompt: true, + reuseEnvironmentId: environmentId, + sectionId, + }, }); - }, [environmentId, navigate, projectId, setRootComposeProjectId]); + }, [environmentId, navigate, projectId, sectionId, setRootComposeProjectId]); } diff --git a/apps/app/src/views/thread-detail/ThreadDetailView.tsx b/apps/app/src/views/thread-detail/ThreadDetailView.tsx index b0604c451b..4ad2f7c815 100644 --- a/apps/app/src/views/thread-detail/ThreadDetailView.tsx +++ b/apps/app/src/views/thread-detail/ThreadDetailView.tsx @@ -1213,6 +1213,7 @@ function ThreadDetailViewInternal(props: ThreadRoutePathArgs) { const createThreadInEnvironment = useCreateThreadInEnvironment({ projectId, environmentId: thread?.environmentId ?? "", + sectionId: thread?.sectionId ?? null, }); const { providers: registeredEnvironmentProviders } = useSystemEnvironmentProviders();