fix(create-issue): forward squad picks across manual→agent switch

Manual mode → agent mode previously only carried `agent_id`, so picking
a squad and then flipping to agent silently fell back to the persisted
actor / first visible agent and lost the user's choice. Carry `squad_id`
on the same branch so the agent panel honors the squad pick.

Adds a sibling test alongside the existing project-carry case.

Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
Jiang Bohan
2026-05-13 22:26:42 +08:00
parent 74e3d8b18c
commit 6f07e2d7f2
2 changed files with 44 additions and 4 deletions

View File

@@ -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(
<ManualCreatePanel
onClose={vi.fn()}
onSwitchMode={onSwitchMode}
isExpanded={false}
setIsExpanded={vi.fn()}
backlogHintIssueId={null}
setBacklogHintIssueId={vi.fn()}
/>,
);
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.

View File

@@ -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 } : {}),
});
};