7.0 KiB
spec, created, status
| spec | created | status |
|---|---|---|
| docs/specs/ui/requirements/quick-chat-idle-dot.md | 2026-08-23 | implemented |
Implementation Plan: Quick Chat Activity Indicators
Overview
Extend the existing completion-only Quick Chat dot into a derived running or finished activity state. First add pure selectors, then update tabs and entry icons, and finally cover the real lifecycle in Playwright.
No backend contract changes are necessary. The frontend already receives session state, foreground activity, preparation progress, and completion events.
Frontend
Activity selectors
- Add
apps/web/lib/state/slices/ui/quick-chat-activity-selectors.ts. - Export
QuickChatActivityStateas"running" | "finished" | null. - Extract the shared live-work predicate to
apps/web/lib/session-working.ts. Use it fromderiveSessionFlags()and the Quick Chat selector. - Add
selectQuickChatSessionIsWorking(state, sessionId). IncludeprepareProgress.bySessionId[sessionId]?.status === "preparing". - Add
selectQuickChatActivity(state, workspaceId). Returnnullwhile the dialog is open or the workspace is absent. - For a closed dialog, return
"running"when any workspace conversation is working. Otherwise, return"finished"when the workspace has an unseen marker. - Keep
quick-chat-unseen-selectors.tsfor the existing marker-level tests and lifecycle helpers.
Tab status
- Update
apps/web/components/quick-chat/quick-chat-modal.tsxwith a conversation-tab wrapper that readsselectQuickChatSessionIsWorkingfor one session. - Add an
isWorkingprop toQuickChatTabIteminquick-chat-tab-item.tsx. - Render
GridSpinnerbefore the tab name whileisWorkingis true. - Do not add a spinner to setup tabs or
QuickTerminalTabItem.
Entry activity bubble
- Add
apps/web/components/quick-chat/quick-chat-activity-indicator.tsxfor the shared bubble. - Use
bg-blue-500forrunningandbg-emerald-500forfinished. - Add
data-testid="quick-chat-activity-indicator",data-state, anddata-legacy-testid="quick-chat-unseen-dot"during the selector migration. - Add
apps/web/components/quick-chat/use-quick-chat-activity.tsto select the aggregate state and resolve the accessible button label. - Use the shared hook and indicator in these entry points:
apps/web/components/app-sidebar/app-sidebar-primary-nav.tsxapps/web/components/app-sidebar/app-sidebar-new-task-item.tsxapps/web/components/kanban/kanban-header.tsxapps/web/components/kanban/kanban-header-mobile.tsxapps/web/components/task/mobile/quick-chat-sheet-button.tsx
- Replace the boolean
dotprops inAppSidebarNavItemandRowActionButtonwith the typed activity state. - Add
sidebar:quickChatRunningin English, Portuguese, Simplified Chinese, Traditional Chinese, and the generated pseudo-locale. Keepsidebar:quickChatUnseenfor the finished label.
Mobile parity
This change modifies status content inside existing controls. It does not change composition, navigation, scrolling, or touch behavior.
The nearest mobile exemplars are the current mobile Quick Chat idle dot and the status dot in session-mobile-bottom-nav.tsx. Keep the existing mobile header and task-switcher entry points, touch targets, and dismissal behavior.
Tests
- What: The shared working predicate includes
STARTING,RUNNING, and background work. File:apps/web/lib/session-working.test.ts. How: Use a table-driven unit test for every session state and foreground activity value. - What: Quick Chat working detection also includes environment preparation.
File:
apps/web/lib/state/slices/ui/quick-chat-activity-selectors.test.ts. How: Use selector tests with two workspaces and two sessions. - What: Running has priority over finished, the dialog suppresses the bubble, and seen results remain clear after close.
File:
apps/web/lib/state/slices/ui/quick-chat-activity-selectors.test.ts. How: Use pure aggregate-state tests. - What: A conversation tab shows the grid spinner only while its session works.
Files:
apps/web/components/quick-chat/quick-chat-tab-item.test.tsxandquick-chat-modal.test.tsx. How: Test the tab prop and the modal mapping for server-backed, setup, and terminal tabs. - What: Blue and emerald map to the correct semantic state.
File:
apps/web/components/quick-chat/quick-chat-activity-indicator.test.tsx. How: Use rendered class anddata-stateassertions. - What: Every desktop, tablet, and mobile Quick Chat entry uses the aggregate state and accessible label. Files: Existing sidebar, kanban-header, and mobile task-switcher component tests. How: Use store-backed rendered tests for no activity, running, and finished.
E2E Tests
- Scenario: A real quick-chat turn starts, the tab shows a grid spinner, the dialog closes, and the entry shows the blue state.
File:
apps/web/e2e/tests/chat/quick-chat-idle-dot.spec.ts. What to verify: Tab spinner visibility and the desktop sidebardata-state="running"value. - Scenario: The last agent settles while the dialog is closed.
File:
apps/web/e2e/tests/chat/quick-chat-idle-dot.spec.ts. What to verify: The same bubble changes todata-state="finished", then disappears after the dialog opens. - Scenario: The same running-to-finished lifecycle occurs at tablet width.
File:
apps/web/e2e/tests/chat/quick-chat-idle-dot.spec.ts. What to verify: The tablet header uses the same state sequence. - Scenario: The mobile header and task-switcher entry expose the same activity state.
File:
apps/web/e2e/tests/chat/mobile-quick-chat-idle-dot.spec.ts. What to verify: Touch entry, close behavior, blue running state, emerald finished state, and clear-on-open behavior.
The mobile Playwright run is also the focused rendered mobile check. It keeps the existing full-height dialog and touch paths unchanged.
Verification Results
- Focused frontend tests passed: 10 files, 107 tests.
pnpm --filter @kandev/web lintpassed with zero warnings.pnpm --filter @kandev/web run typecheckpassed.pnpm --filter @kandev/web run i18n:checkpassed; all supported catalogs are complete and pseudo is in sync.pnpm --filter @kandev/web run i18n:ratchetpassed with zero new violations.pnpm --filter @kandev/web run lint:e2e-sleepspassed.- Desktop and tablet Playwright coverage passed: 2 tests.
- Mobile Playwright coverage passed: 2 tests.
- The full
i18n:zh-hantgenerator remains blocked by pre-existing residual simplified-Chinese keys inagents:dynamicProfileSettings; the targetedsidebarconversion completed successfully for this change.
Implementation Waves And Parallel Candidates
The tasks run sequentially because the UI and E2E work depend on the activity selectors.
Open Questions
None. The plan uses blue for running and emerald for finished to match existing Kandev status-dot semantics.