diff --git a/docs/plans/2026-09-09-terminal-wait-banner-design.md b/docs/plans/2026-09-09-terminal-wait-banner-design.md index d218705..012234a 100644 --- a/docs/plans/2026-09-09-terminal-wait-banner-design.md +++ b/docs/plans/2026-09-09-terminal-wait-banner-design.md @@ -140,5 +140,13 @@ needle 出现 / 超时 / 终端退出。等待期间用户在侧边栏看不到 贡献字符数(本地化句子包裹 needle,整体长度断言与语言相关,原计划内部矛盾)。 - **新测试的 localStorage 兜底**:Node 26 + jsdom 29 组合下测试环境可能无全局 `localStorage`(上游 `bottom-auto-terminal.spec.tsx` 在同环境即失败,属已知 - win32/环境非回归类);新 spec 的 afterEach 加 `typeof localStorage` 守卫, + win32/环境非回归类);新 spec 的 afterEach 加守卫 + try/catch(jsdom opaque + origin 下 localStorage 可以是 throwing accessor,裸 typeof 也会炸), 上游测试一律未动。 +- **已知限制:跨会话 pinned 虚拟 tab 收不到实时 banner/⏳**(Copilot review + 指出):等待状态 feed 按 viewer 会话订阅(`/sidebar/ws/agent-terminals` 按 + 当前 sessionId 连接),钉到其他会话的 pinned 虚拟 agent tab + (`pinned::agent:`)在其 home 会话非当前会话时收不到 + 实时等待状态。修复需跨会话 wait feed 多路复用(连 home 会话推送或聚合 + 推送),超出本特性范围,留待后续设计;跳过 API 按 uuid 全局寻址,跨会话 + 跳过本身可达。 diff --git a/tests/agent-wait-badge.spec.tsx b/tests/agent-wait-badge.spec.tsx index a92337a..5dd4cf2 100644 --- a/tests/agent-wait-badge.spec.tsx +++ b/tests/agent-wait-badge.spec.tsx @@ -80,10 +80,15 @@ function mountSidebar(): { container: HTMLDivElement; store: ReturnType { document.body.innerHTML = '' // Belt and braces (same as bottom-auto-terminal): drop any persisted layout - // a pending 200ms debounce write left behind between tests. Guarded — some - // node/jsdom combos (node >=22 without --localstorage-file) expose no - // working localStorage and a bare access would throw in the hook. - if (typeof localStorage !== 'undefined') localStorage.clear() + // a pending 200ms debounce write left behind between tests. Fully guarded — + // some node/jsdom combos expose no working localStorage, and an opaque + // origin can define it as a THROWING accessor, so even `typeof` can throw; + // the try/catch keeps the cleanup hook itself failure-proof. + try { + if (typeof localStorage !== 'undefined') localStorage.clear() + } catch { + // Opaque origin / no storage: nothing persisted to clear. + } vi.unstubAllGlobals() }) diff --git a/tests/tools.spec.ts b/tests/tools.spec.ts index 197f5b4..c83f004 100644 --- a/tests/tools.spec.ts +++ b/tests/tools.spec.ts @@ -203,9 +203,10 @@ describe('agent terminal tools', () => { it('terminal_wait_for returns skipped (schema-valid) when the registry reports a user skip', async () => { const { captured, registry } = mount() const tool = toolOf(captured, 'terminal_wait_for') - registry.create('s1', 'skipper', '') + // Use the uuid the registry actually minted — no coupling to its id scheme. + const uuid = registry.create('s1', 'skipper', '') registry.nextWaitResult = { kind: 'skipped' } - const value = await tool.execute({ uuid: 'uuid-1', needle: 'BUILD_OK', timeout_ms: 1000 }, exec('s1')) + const value = await tool.execute({ uuid, needle: 'BUILD_OK', timeout_ms: 1000 }, exec('s1')) expect(value).toEqual({ kind: 'skipped', needle: 'BUILD_OK' }) expect(validateJsonSchemaValue(tool.output.schema, value, 'value')).toEqual([]) })