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", () => {...@@ -287,7 +287,7 @@ describe("store reducer thread continuity", () => {
287 ]);287 ]);
288 });288 });
289289
290 it("closes the final terminal and hides the drawer", () => {290 it("closes the final terminal and keeps the drawer visibility unchanged", () => {
291 const state = makeState(291 const state = makeState(
292 makeThread({292 makeThread({
293 terminalOpen: true,293 terminalOpen: true,
...@@ -300,14 +300,14 @@ describe("store reducer thread continuity", () => {...@@ -300,14 +300,14 @@ describe("store reducer thread continuity", () => {
300 terminalId: DEFAULT_THREAD_TERMINAL_ID,300 terminalId: DEFAULT_THREAD_TERMINAL_ID,
301 });301 });
302302
303 expect(next.threads[0]?.terminalOpen).toBe(false);303 expect(next.threads[0]?.terminalOpen).toBe(true);
304 expect(next.threads[0]?.terminalIds).toEqual([DEFAULT_THREAD_TERMINAL_ID]);304 expect(next.threads[0]?.terminalIds).toEqual([`${DEFAULT_THREAD_TERMINAL_ID}-next`]);
305 expect(next.threads[0]?.runningTerminalIds).toEqual([]);305 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`);
307 expect(next.threads[0]?.terminalGroups).toEqual([307 expect(next.threads[0]?.terminalGroups).toEqual([
308 {308 {
309 id: `group-${DEFAULT_THREAD_TERMINAL_ID}`,309 id: `group-${DEFAULT_THREAD_TERMINAL_ID}-next`,
310 terminalIds: [DEFAULT_THREAD_TERMINAL_ID],310 terminalIds: [`${DEFAULT_THREAD_TERMINAL_ID}-next`],
311 },311 },
312 ]);312 ]);
313 });313 });
apps/web/src/store.ts+14-6
...@@ -164,6 +164,13 @@ function fallbackGroupId(terminalId: string): string {...@@ -164,6 +164,13 @@ function fallbackGroupId(terminalId: string): string {
164 return `group-${terminalId}`;164 return `group-${terminalId}`;
165}165}
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
167function assignUniqueGroupId(groupId: string, usedGroupIds: Set<string>): string {174function assignUniqueGroupId(groupId: string, usedGroupIds: Set<string>): string {
168 if (!usedGroupIds.has(groupId)) {175 if (!usedGroupIds.has(groupId)) {
169 usedGroupIds.add(groupId);176 usedGroupIds.add(groupId);
...@@ -269,19 +276,20 @@ function closeThreadTerminal(thread: Thread, terminalId: string): Thread {...@@ -269,19 +276,20 @@ function closeThreadTerminal(thread: Thread, terminalId: string): Thread {
269276
270 const remainingTerminalIds = thread.terminalIds.filter((id) => id !== terminalId);277 const remainingTerminalIds = thread.terminalIds.filter((id) => id !== terminalId);
271 if (remainingTerminalIds.length === 0) {278 if (remainingTerminalIds.length === 0) {
279 const nextTerminalId = replacementTerminalId(terminalId);
280 const nextTerminalGroupId = fallbackGroupId(nextTerminalId);
272 return normalizeThreadTerminals({281 return normalizeThreadTerminals({
273 ...thread,282 ...thread,
274 terminalOpen: false,283 terminalIds: [nextTerminalId],
275 terminalIds: [DEFAULT_THREAD_TERMINAL_ID],
276 runningTerminalIds: [],284 runningTerminalIds: [],
277 activeTerminalId: DEFAULT_THREAD_TERMINAL_ID,285 activeTerminalId: nextTerminalId,
278 terminalGroups: [286 terminalGroups: [
279 {287 {
280 id: fallbackGroupId(DEFAULT_THREAD_TERMINAL_ID),288 id: nextTerminalGroupId,
281 terminalIds: [DEFAULT_THREAD_TERMINAL_ID],289 terminalIds: [nextTerminalId],
282 },290 },
283 ],291 ],
284 activeTerminalGroupId: fallbackGroupId(DEFAULT_THREAD_TERMINAL_ID),292 activeTerminalGroupId: nextTerminalGroupId,
285 });293 });
286 }294 }
287295