authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-02-15 00:07:10-08:00
committergravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-02-15 00:07:10-08:00
log85fe41bad0f6e3ab83de6b83f9635482daee79c4
tree99858fcbeffcd3e6df67ec6aeb5eb6d64aece304
parent0c26396f79b94f8212d3c62d0514dc4188866ee7

Fix terminal close behavior without toggling drawer

Co-authored-by: codex <codex@users.noreply.github.com>

2 files changed, 20 insertions(+), 12 deletions(-)

apps/web/src/store.test.ts+6-6
......@@ -287,7 +287,7 @@ describe("store reducer thread continuity", () => {
287287 ]);
288288 });
289289
290 it("closes the final terminal and hides the drawer", () => {
290 it("closes the final terminal and keeps the drawer visibility unchanged", () => {
291291 const state = makeState(
292292 makeThread({
293293 terminalOpen: true,
......@@ -300,14 +300,14 @@ describe("store reducer thread continuity", () => {
300300 terminalId: DEFAULT_THREAD_TERMINAL_ID,
301301 });
302302
303 expect(next.threads[0]?.terminalOpen).toBe(false);
304 expect(next.threads[0]?.terminalIds).toEqual([DEFAULT_THREAD_TERMINAL_ID]);
303 expect(next.threads[0]?.terminalOpen).toBe(true);
304 expect(next.threads[0]?.terminalIds).toEqual([`${DEFAULT_THREAD_TERMINAL_ID}-next`]);
305305 expect(next.threads[0]?.runningTerminalIds).toEqual([]);
306 expect(next.threads[0]?.activeTerminalId).toBe(DEFAULT_THREAD_TERMINAL_ID);
306 expect(next.threads[0]?.activeTerminalId).toBe(`${DEFAULT_THREAD_TERMINAL_ID}-next`);
307307 expect(next.threads[0]?.terminalGroups).toEqual([
308308 {
309 id: `group-${DEFAULT_THREAD_TERMINAL_ID}`,
310 terminalIds: [DEFAULT_THREAD_TERMINAL_ID],
309 id: `group-${DEFAULT_THREAD_TERMINAL_ID}-next`,
310 terminalIds: [`${DEFAULT_THREAD_TERMINAL_ID}-next`],
311311 },
312312 ]);
313313 });
apps/web/src/store.ts+14-6
......@@ -164,6 +164,13 @@ function fallbackGroupId(terminalId: string): string {
164164 return `group-${terminalId}`;
165165}
166166
167function replacementTerminalId(closedTerminalId: string): string {
168 const normalizedId = closedTerminalId.trim();
169 return normalizedId === DEFAULT_THREAD_TERMINAL_ID
170 ? `${DEFAULT_THREAD_TERMINAL_ID}-next`
171 : DEFAULT_THREAD_TERMINAL_ID;
172}
173
167174function assignUniqueGroupId(groupId: string, usedGroupIds: Set<string>): string {
168175 if (!usedGroupIds.has(groupId)) {
169176 usedGroupIds.add(groupId);
......@@ -269,19 +276,20 @@ function closeThreadTerminal(thread: Thread, terminalId: string): Thread {
269276
270277 const remainingTerminalIds = thread.terminalIds.filter((id) => id !== terminalId);
271278 if (remainingTerminalIds.length === 0) {
279 const nextTerminalId = replacementTerminalId(terminalId);
280 const nextTerminalGroupId = fallbackGroupId(nextTerminalId);
272281 return normalizeThreadTerminals({
273282 ...thread,
274 terminalOpen: false,
275 terminalIds: [DEFAULT_THREAD_TERMINAL_ID],
283 terminalIds: [nextTerminalId],
276284 runningTerminalIds: [],
277 activeTerminalId: DEFAULT_THREAD_TERMINAL_ID,
285 activeTerminalId: nextTerminalId,
278286 terminalGroups: [
279287 {
280 id: fallbackGroupId(DEFAULT_THREAD_TERMINAL_ID),
281 terminalIds: [DEFAULT_THREAD_TERMINAL_ID],
288 id: nextTerminalGroupId,
289 terminalIds: [nextTerminalId],
282290 },
283291 ],
284 activeTerminalGroupId: fallbackGroupId(DEFAULT_THREAD_TERMINAL_ID),
292 activeTerminalGroupId: nextTerminalGroupId,
285293 });
286294 }
287295