fix: stabilize ai design history switching

This commit is contained in:
2026-08-19 10:31:36 +08:00
parent abece81fdb
commit bf0b805d9f
14 changed files with 573 additions and 48 deletions

View File

@@ -0,0 +1,49 @@
# Task: Fix AI design history loading stall
## Identity
- Task ID: 20260819-history-load-stall-a92d
- Mode: Feature
- Branch: codex/20260819-history-load-stall-a92d-history-load-stall
- Worktree: D:\mk-history-load-stall-a92d
- Base commit: abece81fdb178711d4dcbe1f87b987f54d71d6dd
- Owner: codex-root
- Status: Completed
## Scope
- Replace full-history AI Design conversation loading with a cursor-paginated latest-message flow.
- Ensure workspace history becomes visible before generation-task reconciliation completes.
- Make rapid conversation switching safe when an event-stream connection is still pending.
- Update the local and Works Square adapters, shared boundary, main-process route, renderer store/canvas, and focused tests as needed.
## Intent And Constraints
- Initial conversation reads return the newest 10 message records; scrolling upward requests older pages and preserves viewport position.
- Do not retain or transmit an unbounded message history through the normal conversation API, mutation payloads, or snapshots.
- Preserve the existing workspace/conversation identity checks and do not apply stale responses after a switch.
- A pending connection attempt is treated as owned until it settles or is explicitly aborted; returning A -> B -> A must not create duplicate pending streams for A.
- Server and desktop client contracts must remain explicit and bounded; page cursor contents are opaque to the renderer.
## Outcome
- The renderer shows a selected Conversation as soon as its Workspace response arrives; delayed or failed generation-task reconciliation can no longer keep the history view on its loading state.
- Conversation history is cursor-paginated end to end: the initial page is the newest 10 messages, scrolling upward loads one older page at a time, de-duplicates stable message IDs, and retains viewport position.
- Local and Works Square adapters expose the same page metadata. The Main route forwards the opaque cursor without interpreting it.
- Rapid A → B → A switching reuses an in-flight A event-stream attempt instead of opening another non-cancellable request. Renderer disconnection while Main is still opening a relay now closes the eventual subscription, and an upstream WebSocket open is bounded by a 10-second timeout.
## Verification
- `pnpm test` — 183 files and 2167 tests passed.
- `pnpm exec vitest run tests/unit/image-workspace-api.test.ts tests/unit/image-workspace-store.test.ts tests/unit/local-image-workspace.test.ts tests/unit/works-square-design-workspace.test.ts tests/unit/image-workspace-route.test.ts tests/unit/image-canvas-page.test.tsx --reporter=dot` — 154 passed. The Canvas suite still reports three pre-existing React `act(...)` warnings in its stale-auth test.
- `pnpm run typecheck` — passed.
- `pnpm exec eslint electron/api/routes/image-workspace.ts electron/image-workspace/local-workspace.ts electron/image-workspace/module.ts electron/image-workspace/works-square-workspace.ts shared/image-workspace.ts src/lib/image-workspace.ts src/pages/ImageCanvas/index.tsx src/stores/image-workspace.ts tests/unit/image-workspace-route.test.ts tests/unit/image-workspace-store.test.ts tests/unit/local-image-workspace.test.ts tests/unit/works-square-design-workspace.test.ts tests/unit/image-workspace-api.test.ts` — passed.
- `git diff --check` — passed.
## Follow-ups
- Main-branch promotion is pending release of the repository-wide integration lock held by task `20260819-merge-performance-package-6e5a`.
## Promotion Candidates
- None recorded.