diff --git a/packages/views/modals/create-issue.test.tsx b/packages/views/modals/create-issue.test.tsx index 596db8453..998ca7060 100644 --- a/packages/views/modals/create-issue.test.tsx +++ b/packages/views/modals/create-issue.test.tsx @@ -35,8 +35,8 @@ const mockDraftStore = { description: "", status: "todo" as const, priority: "none" as const, - assigneeType: undefined, - assigneeId: undefined, + assigneeType: undefined as "agent" | "squad" | "member" | undefined, + assigneeId: undefined as string | undefined, dueDate: null, }, lastAssigneeType: undefined, @@ -265,6 +265,10 @@ describe("CreateIssueModal", () => { mockSetKeepOpen.mockImplementation((v: boolean) => { mockQuickCreateStore.keepOpen = v; }); + // Reset the shared draft mock so per-test assignee seeding (squad / agent) + // doesn't leak into the next test in the suite. + mockDraftStore.draft.assigneeType = undefined; + mockDraftStore.draft.assigneeId = undefined; mockCreateIssue.mockResolvedValue({ id: "issue-123", identifier: "TES-123", @@ -357,6 +361,37 @@ describe("CreateIssueModal", () => { }); }); + // Manual → agent must also forward the picked squad. Without this branch + // the agent panel silently falls back to the persisted actor / first + // visible agent and the user loses the squad they just chose in manual. + it("forwards the picked squad when switching to agent mode", async () => { + mockDraftStore.draft.assigneeType = "squad"; + mockDraftStore.draft.assigneeId = "squad-1"; + const user = userEvent.setup(); + const onSwitchMode = vi.fn(); + + renderModal( + , + ); + + await user.type(screen.getByPlaceholderText("Issue title"), "Refactor auth"); + await user.click(screen.getByRole("button", { name: /Switch to Agent/i })); + + expect(onSwitchMode).toHaveBeenCalledTimes(1); + const carry = onSwitchMode.mock.calls[0]?.[0]; + expect(carry).toEqual( + expect.objectContaining({ prompt: "Refactor auth", squad_id: "squad-1" }), + ); + expect(carry).not.toHaveProperty("agent_id"); + }); + // Manual → agent must forward the picked project so the new modal pins to // the same target. Without this the agent panel re-seeds from its own // persisted `lastProjectId` and silently routes the issue to a stale one. diff --git a/packages/views/modals/create-issue.tsx b/packages/views/modals/create-issue.tsx index 8d57f13dd..d134cf673 100644 --- a/packages/views/modals/create-issue.tsx +++ b/packages/views/modals/create-issue.tsx @@ -265,15 +265,20 @@ export function ManualCreatePanel({ // Also forward the picked project so the agent panel pins the new issue // to it; without this the agent panel would fall back to its persisted // `lastProjectId`, silently routing the issue to the wrong project. + // Forward squad picks alongside agent picks so the agent panel honors + // the actor the user already chose — otherwise a squad selection silently + // falls back to the persisted actor / first visible agent on flip. const switchToAgent = () => { const desc = descEditorRef.current?.getMarkdown()?.trim() ?? ""; const prompt = [title.trim(), desc].filter(Boolean).join("\n\n"); setLastMode("agent"); onSwitchMode?.({ prompt, - ...(assigneeType === "agent" && assigneeId + ...(assigneeId && assigneeType === "agent" ? { agent_id: assigneeId } - : {}), + : assigneeId && assigneeType === "squad" + ? { squad_id: assigneeId } + : {}), ...(projectId ? { project_id: projectId } : {}), }); };