155 lines
9.2 KiB
Markdown
155 lines
9.2 KiB
Markdown
# Task: Separate AI Design summary from chat messages
|
|
|
|
## Identity
|
|
|
|
- Task ID: 20260904-design-summary-separation-9c4e7a21
|
|
- Mode: Feature
|
|
- Branch: codex/20260904-design-summary-separation-9c4e7a21-design-summary-separation
|
|
- Worktree: D:\Datas\OthersProjects\.codex-worktrees\makelore\20260904-design-summary-separation-9c4e7a21
|
|
- Base commit: 945b40de11efde02fadb7ec6721de8c0b7a3aa85
|
|
- Owner: codex-root
|
|
- Status: Ready for Integration
|
|
|
|
## Scope
|
|
|
|
- Separate in-progress AI Design reasoning from committed conversation messages in
|
|
the ImageCanvas Renderer. Raw assistant stream text must not appear as a finished
|
|
chat bubble; the UI should show an explicit, non-content progress state until the
|
|
canonical turn arrives.
|
|
- Close the supported duplicate-stream path caused by overlapping event-source opens
|
|
and repeated/out-of-order `chunkIndex` delivery.
|
|
- Project a newly submitted chat command into the conversation immediately, before the
|
|
server returns the canonical turn. Keep the provisional message visually honest,
|
|
replace it with the canonical turn without duplication, and restore the draft after
|
|
a definitive failure.
|
|
- Add focused Renderer and Store regression tests. Do not change Works Square server,
|
|
Electron Main DTO/API, Current Specification authority, Quote/generation, Plugin
|
|
navigation, packaging, publication, or the three foreign root task records.
|
|
|
|
## Intent And Constraints
|
|
|
|
- The screenshot proves that transient stream content is visually indistinguishable
|
|
from an assistant reply and that chunks are duplicated. A progress draft is not a
|
|
semantic turn and must not be presented as one.
|
|
- Keep the final persisted assistant question visible in the conversation after the
|
|
command settles. Do not parse model prose to guess where a summary ends or a
|
|
question begins.
|
|
- Preserve stable operation identity and transport-unknown state. A temporarily
|
|
uncertain accepted command may retain its internal stream state, but unfinished
|
|
prose remains hidden behind an honest status label.
|
|
- Preserve ADR-007: Current Specification remains the semantic authority and the
|
|
right-side “AI 听懂的想法” remains its secondary projection.
|
|
- Keep Chinese-only copy, reduced-motion behavior, at least 40 px interactive targets,
|
|
and the current responsive single-mount behavior.
|
|
- Do not create a second chat state machine: the existing pending operation is the
|
|
provisional message identity, while only the returned Workspace turn is canonical.
|
|
|
|
## Project Context Loaded
|
|
|
|
- Concurrent Task Gate: passed in an isolated managed worktree because root `main`
|
|
remains owned by integration task `20260904-integrate-guided-design-6a3f9c82` and
|
|
contains three explicitly preserved foreign untracked task records.
|
|
- Planning Gate: passed after reading the active task, startup memory set, integrated
|
|
state, ADR-007, system overview, business rules, success criteria, evidence index,
|
|
and relevant peer scopes.
|
|
- Relevant peers: the old Enter-only E2E task owns only one historical test path; the
|
|
undefined August assessment task has no implementation scope. Neither semantically
|
|
conflicts with this isolated current-frontier ImageCanvas change. Plugin-navigation
|
|
tasks are in separate worktrees and outside scope.
|
|
- `project-positioning.md` and top-level project success remain placeholders; concrete
|
|
authority comes from ADR-007 and populated current-state, architecture, domain, and
|
|
prior Design task records.
|
|
- Likely files: `src/pages/ImageCanvas/DesignConversationPane.tsx`,
|
|
`src/stores/image-workspace.ts`, `tests/unit/image-canvas-page.test.tsx`, and
|
|
`tests/unit/image-workspace-store.test.ts`.
|
|
- Gate result: Passed.
|
|
|
|
## Outcome
|
|
|
|
- A chat command now appears in the conversation immediately from its existing
|
|
`PendingDesignOperation`, before the server returns the canonical Workspace turn.
|
|
The provisional user bubble carries a small `发送中` state, changes to `正在确认`
|
|
for an unknown accepted outcome, and is filtered to the active Workspace.
|
|
- While that exact draft is projected as a provisional bubble, the composer looks
|
|
cleared without deleting the stored draft. Canonical success atomically replaces
|
|
the provisional bubble with the persisted turn; definitive failure removes the
|
|
pending projection and naturally restores the original draft for correction/retry.
|
|
- First-use guidance is hidden as soon as the first provisional user message exists.
|
|
Other in-flight Design input commands retain the existing composer lock, so the UX
|
|
change does not introduce concurrent reducer writes.
|
|
- `DesignConversationPane` no longer renders raw `assistantStreams` prose as an
|
|
assistant chat bubble. It renders one compact `role=status` surface that explicitly
|
|
says the AI is organizing the idea and that the content is not a new reply. A
|
|
transport-unknown operation instead says the existing result is being confirmed and
|
|
must not be resent.
|
|
- Final canonical `turn.assistantMessage` content remains in the ordinary conversation;
|
|
the implementation does not parse or classify model prose.
|
|
- Event connection startup now has a generation fence. An open that resolves after a
|
|
disconnect/replacement closes itself, so React remounts cannot leave two live sources
|
|
consuming the same stream. A failed open releases the pending connection identity so
|
|
a later retry remains possible.
|
|
- Assistant `chunkIndex` is now consumed as the ordering/deduplication contract;
|
|
replayed or older chunks do not append duplicate text. Chunk progress is cleared with
|
|
successful/definitive settlement and Workspace reset/switch/delete.
|
|
- The root `main` worktree and its three foreign untracked task records were not
|
|
modified.
|
|
|
|
## Verification
|
|
|
|
- New optimistic-message red baseline: Store publication passed, while the Renderer
|
|
regression failed because no `发送中` message existed, the first-use prompt remained,
|
|
and the composer still showed the submitted draft. After the fix, the two focused
|
|
files pass `27/27`, including submitting → unknown → canonical replacement.
|
|
- Adjacent ImageCanvas, Store, Fine Tune, youth summary/projection/copy tests now pass
|
|
`6 files / 51 tests`.
|
|
- Follow-up TypeScript `tsc --noEmit`, changed-file ESLint, and production
|
|
Renderer/Main/Preload/utility Vite build pass. Build output contains only the
|
|
existing browserslist, dynamic-import, and large-chunk warnings.
|
|
- Electron/Playwright AI Design checks both pass individually: Prompt Museum media
|
|
isolation passed in the two-test run; the conversation/adjustment/Quote/Task flow
|
|
initially timed out at the pre-Design auth-fixture readiness gate, then passed `1/1`
|
|
in isolation in 1.8 seconds. The timeout occurred before this feature path and is
|
|
not recorded as product success evidence for the new provisional state.
|
|
- Red baseline: three new regressions failed against the original implementation—raw
|
|
unfinished prose had no progress role, an obsolete concurrent EventSource was not
|
|
closed, and replaying chunk index `0` produced duplicated text. A fourth targeted red
|
|
test caught and prevented a retry regression introduced by the first connection
|
|
fence implementation.
|
|
- Focused conversation/store tests: `25 passed`.
|
|
- Adjacent ImageCanvas, Store, Fine Tune, youth summary/projection/copy tests:
|
|
`6 files / 49 passed`.
|
|
- TypeScript `tsc --noEmit`: passed.
|
|
- Changed-file ESLint: passed.
|
|
- Production Renderer/Main/Preload/utility Vite build: passed; only existing
|
|
browserslist, dynamic-import, and chunk-size warnings were emitted.
|
|
- Electron/Playwright AI Design V2 flow: `2 passed`, covering desktop/mobile layout,
|
|
conversation, optional adjustments, Quote, and generation confirmation.
|
|
- `git diff --check`: passed before task-document completion.
|
|
|
|
## Follow-ups
|
|
|
|
- Integrate the completed source commit onto client `main` after the existing root
|
|
integration owner is safely released or explicitly recovered. Do not force-release
|
|
it or modify its three adopted foreign task records without separate authority.
|
|
|
|
## Promotion Candidates
|
|
|
|
- Target: `.project-docs/30-worklog/current-state.md`, canonical AI Design UX wording,
|
|
and the AI Design stream reconciliation rule in architecture/domain memory.
|
|
- Proposal: record that `design.assistant.delta` is unfinished progress, never a
|
|
committed conversation turn. Renderer may show an explicit progress/uncertainty
|
|
status but must not render its raw prose as a chat reply; only canonical persisted
|
|
turns enter the timeline. A locally submitted chat command may appear immediately as
|
|
a clearly provisional user bubble by projecting its existing pending operation; it
|
|
must disappear when the canonical turn arrives and must not become a second semantic
|
|
message store. Concurrent/replayed stream delivery must converge by connection
|
|
generation and `chunkIndex`.
|
|
- Evidence: the user screenshot, four red-before/green-after regressions, 49 adjacent
|
|
tests, typecheck, scoped lint, production build, and 2/2 Electron E2E.
|
|
- Future impact: later streaming polish must preserve the distinction between transient
|
|
reasoning/progress, authoritative Specification projection, and committed dialogue.
|
|
- Semantic conflicts: none; this sharpens the conversation-primary behavior already
|
|
integrated while preserving ADR-007.
|
|
- Human confirmation: the user explicitly identified the chat-bubble presentation as
|
|
misleading; no additional product-direction decision is required.
|