From 24480683697349fc014767b61e4e03e67b511577 Mon Sep 17 00:00:00 2001 From: HuanLinOTO Date: Wed, 9 Sep 2026 13:15:49 +0800 Subject: [PATCH] =?UTF-8?q?docs(plans):=20=E4=BF=AE=E6=AD=A3=E8=AE=A1?= =?UTF-8?q?=E5=88=92=20Task=205=20=E6=B5=8B=E8=AF=95=EF=BC=88stub=20?= =?UTF-8?q?=E6=8F=8F=E8=BF=B0=E7=AC=A6=E3=80=81UI=20tab=20=E6=96=AD?= =?UTF-8?q?=E8=A8=80=E3=80=81=E6=96=87=E6=9C=AC=E8=AE=A1=E6=95=B0=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2026-09-09-terminal-wait-banner-plan.md | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/docs/plans/2026-09-09-terminal-wait-banner-plan.md b/docs/plans/2026-09-09-terminal-wait-banner-plan.md index 57160d4..2fc03d9 100644 --- a/docs/plans/2026-09-09-terminal-wait-banner-plan.md +++ b/docs/plans/2026-09-09-terminal-wait-banner-plan.md @@ -769,7 +769,7 @@ import { setupReactAct } from './test-utils.ts' setupReactAct() import { Sidebar } from '../src/client/Sidebar.tsx' -import { createSidebarStore, type SidebarStore } from '../src/client/state.ts' +import { createSidebarStore, openTabInActivePane } from '../src/client/state.ts' import { createBetterSidebarService, type BetterSidebarService } from '../src/client/service.ts' /** jsdom has no WebSocket; the agent-terminals push effect constructs one on mount. */ @@ -803,6 +803,13 @@ function mountSidebar(): { container: HTMLDivElement; store: ReturnType 'Terminal', + component: () => null, + }) const localeSnapshot = { active: 'en' } const sessionsSnapshot = { current: sessionId, @@ -858,12 +865,18 @@ describe('agent terminal wait badge (push → state → tab pill)', () => { expect(container.textContent).not.toContain('⏳') }) - it('never shows ⏳ on UI-owned terminal tabs', () => { - const { container } = mountSidebar() - // A UI terminal tab (id NOT agent:) with a same-named wait never badges — - // the lookup keys on the agent uuid only. - act(() => { feedsSocket().onmessage?.({ data: JSON.stringify([{ uuid: 'u2', title: 'ui', command: '', exited: false, waiting: { needle: 'N', since: 1 } }]) }) }) - act(() => { feedsSocket().onmessage?.({ data: JSON.stringify([]) }) }) + it('shows ⏳ only on agent tabs, never on UI-owned terminal tabs', () => { + const { container, store } = mountSidebar() + // A UI-owned terminal tab (id NOT agent:) lives in the strip too; the + // badge lookup keys on the agent uuid, so it never badges. + act(() => { store.reduce(s => openTabInActivePane(s, { id: 'terminal:manual-1', type: 'terminal', title: 'UI terminal' })) }) + const terminal = { uuid: 'u1', title: 'dev server', command: '', exited: false } + act(() => { feedsSocket().onmessage?.({ data: JSON.stringify([{ ...terminal, waiting: { needle: 'READY_1', since: 1 } }]) }) }) + // Exactly ONE hourglass: the agent tab. (Counted from textContent — CSS + // module class names are not stable under the test transform.) + expect((container.textContent.match(/⏳/g) ?? []).length).toBe(1) + // The wait resolved → the pill disappears entirely. + act(() => { feedsSocket().onmessage?.({ data: JSON.stringify([terminal]) }) }) expect(container.textContent).not.toContain('⏳') }) })