fix(tui): la bascule TUI native <-> CLI custom ne déclenche plus de faux conflit de visibilité (#189)
This commit is contained in:
@ -159,7 +159,7 @@ describe("LayoutGrid custom agent CLI (#147)", () => {
|
||||
await waitFor(() =>
|
||||
expect(screen.getByRole("alertdialog", { name: "Confirmer le changement de CLI" })).toBeTruthy(),
|
||||
);
|
||||
fireEvent.click(screen.getByText("Arrêter et relancer"));
|
||||
fireEvent.click(screen.getByText("Basculer"));
|
||||
await waitFor(() =>
|
||||
expect(screen.getByTestId("custom-agent-chat-view")).toBeTruthy(),
|
||||
);
|
||||
@ -264,7 +264,7 @@ describe("LayoutGrid custom agent CLI (#147)", () => {
|
||||
await waitFor(() =>
|
||||
expect(screen.getByRole("alertdialog", { name: "Confirmer le changement de CLI" })).toBeTruthy(),
|
||||
);
|
||||
fireEvent.click(screen.getByText("Arrêter et relancer"));
|
||||
fireEvent.click(screen.getByText("Basculer"));
|
||||
|
||||
await waitFor(() =>
|
||||
expect(closeChat).toHaveBeenCalledWith(expect.stringMatching(/^mock-agent-chat-/)),
|
||||
@ -273,13 +273,26 @@ describe("LayoutGrid custom agent CLI (#147)", () => {
|
||||
await waitFor(() => expect(screen.getByTestId("terminal-view")).toBeTruthy());
|
||||
});
|
||||
|
||||
it("requires confirmation before switching a live native TUI session", async () => {
|
||||
renderGrid(await seeded(structuredProfile));
|
||||
it("switches a live native TUI session to custom CLI without stopping it first (#189)", async () => {
|
||||
const gateways = await seeded(structuredProfile);
|
||||
const agent = gateways.agent as MockAgentGateway;
|
||||
const terminal = gateways.terminal as MockTerminalGateway;
|
||||
const layout = gateways.layout as MockLayoutGateway;
|
||||
const leafId = leaves(await layout.loadLayout("p1"))[0].id;
|
||||
const stopLive = vi.spyOn(agent, "stopLiveAgent");
|
||||
const closeTerminal = vi.spyOn(terminal, "closeTerminal");
|
||||
const launchChat = vi.spyOn(agent, "launchAgentChat");
|
||||
|
||||
renderGrid(gateways);
|
||||
|
||||
await waitFor(() => expect(screen.getByText("CLI custom")).toBeTruthy());
|
||||
await waitFor(() =>
|
||||
expect(screen.getByTestId("terminal-view")).toBeTruthy(),
|
||||
);
|
||||
await waitFor(async () => {
|
||||
const updated = await layout.loadLayout("p1");
|
||||
expect(leaves(updated)[0].session).toMatch(/^mock-agent-session-/);
|
||||
});
|
||||
|
||||
fireEvent.click(screen.getByText("CLI custom"));
|
||||
|
||||
@ -288,10 +301,18 @@ describe("LayoutGrid custom agent CLI (#147)", () => {
|
||||
);
|
||||
expect(screen.getByText(/Une reprise est possible/)).toBeTruthy();
|
||||
|
||||
fireEvent.click(screen.getByText("Arrêter et relancer"));
|
||||
fireEvent.click(screen.getByText("Basculer"));
|
||||
await waitFor(() =>
|
||||
expect(screen.getByTestId("custom-agent-chat-view")).toBeTruthy(),
|
||||
);
|
||||
expect(stopLive).not.toHaveBeenCalled();
|
||||
expect(closeTerminal).not.toHaveBeenCalled();
|
||||
await waitFor(() => expect(launchChat).toHaveBeenCalled());
|
||||
expect(launchChat.mock.calls.at(-1)?.[2]).toMatchObject({ nodeId: leafId });
|
||||
await waitFor(async () => {
|
||||
const updated = await layout.loadLayout("p1");
|
||||
expect(leaves(updated)[0].session).toMatch(/^mock-agent-chat-/);
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps a restored custom CLI mode while the agent/profile catalog is still loading (#149)", async () => {
|
||||
|
||||
@ -701,8 +701,13 @@ function LeafView({
|
||||
await vm.setSession(id, nextSession);
|
||||
}
|
||||
|
||||
async function stopCurrentSessionForSwitch(): Promise<void> {
|
||||
async function prepareSessionForModeSwitch(target: AgentCellMode): Promise<void> {
|
||||
if (!session) return;
|
||||
if (target === "custom") {
|
||||
await setSessionWithInstrumentation("mode-switch", null);
|
||||
refreshLive();
|
||||
return;
|
||||
}
|
||||
if (cellMode === "custom" && agentGateway?.closeAgentChat) {
|
||||
await agentGateway.closeAgentChat(session);
|
||||
} else if (agentId && agentGateway?.stopLiveAgent) {
|
||||
@ -721,7 +726,7 @@ function LeafView({
|
||||
if (!target) return;
|
||||
setBusyNotice(null);
|
||||
try {
|
||||
await stopCurrentSessionForSwitch();
|
||||
await prepareSessionForModeSwitch(target);
|
||||
setCellMode(target);
|
||||
setPendingModeSwitch(null);
|
||||
} catch (err) {
|
||||
@ -1522,16 +1527,16 @@ function LeafView({
|
||||
Changer de CLI agent
|
||||
</h2>
|
||||
<p style={{ margin: "8px 0 0", fontSize: 12, color: "var(--color-content-muted, #9a9a9a)" }}>
|
||||
La session courante va être arrêtée avant de relancer{" "}
|
||||
IdeA va basculer cette cellule vers{" "}
|
||||
{pendingModeSwitch.target === "custom"
|
||||
? "la CLI custom"
|
||||
: "la TUI native"}
|
||||
.
|
||||
{" "}et reprendre la session depuis cette surface.
|
||||
</p>
|
||||
<p style={{ margin: "8px 0 0", fontSize: 12, color: "var(--color-warning, #d49b3a)" }}>
|
||||
{conversationId
|
||||
? "Une reprise est possible si le profil et le backend conservent cette conversation."
|
||||
: "Aucune conversation reprenable n'est enregistrée pour cette cellule; la relance repartira à neuf."}
|
||||
: "Aucune conversation reprenable n'est enregistrée pour cette cellule; la bascule repartira à neuf si le backend ne peut pas reprendre."}
|
||||
</p>
|
||||
<div
|
||||
style={{
|
||||
@ -1567,7 +1572,7 @@ function LeafView({
|
||||
cursor: "pointer",
|
||||
}}
|
||||
>
|
||||
Arrêter et relancer
|
||||
Basculer
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user